今天,我们就使用 Sentinel 实现接口的限流,并使用 Feign 整合 Sentinel 实现服务容错的功能,让我们体验下微服务使用了服务容错功能的效果。

因为内容仅仅围绕着 SpringCloud Alibaba技术栈展开,所以,这里我们使用的服务容错组件是阿里开源的 Sentinel。

当然,能够实现服务容错功能的组件不仅仅有 Sentinel,比如:Hystrix 和 Resilience4J 也能够实现服务容错的目的。

1. 关于 Sentinel

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性

1.1 Sentinel 的特征

丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 SpringCloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等

1.2 Sentinel 的主要特性

Sentinel 分为两个部分:

核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo /Spring Cloud 等框架也有较好的支持。控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器

2. 项目集成 Sentinel

在微服务项目中整合 Sentinel 是非常简单的,只需要在项目的 pom.xml 文件中引入 Sentinel 的依赖即可。不过在使用 Sentinel 时,需要安装 Sentinel 的控制台

2.1 安装 Sentinel 控制台

Sentinel 提供一个轻量级的控制台, 它提供机器发现、单机资源实时监控以及规则管理等功能

2.1.1 下载 sentinel-dashboard

到链接 下载链接 下载 Sentinel 控制台。我这里下载的是 sentinel-dashboard-1.8.5.jar

2.1.2 启动 sentinel-dashboard

Sentinel 控制台下载完成后,在本地启动 Sentinel 控制台,如下所示:

java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=localhost:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.5.jar

2.1.3 访问 sentinel-dashboard

启动后在浏览器中输入 http://localhost:8888 访问 Sentinel 控制台,如下所示: 输入默认的用户名 sentinel 和密码 sentinel,登录 Sentinel 控制台,如下所示: 至此,Sentinel 控制台下载并启动成功

2.2 项目集成 Sentinel

1、在订单微服务的 shop-orde r的 pom.xml 文件中添加Sentinel的相关依赖,如下所示

com.alibaba.cloud

spring-cloud-starter-alibaba-sentinel

2、在订单微服务的 shop-order 的 application.yml 文中加入 Sentinel 相关的配置,如下所示:

spring:

cloud:

sentinel:

transport:

port: 9999 #指定和Sentinel控制台交互的端口,任意指定一个未使用的端口即可

dashboard: 127.0.0.1:8888 #Sentinel控制台服务地址

3、为了让大家直观的感受到 Sentinel 的功能,这里我们先在订单微服务的 OrderController 类中新增一个测试接口,如下所示:

@GetMapping(value = "/test_sentinel")

public String testSentinel(){

log.info("测试Sentinel");

return "sentinel";

}

4、启动订单微服务,在浏览器中输入 http://localhost:8080/order/test_sentinel 访问在订单微服务中新增的接口。

5、刷新 Sentinel 页面,会发现已经显示了订单微服务的菜单,如下所示: 这里注意一下:

注意:直接启动订单微服务和 Sentinel,会发现 Sentinel 中没有订单微服务的数据,因为 Sentinel 是懒加载机制,所以需要访问一下接口,再去访问Sentinel 就有数据了

至此,订单微服务成功集成了 Sentinel

2.3 集成 Sentinel 限流功能

对提交订单的接口限流

在提交订单的接口 http://localhost:8080/order/submit_order 上实现限流,步骤如下:

1、首先访问下提交订单的接口 http://localhost:8080/order/submit_order ,使得 Sentinel 中能够捕获到提交订单的接口,并点击操作中的 流控 按钮,如下所示:

2、在新增流控规则显示框中的 QPS 单机阈值设置为 1,点击新增按钮,如下所示:

3、在浏览器中不断刷新 http://localhost:8080/order/submit_order? userId=1001&productId=1001&count=1 使得每秒访问的频率超过 1 次,会被 Sentinel 限流,如下所示:

至此,项目中集成了 Sentinel 并使用 Sentinel 实现了接口的限流。

3. Feign 整合 Sentinel 实现容错

我们之前在项目中集成了 Sentinel,并使用Sentinel实现了限流,如果订单微服务的下游服务,比如用户微服务和商品微服务出现故障,无法访问时,那订单微服务该如何实现服务容错呢?使用Sentinel就可以轻松实现

3.1 添加依赖并开启支持

1、在订单微服务的 shop-order 的 pom.xml 文件中添加 Sentinel 的相关依赖,如下所示:

com.alibaba.cloud

spring-cloud-starter-alibaba-sentinel

2、在订单微服务的 application.yml 文件中添加如下配置开启 Feign 对 Sentinel 的支持:

feign:

sentinel:

enabled: true

3.2 为远程调用实现容错

需要在订单微服务 shop-order 中,为远程调用接口实现容错方法。

1、这里,先为用户微服务实现容错。在订单微服务中新建 com.zzc.order.feign.fallback 包,并在此包下创建 UserServiceFallBack 类实现 UserService 接口,用于调用用户微服务的容错类,如下所示:

@Component

public class UserServiceFallBack implements UserService {

@Override

public User getUser(Long uid) {

User user = new User();

user.setId(-1L);

return user;

}

}

注意:

容错类需要实现一个被容错的接口,并实现这个接口的方法

2、指定容错类。,在订单微服务的 com.zzc.order.feign.UserService 接口上的 @FeignClient 注解上指定容错类,如下所示:

@FeignClient(value = "server-user", fallback = UserServiceFallBack.class)

public interface UserService {

@GetMapping(value = "/user/get/{uid}")

User getUser(@PathVariable("uid") Long uid);

}

3、修改订单微服务的业务实现类中提交订单的业务方法,如下所示:

// ...

if (user == null){

throw new RuntimeException("未获取到用户信息: " + JSONObject.toJSONString(orderParamVo));

}

if (user.getId() == -1){

throw new RuntimeException("触发了用户微服务的容错逻辑: " + JSONObject.toJSONString(orderParamVo));

}

Product product = productService.getProduct(orderParamVo.getProductId());

if (product == null){

throw new RuntimeException("未获取到商品信息: " + JSONObject.toJSONString(orderParamVo));

}

if (product.getId() == -1){

throw new RuntimeException("触发了商品微服务的容错逻辑: " + JSONObject.toJSONString(orderParamVo));

}

// ...

Result result = productService.updateCount(orderParamVo.getProductId(), orderParamVo.getCount());

if (result.getCode() != HttpCode.SUCCESS){

throw new RuntimeException("库存扣减失败");

}

if (result.getCode() == 1001){

throw new RuntimeException("触发了商品微服务的容错逻辑: " + JSONObject.toJSONString(orderParamVo));

}

可以看到,修改后的提交订单的业务方法主要增加了服务容错的判断逻辑

至此,我们在项目中使用Sentinel实现了服务容错的功能

3.3 测试服务容错

停掉所有的用户微服务和商品微服务(也就是只启动订单微服务),在浏览器中访问 http://localhost:8080/order/submit_order?userId=1001&productId=1001&count=1 ,结果如下所示:

当然,读者也可以测试:只启动用户、订单微服务;商品、订单微服务。

返回的原始数据:

触发了用户微服务的容错逻辑: {“count”:1,“empty”:false,“productId”:1001,“userId”:1001}

说明项目集成Sentinel成功实现了服务的容错功能

代码地址

代码已经上传至码云,码云地址

其中,数据库文件位于 db 文件夹下。

好文推荐

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: