赞
踩
在微服务架构中,一个请求需要调用多个服务是非常常见的。如客户端访问A服务,而A服务需要调用B 服务,B服务需要调用C服务,由于网络原因或者自身的原因,如果B服务或者C服务不能及时响应,A服 务将处于阻塞状态,直到B服务C服务响应。此时若有大量的请求涌入,容器的线程资源会被消耗完毕, 导致服务瘫痪。服务与服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难 性的严重后果,这就是服务故障的“雪崩”效应
服务隔离的分类:
1. 线程池隔离
2. 信号量隔离
在互联网系统中,当下游服务因访问压 力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。这 种牺牲局部,保全整体的措施就叫做熔断。
限流可以认为服务降级的一种,限流就是限制系统的输入和输出流量已达到保护系统的目的。一般来说系统的吞吐量是可以被测算的,为了保证系统的稳固运行,一旦达到的需要限制的阈值,就需要限制流量并采取少量措施以完成限制流量的目的。比方:推迟解决,拒绝解决,或者者部分拒绝解决
Hystrix是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失 败,从而提升系统的可用性与容错性。
@EntityScan("cn.itcast.entity")
@SpringCloudApplication
public class OrderApplication {
//创建RestTemplate对象
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
} }
//我们类上的注解越来越多,在微服务中,经常会引入上面的三个注解,于是Spring就提供了 一个组合注解:@SpringCloudApplication
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000
实现步骤
1. 创建工程
2. 修改application.yml在Fegin中开启hystrix
Feign中已经内置了hystrix,但是默认是关闭的需要在工程的 application.yml 中开启对hystrix的 支持
feign:
hystrix: #在feign中开启hystrix熔断
enabled: true
3. 配置FeignClient接口的实现类
基于Feign实现熔断降级,那么降级方法需要配置到FeignClient接口的实现类中
/**
* 实现自定义的ProductFeginClient接口 * 在接口实现类中编写熔断降级方法 */
@Component
public class ProductFeginClientCallBack implements ProductFeginClient {
/**
* 降级方法 */
public Product findById(Long id) {
Product product = new Product(); product.setId(-1l); product.setProductName("熔断:触发降级方法"); return product;
} }
4. 修改FeignClient添加hystrix熔断
@FeignClient注解中添加降级方法
//指定需要调用的微服务名称 @FeignClient(name="shop-service-product",fallback = ProductFeginClientCallBack.class)
public interface ProductFeginClient {
//调用的请求路径
@RequestMapping(value = "/product/{id}",method = RequestMethod.GET)
public Product findById(@PathVariable("id") Long id);
}
@FeignClient注解中以fallback声明降级方法
Hystrix还提供了近乎实时的监控,状态会暴露在Actuator提供的/health端点中。只需为项目添加 spring-boot-actuator 依赖,重启项目,访问http://localhost:9001/actuator/hystrix.stream ,即可看到实时的监控数据。
在微服务架构体系中,每个服务都需要配置Hystrix DashBoard监控。如果每次只能查看单个实例的监 控数据,就需要不断切换监控地址,这显然很不方便。要想看这个系统的Hystrix Dashboard数据就需 要用到Hystrix Turbine。
Turbine是一个聚合Hystrix 监控数据的工具,他可以将所有相关微服务的 Hystrix 监控数据聚合到一起,方便使用
1、搭建TurbineServer
2、配置多个微服务的hystrix监控
server:
port: 8031
spring:
application:
name: microservice-hystrix-turbine
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
turbine:
# 要监控的微服务列表,多个用,分隔 appConfig: shop-service-order clusterNameExpression: "'default'"
1. eureka相关配置 : 指定注册中心地址
2. turbine相关配置:指定需要监控的微服务列表
3、配置启动类
@SpringBootApplication
@EnableTurbine
@EnableHystrixDashboard
public class TurbineServerApplication {
public static void main(String[] args) {
SpringApplication.run(TurbineServerApplication.class, args);
} }
4、测试
熔断器有三个状态 CLOSED 、 OPEN 、 HALF_OPEN 熔断器默认关闭状态,当触发熔断后状态变更为 OPEN,在等待到指定的时间,Hystrix会放请求检测服务是否开启,这期间熔断器会变为HALF_OPEN 半
1. Closed:关闭状态(断路器关闭),所有请求都正常访问。代理类维护了最近调用失败的次数, 如果某次调用失败,则使失败次数加1。如果最近失败次数超过了在给定时间内允许失败的阈值, 则代理类切换到断开(Open)状态。此时代理开启了一个超时时钟,当该时钟超过了该时间,则切 换到半断开(Half-Open)状态。该超时时间的设定是给了系统一次机会来修正导致调用失败的错 误。
2. Open:打开状态(断路器打开),所有请求都会被降级。Hystix会对请求情况计数,当一定时间 内失败请求百分比达到阈值,则触发熔断,断路器会完全关闭。默认失败比例的阈值是50%,请求 次数最少不低于20次。
3. Half Open:半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。随后断路 器会自动进入半开状态。此时会释放1次请求通过,若这个请求是健康的,则会关闭断路器,否则 继续保持打开,再次进行5秒休眠计时。
使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超 时时间,堆积的请求堆积入线程池队列。
使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判 断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请 求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发 流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)
1. toObservable() 方法 :未做订阅,只是返回一个Observable 。
2. observe() 方法 :调用 #toObservable() 方法,并向 Observable 注册 rx.subjects.ReplaySubject 发起订阅。
3. queue() 方法 :调用 #toObservable() 方法的基础上,调用:Observable#toBlocking() 和 BlockingObservable#toFuture() 返回 Future 对象
4. execute() 方法 :调用 #queue() 方法的基础上,调用 Future#get() 方法,同步返回 #run() 的执 行结果。
Sentinel 是阿里巴巴开源的一款断路器实现
1. Sentinel 核心库
2. Dashboard
3. Sentinel 来进行熔断保护
1. 定义资源
资源:可以是任何东西,一个服务,服务里的方法,甚至是一段代码
2. 定义规则
规则:Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则和 热点参数规则。Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效
3. 检验规则是否生效
下载启动控制台
(1)获取 Sentinel 控制台
(2)启动
客户端能接入控制台
(1) 引入JAR包
(2)配置启动参数
查看机器列表以及健康情况
实现步骤
1、搭建工程
2、引入依赖
3、 配置熔断降级方法
Spring Cloud Alibaba Sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,在构造RestTemplate bean的时候需要加上 @SentinelRestTemplate 注解。
注意:@SentinelRestTemplate 注解中 ExceptionUtil 的 handleException 属性对应的方法 声明如下:
/** * 熔断降级 */ public class ExceptionUtil { //限流熔断业务逻辑 public static SentinelClientHttpResponse handleBlock(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) { System.err.println("Oops: " + ex.getClass().getCanonicalName()); return new SentinelClientHttpResponse("限流熔断降级"); } //异常熔断业务逻辑 public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) { System.err.println("fallback: " + ex.getClass().getCanonicalName()); return new SentinelClientHttpResponse("异常熔断降级"); } }
Sentinel RestTemplate 限流的资源规则提供两种粒度
httpmethod:schema://host:port/path :协议、主机、端口和路径
httpmethod:schema://host:port :协议、主机和端口
实现步骤
(1) 引入依赖
(2) 开启sentinel 支持
feign:
sentinel:
enabled: true
(3)配置FeignClient
//指定需要调用的微服务名称 @FeignClient(name="shop-service-product",fallback = ProductFeginClientCallBack.class)
public interface ProductFeginClient {
//调用的请求路径
@RequestMapping(value = "/product/{id}",method = RequestMethod.GET) public Product findById(@PathVariable("id") Long id);
}
和使用Hystrix的方式基本一致,需要配置FeignClient接口以及通过fallback 指定熔断降级方法
(4)配置熔断方法
/**
* 实现自定义的ProductFeginClient接口 * 在接口实现类中编写熔断降级方法 */
@Component
public class ProductFeginClientCallBack implements ProductFeginClient {
/**
* 降级方法 */
public Product findById(Long id) {
Product product = new Product(); product.setId(-1l); product.setProductName("熔断:触发降级方法"); return product;
} }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。