Spring Cloud Alibaba微服务组件Sentinel实现熔断限流

目录
  • Sentinel简介
    • Sentinel具有如下特性:
  • 安装Sentinel控制台
  • 创建sentinel-service模块
  • 限流功能
    • 创建RateLimitController类
    • 根据URL限流
    • 自定义限流处理逻辑
  • 熔断功能
  • 与Feign结合使用
  • 使用Nacos存储规则
    • 原理示意图
    • 功能演示

Sentinel简介

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案,Sentinel 作为其核心组件之一,具有熔断与限流等一系列服务保护功能,本文将对其用法进行详细介绍。

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

Sentinel具有如下特性:

  • 丰富的应用场景:承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀,可以实时熔断下游不可用应用;
  • 完备的实时监控:同时提供实时的监控功能。可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况;
  • 广泛的开源生态:提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合;
  • 完善的 SPI 扩展点:提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。

安装Sentinel控制台

Sentinel控制台是一个轻量级的控制台应用,它可用于实时查看单机资源监控及集群资源汇总,并提供了一系列的规则管理功能,如流控规则、降级规则、热点规则等。

我们先从官网下载Sentinel,这里下载的是sentinel-dashboard-1.6.3.jar文件,

下载地址:https://github.com/alibaba/Sentinel/releases

下载完成后在命令行输入如下命令运行Sentinel控制台:

java -jar sentinel-dashboard-1.6.3.jar

Sentinel控制台默认运行在8080端口上,登录账号密码均为 sentinel,通过如下地址可以进行访问:http://localhost:8080

Sentinel控制台可以查看单台机器的实时监控数据。

创建sentinel-service模块

这里我们创建一个sentinel-service模块,用于演示Sentinel的熔断与限流功能。

在pom.xml中添加相关依赖,这里我们使用Nacos作为注册中心,所以需要同时添加Nacos的依赖:

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

在application.yml中添加相关配置,主要是配置了Nacos和Sentinel控制台的地址:

server:
  port: 8401
spring:
  application:
    name: sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置sentinel dashboard地址
        port: 8719
service-url:
  user-service: http://nacos-user-service
management:
  endpoints:
    web:
      exposure:
        include: '*'

限流功能

Sentinel Starter 默认为所有的 HTTP 服务提供了限流埋点,我们也可以通过使用@SentinelResource来自定义一些限流行为。

创建RateLimitController类

用于测试熔断和限流功能。

/**
 * 限流功能
 * Created by macro on 2019/11/7.
 */
@RestController
@RequestMapping("/rateLimit")
public class RateLimitController {
    /**
     * 按资源名称限流,需要指定限流处理逻辑
     */
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandler = "handleException")
    public CommonResult byResource() {
        return new CommonResult("按资源名称限流", 200);
    }
    /**
     * 按URL限流,有默认的限流处理逻辑
     */
    @GetMapping("/byUrl")
    @SentinelResource(value = "byUrl",blockHandler = "handleException")
    public CommonResult byUrl() {
        return new CommonResult("按url限流", 200);
    }
    public CommonResult handleException(BlockException exception){
        return new CommonResult(exception.getClass().getCanonicalName(),200);
    }
}

根据资源名称限流

我们可以根据@SentinelResource注解中定义的value(资源名称)来进行限流操作,但是需要指定限流处理逻辑。

  • 流控规则可以在Sentinel控制台进行配置,由于我们使用了Nacos注册中心,我们先启动Nacos和sentinel-service;
  • 由于Sentinel采用的懒加载规则,需要我们先访问下接口,Sentinel控制台中才会有对应服务信息,我们先访问下该接口:http://localhost:8401/rateLimit/byResource
  • 在Sentinel控制台配置流控规则,根据@SentinelResource注解的value值:

快速访问上面的接口,可以发现返回了自己定义的限流处理信息:

根据URL限流

我们还可以通过访问的URL来限流,会返回默认的限流处理信息。

在Sentinel控制台配置流控规则,使用访问的URL:

多次访问该接口,会返回默认的限流处理结果:http://localhost:8401/rateLimit/byUrl

自定义限流处理逻辑

我们可以自定义通用的限流处理逻辑,然后在@SentinelResource中指定。

创建CustomBlockHandler类用于自定义限流处理逻辑:

/**
 * Created by macro on 2019/11/7.
 */
public class CustomBlockHandler {
    public CommonResult handleException(BlockException exception){
        return new CommonResult("自定义限流信息",200);
    }
}

