一、简介
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。
Sentinel
以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel
具有以下特征
:
-
丰富的应用场景 : Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
-
完备的实时监控 : Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
-
广泛的开源生态 : Sentinel 提供开箱即用的与其它开源框架 / 库的整合模块,例如与 SpringCloud、 Dubbo 、 gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入Sentinel。
-
完善的 SPI 扩展点 : Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel
与
Hystrix
的区别:
有关的名词:
Sentinel
可以简单的分为
Sentinel
核心库和
Dashboard
。核心库不依赖
Dashboard
,但是结合Dashboard 可以取得最好的效果。
使用
Sentinel
来进行熔断保护,主要分为几个步骤:
(1)
定义资源
(2)
定义规则
(3)
检验规则是否生效
资源
:可以是任何东西,一个服务,服务里的方法,甚至是一段代码。
规则
:
Sentinel
支持以下几种规则:流量控制规则、熔断降级规则、系统保护规则、来源访问控制规则
和 热点参数规则。
Sentinel
的所有规则都可以在内存态中动态地查询及修改,修改之后立即生效 。
先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。
下载(您可以从官方网站中下载最新版本的控制台 jar 包):
https://github.com/alibaba/Sentinel/releases/download/1.6.3/sentinel-dashboard-1.6.3.jar
java -Dserver.port=9090 -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 及以上版本。
启动成功!!!
浏览器输入localhost:9090。
登陆之后:
二、微服务注册到sentinel
基础的项目目录。
首先父工程需要引入:
<dependencyManagement>
<dependencies>
<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>
</dependencies>
</dependencyManagement>
feign和rest子工程引入:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
配置文件放入:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:9090 #sentinel控制台的请求地址
分别启动两个子项目一个是9003端口,一个是9004。注册中心、以及消费者。
先分别访问两个接口:
之后刷新:
就出来了。对应的信息。
三、配置rest资源保护(熔断降级)
修改rest的order-service
package cn.itcast.order.controller;
import cn.itcast.order.entity.Product;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
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;
import java.util.List;
@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;
}
}
这里我们有两个方法,分别是熔断执行的降级方法,和抛出异常执行的降级方法。在hystrix中这个是不区分的,但是在sentinel是区分开的。
配置降级规则:
输入:
过5s再访问就可以了。这种全都是fallback的降级处理。其他处理看表:
四、加载本地配置和另一种配置
大家有没有发现,如果我们重启项目之后,再sentinel中配置的东西就都没了。我们可以搞一个本地配置。
写一个json
[
{
"resource": "orderFindById",
"controlBehavior": 0,
"count": 1,
"grade": 1,
"limitApp": "default",
"strategy": 0
}
]
- resource:资源名,即限流规则的作用对象
- count: 限流阈值
- grade: 限流阈值类型(QPS 或并发线程数)
- limitApp: 流控针对的调用来源,若为 default 则不区分调用来源
- strategy: 调用关系限流策略
- controlBehavior: 流量控制效果(直接拒绝、Warm Up、匀速排队)
然后在配置文件中加入,就可以了
cloud:
sentinel:
datasource:
ds1:
file:
file: classpath:flowrule.json
data-type: json
rule-type: flow
另一种配置rest方法:
定义一个类:
package cn.itcast.order.exception;
import cn.itcast.order.entity.Product;
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import feign.Feign;
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));
}
}
启动类加入:
package cn.itcast.order;
import cn.itcast.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.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EntityScan("cn.itcast.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);
}
}
之后就不需要之前 @SentinelResource(value="orderFindById",blockHandler = "orderBlockHandler",fallback = "orderFallback") 的配置了。
配置sentinel
配置feign组件的熔断降级:
实际上什么都不用变,就将添加依赖和配置文件修改为支持sentinel就可以了
#激活sentinel的支持
feign:
sentinel:
enabled: true
源码:git@gitee.com:Zesystem/springclouddemosentinel.git