springcloud
2021-11-23 23:44:26 20 举报
AI智能生成
springcloud
作者其他创作
大纲/内容
分支主题
Hystrix容错处理组件
Hystix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败
雪崩问题
微服务中,服务间调用关系错综复杂,一个请求,可能需要调用多个微服务接口才能实现,会形成非常复杂的调用链路:
如图,一次业务请求,需要调用A、P、H、I四个服务,这四个服务又可能调用其它服务。
如果此时,某个服务出现异常:
如果此时,某个服务出现异常:
例如微服务I发生异常,请求阻塞,用户不会得到响应,则tomcat的这个线程不会释放,于是越来越多的用户请求到来,越来越多的线程会阻塞:
服务器支持的线程和并发数有限,请求一直阻塞,会导致服务器资源耗尽,从而导致所有其它服务都不可用,形成雪崩效应。
这就好比,一个汽车生产线,生产不同的汽车,需要使用不同的零件,如果某个零件因为种种原因无法使用,那么就会造成整台车无法装配,陷入等待零件的状态,直到零件到位,才能继续组装。 此时如果有很多个车型都需要这个零件,那么整个工厂都将陷入等待的状态,导致所有生产都陷入瘫痪。一个零件的波及范围不断扩大。
服务器支持的线程和并发数有限,请求一直阻塞,会导致服务器资源耗尽,从而导致所有其它服务都不可用,形成雪崩效应。
这就好比,一个汽车生产线,生产不同的汽车,需要使用不同的零件,如果某个零件因为种种原因无法使用,那么就会造成整台车无法装配,陷入等待零件的状态,直到零件到位,才能继续组装。 此时如果有很多个车型都需要这个零件,那么整个工厂都将陷入等待的状态,导致所有生产都陷入瘫痪。一个零件的波及范围不断扩大。
Hystix解决雪崩问题
线程隔离
线程隔离,服务降级
服务降级步骤(consumer:在调用方改造)
1、引入Hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2、覆盖默认配置
可以修改超时时间,Hystix的默认超时时长为1s
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000 # 设置hystrix的超时时间为6000ms
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000 # 设置hystrix的超时时间为6000ms
3、开启熔断,在调用方引导类上加@EnableCircuitBreaker
4、编写降级逻辑
局部熔断方法
返回值和参数列表要和被熔断方法一致
在被熔断方法上添加注解@HystrixCOmmand(fallbackMethod="熔断方法名")
全局熔断方法
defaultFallback:默认降级方法,不用任何参数,以匹配更多方法,但是返回值一定一致
@DefaultProperties(defaultFallback = "defaultFallBack"):在Controller类上指明统一的失败降级方法
服务熔断
熔断器,也叫断路器,其英文单词为:Circuit Breaker
熔断状态机3个状态
Closed
关闭状态,所有请求都正常访问。
Open
打开状态,所有请求都会被降级。
Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,
断路器会完全打开。默认失败比例的阈值是50%,请求次数最少不低于20次。
Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,
断路器会完全打开。默认失败比例的阈值是50%,请求次数最少不低于20次。
Half Open
半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。
随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,
则会完全关闭断路器,否则继续保持打开,再次进行休眠计时
随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,
则会完全关闭断路器,否则继续保持打开,再次进行休眠计时
步骤
为了能够精确控制请求的成功或失败,我们在consumer的调用业务中加入一段逻辑
如果在一定时间内触发多次降级,失败的比例不小于50%或者次数不少于20次,
触发熔断5s内所有请求无法正常访问。过了休眠期会进入半开状态,放部分请求通过
触发熔断5s内所有请求无法正常访问。过了休眠期会进入半开状态,放部分请求通过
可以手动修改配置、
Zuul网关组件
使用网关步骤
1、引入依赖
如果需要通过serviceId来访问路径,则需要加入注册中心去拿service-provider
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
2、覆盖默认配置
这里只能通过service-provider的路径来访问,consumer访问不行
路由规则
推荐使用上面的写法,使用动态路由
通常还会指定一个路由前缀(官方推荐)
prefix: /api (与routes同级,注意不要写错了)
通常还会指定一个路由前缀(官方推荐)
prefix: /api (与routes同级,注意不要写错了)
zuul:
routes:
service-provider:
path: /service-provider/** # 这里是映射路径
url: http://127.0.0.1:8081 # 这里写死
routes:
service-provider:
path: /service-provider/** # 这里是映射路径
url: http://127.0.0.1:8081 # 这里写死
路由配置也可以省略,路由前缀默认是服务名
zuul:
routes:
service-provider: /service-provider/** # 这里是映射路径
zuul:
routes:
service-provider: /service-provider/** # 这里是映射路径
3、在引导类上添加@EnableZuulProxy
@SpringBootApplication
@EnableDiscoveryClient //如需要使用负载均衡要开启eureka客户端
@EnableZuulProxy // 开启网关功能
@EnableDiscoveryClient //如需要使用负载均衡要开启eureka客户端
@EnableZuulProxy // 开启网关功能
介绍
Zuul加入后的架构
过滤器
Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的
过滤器类型filterType
各个过滤器的执行顺序
使用场景
请求鉴权(常用)
一般放在pre类型,如果发现没有访问权限,直接就拦截了
步骤
1、编写一个类继承ZuulFilter(顶级接口)
2、重写4个方法
filterType:过滤器类型(pre route post error)
filterOrder:过滤器执行顺序,返回值越小优先级越高
shouldFilter:是否执行run方法,返回值为true执行run
run:执行拦截的业务逻辑 RquestContext类(注意是zuul的类)
3、添加@Component注入容器
异常处理
服务调用时长统计
负载均衡和熔断
不需要集成feign,zuul自己包含eureka client与Ribbon还有hystrix必要的依赖。feign在服务互相调用的时候用就行了
Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置:
Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置:
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000 # 设置hystrix的超时时间为6000ms
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000 # 设置hystrix的超时时间为6000ms
Eureka注册中心
eureka-server
1、引入依赖
至少要有springcloud服务端依赖和启动器依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
依赖管理
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2、添加配置
3、在引导类上添加@EnableEurekaServer//启用eureka服务端
eureka-client
provider
1、引入依赖
引入springcloud客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、添加配置
3、在引导类上添加@EnableDiscoveryClient //开启eureka客户端
consumer
1、引入依赖
引入springcloud客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、添加配置
3、在引导类上添加@EnableDiscoveryClient //开启eureka客户端
4、提出需求
可以通过注册中心获取服务地址列表
以获取服务
可以通过注册中心获取服务地址列表
以获取服务
private DiscoveryClient discoveryClient; // 注入discoveryClient,通过该客户端获取服务列表
// 通过client获取服务提供方的服务列表,这里我们只有一个
ServiceInstance instance = discoveryClient.getInstances("service-provider").get(0);
// 通过client获取服务提供方的服务列表,这里我们只有一个
ServiceInstance instance = discoveryClient.getInstances("service-provider").get(0);
Ribbon负载均衡组件
多个provider服务实例下,consumer进行选择
开启负载均衡
Eureka中已经集成了Ribbon,所以我们无需引入新的依赖
1、修改consumer的引导类,在RestTemplate的配置方法上添加`@LoadBalanced`注解
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
2、controller方法使用服务名获取服务地址
负载均衡策略
默认是轮询
springboot的test与spring类似
修改负载均衡规则
在consumer配置中加`{服务名称}.ribbon.NFLoadBalancerRuleClassName`,值就是IRule的实现类
随机,该配置没有提示
service-provider:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
service-provider:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
Feign 声明式、模板化的Http客户端
集成了Ribbon和Hystrix
步骤
1、导入Feign依赖
2、开启feign
在调用方引导类上加一个注解@EnableFeignClients // 开启feign客户端
3、覆盖默认配置
设置Hystrix熔断方法
在调用方application配置设置
feign:
hystrix:
enabled: true # 开启Feign的熔断功能
hystrix:
enabled: true # 开启Feign的熔断功能
给feign接口(Client接口)添加实现类,实现方法就是熔断方法
在Client接口注解指定熔断实现类@FeignClient(value = "service-provider",fallback="实现类".class)
负载均衡
Feign中本身已经集成了Ribbon依赖和自动配置
4、定义一个Client接口客户端
1、在接口上添加注解并指定被调用服务的名称@FeignClient(value = "service-provider") // 标注该类是一个feign接口
2、在接口中定义方法,跟服务提供方controller的方法一致 如果有一级目录 则目录写在方法上
5、在调用方的controller通过@Autowired注入接口的动态代理对象使用(底层也是restTemplate)
0 条评论
下一页