在RateLimitController中使用自定义限流处理逻辑:

/**
 * 限流功能
 * Created by macro on 2019/11/7.
 */
@RestController
@RequestMapping("/rateLimit")
public class RateLimitController {
    /**
     * 自定义通用的限流处理逻辑
     */
    @GetMapping("/customBlockHandler")
    @SentinelResource(value = "customBlockHandler", blockHandler = "handleException",blockHandlerClass = CustomBlockHandler.class)
    public CommonResult blockHandler() {
        return new CommonResult("限流成功", 200);
    }
}

熔断功能

Sentinel 支持对服务间调用进行保护,对故障应用进行熔断操作,这里我们使用RestTemplate来调用nacos-user-service服务所提供的接口来演示下该功能。

首先我们需要使用@SentinelRestTemplate来包装下RestTemplate实例:

/**
 * Created by macro on 2019/8/29.
 */
@Configuration
public class RibbonConfig {
    @Bean
    @SentinelRestTemplate
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

添加CircleBreakerController类,定义对nacos-user-service提供接口的调用:

/**
 * 熔断功能
 * Created by macro on 2019/11/7.
 */
@RestController
@RequestMapping("/breaker")
public class CircleBreakerController {
    private Logger LOGGER = LoggerFactory.getLogger(CircleBreakerController.class);
    @Autowired
    private RestTemplate restTemplate;
    @Value("${service-url.user-service}")
    private String userServiceUrl;
    @RequestMapping("/fallback/{id}")
    @SentinelResource(value = "fallback",fallback = "handleFallback")
    public CommonResult fallback(@PathVariable Long id) {
        return restTemplate.getForObject(userServiceUrl + "/user/{1}", CommonResult.class, id);
    }
    @RequestMapping("/fallbackException/{id}")
    @SentinelResource(value = "fallbackException",fallback = "handleFallback2", exceptionsToIgnore = {NullPointerException.class})
    public CommonResult fallbackException(@PathVariable Long id) {
        if (id == 1) {
            throw new IndexOutOfBoundsException();
        } else if (id == 2) {
            throw new NullPointerException();
        }
        return restTemplate.getForObject(userServiceUrl + "/user/{1}", CommonResult.class, id);
    }
    public CommonResult handleFallback(Long id) {
        User defaultUser = new User(-1L, "defaultUser", "123456");
        return new CommonResult<>(defaultUser,"服务降级返回",200);
    }
    public CommonResult handleFallback2(@PathVariable Long id, Throwable e) {
        LOGGER.error("handleFallback2 id:{},throwable class:{}", id, e.getClass());
        User defaultUser = new User(-2L, "defaultUser2", "123456");
        return new CommonResult<>(defaultUser,"服务降级返回",200);
    }
}

启动nacos-user-service和sentinel-service服务:

由于我们并没有在nacos-user-service中定义id为4的用户,所有访问如下接口会返回服务降级结果:http://localhost:8401/breaker/fallback/4

{
	"data": {
		"id": -1,
		"username": "defaultUser",
		"password": "123456"
	},
	"message": "服务降级返回",
	"code": 200
}

由于我们使用了exceptionsToIgnore参数忽略了NullPointerException,所以我们访问接口报空指针时不会发生服务降级:http://localhost:8401/breaker/fallbackException/2

与Feign结合使用

Sentinel也适配了Feign组件,我们使用Feign来进行服务间调用时,也可以使用它来进行熔断。

首先我们需要在pom.xml中添加Feign相关依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

在application.yml中打开Sentinel对Feign的支持:

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

在应用启动类上添加@EnableFeignClients启动Feign的功能;

创建一个UserService接口,用于定义对nacos-user-service服务的调用:

/**
 * Created by macro on 2019/9/5.
 */
@FeignClient(value = "nacos-user-service",fallback = UserFallbackService.class)
public interface UserService {
    @PostMapping("/user/create")
    CommonResult create(@RequestBody User user);
    @GetMapping("/user/{id}")
    CommonResult<User> getUser(@PathVariable Long id);
    @GetMapping("/user/getByUsername")
    CommonResult<User> getByUsername(@RequestParam String username);
    @PostMapping("/user/update")
    CommonResult update(@RequestBody User user);
    @PostMapping("/user/delete/{id}")
    CommonResult delete(@PathVariable Long id);
}

创建UserFallbackService类实现UserService接口,用于处理服务降级逻辑:

/**
 * Created by macro on 2019/9/5.
 */
@Component
public class UserFallbackService implements UserService {
    @Override
    public CommonResult create(User user) {
        User defaultUser = new User(-1L, "defaultUser", "123456");
        return new CommonResult<>(defaultUser,"服务降级返回",200);
    }
    @Override
    public CommonResult<User> getUser(Long id) {
        User defaultUser = new User(-1L, "defaultUser", "123456");
        return new CommonResult<>(defaultUser,"服务降级返回",200);
    }
    @Override
    public CommonResult<User> getByUsername(String username) {
        User defaultUser = new User(-1L, "defaultUser", "123456");
        return new CommonResult<>(defaultUser,"服务降级返回",200);
    }
    @Override
    public CommonResult update(User user) {
        return new CommonResult("调用失败,服务被降级",500);
    }
    @Override
    public CommonResult delete(Long id) {
        return new CommonResult("调用失败,服务被降级",500);
    }
}

在UserFeignController中使用UserService通过Feign调用nacos-user-service服务中的接口:

/**
 * Created by macro on 2019/8/29.
 */
@RestController
@RequestMapping("/user")
public class UserFeignController {
    @Autowired
    private UserService userService;
    @GetMapping("/{id}")
    public CommonResult getUser(@PathVariable Long id) {
        return userService.getUser(id);
    }
    @GetMapping("/getByUsername")
    public CommonResult getByUsername(@RequestParam String username) {
        return userService.getByUsername(username);
    }
    @PostMapping("/create")
    public CommonResult create(@RequestBody User user) {
        return userService.create(user);
    }
    @PostMapping("/update")
    public CommonResult update(@RequestBody User user) {
        return userService.update(user);
    }
    @PostMapping("/delete/{id}")
    public CommonResult delete(@PathVariable Long id) {
        return userService.delete(id);
    }
}

调用如下接口会发生服务降级,返回服务降级处理信息:http://localhost:8401/user/4

{
	"data": {
		"id": -1,
		"username": "defaultUser",
		"password": "123456"
	},
	"message": "服务降级返回",
	"code": 200
}

使用Nacos存储规则

默认情况下,当我们在Sentinel控制台中配置规则时,控制台推送规则方式是通过API将规则推送至客户端并直接更新到内存中。一旦我们重启应用,规则将消失。下面我们介绍下如何将配置规则进行持久化,以存储到Nacos为例。

原理示意图

首先我们直接在配置中心创建规则,配置中心将规则推送到客户端;

Sentinel控制台也从配置中心去获取配置信息。

功能演示

先在pom.xml中添加相关依赖:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

修改application.yml配置文件,添加Nacos数据源配置:

spring:
  cloud:
    sentinel:
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848
            dataId: ${spring.application.name}-sentinel
            groupId: DEFAULT_GROUP
            data-type: json
            rule-type: flow

在Nacos中添加配置:

添加配置信息如下:

[
    {
        "resource": "/rateLimit/byUrl",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false
    }
]

相关参数解释:

