面试过程:
1.SpringCloud的工作原理
SpringCloud由以下几个核心组件构成
Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从而知道其他服务在哪里。
Ribbon:服务间发起请求的时候,基于Ribbon做负载均衡,从一个服务的多台机器中选择一台。
Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求。
Hystrix:发起请求是通过Hystrix的线程池来走的,不同的服务走不同线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题。
Zuul:如果前端、移动端要调用后端系统,统一从Zuul网关进入,由于Zull网关转发请求给对应的服务。
2.用什么组件发请求
在SpringCloud中使用Feign,我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。
3.注册中心心跳是几秒
1、Eureka的客户端默认每隔30s会向Eureka服务端更新实例,注册中心也会定时进行检查,发现某个实例默认90S内没有再收到心跳,会注销此实例,这些时间间隔是可配置的。
2、不过注册中心还有一个保护模式(服务端在短时间内丢失过多客户端的时候,会进入保护模式),在这个保护模式下,他会认为是网络问题,不会注销任何过期的实例。
4.消费者是如何发现服务提供者的
a. 当一个服务实例启动,会将它的ip地址等信息注册到Eureka;
b. 当a服务调用b服务,a服务会通过Ribbon检查本地是否有bf服务实例信息的缓存;
c. Ribbon会定期从Eureka刷新本地缓存。
5.多个消费者调用同一接口,Eruka默认的分配方式是什么
a.RoundRobinRule:轮询策略, Ribbon以轮询的方式选择服务器,这个是默认值。所以示例中所启动的两个服务会被循环访问;
b.RandomRule:随机选择,也就是说Ribbon会随机从服务器列表中选择一个进行访问;
c.BestAvailableRule:最大可用策略,即先过滤故障服务器后,选择一个当前并发请求数量最小的。
d.WeightedResponseTimeRule:带有加权的轮询策略,对各个服务器响应时间进行加权处理,然后在采用轮询的方式来获取相应的服务器;
e.AvailabilityFilteringRule:可用过滤策略,先过滤出故障的或并发请求大于阈值一部分服务实例,然后再以线性轮询的⽅式从过滤后的实例清单中选出一个;
f.ZoneAvoidanceRule:区域感知策略,先使用主过滤条件(区域负载器,选择最优区域)对所有实例过滤并返回过滤后的实例清单,依次使用次过滤条件列表中的过滤条件对主过滤条件的结果进行过滤,判断最小过滤数(默认1)和最小过滤百分比(默认0),最后对满⾜足条件的服务器则使用RoundRobinRule(轮询⽅方式)选择⼀个服务器实例。
6. 说说常用的springboot注解,及其实现?
a.@Bean:注册Bean
i. 默认使⽤用方法名作为id,可以在后面定义id如@Bean("xx");
ii. 默认为单例。
iii. 可以指定init方法和destroy方法:
1. 对象创建和赋值完成,调用初始化方法;
2. 单实例bean在容器销毁的时候执⾏destroy方法;
3. 多实例bean,容器关闭是不会调用destroy⽅方法。
b. @Scope:Bean作用域
i. 默认为singleton;
ii. 类型:
1. singleton单实例(默认值):ioc容器启动时会调用方法创建对象放到ioc容器中,以后每次获取就是直接从容器中拿实例;
2. prototype多实例:ioc容器启动不会创建对象,每次获取时才会调用方法创建实例;
3. request同一次请求创建一个实例;
4. session同一个session创建一个实例。
c. @Value:给变量赋值
i. 代码:
ii. 方式:
1.基本数字
2. 可以写SpEL(Spring EL表达式):#{}
3. 可以写${},取出配置⽂文件中的值(在运行环境变量里⾯的值)
d. @Autowired:自动装配
i. 默认优先按照类型去容器中找对应的组件:BookService bookService =applicationContext.getBean(BookService.class);
ii. 默认一定要找到,如果没有找则报错。可以使用@Autowired(required = false)标记bean为非必须的。
iii. 如果找到多个相同类型的组件,再根属性名称去容器中查找。
iv. @Qualifier("bookDao2")明确的指定要装配的bean。
v. @Primary:让spring默认装配⾸首选的bean,也可以使⽤@Qualifier()指定要装配的bean。
e. @Profile:环境标识
i. Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能;
ii. @Profile指定组件在哪个环境才能被注册到容器中,默认为"default"@Profile("default")。
iii. 激活方式:
1. 运行时添加虚拟机参数:-Dspring.profiles.active=test
2. 代码方式:
7. spring的事务注解是什么?什么情况下事物才会回滚
a. spring事务实现机制:
b. 事务注解@transactional;
c. 默认情况下,如果在事务中抛出了未检查异常(继承自RuntimeException 的异常)或者 Error,则Spring 将回滚事务。
d. @Transactional 只能⽤到 public 方法才有效:只有@Transactional 注解应⽤用到 public ⽅方法,才能进⾏事务管理。这是因为在使用 Spring AOP 代理时,Spring 在调⽤图 1 中的 TransactionInterceptor 在目标⽅法执行前后进行拦截之前,
DynamicAdvisedInterceptor(CglibAopProxy 的内部类)的 intercept ⽅法或 JdkDynamicAopProxy 的 invoke 方法会间接调
用AbstractFallbackTransactionAttributeSource(Spring 通过这个类获取表 1. @Transactional 注解的事务属性配置属性信息)的 computeTransactionAttribute ⽅法。
8. 说说spring事物的传播性和隔离级别
a. 七个事物传播属性:
1. PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
2. PROPAGATION_SUPPORTS --⽀持当前事务,如果当前没有事务,就以非事务方式执行。
3. PROPAGATION_MANDATORY-- 支持当前事务,如果当前没有事务,就抛出异常。
4. PROPAGATIONREQUIRESNEW-- 新建事务,如果当前存在事务,把当前事务挂起。
5. PROPAGATIONNOTSUPPORTED-- 以非事务方式执行行操作,如果当前存在事务,就把当前事务挂起。
6. PROPAGATION_NEVER -- 以非事务方式执⾏,如果当前存在事务,则抛出异常。
7. PROPAGATIONNESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATIONREQUIRED类似的操作。
b. 五个隔离级别:
1. ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使⽤用数据库默认的事务隔离级别。
2. 另外四个与JDBC的隔离级别相对应。
3. ISOLATIONREADUNCOMMITTED这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻读。
4. ISOLATIONREADCOMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻读。
5. ISOLATIONREPEATABLEREAD这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免不可重复读。
6. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻读。
c. 关键词:
1.脏读(新增或删除):脏读就是指当一个事务正在访问数据,并且对数据进行了修改,⽽而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
2.不不可重复读(修改):是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(解决:只有在修改事务完全提交之后才可以读取数据,则可以避免该问题)
3.幻读(新增或删除):是指当事务不是独立执行时发生的一种现象,例如第⼀个事务对一个表中的数据进⾏了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插⼊一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好像发生了幻觉一样(解决:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题)。