08.Sentinel整合Spring Cloud
一、项目配置
1.父亲POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.luoruiyuan</groupId>
<artifactId>Spring-Cloud-Lry</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Spring-Cloud-Lry</name>
<description>Spring-Cloud-Lry</description>
<packaging>pom</packaging>
<modules>
<module>stock</module>
<module>order</module>
<module>nacos-config</module>
<module>sentinel-java</module>
<module>order-sentinel</module>
</modules>
<properties>
<java.version>1.8</java.version>
<spring.boot.version>2.3.12.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR12</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.8.RELEASE</spring.cloud.alibaba.version>
</properties>
<!-- 版本管理(子工程引入了才会导jar包) -->
<dependencyManagement>
<dependencies>
<dependency>
<!--Spring Boot 版本管理-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Cloud 版本管理-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Cloud Alibaba 版本管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 直接导入jar包 -->
<dependencies>
<!-- Spring Boot启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- WEB场景 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 开发工具 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
2.子POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Spring-Cloud-Lry</artifactId>
<groupId>cn.luoruiyuan</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>order-sentinel</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- sentinel启动器 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
</project>
2.配置文件
server:
port: 8001
spring:
#应用名
application:
name: OrderSentinel
#热部署
devtools:
restart:
enabled: true
#sentinel服务端IP,端口
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:9908
3.controller
package cn.luoruiyuan.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author LRY
* @date 2022/8/6
*/
@RestController
public class OrderSentinelController {
@RequestMapping("/order")
public String order(){
return "订单访问";
}
}
4.控制台添加规则
5.一秒内访问两次以上就会被流控
二、异常处理
1.默认异常
2.通过@SentinelResource注解给单方法添加异常内容
/**
* @author LRY
* @date 2022/8/6
*/
@RestController
public class OrderSentinelController {
@RequestMapping("/order")
@SentinelResource(value = "order",blockHandler = "blockHandlerForOrder")
public String order(){
return "订单访问";
}
@RequestMapping("/orderA")
@SentinelResource(value = "orderA",blockHandler = "blockHandlerForOrder")
public String orderA(){
return "订单访问A";
}
public String blockHandlerForOrder(BlockException e){
return "访问被流控";
}
}
给资源名添加规则
访问就会显示自定义的错误信息了
3.统一异常处理
异常处理类
package cn.luoruiyuan.exception;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author LRY
* @date 2022/8/6
*/
@Component
@Slf4j
public class MyBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
log.info("=====================规则详细信息:"+e.getRule().toString());
//在 BlockException 类上面按 F4 可以看到所有实现类
//返回类型
String str="";
if(e instanceof FlowException){
str="流控了";
}else if(e instanceof DegradeException){
str="降级了";
}else if(e instanceof ParamFlowException){
str="热点参数限流";
}else if(e instanceof AuthorityException){
str="授权规则不通过";
}else if(e instanceof SystemBlockException){
str="触发系统保护规则";
}
response.setStatus(500);
response.setCharacterEncoding("utf-8");
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
new ObjectMapper().writeValue(response.getWriter(),str);
}
}
controller
package cn.luoruiyuan.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author LRY
* @date 2022/8/6
*/
@RestController
@RequestMapping("order")
public class OrderSentinelController {
@RequestMapping("/add")
public String add(){
return "添加订单";
}
@RequestMapping("/get")
public String get(){
return "查询订单";
}
}
规则设置,并访问
三、规则说明
1.流控
【流控模式】
1)关联
说明:/order/add 一秒访问1次以上,/order/get就会被流控
2)链路
说明:多个地址去访问一个资源,只限制其中一个。
修改配置文件“web-context-unify: false”
server:
port: 8001
spring:
#应用名
application:
name: OrderSentinel
#热部署
devtools:
restart:
enabled: true
#sentinel服务端IP,端口
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:9908
#默认为true没有维护链路
web-context-unify: falseb
controllern
package cn.luoruiyuan.controller;
import cn.luoruiyuan.service.OrderSentinelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author LRY
* @date 2022/8/6
*/
@RestController
@RequestMapping("order")
public class OrderSentinelController {
@Autowired
private OrderSentinelService service;
@RequestMapping("/list1")
public String list1(){
return service.getList("1");
}
@RequestMapping("/list2")
public String list2(){
return service.getList("2");
}
}
service
package cn.luoruiyuan.service;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;
/**
* @author LRY
* @date 2022/8/6
*/
@Service
public class OrderSentinelService {
@SentinelResource(value = "list",blockHandler ="blockHandlerForGetList" )
public String getList(String str){
return "List:"+str;
}
public String blockHandlerForGetList(String str, BlockException e){
return "List:"+str+". 被流控了.";
}
}
访问
【流控效果】
1)预热
说明:阈值为30,并不是一下就能接受30个请求,而是在10秒后接受30个请求,10秒内接受的请求是递增的效果进行接受,如下图:
2)等待
说明:比较适合洪峰流量(如下图),一秒超过10下一秒没有流量,就可以让超过的流动等待2000毫秒,然后进行处理。
2.熔断
1)慢调用比例
让服务休眠1秒
降级规则
说明:在1000毫秒内,10个请求调用时长大于200毫秒的数量占比为1%就进行熔断10秒,10秒后进入半开状态,如果接下来的第一次请求再慢于200毫秒就直接熔断,不会按照条件进行判断。
2)异常比例
说明:在10000毫秒内,10个请求有1%报错就熔断10秒,10后进入半开状态。
3)异常数
说明:10000毫秒内,10个请求有1个请求报错就熔断10秒,10秒后进入半开状态,如果在调用失败一次就直接熔断,不会按照设定的条件进行判断。
3.热点
热点异常使用@SentinelResource方式
@RestController
@RequestMapping("order")
public class OrderSentinelController {
@Autowired
private OrderSentinelService service;
@RequestMapping("/list/{id}")
public String list(@PathVariable("id") String id){
return service.getList(id);
}
}
@Service
public class OrderSentinelService {
@SentinelResource(value = "list",blockHandler ="blockHandlerForGetList" )
public String getList(String str){
return "List:"+str;
}
public String blockHandlerForGetList(String str, BlockException e){
return "List:"+str+". 热点异常处理.";
}
}
要在资源上面添加热点
要先新增然后去修改,才有高级部分
说明:普通限流是一秒5次,第0个参数为1(字符串类型)的资源限流一秒2次。
4.系统
说明:CPU占用率到达20%就进行处理
赞(1)
赏