  • resource:资源名称;
  • limitApp:来源应用;
  • grade:阈值类型,0表示线程数,1表示QPS;
  • count:单机阈值;
  • strategy:流控模式,0表示直接,1表示关联,2表示链路;
  • controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;

clusterMode:是否集群。

发现Sentinel控制台已经有了如下限流规则:

快速访问测试接口,可以发现返回了限流处理信息:

参考资料

Spring Cloud Alibaba 官方文档:https://github.com/alibaba/spring-cloud-alibaba/wiki

使用到的模块

springcloud-learning
├── nacos-user-service -- 注册到nacos的提供User对象CRUD接口的服务
└── sentinel-service -- sentinel功能测试服务

项目源码地址

https://github.com/macrozheng/springcloud-learning

以上就是Spring Cloud Alibaba微服务组件Sentinel实现熔断限流的详细内容,更多关于Spring Cloud Sentinel熔断限流的资料请关注我们其它相关文章!

(0)

相关推荐

  • 聊聊SpringCloud和SpringCloudAlibaba的区别

    目录 SpringCloud和SpringCloudAlibaba的区别 SpringCloud Alibaba与Spring Cloud搭配方案 开源地址 SpringCloud几大痛点 SpringCloud Alibaba 的优势 SpringCloud Alibaba 和 Spring Cloud 搭配方案 版本配套关系 Spring Cloud Alibaba的依赖 注册中心.配置中心.网关的架构图 SpringCloud和SpringCloudAlibaba的区别 SpringClo

  • SpringCloudAlibaba整合Feign实现远程HTTP调用的简单示例

    目录 前言 环境 简单示例 Feign 的组成和支持的配置项 Feign 的组成 Feign 支持的配置项 Feign 的日志 Feign 的日志级别 自定义配置 Feign 的日志级别 全局配置 Feign 的日志级别 Feign 日志级别配置方式总结 项目源码 前言 Feign是Netflix开源的声明式HTTP客户端,致力于让编写http client更加简单,Feign可以通过声明接口自动构造请求的目标地址完成请求 环境 Spring Cloud Hoxton.SR9 + Spring

  • 使用SpringCloudAlibaba整合Dubbo

    目录 SpringCloudAlibaba整合Dubbo 构建服务接口 构建服务接口提供方 构建服务接口消费方法 SpringCloudAlibaba之Dubbo总结 Dubbo概述 Dubbo配置方式 其他一些有意思的地方 SpringCloudAlibaba整合Dubbo Spring Cloud是一套较为完整的架构方案,而Dubbo只是服务治理与RPC实现方案. Dubbo的注册中心采用了ZooKeeper,而Spring Cloud体系中的注册中心并不支持ZooKeeper.直到Spri

  • SpringCloud Alibaba项目实战之nacos-server服务搭建过程

    目录 1.Nacos简介 1.1.什么是Nacos 1.2.Nacos基本原理 2.Nacos-Server服务部署 2.1.standalone 模式 2.2.cluster 模式 源码地址:https://gitee.com/fighter3/eshop-project.git 持续更新中-- 大家好,我是三分恶. 这一节我们来学习SpringCloud Alibaba体系中一个非常重要的组件--Nacos. 1.Nacos简介 Nacos官方网站:https://nacos.io/zh-c

  • SpringCloudAlibaba分布式组件详解

    目录 分布式组件-SpringCloud Alibaba 简介 Nacos注册中心 OpenFeign远程调用 配置中心-简单实例 配置中心-命名空间 配置分组的概念 配置中心-加载多配置集 Gateway网关核心 Gateway创建测试网关 总结 分布式组件-SpringCloud Alibaba 简介 SpringCloudAlibaba的优势: 阿里使用过的组件经历了考验,性能强悍,设计合理,现在开源出来大家用成套的产品搭配完善的可视化界面给开发运维带来了极大的便利,搭建简单,学习曲线低.

  • SpringCloud Alibaba Nacos 整合SpringBoot Admin实战

    目录 1. Spring Boot Admin 是什么 2. Spring Boot Admin 服务端 2.1. 添加依赖(服务端) 2.2. 配置 application.yml 2.3启动类:AdminServerMain 2.4配置类 :SecuritySecureConfig (直接cp官方文档) 3. Spring Boot Admin 客户端 3.1 客户端依赖 3.2 客户端配置 3.3. 客户端运行 4. Spring Boot Admin 功能 1. Spring Boot

  • Spring Cloud Alibaba微服务组件Sentinel实现熔断限流

    目录 Sentinel简介 Sentinel具有如下特性: 安装Sentinel控制台 创建sentinel-service模块 限流功能 创建RateLimitController类 根据URL限流 自定义限流处理逻辑 熔断功能 与Feign结合使用 使用Nacos存储规则 原理示意图 功能演示 Sentinel简介 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案,Sentinel 作为其核心组件之一,具有熔断与限流等一系列服务保护功能,本文将对其用法进行详细介

  • Spring Cloud Alibaba Nacos服务治理平台,服务注册、RestTemplate实现微服务之间访问负载均衡访问的问题

    目录 Nacos简介 ☘Spring Cloud 组件依赖版本 ☘Nacos部署 ☘访问Nacos平台 Nacos服务注册.微服务访问.负载均衡实现 nacos-consumer微服务创建 ☘nacos-provider微服务创建 测试 Nacos简介 Github:https://github.com/alibaba/nacos官网文档:https://nacos.io/zh-cn/docs/what-is-nacos.htmlNacos 提供了发现.配置和管理微服务能力,能快速实现动态服务发

  • Spring Cloud Alibaba之Sentinel实现熔断限流功能

    微服务中为了防止某个服务出现问题,导致影响整个服务集群无法提供服务的情况,我们在系统访问量和业务量高起来了后非常有必要对服务进行熔断限流处理. 其中熔断即服务发生异常时能够更好的处理:限流是限制每个服务的资源(比如说访问量). spring-cloud中很多使用的是Hystrix组件来进行限流的,现在我们这里使用阿里的sentinel来实现熔断限流功能. sentinel简介 这个在阿里云有企业级的商用版本 应用高可用服务 AHAS:现在有免费的入门级可以先体验下,之后再决定是否使用付费的专业版

