Java之 Spring Cloud 微服务搭建Sentinel (第二个阶段)SpringBoot项目实现商品服务器端是调用
Posted 蓝盒子itbluebox
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java之 Spring Cloud 微服务搭建Sentinel (第二个阶段)SpringBoot项目实现商品服务器端是调用相关的知识,希望对你有一定的参考价值。
Java之 Spring Cloud 微服务搭建Sentinel (第二个阶段)【三】【SpringBoot项目实现商品服务器端是调用】
一、服务熔断Hystrix的替换方案
18年底Netflix官方宣布Hystrix 已经足够稳定,不再积极开发 Hystrix,该项目将处于维护模式。就目前来看Hystrix是比较稳定的,并且Hystrix只是停止开发新的版本,并不是完全停止维护,Bug什么的依然会维护的。因此短期内,Hystrix依然是继续使用的。但从长远来看,Hystrix总会达到它的生命周期,那么Spring Cloud生态中是否有替代产品呢?
1、替换方案介绍
Alibaba Sentinel
Sentinel 是阿里巴巴开源的一款断路器实现,目前在Spring Cloud的孵化器项目Spring Cloud Alibaba中的一员Sentinel本身在阿里内部已经被大规模采用,非常稳定。因此可以作为一个较好的替代品。
Resilience4J
Resilicence4J 一款非常轻量、简单,并且文档非常清晰、丰富的熔断工具,这也是Hystrix官方推荐的替代产品。
不仅如此,Resilicence4j还原生支持Spring Boot 1.x/2.x,而且监控也不像Hystrix一样弄Dashboard/Hystrix等一堆轮子,而是支持和Micrometer(Pivotal开源的监控门面,Spring Boot 2.x中的Actuator就是基于Micrometer的)、prometheus(开源监控系统,来自谷歌的论文)、以及Dropwizard metrics(Spring Boot曾经的模仿对象,类似于Spring Boot)进行整合。
2、 Sentinel概述
(1) Sentinel简介
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 的主要特性:
(2) Sentinel与Hystrix的区别
(3) 迁移方案
Sentinel官方提供了详细的由Hystrix 迁移到Sentinel 的方法
(4) 名词解释
Sentinel 可以简单的分为 Sentinel 核心库和 Dashboard。核心库不依赖 Dashboard,但是结合Dashboard 可以取得最好的效果。
使用 Sentinel 来进行熔断保护,主要分为几个步骤:
- 定义资源
- 定义规则
- 检验规则是否生效
资源:可以是任何东西,一个服务,服务里的方法,甚至是一段代码。
规则:Sentinel 支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则和 热点参数规则。
Sentinel 的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效先把可能需要保护的资源定义好,之后再配置规则。
也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。
3、Sentinel中的管理控制台
(1)下载启动控制台
1)获取 Sentinel 控制台
您可以从官方网站中下载最新版本的控制台 jar 包,下载地址如下:
https://github.com/alibaba/Sentinel/releases/download/1.6.3/sentinel-dashboard-1.6.3.jar
2)启动
使用如下命令启动控制台:java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.6.3.jar
其中 -Dserver.port=8080
用于指定 Sentinel
控制台端口为 8080
。
从 Sentinel 1.6.0
起,Sentinel
控制台引入基本的登录功能,默认用户名和密码都是 sentinel
。可以参考 鉴权模块文档 配置用户名和密码。
启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。
访问:
http://localhost:8080/#/login
4 、基于Sentinel的服务保护
(1)客户端能接入控制台(将所有的服务交给控制台管理)
控制台启动后,客户端需要按照以下步骤接入到控制台。
1)创建案例
之前都已经创建过这里直接导入代码学习即可
代码下载地址
https://download.csdn.net/download/qq_44757034/49774279
启动所有项目
2)引入依赖
需要注意SpringCloud-Alibaba与SpringCloud的版本关系
父工程引入alibaba实现的SpringCloud
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
子工程中引入sentinel
- order_service_feign
- order_service_rest
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
3)配置参数
- 在order_service_rest当中的application.yml
cloud:
sentinel:
transport:
dashboard: localhost:8080 #sentinel控制台的请求地址
- order_service_feign当中的application.yml
cloud:
sentinel:
transport:
dashboard: localhost:8080 #sentinel控制台的请求地址
4)启动运行测试
访问:http://localhost:9003/order/buy/1
http://localhost:9004/order/buy/1
访问:http://localhost:8080/#/login
(2)通用的资源保护
1)修改order_service_rest当中的OrderController
package cn.itbluebox.order.controller;
import cn.itbluebox.order.entity.Product;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/order")
public class OrderController
@Autowired
private RestTemplate restTemplate;
/**
* @SentinelResource
* blockHandler : 声明熔断时调用的降级方法
* fallback : 抛出异常执行的降级方法
* value : 自定义的资源名称
* * 不设置:当前全类名.方法名
*/
@SentinelResource(value="orderFindById",blockHandler = "orderBlockHandler",fallback = "orderFallback")
@RequestMapping(value = "/buy/id",method = RequestMethod.GET)
public Product findById(@PathVariable Long id)
if(id != 1)
throw new RuntimeException("错误");
return restTemplate.getForObject("http://service-product/product/1",Product.class);
/**
* 定义降级逻辑
* hystrix和sentinel
* 熔断执行的降级方法
* 抛出异常执行的降级方法
*/
public Product orderBlockHandler(Long id)
Product product = new Product();
product.setProductName("触发熔断的降级方法");
return product;
public Product orderFallback(Long id)
Product product = new Product();
product.setProductName("抛出异常执行的降级方法");
return product;
在需要被保护的方法上使用@SentinelResource注解进行熔断配置。与Hystrix不同的是,Sentinel对抛
出异常和熔断降级做了更加细致的区分,通过 blockHandler 指定熔断降级方法,通过 fallback 指定
触发异常执行的降级方法。
2)运行测试
访问http://localhost:9004/order/buy/1
访问http://localhost:8080/#/dashboard/metric/service-order-rest
访问测试:http://localhost:9004/order/buy/2进入降级方法
多刷新上述访问我们再次访问http://localhost:9004/order/buy/1也进入降级方法
等待5s以后再次访问http://localhost:9004/order/buy/1
恢复正常状态,退出降级方法
3)对于@SentinelResource的其他配置如下表:
注:1.6.0 之前的版本 fallback 函数只针对降级异常( DegradeException )进行处理,不能针对业务异常进行处理。
特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。
若未配置 blockHandler 、 fallback 和 defaultFallback ,则被限流降级时会BlockException 直接抛出。
5 、加载本地配置
一条限流规则主要由下面几个因素组成:
resource:资源名,即限流规则的作用对象
count: 限流阈值
grade: 限流阈值类型(QPS 或并发线程数)
limitApp: 流控针对的调用来源,若为 default 则不区分调用来源
strategy: 调用关系限流策略
controlBehavior: 流量控制效果(直接拒绝、Warm Up、匀速排队)
java代码 RuleConstant
配置文件添加如下配置
#通过文件读取限流规则
spring.cloud.sentinel.datasource.ds1.file.file=classpath: flowrule.json
spring.cloud.sentinel.datasource.ds1.file.data-type=json
spring.cloud.sentinel.datasource.ds1.file.rule-type=flow
1)修改order_service_rest当中的application.yml
ds1:
file:
file: classpath:flowrule.json
data-type: json
rule-type: flow
eager: true #立即加载
2)创建flowrule.json
[
"resource": "orderFindById",
"controlBehavior": 0,
"count": 1,
"grade": 1,
"limitApp": "default",
"strategy": 0
]
3)运行测试
访问:http://localhost:9004/order/buy/1
访问:http://localhost:8080/#/dashboard/identity/service-order-rest
6 、RestTemplate的资源保护
(1)修改order_service_rest当中的OrderController
去除之前配置的关于熔断的方法
package cn.itbluebox.order.controller;
import cn.itbluebox.order.entity.Product;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@RequestMapping("/order")
public class OrderController
@Autowired
private RestTemplate restTemplate;
/**
* @SentinelResource
* blockHandler : 声明熔断时调用的降级方法
* fallback : 抛出异常执行的降级方法
* value : 自定义的资源名称
* * 不设置:当前全类名.方法名
*/
@RequestMapping(value = "/buy/id",method = RequestMethod.GET)
public Product findById(@PathVariable Long id)
if(id != 1)
throw new RuntimeException("错误");
return restTemplate.getForObject("http://service-product/product/1",Product.class);
(2)在order_service_rest当中的RestOrderApplication上测试
1)创建ExceptionUtils
package cn.itbluebox.order.exception;
import cn.itbluebox.order.entity.Product;
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
public class ExceptionUtils
/**
* 静态方法
* 返回值: SentinelClientHttpResponse
* 参数 : request , byte[] , clientRquestExcetion , blockException
*/
//限流熔断业务逻辑
public static SentinelClientHttpResponse handleBlock(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution,
BlockException ex)
Product product = new Product();
product.setProductName("限流熔断降级");
return new SentinelClientHttpResponse(JSON.toJSONString(product));
//异常降级业务逻辑
public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution,
BlockException ex)
Product product = new Product();
product.setProductName("异常熔断降级");
return new SentinelClientHttpResponse(JSON.toJSONString(product));
2)完善RestOrderApplication
package cn.itbluebox.order;
import cn.itbluebox.order.exception.ExceptionUtils;
import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EntityScan("cn.itbluebox.order.entity")
public class RestOrderApplication
/**
* sentinel支持对restTemplate的服务调用使用sentinel方法.在构造
* RestTemplate对象的时候,只需要加载@SentinelRestTemplate即可
* 资源名:
* httpmethod:schema://host:port/path :协议、主机、端口和路径
* httpmethod:schema://host:port :协议、主机和端口
* @SentinelRestTemplate:
* 异常降级
* fallback : 降级方法
* fallbackClass : 降级配置类
* 限流熔断
* blockHandler
* blockHandlerClass
*/
@LoadBalanced
@Bean
@SentinelRestTemplate(fallbackClass = ExceptionUtils.class,fallback = "handleFallback",
blockHandler = "handleBlock",blockHandlerClass = ExceptionUtils.class)
public RestTemplate restTemplate()
return new RestTemplate();
public static void main(String[] args)
SpringApplication.run(RestOrderApplication.class,args);
3)运行测试
访问:http://localhost:9004/order/buy/1
访问:http://localhost:9004/order/buy/2
访问管理控制台:http://localhost:8080/#/dashboard/degrade/service-order-rest
访问测试:慢一些访问:http://localhost:9004/order/buy/1
快速多次访问
7 、Feign实现熔断
Sentinel 适配了 Feign 组件。如果想使用,除了引入 sentinel-starter 的依赖外还需要 2 个步骤:
- 配置文件打开 sentinel 对 feign 的支持: feign.sentinel.enabled=true
- 加入 openfeign starter 依赖使 sentinel starter 中的自动化配置类生效:
在order_service_feign当中的
(1)引入依赖
<!-- feign对Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId以上是关于Java之 Spring Cloud 微服务搭建Sentinel (第二个阶段)SpringBoot项目实现商品服务器端是调用的主要内容,如果未能解决你的问题,请参考以下文章