SpringCloud Alibaba - Sentinel篇

一、Sentinel快速入门


image-20230920210017106

Sentinel官网地址:https://sentinelguard.io/zh-cn/index.html

Sentinel项目地址:https://github.com/alibaba/Sentinel

Sentinel是阿里巴巴开源的一款微服务流量治理组件,主要以流量为切入点,从流量限流、熔断降级、系统负载保护等多个维度来帮助开发者保障微服务的稳定性。(对标产品:Springcloud Hystrix 豪猪哥)

Sentinel分为两个部分:

  • 核心库(Java客户端):该jar包不依赖任何框架,能够运行于 Java 8 及以上版本,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
  • 控制台(Dashboard):相当于是Sentinel框架的管理中心,可以通过图形化界面对Sentinel进行配置、监控(可以对服务的流量、请求、响应等指标进行监控)等操作,从而更好地保障应用的稳定性和可靠性。

image-20230920213830678

两款熔断框架对比:

功能SentinelHystrix(豪猪哥)
线程隔离信号量隔离线程池隔离/信号量隔离
熔断策略基于慢调用比例或异常比例基于异常比例
限流基于QPS,支持流量整形有限的支持
Fallback支持支持
控制台开箱即用,可配置规则、查看秒级监控、机器发现等不完善
配置方式基于控制台,重启后失效基于注解或配置文件,永久生效

1. 启动sentinel-dashboard控制台


通过可视化更方便操作Sentinel。

1、下载sentinel-dashboard的jar包:https://github.com/alibaba/Sentinel/releases/tag/1.8.6

image-20230921001906722

2、命令行运行jar方式启动控制台:(或者构建镜像丢到容器中启动)

java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar

参数介绍:

  • -Dserver.port=8090:指定Sentinel控制台程序的端口为8090。

  • -Dcsp.sentinel.dashboard.server=localhost:8090:Sentinel控制台的访问地址,客户端会自动向该地址发送心跳包。

  • -Dproject.name=sentinel-dashboard:指定Sentinel控制台程序显示的名称。

  • 文档地址:https://github.com/alibaba/Sentinel/wiki/%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E9%A1%B9

image-20230921004704830

3、访问sentinel的控制台:http://localhost:8090/,默认账号/密码:都是sentinel。

image-20230921005003769

登录成功后,便可查看控制台内部信息,默认会监控sentinel-dashboard服务本身:

image-20230921005247618

image-20230921005457889

image-20230921005524797


2. 构建微服务环境


数据库准备:

CREATE DATABASE cloud_demo DEFAULT CHARACTER SET utf8mb4;use cloud_demo;DROP TABLE IF EXISTS `tb_user`;CREATE TABLE `tb_user`  (`id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '收件人',`address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址',PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;INSERT INTO `tb_user` VALUES (1, '潘掌柜', '黑龙江省牡丹江市');
INSERT INTO `tb_user` VALUES (2, '文二狗', '陕西省西安市');
INSERT INTO `tb_user` VALUES (3, '华沉鱼', '湖北省十堰市');
INSERT INTO `tb_user` VALUES (4, '张必沉', '天津市');
INSERT INTO `tb_user` VALUES (5, '郑爽爽', '辽宁省沈阳市大东区');
INSERT INTO `tb_user` VALUES (6, 'kunkun', '山东省青岛市');DROP TABLE IF EXISTS `tb_order`;CREATE TABLE `tb_order`  (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单id',`user_id` bigint(20) NOT NULL COMMENT '用户id',`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品名称',`price` bigint(20) NOT NULL COMMENT '商品价格',`num` int(10) NULL DEFAULT 0 COMMENT '商品数量',PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `username`(`name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;INSERT INTO `tb_order` VALUES (101, 1, 'Apple 苹果 iPhone 12 ', 699900, 1);
INSERT INTO `tb_order` VALUES (102, 2, '雅迪 yadea 新国标电动车', 209900, 1);
INSERT INTO `tb_order` VALUES (103, 3, '骆驼(CAMEL)休闲运动鞋女', 43900, 1);
INSERT INTO `tb_order` VALUES (104, 4, '小米10 双模5G 骁龙865', 359900, 1);
INSERT INTO `tb_order` VALUES (105, 5, 'OPPO Reno3 Pro 双模5G 视频双防抖', 299900, 1);
INSERT INTO `tb_order` VALUES (106, 6, '美的(Midea) 新能效 冷静星II ', 544900, 1);
INSERT INTO `tb_order` VALUES (107, 2, '西昊/SIHOO 人体工学电脑椅子', 79900, 1);
INSERT INTO `tb_order` VALUES (108, 3, '梵班(FAMDBANN)休闲男鞋', 31900, 1);

image-20230921020130649


2.1 创建父工程

springboot版本2.7.12,springcloud版本2021.0.3。

创建maven工程,删除src目录,并向pom文件中引入一些依赖:

image-20230921011829295

image-20230921012711687

<?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"><modelVersion>4.0.0</modelVersion><groupId>cn.z3inc</groupId><artifactId>sentinel-demo</artifactId><packaging>pom</packaging><!--pom代表聚合工程--><version>1.0</version><!-- springboot工程 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version><relativePath/> <!-- lookup parent from repository --></parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><org.projectlombok.version>1.18.20</org.projectlombok.version><spring-cloud.version>2021.0.3</spring-cloud.version><spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version><mybatis-plus.version>3.4.3</mybatis-plus.version><hutool.version>5.8.11</hutool.version><mysql.version>8.0.23</mysql.version></properties><!-- 对依赖包进行管理 --><dependencyManagement><dependencies><!-- 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><!-- 数据库驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- mybatis plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!-- hutool工具类 --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency></dependencies></dependencyManagement><dependencies><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${org.projectlombok.version}</version></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><!--打包跳过单元测试--><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><skipTests>true</skipTests></configuration></plugin></plugins>
</build></project>

2.2 创建用户微服务

1、创建用户模块

image-20230921013420839

2、引入依赖:

<?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"><modelVersion>4.0.0</modelVersion><parent><groupId>cn.z3inc</groupId><artifactId>sentinel-demo</artifactId><version>1.0</version></parent><artifactId>user-service</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--nacos注册中心依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><!--springmvc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mp--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--hutool工具类--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency></dependencies><!--打包插件--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

3、编写application.yml文件配置:

server:port: 9001spring:application:name: user-service #服务名称cloud:nacos:# nacos注册中心配置discovery:server-addr: 127.0.0.1:8848 #nacos服务器地址# 数据库配置datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/cloud_demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456# mp配置
mybatis-plus:mmapper-locations: classpath:mapper/*.xml #mapper配置文件存放路径type-aliases-package: cn.z3inc.user.pojo # 类型别名(实体类所在包)configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #配置标准sql输出map-underscore-to-camel-case: true #开启驼峰映射#日志级别
logging:level:cn.z3inc: debugpattern:dateformat: MM-dd HH:mm:ss:SSS # 格式化输出日期

4、编写启动类:

@SpringBootApplication
@MapperScan("cn.z3inc.user.mapper")
public class UserServiceApplication {public static void main(String[] args) {SpringApplication.run(UserServiceApplication.class, args);}
}

5、编写业务:

实体类:

package cn.z3inc.user.pojo;import lombok.Data;@Data
public class User {private Long id;private String username;private String address;
}

mapper接口:

package cn.z3inc.user.mapper;import cn.z3inc.user.pojo.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper extends BaseMapper<User> {}

service接口:

package cn.z3inc.user.service;import cn.z3inc.user.pojo.User;
import com.baomidou.mybatisplus.extension.service.IService;public interface UserService extends IService<User> {
}
package cn.z3inc.user.service.impl;import cn.z3inc.user.mapper.UserMapper;
import cn.z3inc.user.pojo.User;
import cn.z3inc.user.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

controller:

package cn.z3inc.user.controller;import cn.z3inc.user.pojo.User;
import cn.z3inc.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 根据ID获取用户信息** @param id 用户ID* @return*/@GetMapping("/{id}")public User findById(@PathVariable("id") Long id) {return userService.getById(id);}/*** 修改用户信息** @param user 用户信息*/@PutMapping("/update")public void updateUser(@RequestBody User user) {userService.updateById(user);}/*** 根据ID删除用户** @param id* @return*/@DeleteMapping("/{id}")public void deleteUser(@PathVariable("id") Long id) {userService.removeById(id);}/***  新增用户* @param user*/@PostMapping("/save")public void saveUser(@RequestBody User user) {userService.save(user);        }
}

image-20230921153653979

6、启动nacos、用户微服务测试

.\startup.cmd -m standalone

image-20230921102040129

image-20230921154742489


2.3 创建订单微服务

1、创建订单模块

image-20230921155433895

2、引入依赖:

<?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"><modelVersion>4.0.0</modelVersion><parent><groupId>cn.z3inc</groupId><artifactId>sentinel-demo</artifactId><version>1.0</version></parent><artifactId>order-service</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- openfeign 微服务远程调用  --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- loadbalancer 实现客户端做负载均衡 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!--nacos注册中心依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><!--springmvc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mp--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--hutool工具类--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency></dependencies><!--打包插件--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

3、编写application.yml配置:

server:port: 9001spring:application:name: user-service #服务名称cloud:nacos:# nacos注册中心配置discovery:server-addr: 127.0.0.1:8848 #nacos服务器地址# 数据库配置datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/cloud_demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456# mp配置
mybatis-plus:mmapper-locations: classpath:mapper/*.xml #mapper配置文件存放路径type-aliases-package: cn.z3inc.order.pojo # 类型别名(实体类所在包)configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #配置标准sql输出map-underscore-to-camel-case: true #开启驼峰映射global-config:db-config:id-type: auto # 主键策略table-prefix: tb_ # 表名前缀配置#日志级别
logging:level:cn.z3inc: debugpattern:dateformat: MM-dd HH:mm:ss:SSS # 格式化输出日期

4、编写启动类:

package cn.z3inc.order;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@EnableFeignClients(basePackages = "cn.z3inc.order.feign") //开启feign远程调用
@SpringBootApplication
@MapperScan("cn.z3inc.order.mapper")
public class OrderServiceApplication {public static void main(String[] args) {SpringApplication.run(OrderServiceApplication.class, args);}
}

5、编写业务:

实体类:

//用户实体
@Data
public class User {private Long id;private String username;private String address;
}// 订单实体
@Data
public class Order {private Long id;private String name;private Long price;private Integer num;private Long userId;@TableField(exist = false) // 排除数据表中不存在的字段private User user;
}

mapper接口:

package cn.z3inc.order.mapper;import cn.z3inc.order.pojo.Order;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface OrderMapper extends BaseMapper<Order> {}

service接口:

package cn.z3inc.order.service;import cn.z3inc.order.pojo.Order;
import com.baomidou.mybatisplus.extension.service.IService;public interface OrderService extends IService<Order> {//根据id查订单Order findById(Long id);
}

feign接口:

package cn.z3inc.order.feign;import cn.z3inc.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;/***  用户服务Feign接口*/
@FeignClient("user-service")//指定要调用的服务名称
public interface UserClient {/*主要是基于SpringMVC的注解来声明远程调用的信息,比如:- 服务名称:userservice- 请求方式:GET- 请求路径:/user/{id}- 请求参数:Long id- 返回值类型:User*/// 定义远程调用方法// 通过id查用户@GetMapping("/user/{id}") //调用对应controller的方法路径User findById(@PathVariable("id") Long id);// @PathVariable注解一定要指定参数名称,否则会报错
}

service接口实现类:

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {@Autowiredprivate UserClient userClient;@Overridepublic Order findById(Long id) {Order order = super.getById(id);User user = userClient.findById(order.getUserId());//微服务远程调用order.setUser(user);return order;}
}

controller:

package cn.z3inc.order.controller;import cn.z3inc.order.pojo.Order;
import cn.z3inc.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/order")
public class OrderController {@Autowiredprivate OrderService orderService;@GetMapping("/{orderId}")public Order findById(@PathVariable("orderId") Long orderId) {return orderService.findById(orderId);}
}

6、测试:

image-20230921163715671


2.4 搭建网关微服务

1、创建网关模块

image-20230921164143848

2、引入依赖:

<dependencies><!--gateway网关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--loadbalancer代替ribbon--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!--nacos注册中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>
</dependencies>

3、修改application.yml配置:

server:port: 10010 # 网关的服务端口
spring:application:name: gateway # 服务名称cloud:nacos:server-addr: localhost:8848 # nacos服务地址# 网关的配置gateway:# 跨域配置globalcors:cors-configurations:'[/**]':allowed-origin-patterns: "*"allowed-headers: "*"allow-credentials: trueallowed-methods:- GET- POST- DELETE- PUT- OPTION# 网关路由配置        routes: - id: user-service # 路由id    uri: lb://user-service # 路由地址predicates: # 路由断言(匹配规则)- Path=/user/** - id: order-serviceuri: lb://order-servicepredicates:- Path=/order/**

4、编写启动类:

package cn.z3inc.gateway;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class, args);}
}

image-20230921202520666

5、测试:

image-20230921202050740

image-20230921202210196


3. 整合Sentinel


向订单微服中引入sentinel依赖,并连接sentinel-dashboard控制台进行监控。

1、引入sentinel依赖:

<!--sentinel-->
<dependency><groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2、修改订单服务的application.yml文件,添加sentinel控制台配置:

spring:cloud: sentinel:transport:dashboard: localhost:8090 #控制台地址http-method-specify: true #开启请求方式前缀  

image-20230922212832817

3、重启订单微服务

4、访问订单微服务接口:http://localhost:9002/order/102

5、访问sentinel-dashboard控制台,查看订单服务请求资源:http://localhost:8090

image-20230922113918905

image-20230922113445998

簇点链路:就是项目内的调用链路。链路中被Sentinel监控的每个接口就是一个资源。默认情况下Sentinel会监控SpringMVC的每一个Endpoint(http接口)。限流、熔断等都是针对簇点链路中的资源设置的,而资源名默认就是接口的请求路径。


二、请求限流


请求限流:限制访问接口的请求的并发量,避免服务因流量激增出现故障。

也是在sentinel控制台中配置,点击指定簇点链路后面的流控按钮,便可做限流处理:

image-20230922120334138

image-20230922120746025


使用 JMeter做压测:

(1)为测试计划创建线程组

image-20230922124550510

image-20230922125347750

(2)为线程组添加http取样器:

image-20230922125853615

image-20230922130155922

(3)为http取样器添加监听报告:

image-20230922130423316

(4)为http取样器添加查看结果树:

image-20230922130624205

(5)执行测试

image-20230922131029049

image-20230922131235248

image-20230922132722842


最后控制台查看监控结果:

image-20230922131159127

可以看出这个接口,通过的QPS为6,拒绝的QPS为4,符合我们的预期。


三、线程隔离


限流可以降低服务器压力,尽量减少因并发流量引起的服务故障的概率,但并不能完全避免服务故障。一旦某个服务出现故障,我们必须隔离对这个服务的调用,避免发生雪崩。

线程隔离:也叫做舱壁模式,模拟船舱隔板的防水原理。通过限定每个业务使用的线程数量,将故障业务隔离,避免故障扩散。(好处:即使服务崩了损失一部分线程,也不会影响到整个 tomcat 的资源)

image-20230922134001388


1. OpenFeign整合Sentinel


对订单服务的FeignClient接口做线程隔离。

修改订单服务的application.yml文件,配置开启Feign的sentinel功能:

feign:sentinel:enabled: true # 开启feign对sentinel的支持

image-20230922135021576

重启订单服务,可以看到查询用户的FeignClient自动变成了一个簇点资源:

image-20230922135404445


2. 配置线程隔离


给查询用户feign接口的簇点资源配置并发线程数:(最多使用5个线程)

image-20230922140117810

image-20230922135836861

image-20230922200857542

执行JMeter测试脚步,每秒发送100个请求:

image-20230922140908719

测试结果如下:

image-20230922195816752


四、服务熔断


服务熔断:由 断路器 统计请求的异常比例或慢调用比例,如果超出阈值则会 熔断 该业务,则拦截该接口的请求。熔断期间,所有请求快速失败,全都走fallback降级逻辑,避免影响到当前服务。(Hystrix豪猪哥的做法:如果feign接口调不通,那就走feign接口实现类的逻辑,避免服务雪崩)

image-20230923144019242


1. 编写降级逻辑


跟豪猪哥的用法类似。

触发限流或熔断后的请求不一定要直接报错,也可以返回一些默认数据或者友好提示,用户体验会更好。

通常为FeignClient编写失败后的降级逻辑有两种方式:

  • 方式一:FallbackClass,无法对远程调用的异常做处理。
  • 方式二:FallbackFactory,可以对远程调用的异常做处理(推荐使用)。

1、为订单服务的UserClient定义降级处理类,实现FallbackFactory接口。

package cn.z3inc.order.fallback;import cn.z3inc.order.feign.UserClient;
import cn.z3inc.order.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;/*** UserClient降级处理类**/
@Slf4j
public class UserClientFallback implements FallbackFactory<UserClient> {// 定义userclient降级逻辑@Overridepublic UserClient create(Throwable cause) {return new UserClient(){@Overridepublic User findById(Long id) { log.error("远程调用UserClient#findById方法出现异常,参数:{}", id, cause);return new User();}};}
}

image-20230923151519698

2、创建一个配置类,把UserClientFallback注册为一个Bean:

package cn.z3inc.order.config;import cn.z3inc.order.fallback.UserClientFallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;@Slf4j
public class DefaultFeignConfig {@Beanpublic UserClientFallback userClientFallback() {return new UserClientFallback();}
}

3、在UserClient中配置刚才创建的降级处理类:

/***  用户服务Feign接口*/
@FeignClient(value = "user-service", //指定要调用的服务名称configuration = DefaultFeignConfig.class, // 指定Feign的配置类fallbackFactory = UserClientFallback.class // 指定回退工厂类
)
public interface UserClient {

image-20230923152127413

4、重启订单服务,将用户服务停掉&测试:

image-20230923152307420


2. 服务熔断


当远程调用的服务挂掉后,直接走降级逻辑,避免影响到当前服务。也就是将feign接口进行熔断。当远程调用服务恢复正常后,再允许调用该接口。这其实就是断路器的工作模式了。

Sentinel中的断路器不仅可以统计某个接口的慢请求比例,还可以统计异常请求比例。当这些比例超出阈值时,就会熔断该接口,即拦截访问该接口的一切请求,降级处理;当该接口恢复正常时,再放行对于该接口的请求。
断路器的工作状态切换有一个状态机来控制:

状态机包括三个状态:

  • closed:关闭状态,断路器放行所有请求,并开始统计异常比例、慢请求比例。超过阈值则切换到open状态
  • open:打开状态,服务调用被熔断,访问被熔断服务的请求会被拒绝,快速失败,直接走降级逻辑。Open状态持续一段时间后会进入half-open状态
  • half-open:半开状态,放行一次请求,根据执行结果来判断接下来的操作。
    • 请求成功:则切换到closed状态
    • 请求失败:则切换到open状态

我们可以在控制台通过点击簇点链路后的熔断按钮来配置熔断策略:(持久化需要写到nacos配置文件里)

image-20230923153302326

image-20230923153424668

这种是按照慢调用比例来做熔断,上述配置的含义是:

  • RT超过200毫秒的请求调用就是慢调用
  • 统计最近1000ms内的最少5次请求,如果慢调用比例不低于0.5,则触发熔断
  • 熔断持续时长20s

使用jmeter测试:

image-20230923154511253

image-20230923154811934

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/139956.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Linux MyFile

在之前&#xff0c;我们应该都多少接触过了C语言的文件管理&#xff0c;fopen&#xff0c;fclose&#xff0c;fputs....等函数的用法&#xff0c;也分析了系统层面上C语言是如何实现文件管理的。 回顾 上一个文章&#xff0c;我们讲解了十分重要的知识&#xff0c;在文件被打…

成集云 | 用友NC集成聚水潭ERP(用友NC主管供应链)| 解决方案

源系统成集云目标系统 方案介绍 用友NC是用友NC产品的全新系列&#xff0c;是面向集团企业的世界级高端管理软件。它以“全球化集团管控、行业化解决方案、全程化电子商务、平台化应用集成”的管理业务理念而设计&#xff0c;采用J2EE架构和先进开放的集团级开发平台…

平板用的触控笔什么牌子好?性价比高的触控笔推荐

随着平板电脑的普及&#xff0c;越来越多用户为了方便都选择了电容笔&#xff0c;电容笔已经完全代替了我们的手指&#xff0c;并且使我们的书写速度得到了极大的提升。然而&#xff0c;因为其的独特的重力压感功能与芯片技术&#xff0c;导致了原装笔的售价一直居高不下&#…

JavaScript - canvas - 放大镜

效果 示例 项目结构&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>放大镜</title><style type"text/css">div {width: 200px;height: 200px;display: inline-bl…

2023-09-20 Android CheckBox 让文字显示在选择框的左边

一、CheckBox 让文字在选择框的左边 &#xff0c;在布局文件里面添加下面一行就可以。 android:layoutDirection"rtl" 即可实现 android:paddingStart"10dp" 设置框文间的间距 二、使用的是left to right <attr name"layoutDirection">&…

RGB格式

Qt视频播放器实现&#xff08;目录&#xff09; RGB的使用场景 目前&#xff0c;数字信号源&#xff08;直播现场的数字相机采集的原始画面&#xff09;和显示设备&#xff08;手机屏幕、笔记本屏幕、个人电脑显示器屏幕&#xff09;使用的基本上都是RGB格式。 三原色 RGB是…

网络协议层次模型

OSI 七层模型 在 OSI 网络分层模型中&#xff0c;每个分层都接收由它下一层所提供的特定服务&#xff0c;并且负责为自己的上一层提供特定的服务。上下层之间进行交互时所遵循的约定叫做接口 &#xff1b;同一层之间的交互所遵循的约定叫做协议&#xff0c; 下图是 OSI 七层…

2023华为杯研究生数学建模竞赛CDEF题思路+模型代码

全程更新华为杯研赛CDEF题思路模型及代码&#xff0c;大家查看文末名片获取 华为杯C题思路分析 问题一 在每个评审阶段&#xff0c;作品通常都是随机分发的&#xff0c;每份作品需要多位评委独立评审。为了增加不同评审专家所给成绩之间的可比性&#xff0c;不同专家评审的作…

SpringBoot轻松实现项目集成Knife4j接口文档

Knife4j 介绍 Knife4j 官网 Knife4j是一款基于Swagger生成API文档的增强工具&#xff0c;它简化了开发者构建和管理RESTful API文档的过程。通过自动扫描项目中的接口信息&#xff0c;Knife4j能够生成详细、易读的API文档&#xff0c;无需手动编写和维护。它提供交互式的接口调…

CSP-J/S 2023第一轮认证晋级分数线有些爆冷,超出想象

昨天广东、江西、内蒙古、河北、江苏、吉林、四川相继公布了第一轮认证成绩和晋级分数线。 爆冷 说实在话&#xff0c;看到这个分数线&#xff0c;我有些意外。 省份 CSP-J CSP-S 江西 55 29 内蒙古 30 20 河北 48 20 江苏 72.5 52.5 吉林 52 33 四川 67 55 就拿我们大河北来…

02强化学习基本概念

强化学习基本概念 前言1、State、Action、Policy等① State② Action③ State transition④ State transition probability⑤ Polity 2、Reward、Return、MDP等① Reward② Trajectory and return③ Discounted return④ Episode⑤ MDP 总结&#xff1a; 前言 本文来自西湖大学…

一、荔枝派nano启动USB虚拟串口功能FLASH版

一、搭建环境 本次使用的是ubuntu16.04进行搭建编译环境&#xff0c;具体的配置编译登都在荔枝派官网有介绍&#xff1a;https://wiki.sipeed.com/soft/Lichee/zh/Nano-Doc-Backup/build_sys/build_flash_copy.html 特别注意&#xff1a;本次需要使用的USB转串口功能&#xff0…

解决方案 | 如何构建市政综合管廊安全运行监测系统?

如何构建市政综合管廊安全运行监测系统&#xff1f;WITBEE万宾城市生命线智能监测仪器&#xff0c;5年免维护设计&#xff0c;集成10多项结构与气体健康监测指标&#xff0c;毫秒级快速响应&#xff0c;时刻感知综合管廊运行态势

【kafka】可视化工具KAFKA EAGLE安装分享

目录 准备&#xff1a; 开始&#xff1a; 1.解压 2.环境变量配置 3.生效环境变量配置文件 3.修改配置文件 1.修改zookeeper集群信息 2.修改mysql配置信息 4.启动 5.异常排查 6.页面 创作不易&#xff0c;你的动力是我创作的动力&#xff0c;如果有帮助请关注我&…

C 初级学习笔记(基础)

目录 1.预处理器指令 预定义宏 预处理器运算符 &#xff08;\&#xff09; 参数化的宏 头文件 .h 引用头文件操作 2.函数&#xff08;标识符&关键字&运算符&#xff09;存储类 函数参数 a. 标识符&关键字 b. 运算符&#xff08;算术、关系、逻辑、位、赋…

千巡翼X1 让航测无人机更小更轻更高效

利用无人机进行航空摄影测量&#xff0c;已成为测绘外业生产的主要方式&#xff0c;不仅方便快捷&#xff0c;更能全面准确获得成果。近年来&#xff0c;凭借快速高效、机动灵活、安全可靠、低成本等诸多优势&#xff0c;小型多旋翼无人机逐渐成为一些航测项目作业的新利器。 千…

方案:基于AI烟火识别与视频技术的秸秆焚烧智能化监控预警方案

一、方案背景 为严控秸秆露天焚烧&#xff0c;改善环境空气质量&#xff0c;各省相继发布秸秆禁烧工作内容。以安徽省为例&#xff0c;大气污染防治联席会议下发了该省2020年秸秆禁烧工作部署通知。2020年起&#xff0c;气象局将对全省秸秆焚烧火点实施卫星全年全时段监测&…

C语言入门Day_24 函数与指针

目录 前言&#xff1a; 1.指针和数组 2.函数和指针 3.易错点 4.思维导图 前言&#xff1a; 我们知道数组是用来存储多个数据的&#xff0c;以及我们可以用指针来指向一个变量。那么我们可以用指针来指向一个数组中的数据么&#xff1f; 指针除了可以像指向一个变量一样指…

三维模型3DTile格式轻量化压缩处理的数据质量提升方法分析

三维模型3DTile格式轻量化压缩处理的数据质量提升方法分析 在处理三维模型3DTile格式的轻量化压缩时&#xff0c;如何在减少数据量的同时&#xff0c;保证或提升数据质量是一大挑战。以下为一些提升数据质量的方法分析&#xff1a; 改进几何简化算法&#xff1a;在进行几何简化…

centos 7.9系统安装向日葵

1.下载地址 向日葵远程控制app官方下载 - 贝锐向日葵官网 2.下载依赖 yum install -y libappindicator-gtk3 安装好依赖之后&#xff0c;然后再安装向日葵软件 3.安装软件 sudo rpm -ivh 文件名.rpm 4.安装成功之后的位置