  • 浅谈Spring Cloud下微服务权限方案

    背景 从传统的单体应用转型Spring Cloud的朋友都在问我,Spring Cloud下的微服务权限怎么管?怎么设计比较合理?从大层面讲叫服务权限,往小处拆分,分别为三块:用户认证.用户权限.服务校验. 用户认证 传统的单体应用可能习惯了session的存在,而到了Spring cloud的微服务化后,session虽然可以采取分布式会话来解决,但终究不是上上策.开始有人推行Spring Cloud Security结合很好的OAuth2,后面为了优化OAuth 2中Access Token

  • spring cloud中微服务之间的调用以及eureka的自我保护机制详解

    上篇讲了spring cloud注册中心及客户端的注册,所以这篇主要讲一下服务和服务之间是怎样调用的 不会搭建的小伙伴请参考我上一篇博客:idea快速搭建spring cloud-注册中心与注册 基于上一篇的搭建我又自己搭建了一个客户端微服务: 所以现在有两个微服务,我们所实现的就是微服务1和微服务2之间的调用 注册中心就不用多说了,具体看一下两个微服务 application.yml配置也不用说了,不知道怎么配置的请参考我上篇博客 在project-solr中的constroller中: @R

  • spring cloud eureka微服务之间的调用详解

    微服务之间的调用如何实现 首先 你需要两个或以上的微服务模块 至于怎么创建可以参考我上一篇博客 spring cloud eureka注册中心 如果想在页面显示 那么需要先加上 compile 'org.springframework.boot:spring-boot-starter-thymeleaf' 这个thymeleaf依赖 springboot推荐使用thymeleaf模板 它的最大好处就是原型即是模板 后缀是html html文件 需要放在resources/templates文件夹

  • Spring Cloud Stream微服务消息框架原理及实例解析

    随着近些年微服务在国内的盛行,消息驱动被提到的越来越多.主要原因是系统被拆分成多个模块后,一个业务往往需要在多个服务间相互调用,不管是采用HTTP还是RPC都是同步的,不可避免快等慢的情况发生,系统性能上很容易遇到瓶颈.在这样的背景下,将业务中实时性要求不是特别高且非主干的部分放到消息队列中是很好的选择,达到了异步解耦的效果. 目前消息队列有很多优秀的中间件,目前使用较多的主要有 RabbitMQ,Kafka,RocketMQ 等,这些中间件各有优势,有的对 AMQP(应用层标准高级消息队列协议

  • 详解spring cloud构建微服务架构的网关(API GateWay)

    前言 在我们前面的博客中讲到,当服务A需要调用服务B的时候,只需要从Eureka中获取B服务的注册实例,然后使用Feign来调用B的服务,使用Ribbon来实现负载均衡,但是,当我们同时向客户端暴漏多个服务的时候,客户端怎么调用我们暴漏的服务了,如果我们还想加入安全认证,权限控制,过滤器以及动态路由等特性了,那么就需要使用Zuul来实现API GateWay了,下面,我们先来看下Zuul怎么使用. 一.加入Zuul的依赖 <dependency> <groupId>org.spri

  • 详解Spring Cloud Alibaba Sidecar多语言微服务异构

    自 Spring Cloud Alibaba 2.1.1 版本后增加了 spring-cloud-alibaba-sidecar 模块作为作为一个代理的服务来间接性的让其他语言可以使用spring cloud alibaba等相关组件.通过与网关的来进行路由的映射,从而可以做到服务的获取,然后可以使用Ribbon间接性调用. 如上图, Spring Cloud 应用 请求 sidercar 然后转发给其他语言的模块,优势是对于异构服务代码 零侵入,不需要直接根据 nacos 或其他注册中心 ap

  • Spring Cloud Alibaba使用Sentinel实现接口限流

    最近管点闲事浪费了不少时间,感谢网友 libinwalan 的留言提醒.及时纠正路线,继续跟大家一起学习Spring Cloud Alibaba. Nacos作为注册中心和配置中心的基础教程,到这里先告一段落,后续与其他结合的内容等讲到的时候再一起拿出来说,不然内容会有点跳跃.接下来我们就来一起学习一下Spring Cloud Alibaba下的另外一个重要组件:Sentinel. Sentinel是什么 Sentinel的官方标题是:分布式系统的流量防卫兵.从名字上来看,很容易就能猜到它是用来

随机推荐