- 1,MyBatis
- 2,MyBatis缓存
- 3,Spring
- 4,SpringMVC
- 5,SpringMVC执行流程
- 6,SpringBoot
- 7,SpringCloud
- 8,说一下你对IOC的理解
- 9,说一个你对AOP的理解
- 10,AOP的应用场景
- 11,AOP的使用以及实现
- 12,如何自定义一个AOP,实现切面
- 13,BeanFactory和ApplicationContext有什么区别
- 14,Spring的Bean懒加载和非懒加载有什么区别
- 15,singleton和protype有什么区别
- 16,Spring支持几种Bean的作用域
- 17,Spring的依赖注入方式及实现有哪几种
- 18,Spring的Bean创建方式及生命周期,Bean的自动装配原理?
- 19,SpringBoot如何配置事务;
- 20,有哪些方式可以注册一个Bean到容器中
- 21,将一个类声明为Spring的Bean的注解有哪些?
- 22,Spring的IOC启动原理
- 23,Spring是如何管理事务的?
- 24,Spring事务的回滚机制
- 25,Spring用到了那些设计模式
- 26,RequestMapping和GetMapping区别?
- 27,SpringMVC怎么样设定重定向和转发的
- 28,SpringMVC如何对时间格式的参数进行格式化?
- 29,SpringMVC常用的注解有哪些?
- 29,如何定义SpringMVC的拦截器
- 30,过滤器和拦截器的区别:
- 31,HandIerInterceptor和HandlerInterceptorAdapter的区别?
- 32,SpringMVC的Controller是单列还是多列,有没有并发安全问题,如何解决?
- 33、SpringBoot有哪些优点?
- 34、SpringBoot如何做全局异常处理?
- 35、SpringBoot如何读取配置文件中的配置项?
- 36、@SpringBootApplication标签的组成
- 37、.SpringBoot是如何整合SpringMVC的?SpringBoot是如何整合DataSource的?
- 38.SpringBoot的启动流程
- 39.SpringBoot和SpringCloud的区别?
- 40、SpringCloud常用组件和作用?
- 41.Eureka心跳和服务剔除机制是什么
- 42.Eureka的服务注册与发现的工作流程
- 43.对于CAP理论,Eureka选择的是AP还是CP?它保证了一致性还是可用性?
- 44.说下Ribbon和Feign的区别呢?
- 45.一个请求过来,在你们的微服务项目中经过哪些流程?
- 46、如何实现Eureka的高可用集群?
- 47、Hystrix的限流有几种方式,有什么区别?
- 48,Hystrix的熔断有几种状态?这几种状态是怎么变换的?
- ,49、服务A使用ribbon调用服务B,Ribbon是如何工作的?
- 50、为什么Feign的接口可以直接注入进来用?
- 51、Ribbon的负载均衡算法有哪些?
- 52、Zuul有哪几类Filter,他们的执行顺序是怎么样的?
- 53. 在Zuul中做登录检查如何实现?
- 54、EurekaClient拉取注册表&心跳续约用到了什么技术来实现?
- 55、Springcloud分布式SpringSecurity项目授权、鉴权流程
- 一、微服务授权认证方式:
- 二、微服务分布式项目采取:
- 二、微服务项目认证授权怎么实现的?
- 四、常见的权限框架有
1,MyBatis
①MyBatis是一个半自动ORM(对象关系映射)持久化框架,
②底层是对JDBC的封装,加载驱动、创建连接、创建statement等繁杂的过程
2,MyBatis缓存
①一级缓存:是指Session缓存(默认开启),作用域默认是一个SqlSession
②二级缓存:是指mapper映射文件或者SqlSessionFactory级别缓存,需要手动开启
3,Spring
①是一个轻量级开源DI,IOC,AOP的容器框架。它有需要衍生产品,比如boot,security,jpa等等
②IOC \ DI :依赖注入的容器
③AOP:面向切面编程 作用:解耦
4,SpringMVC
①SpringMVC是spring基础之上的一个MVC框架,主要处理web开发的路径映射和试图渲染,属于spring框架中WEB层开发的一部分;
5,SpringMVC执行流程
①客户端 > 的请求统一提交到 > 前端控制器(DispatcherServlet)
②前端控制器 > 会将请求交给 > 处理映射器(HandlerMapping) > 匹配该请求的Handler
③前端控制器 > 再次请求 > 处理适配性(HandlerAdapter) > 返回ModelAndView对象
④前端控制器 > 再次 > 视图解析器(ViewResoler) > 返回指定的View
⑤前端控制器 > 对view 进行渲染
⑥前端控制器 > 将页面响应给用户
6,SpringBoot
①作用:简化配置文件,使得项目配置变得简单 部署简单。 为了关注开放微服务后台接口,通过maven方式对spring应用开发进行进一步封装和简化。
7,SpringCloud
①大部分的功能插件都是基于SpringBoot去实现的。SpringBoot更加关注的是全局微服务的整体和管理,相对于管理多个SpirngBoot框架的单体微服务,将多个SpringBoot单个微服务进行整合以及管理;SpringCloud依赖于SpringBoot开发,而SpringBoot可以独立开发;
8,说一下你对IOC的理解
①DI依赖注入:是指将容器赋值创建和维护对象之间的依赖关系,并不是通过对象本身赋值创建完成依赖的
②IOC控制反转:传统是通过new来创建对象,而Spring帮我们解决这个问题,通过Bean属性完成实例化,Bean是交给Spring容器中,控制反转是通过DI依赖注入实现的。
9,说一个你对AOP的理解
①AOP是对OOP的增强模式:面向切面编程,通过预编译的方式和运行期动态代理实现。
②
10,AOP的应用场景
11,AOP的使用以及实现
①一种是基于注解xml配置实现
②Spring的AOP的实现:通过动态代理模式来实现的
③动态代理实现方式
⑴ jdk 动态代理实现 有接口
⑵ cglib 动态代理实现 没有接口
12,如何自定义一个AOP,实现切面
①声明自定义注解(获取切面)
②AOP的实现类:
⑴ @compet注解交给Spring容器管理
⑵ 声明Bean属性
–@Before: 前置通知, 在方法执行之前执行
· –@After: 后置通知, 在方法执行之后执行
–@AfterRunning: 返回通知, 在方法返回结果之后执行
–@AfterThrowing: 异常通知, 在方法抛出异常之后
–@Around: 环绕通知, 围绕着方法执行
13,BeanFactory和ApplicationContext有什么区别
①ApplicationContext是BeanFactory的子接口,拥有更多的功能(国际化,邮件,模板)
ApplicationContext:在读取配置文件的时候就开始创建配置文件里面的对象。 称为:迫切加载
BeanFactory:使用的时候才会创建配置文件里面的对象。 称为:懒加载
14,Spring的Bean懒加载和非懒加载有什么区别
①懒加载:使用对象的时候才去创建对象,节省资源,但是不利于提前发现错误
②提前加载:容器启动的时候就去创建,消耗资源,有利于提前发现错误
Spring容器默认是非懒加载
15,singleton和protype有什么区别
①singleton:单列模式 当Bean使用单列模式的时候,Spring容器仅创建一个对象,每次使用的对象都是同一个(默认,线程不安全,性能高)
②protype:原型模式 当Bean使用原型模式时。Spring容器会创建一个新的对象,每次使用都是一个新的(多线程,多个实例)
16,Spring支持几种Bean的作用域
①singleton:单列模式 Spring IOC容器只会创建Bean实例;
②prototype:原型模式: 每次使用都会创建一个新的Bean实例;频繁的创建和销毁会带来很大的开销
③request :web下 每次http请求都会创建一个Bean
④session :web下 同一个http session 请求共享同一个Bean实例
⑤global-session:用于 portlet 容器,因为每个 portlet 有单独的 session,globalsession 提供一个全局性的 http session
17,Spring的依赖注入方式及实现有哪几种
注入方式 4种
①Set方法注入 :注入最简单,最常用的注入方式,支持注解+xml。
②构造器注入 :是指带有参数的构造函数注入,支持注解+xml
③静态工厂方式的注入 :调用静态工厂的方法来获取自己需要的对象,只支持xml。
④实例工厂方式的注入 :获取对象实例的方法不是静态的,所以需要new一个工厂类,再调用普通的实例方法,只支持xml。
实现方式 2种
①Autowired (默认先通过名称,现通过类型来获取对象)
②Required (默认先通过名称,现通过类型来获取对象)
18,Spring的Bean创建方式及生命周期,Bean的自动装配原理?
①创建方式
②Bean生命周期
③Spring Bean的自动装配原理
19,SpringBoot如何配置事务;
①在处理的事务server业务层的类上打注解@Transactional 代表这个类里面的所有事务都是同一个事务,打在方法上表示这个方法支持这个事务;
20,有哪些方式可以注册一个Bean到容器中
①通过配置xml
②通过注解:@Controller、@Component、@Service,@Bean等
③实现FactoryBean接口 :
④通过@Import注解 :导入外部包的时候,有大量的bean需要创建 批量导入 也叫强制导入
⑤向BeanDefinitionRegistry 注册表中直接注册一个bean 不常用
21,将一个类声明为Spring的Bean的注解有哪些?
①Autowired:自动装配bean
②@Component:通用的注解,可标注任意类为 Spring 组件。如果一个Bean不知道属于哪个层,可以使用
③@Repository : 对应持久层即 Dao 层,主要用于数据库相关操作
④@Service :对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao层。
⑤@Controller :对应 Spring MVC控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。
22,Spring的IOC启动原理
①IOC:控制反转,把对象的创建,初始化,销毁等等都交给Spring管理,减少我们的工作量
配置文件的方式启动IOC 和 注解的方式启动IOC
23,Spring是如何管理事务的?
24,Spring事务的回滚机制
25,Spring用到了那些设计模式
单列,工厂,适配器,代理,观察者,模板方法,包装器设计模式
单例设计模式:Spring中的Bean都是单例模式(默认)
工厂设计模式:Spring使用工厂模式通过BeanFactory,applicationContext创建bean对象。
适配器模式:SpringAOP的增强或通知(Advice)使用到了适配器模式,SpringMVC中也用到了适配器contriller
代理设计模式:Spring中的动态代理模式
观察者模式:Spring事件驱动模型就是观察者模式
模板方法模式:Spring中jdbcTemplate,hibemateTemplate等template结尾的对数据库操作的类,他们就使用到了模板模式。
包装器设计模式:项目中需要连接多个数据库,而且不同的客户访问都需要去访问不同的数据库,这种模式让我们可以根据客户的需求能够动态的去切换不同的数据源。
26,RequestMapping和GetMapping区别?
①@RequestMapping可以指定GET,POST请求方式。
②@GetMapping 用于将HTTP get请求映射到特定处理程序的方法注解。
③@PostMapping用于将HTTP post请求映射到特定处理程序的方法注解。
27,SpringMVC怎么样设定重定向和转发的
一般请求下,控制器方法返回字符串类型的值会被当成逻辑视图名处理,如果返回的字符串中带有forward或redirect前置时,SpringMVC 会对他们进行特殊的处理,将forward和redirect当成指示符
①转发:在返回值前面加”forward:”,譬如”forward:user.do?name=method4”
②重定向:在返回值前面加”redirect:”,譬如”redirect:http://www.baidu.com“
28,SpringMVC如何对时间格式的参数进行格式化?
① 在控制器中使用@InitBind注解
②在POJO(实体类)中日期属性上添加@DateTimeFormat
29,SpringMVC常用的注解有哪些?
①@Controller
在SpringMVC中,controller主要负责处理前端控制器发过来的请求,经过业务处理层之后封装一个model,并将其返回给view进行展示,@controller注解通常用于类上,如果Thymeleaf模板使用的话,会返回一个页面。如果是前后端分离的项目,则使用@RestController,表明返回的是json格式数据
②@RestController @controller + @responsebody 将返回的数据格式装换为json格式
③@RequsetMapping 是一个用来处理请求地址映射的注解,它可以用于类上,也可以用于方法上,用来将特定请求或者请求模式映射到一个控制器之上,表示进一步指定到处理方法的映射关系
④@PathVariable 主要用来获取url参数
⑤@RequestParam 是从request里获取参数值 @pathvaliable 也是获取请求参数
⑥@RequestBody 接受前端传过来的参数是一个对象
29,如何定义SpringMVC的拦截器
方式一:实现接口
创建拦截器类实现Handlerlnterceptor接口
配置拦截器配置文件
方式二:在自己的SpringMVC.xml中配置拦截器
方式三: 继承适配器:
30,过滤器和拦截器的区别:
1,拦截器是基于java的反射机制,而过滤器是基于函数回调。
2,过滤器是servlet规范规定的,只能用于web程序中,而拦截器是在spring容器中,它不依赖servlet容器。
3,过滤器可以拦截几乎所有的请求(包含对请求资源的请求),而拦截器只拦截action请求(不拦截静态资源请求)
4,拦截器可以访问action上下文,值栈里的对象,而过滤器不能访问。
5,在action的生命周期中,拦截器可以多次被调用,而过滤器只能在初始化时被调用一次
6,拦截器可以获取ioc容器中的各个bean,而过滤器就不行,在拦截器李里注入一个service 可以调用业务逻辑
7,拦截器是被包裹在过滤器之中
31,HandIerInterceptor和HandlerInterceptorAdapter的区别?
相同:
日志记录,可以记录请求信息的日志,以便进行信息监控,信息统计等。
权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面。
性能监控:典型的是慢日志
不同:
HandlerInterceptor(拦截器):HandInterceptor需要实现 重写三个方法preHandle,postHandle,afterCompletion
HandlerInterceptorAdapter(拦截器适配器):HandlerInterceptorAdapter需要继承,重写一个方法proHandle
32,SpringMVC的Controller是单列还是多列,有没有并发安全问题,如何解决?
controller默认是单列的,不要使用非静态的成员变量,否则会发生数据逻辑混乱。正因为单列所以不是线程安全的(线程不安全)
33、SpringBoot有哪些优点?
框架相对于springMvc框架来说,更专注于开发微服务后台接口,不开发前端视图,同时遵循默认优于配置,简化了插件配置流程,不需要配置xml,相对springmvc,大大简化了配置流程;采用maven的模块,在使用SPring就不需以传统的方式来用,只需要以maven导入对应的springboot模块,就能完成一大堆操作。简单的说,它使用maven的方式对Spring应用开发进行进一步封装和简化。
34、SpringBoot如何做全局异常处理?
一、为什么要用全局异常处理?
在日常开发中,为了处理出现很多的异常,不把异常抛给堆栈信息给前端页面,异常多了 try cath多了,代码耦合性较高,且不美观,不利于后期维护。为解决该问题,所以就将异常信息统一封装处理,更能区分Controller层方法返回给前端的String、Map、JSONObject、ModelAndView等结果数据的类型。
二,应用场景是什么?
①、非常方便的去掉了try catch这类冗杂难看的代码,有利于代码的整洁和优雅。
②、自定义参数校验时候全局异常处理会捕获异常,将该异常统一返回给前端,省略很多if else代码。
③、当后端出现异常时,需要返回给前端一个友好的界面的时候就需要全局异常处理
④、因为异常时层层向上抛出的,为了避免控制台打印一长串异常信息
三、如何进行全局异常捕获和处理?
方式一、 Spring的AOP(较复杂)
方式二、@ControllerAdvice结合@ExceptionHandler(简单)
(JSR303校验)在需要校验的类型的字段上打上@NotNull注解 @NotEmpty注解,在全局异常处理中 使用异常对象可以获取到BindingErrors从而可以调用方法获取到所有校验未通过的字段及信息,自定义自己的状态码。
35、SpringBoot如何读取配置文件中的配置项?
对于 properties 文件的读取,采用 @PropertySource 、@Value 注解即可直接获取指定配置项。
@Data : 用于提供 getter,setter。简化代码
方式一、@PropertySource : 用于指定 properties 文件,需将 properties 文件放置在 能够获取到路径的地方
@Component: 注入 bean ,不能省略,不然 @Value 注解不能获取到配置项
方式二、Environment : 获取配置文件属性的接口
方式三、ConfigurationProperties 方式获取
36、@SpringBootApplication标签的组成
是一个合成体,但其中最重要的三个注解分别是:三体结构 ”
①、@SpringBootConfiguration:读取配置文件,配置文件的路径是当前根目录(src/main/resources/application.yml等)
@Component:spring内置组件注解,用途是让spring容器扫描
@Target(ElementType.TYPE) :用于描述注解的使用范围
@Retention(RetentionPolicy.RUNTIME) :保留,指定保留时间,三个枚举,分别为source,class,runtime
@Documented:可被javadoc等工具记录,注解类型信息会保存到生成的文档中
@Inherited:个人认为是一个成员变量,父类被子类覆盖之后无法继承,子类中可以继承父类中未被覆盖的父类注解的值
②、@EnableAutoConfiguration:这个注解主要是继承@Configuration注解,这个我们就是为了加载配置文件用的;
③、@ComponentScan:就是用来自动扫描被这些注解标识的类,最终生成ioc容器里的bean.
对应于XML配置形式中的
@Controller
@Entity
@Component
@Service
@Repository
37、.SpringBoot是如何整合SpringMVC的?SpringBoot是如何整合DataSource的?
1)、主类:@SpringBootApplication
2)、开启自动配置:@EnableAutoConfiguration
3)、导入EnableAutoConfiguration自动装配的选择器:
@Import(AutoConfigurationImportSelector.class)
4)、AutoConfigurationImportSelector.selectImports选择加载自动配置的类的名字
5)、SpringFactoriesLoader加载一些配置类,扫描classpath中的jar ,找到META-INF/spring.factories(就是springboot的接口,存储需要自动装配的bean)
6)、spring-boot-2.0.5.RELEASE.jar里面的META-INF/spring.factories/EnableAutoConfiguration配置项目后面的类
7)、比如:HttpEncodingAutoConfiguration编码过滤器的自动配置,以Bean的方式定义好了。
比如;WebMvcAutoConfiguration对SpringMVC的自动配置, InternalResourceViewResolver 视图解析器以Bean的方式注册好了
比如:DispatcherServletAutoConfiguration就是针对于前端控制器的自动配置,以Bean的方式吧DispatcherServlet注册好了
比如:DataSourceAutoConfiguration针对于DataSource自动配置
-> 通过DataSourceProperties加装yml配置
-> DataSourceConfiguration.Generic.class 配置DataSource
->如果没有定义DataSource,会自动创建一个DataSource(根据连接池的类型反射创建)
->注册到容器。
38.SpringBoot的启动流程
1)、SpringApplication#run:开启秒表StopWatch计时
2)、获取SpringApplicationRunListeners监听器
3)、启动SpringApplicationRunListeners监听器
4)、获取ApplicationArguments应用参数
5)、获取环境:ConfigurableEnvironment,这个环境对象中可以获取property
6)、打印Bananer
7)、创建上下文:ConfigurableApplicationContext(AnnotationConfigApplicationContext)
8)、获取异常报告事件监听exceptionReporters
9)、准备上下文:prepareContext
- ConfigurableEnvironment环境对象设置到容器中
- 初始化ApplicationContextInitializer
- 注册:applicationArguments到容器
- 注册:Banner到容器
10)、刷新上下文:refreshContext ,Spring和核心启动方法,注册Bean就在这里
- (invokeBeanFactoryPostProcessors 执行后置处理器)自动配置就着这执行的
11)、刷新上下文后置工作:afterRefresh
12)、执行ApplicationRunListeners中的started(),发布 ApplicationStartedEvent 事件
13)、执行Runner(ApplicationRunner和CommandLineRunner)
39.SpringBoot和SpringCloud的区别?
一、SpringBoot是什么?
SpringBoot是一个快速开发的轻量级框架,帮助快速整合第三方常用框架,完全采用注解化(使用注解启动SpringMVC),简化XML配置,内置HTTP服务器(Tomcat、Jetty)。作用是简化Spring应用的初始搭建及开发,解决各种jar包版本冲突问题。
二、SpringCloud是什么?
SpringCloud是一系列框架的有序集合,是一个分布式服务治理的框架,本身不会提供具体功能性的操作,是一个为开发者提供快速构建分布式系统的工具。简化了分布式系统基础设施的开发,包括服务发现、服务注册、配置中心、消息总线、负载均衡、断路器、数据监控等。
SpringCloud不是重复制造轮子,而是将目前各家公司开发的比较成熟的服务框架组合起来,通过SpringBoot风格进行再封装,屏蔽掉复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包,即默认大于配置;
三、SpringBoot和SpringCloud的联系?
SpringBoot+SpringCloud实现微服务开发。具体就是,SpringCloud具备微服务开发的核心技术:RPC远程调用技术;SpringBoot的web组件默认集成了SpringMVC,可以实现HTTP+JSON(Restfull)的轻量级传输,编写微服务接口,所以SpringCloud是依赖SpringBoot框架实现微服务开发。
四、SpringBoot和SpringCloud的区别?
1.SpringBoot专注于快速开发单个微服务,SpringCloud是将SpringBoot开发的一个个单体微服务整合并管理起来,它是关注全局的服务治理框架(RPC远程调用技术、服务治理等);
2.SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖的关系。
40、SpringCloud常用组件和作用?
(1)、服务注册与发现——Netflix Eureka
硬编码服务提供者地址的方式有不少问题。要想解决这些问题,服务消费者需要一个强大的服 务发现机制,服务消费者使用这种机制获取服务提供者的网络信息。不仅如此,即使服务提供者的网络地址发生变化,服务消费者也无须修改配置文件。
(2)、客户端负载均衡——Netflix Ribbon
1、Ribbon 的作用是负载均衡,会帮你在每次请求时选择一台服务器,均匀的把请求分发到各个服务器上。
2、Ribbon负载均衡策略:(随机、轮询、权重、地区、响应)在配置类上加上一个IRule上加上一个@bean
(3)、服务接口调用——Netflix Feign(解决服务负载均衡调用的Feign 底层就是Ribbon)——集成在客户端)——解决Ribbon负载均衡中的请求的字符串拼接
1、Feign Client 会在底层根据你的注解,跟你指定的服务建立连接、构造请求、发起请求、获取响应、解析响应,等等。
2、Feign负载均衡步骤
(4)、服务熔断器——Netflix Hystrix ((豪猪)熔断器-服务保护 保证服务健壮性——集成在服务提供端)
- 降级 :请求一个服务出现了异常(报错,超时,熔断,限流)会触发降级,返回事先准备好的兜底数据
- 熔断 :一个服务多次访问失败,这个服务会被标记为熔断(短路)状态,被熔断的服务如果有其他服务来请求它,快速失败,触发降级,不要等待。
- 限流 :限制请求的并发量
服务链上,因为某个微服务的异常,而导致雪崩效应,整条服务链宕机的问题;Hystrix回去捕获这个异常,利用Hystrix接口处理这类异常。
1、Hystrix熔断器如何做熔断与解决雪崩的?
①、资源隔离
线程池隔离 :(线程池隔离和请求线程不是同一个线程
信号量隔离 :信号量和请求线程是同一个线程)
②.熔断
当错误到达一定阈值 熔断 每个一段时间 进入半熔断状态 允许少量请求进入 如果成功 闭合 如果失败 继续熔断
③.降级
针对一些不是特别重要的业务 不影响整个流程的业务 可以在隔离和熔断后 进行一些托底数据的返回
④、缓存:提供了请求缓存、请求合并实现。
(5)、服务网关——Netflix Zuul
负责网络路由,可以做统一的降级、限流、认证授权、安全,等等。
(6)、服务跟踪——Netflix Sleuth
(7)、聚合Hystrix监控数据——Netflix Turbine
(8)、分布式配置——Spring Cloud Config
常用组件:
①、Eureka
Eureka是微服务架构中的注册中心,专门负责服务的注册与发现;
每个微服务中都有一个Euraka client组件,专门负责将这个服务的服务id(serviceId)、ip、端口等信息注册到Eureka server中;
Euraka Server是一个注册中心,该组件内部维护了一个注册表,保存了各个服务所在的机器ip和端口号等信息。
②、Feign
Feign主要负责与其他服务建立连接,构造请求,发起请求,获取响应等等,用来远程调用其他的服务;
Feign使用Jdk的动态代理来针对FeignClient注解修饰的接口创建动态代理;
调用FeignClient注解修饰的接口,实际是调用Feign创建出来的动态代理;
根据RequestMapping等注解信息,动态构造出要请求的服务地址;
针对该构造出来的地址,发起请求,解析响应;
③、Ribbon
Ribbon主要负责负载均衡,针对每次请求,Ribbon会从Euraka client服务列表中选择一个服务发起请求,均匀的把请求分发到各个服务中;
默认使用的是Round Robin轮询算法;
Feign使用Ribbon去获取服务信息,例如服务的ip、端口等信息,然后针对服务的信息构造
并发起请求。
Ribbon的主要组件与工作流程
Ribbon的主要组件:
Ribbon的核心组件(均为接口类型)有以下几个:
ServerList
用于获取地址列表。它既可以是静态的(提供一组固定的地址),也可以是动态的(从注册中心中定期查询地址列表)。
ServerListFilter
仅当使用动态ServerList时使用,用于在原始的服务列表中使用一定策略过虑掉一部分地址。
IRule
选择一个最终的服务地址作为LB结果。选择策略有轮询、根据响应时间加权、断路器(当Hystrix可用时)等。
Ribbon的工作流程:
Ribbon在工作时首选会通过ServerList来获取所有可用的服务列表,然后通过ServerListFilter过虑掉一部分地址,最后在剩下的地址中通过IRule选择出一台服务器作为最终结果。
④、Hystrix
微服务架构中,存在着恐怖的服务雪崩问题,也是当服务直接互相调用,如果其中某个服务挂掉了,会导致其他服务不可用,甚至导致其他服务也挂掉了;
Hystrix是隔离、熔断以及降级的一个框架;
Hystrix默认是通过线程池技术对服务进行隔离,每个微服务对应一个线程池,对每个服务进行调用时,都是通过在自己的线程池中调用;
如果某个服务挂了,hystrix就直接返回,这个过程就是熔断;
如果某个服务挂了,hystrix就执行一个默认的方法逻辑,这个过程就是降级;
⑤、Zuul
Zuul是微服务的网关,这个组件是负责网络的路由;
所有请求都往网关走,网关会根据请求中的特征,将请求转发给后端的各个服务;
41.Eureka心跳和服务剔除机制是什么
Eureka心跳机制:
客户端每30秒发送一个心跳,询问是否还在。
Eureka服务剔除机制:
当 Eureka Client 和 Eureka Server 不再有心跳时,Eureka Server 会将该服务实例从服务注册列表中删除,即服务剔除。
Eureka自我保护机制:
在默认配置中,Eureka Server在默认90s没有得到客户端的心跳,则注销该实例,但是往往因为微服务跨进程调用,网络通信往往会面临着各种问题,比如微服务状态正常,但是因为网络分区故障时,Eureka Server注销服务实例则会让大部分微服务不可用,这很危险,因为服务明明没有问题。
当Eureka Server节点在短时间内丢失过多的客户端时(可能发送了网络故障),那么这个节点将进入自我保护模式,不再注销任何微服务,当网络故障回复后,该节点会自动退出自我保护模式。
42.Eureka的服务注册与发现的工作流程
Eureka注册中心工作原理(服务注册,发现,续约,下线)
1、Eureka Server 启动成功,等待服务端注册。在启动过程中如果配置了集群,集群之间定时通过 Replicate 同步注册表,每个 Eureka Server 都存在独立完整的服务注册表信息,服务提供者在启动的时候需要向注册中心注册自己的信息,而注册中心把向自己注册的服务提供者都保存下来,以便服务消费者获取用来发起请求,而服务消费者需要从注册中心获取服务提供者列表,然后向服务提供者发起调用。
2、Eureka Client 启动时根据配置的 Eureka Server 地址去注册中心注册服务
3、而服务消费者向注册中心获取服务提供者列表有两种方式:
1、消费者主动向注册中心拉取;
2、注册中心主动给服务消费者推送。
其实,服务提供者注册完自己之后还会和注册中心保持心跳,以此来证明自己还能正常提供服务。这样上面说到的那些情况无论动态感知上下线还是负载均衡,都不需要人为的去操作了,这些都交给服务自己去完成。这样就达到了服务解耦的作用。
2、eureka的主要角色分为服务端(server)和客户端(client);
(1)、Eureka Client 会每 30s 向 Eureka Server 发送一次心跳请求,证明客户端服务正常;
(2)、Eureka Server 90s 内没有收到 Eureka Client 的心跳,注册中心则认为该节点失效,会注销该实例,而服务提供者会向server注册、注销、续约(默认30s,超过90s不续约将被注册中心剔除)、以及获取服务列表(客户端会缓存获取下来的列表);
单位时间内 Eureka Server 统计到有大量的 Eureka Client 没有上送心跳,则认为可能为网络异常,进入自我保护机制,不再剔除没有上送心跳的客户端;
当 Eureka Client 心跳请求恢复正常之后,Eureka Server 自动退出自我保护模式;
5、然后向服务提供者发起远程调用;
(1)、服务调用时,服务消费者会向注册中心获取服务列表,会先从本地缓存找寻调取的服务。如果获取不到,先从注册中心刷新注册表,再同步到本地缓存,Eureka Client 获取到目标服务器信息,发起服务调用
6、Eureka Client 程序关闭时向 Eureka Server 发送取消请求,Eureka Server 将实例从注册表中删除
43.对于CAP理论,Eureka选择的是AP还是CP?它保证了一致性还是可用性?
1.CAP指的是 一致性(Consistency) ,可用性(Availability), 分区容错性(Partition tolerance),在分布式中,网络是不可控的,所以首先要保证 P ,然后在A和C之间做选择。要么AP ,要么CP 。
2.Eureak选择AP 保证了可用性降低了一致性 , Nacos 默认 AP ,可以 CP和AP可以切换 , Zookeeper 就是 CP ; Redis AP
44.说下Ribbon和Feign的区别呢?
Ribbon添加maven依赖 spring-starter-ribbon 使用@RibbonClient(value=”服务名称”) 使用RestTemplate调用远程服务对应的方法
feign添加maven依赖 spring-starter-feign 服务提供方提供对外接口 调用方使用 在接口上使用@FeignClient(“指定服务名”)
Ribbon和Feign的区别:
Ribbon和Feign都是用于调用其他服务的,不过方式不同。
1.启动类使用的注解不同,Ribbon用的是@RibbonClient,Feign用的是@EnableFeignClients。
2.服务的指定位置不同,Ribbon是在@RibbonClient注解上声明,Feign则是在定义抽象方法的接口中使用@FeignClient声明。
3.调用方式不同,Ribbon需要自己构建http请求,模拟http请求然后使用RestTemplate发送给其他服务,步骤相当繁琐。
Feign则是在Ribbon的基础上进行了一次改进,采用接口的方式,将需要调用的其他服务的方法定义成抽象方法即可,
不需要自己构建http请求。不过要注意的是抽象方法的注解、方法签名要和提供服务的方法完全一致。
45.一个请求过来,在你们的微服务项目中经过哪些流程?
(1)、一个前端的界面入口普通链接(调用微服务)
(2)、请求来到Nginx(配置访问转发到的地址,这里是gateway或者zuul、系统的唯一入口 网关)
(3)、网关(gateway、zuul) routes路由配置
(4)、Eureka上找到服务,访问到服务
46、如何实现Eureka的高可用集群?
防止单点故障
配置文件yml里面配置相关的信息,对Eureka进行集群,各个Eureka进行注册。
1.配置环境名:profiles
2.服务名
3.eureka主机
4.ip注册
5.实例ID、6.端口
47、Hystrix的限流有几种方式,有什么区别?
两种方式:
线程池隔离 :(线程池隔离和请求线程不是同一个线程)
执行流程:使用一个线程池来限制请求的数量,一个请求过来分配一个线程去执行,如果没有线程分配了,进入排队, 线程没有了也没有排队了,请求被拒绝,触发降级
最大并发:线程数+排队数
是否异步:是
性能开销:线程切换开销
信号量隔离 :信号量和请求线程是同一个线程)
执行流程:通过一个信号量(数字)来限制请求的数量,一个请求过来,计数器+1,走一个请求计数器-1,如果计数器达到信号量,请求直接拒绝,触发降级
最大并发:信号量
是否异步:否
性能开销:没有线程切换开销
- 缓存:对请求做缓存,提高并发请求的效率
**二者区别:信号量、线程池。两者最大的区别就是信号量只做限流,不会另外开启线程去执行任务。而线程池则是线程耗尽,队列满的情况 下进行限流。
48,Hystrix的熔断有几种状态?这几种状态是怎么变换的?
熔断状态机3个状态:
Closed:关闭状态,所有请求都正常访问。
Open:打开状态,所有请求都会被降级。Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全打开。默认失败比例的阈值是50%,请求次数最少不低于20次。
Half Open:半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,则会完全关闭断路器,否则继续保持打开,再次进行休眠计时
这几种状态是怎么变换的:
当错误到达一定阈值 进入熔断 每个一段时间 进入半熔断状态 允许少量请求进入 如果成功 进入闭合状态 如果失败 继续熔断
,49、服务A使用ribbon调用服务B,Ribbon是如何工作的?
- 发送请求,被LoadBalancerInterceptor拦截器拦截,请求被交给ribbon来处理
- 拦截器拦截请求,交给了RibbonLoadBalancerClient的execute方法(下面的逻辑都是包含在这个方法中)
- 在进行负载均衡之前首先得知道有哪些服务实例信息,所以通过DynamicServerListLoadBalancer的updateListOfServers方法从注册中心(Eureka)那里获取到了所有的服务实例信息,并且会定时更新
- 使用负载均衡算法(默认轮询算法)从所有的服务实例信息中选择一台机器出来
- 将请求发送给负载均衡选择出来的服务实例上去
50、为什么Feign的接口可以直接注入进来用?
Spring低层对 fegin进行了整合
启动类:spring启动的时候就开启对fegin加载扫描
Fegin的接口打上注解 类似交给spring管理
@EnableFeignClients(“cn.hemaming.hrm.client”)
@FeignClient(_value = “auth-service” ,fallbackFactory = AuthClientFallback.class)_
51、Ribbon的负载均衡算法有哪些?
地区
轮询:RoundRobinRule:默认轮询的方式
随机:RandomRule:随机方式
权重、响应WeightedResponseTimeRule: 根据响应时间来分配权重的方式,响应的越快,分配的值越大。
BestAvailableRule: 选择并发量最小的方式
RetryRule: 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
ZoneAvoidanceRule: 根据性能和可用性来选择。
AvailabilityFilteringRule: 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)
52、Zuul有哪几类Filter,他们的执行顺序是怎么样的?
1)pre
可以在请求被路由之前调用。适用于身份认证的场景,认证通过后再继续执行下面的流程。
2)route
在路由请求时被调用。适用于灰度发布场景,在将要路由的时候可以做一些自定义的逻辑。
3)post
在 route 和 error 过滤器之后被调用。这种过滤器将请求路由到达具体的服务之后执行。适用于需要添加响应头,记录响应日志等应用场景。
4)error
处理请求时发生错误时被调用。在执行过程中发送错误时会进入 error 过滤器,可以用来统一记录错误信息。
前置路由——》后置——》返回数据给前端。
前置报错——》走异常——》走后置
后置报错——》走异常直接结束
53. 在Zuul中做登录检查如何实现?
写一个前置拦截器,对所有的资源路径进行拦截,放行登录的路径,当访问某一资源路径时,进行登录拦截检查,看是否有登录的携带token
47.在Zuul中如何做限流?
写一个拦截器,在zuul配置文件里面限定最大的访问量。通过令牌桶算法
从单个服务的角度实现限流,原理:利用redis键过期的自动删除的特性。以url为key,如果key不存在,创建key,并设置键过期时间,相同请求过来就对这个key进行计数,使用redis.incr原子方法,当请求超过limit时,则不让请求api。
54、EurekaClient拉取注册表&心跳续约用到了什么技术来实现?
创建的一个ScheduledExecutorService线程池+定时任务,可以进行定时或周期性的工作调度服务。
55、Springcloud分布式SpringSecurity项目授权、鉴权流程
一、微服务授权认证方式:
1、微服务授权常见方案
1、CAS单点登录:登录一个相同的服务,其他的服务都可以访问,是基于cookion实现单点登录的
流程:单点登录全称Single Sign On(以下简称SSO),是指在多系统应用群中登录一个系统,便可在其他所有系统中得到授权而无需再次登录,包括单点登录与单点注销两部分。
单点登录
sso需要一个独立的认证中心,只有认证中心能接受用户的用户名密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权通过令牌实现,sso认证中心验证用户的用户名密码没问题,创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式与单系统的登录方式相同。这个过程,也就是单点登录的原理
1,当用户访问保护资源,验证是没有登录,会跳转到SSO认证中心
2,SSO认证中心发现用户未登录,将用户引导至登录页面;
3,输入账号和密码提交登录。
4,SSO认证中心校验用户信息,创建用户和SSO认证中心的全局会话,同时创建授权令牌
5,SSO带着令牌去跳转到受保护的系统
6,系统去SSO认证中心效验令牌,如果有效就注册系统,并使用该令牌创建用户的剧部会话
2、分布式会话(session)+网关+redis
优点:简单好实用
缺点:redis的安全性
流程:
3、客户端Token+网关
优点:服务端不用存储token
缺点:token太长了
流程:
4、客户端 Token 与 API 网关结合
这个方案意味着所有请求都通过网关,从而有效地隐藏了微服务。在请求时,网关将原始用户令牌转换为内部会话 ID 令牌。在这种情况下,注销就不是问题,因为网关可以在注销时撤销用户的令牌。
二、微服务分布式项目采取:
方式一:客户端Token+zuul+SpringSecurity+SpringCloud+Oauth2+JWT
解释:
² 客户端 : web端,移动端,三方程序
² 认证服务:负责认证逻辑(登录)和颁发令牌(token)等
² 网关:负责token统一校验和统一授权
² 资源服务:负责授权(用户对资源的访问权限检查)和返回资源
方式二、Token+SpringSecurity+Oauth2+JWT不使用网关授权
二、微服务项目认证授权怎么实现的?
方案、Token+SpringSecurity+Oauth2+JWT不使用网关授权
OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。
JWT(json+web+token)相当于就是token JWT以 JSON 对象的形式安全传递信息。因为存在数字签名,因此所传递的信息是安全的。
SpringSecurity认证流程
² 请求过来会被过滤器链中的UsernamePasswordAuthenticationFilter拦截到,请求中的用户名和密码被封装成UsernamePasswordAuthenticationToken(Authentication的实现类)
² 过滤器将UsernamePasswordAuthenticationToken提交给认证管理器(AuthenticationManager)进行认证.
² AuthenticationManager委托AuthenticationProvider(DaoAuthenticationProvider)进行认证,AuthenticationProvider通过调用UserDetailsService获取到数据库中存储的用户信息(UserDetails),然后调用passwordEncoder密码编码器对UsernamePasswordAuthenticationToken中的密码和UserDetails中的密码进行比较
² AuthenticationProvider认证成功后封装Authentication并设置好用户的信息(用户名,密码,权限等)返回
² Authentication被返回到UsernamePasswordAuthenticationFilter,通过调用SecurityContextHolder工具把Authentication封装成SecurityContext中存储起来。然后UsernamePasswordAuthenticationFilter调用AuthenticationSuccessHandler.onAuthenticationSuccess做认证成功后续处理操作
² 最后SecurityContextPersistenceFilter通过SecurityContextHolder.getContext()获取到SecurityContext对象然后调用SecurityContextRepository将SecurityContext存储起来,然后调用SecurityContextHolder.clearContext方法清理SecurityContext。
注意:SecurityContext是一个和当前线程绑定的工具,在代码的任何地方都可以通过SecurityContextHolder.getContext()获取到登陆信息。
四、常见的权限框架有
1,Shiro 框架Java的一个安全框架;对比Spring Security,可能没有Spring Security做的功能强大
2,spring Security一个轻量级的安全框架,它确保基于Spring的应用程序提供身份验证和授权支持