Sentinel + Gateway 在网关统一流控

2022-12-08 13:42:30 浏览数 (1)

很久之前,姜同学写过一篇使用Hystrix对微服务进行保护,里面介绍了一些Hystrix是怎么对服务器的资源进行限流的,但是令人遗憾的是,Hystrix在github上的仓库已经停止维护了,但不可否认的是Hystrix就算是在今天依旧强大,它依然是微服务弹性架构的保障。强大归强大,一些不好用的缺点姜同学还是得拿出来说说。

Hystrix存在的不足

sentinel

针对上面Hystrix的不足,阿里的同学们出手了,推出了功能更加强大并且使用更加简单的sentine。这是sentinel的官方文档,上面详细的介绍了sentinel是如何对资源和规则进行定义了,以及sentinel对流控服务熔断和降级的介绍。

启动sentinel的控制台

只能说是相当的easy。

1. 获取 Sentinel 控制台

您可以从 release 页面 下载最新版本的控制台 jar 包。

2. 启动

注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。

使用如下命令启动控制台:

代码语言:javascript复制
java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=192.168.1.159:8888 -Dproject.name=sentinel-dashboard -jar -Dsentinel.dashboard.auth.username=jiangtongxue -Dsentinel.dashboard.auth.password=jiangtongxue -Dserver.servlet.session.timeout=7200 sentinel-dashboard-1.8.6.jar
shell

端口,用户名,密码之类的参数记得改成自己的。是那个想必一眼就看出来了吧。

3. 登陆

SpringBoot Sentinel

光有一个控制台能有毛用,sentinel还没那么只能到你看一眼控制台就能保护你心中所想的资源,所以体验一下Springboot Sentinel的快速启动吧。

1. 加个sentinel的依赖

代码语言:javascript复制
<dependency>
  	<groupId>com.alibaba.cloud</groupId>
  	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
xml

为什么用这个依赖呢,因为姜同学的项目都是SpringCloudAlibaba呀~,如果你的项目只是一个简单的SpringBoot项目,那么用下面这个依赖吧。依赖放哪都不知道?那你先看看姜同学写的其他文章吧。

代码语言:javascript复制
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>x.y.z</version>
</dependency>
xml

2. 配置控制台信息

代码语言:javascript复制
spring:
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: 192.168.1.159:8888
yaml

3. 定义资源

在SpringBoot中定义一个sentinel的资源那可是very的easy,加个注解就行了,不信你往下看。

这不一下子就把资源名称,流控处理,降级逻辑一下全完成了吗。更多的代码就不截了,一眼看出个BUG我很尴尬的。

SentinelResource的更多使用方法请移步这里。注解支持

4. 控制台配置流控规则

配置流控规则之前记得请求下你定义的资源预热下,不然在sentinel的控制台上找不到资源的时候可别怪我没提醒你哦

这不就出来了吗,好啦,出于模拟的角度考虑,QPS到5就限流吧。

在我框框一顿刷之后,这不就限流啦。

这不就和上面定义的注解对上啦。

Sentinel Gateway

事实上,姜同学的工作没那么轻松,我平时要维护很多线上的应用,为每个应用都进行上面的配置很明显是一件很烦的事情,姜同学这么懒自然不愿意干这种事情。

但是幸运的是,姜同学在过去的一年已经将我司大体的架构改成了如上的样子,API Gateway我使用的是Spring Cloud Gateway。为什么说这是幸运的呢?因为Sentinel可以集成到Springcloud Gateway上获得所有经过Gateway的聚簇链路。

1. 在网关工程中加入依赖

代码语言:javascript复制
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
xml

同时请将 spring.cloud.sentinel.filter.enabled 配置项置为 false(若在网关流控控制台上看到了 URL 资源,就是此配置项没有置为 false)为什么设置呢,因为gateway限流只支持ROUT ID 和 API分组,对单个URL的流控是无效的。

2.配置控制台信息

代码语言:javascript复制
spring:
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: 127.0.0.1:8888
      filter:
        enabled: false
yaml

3.统一限流返回结果

代码语言:javascript复制
@Configuration
public class ExceptionHandlerConfiguration {
    public ExceptionHandlerConfiguration(){
        BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
                Map<String, String> result = new HashMap<>(3);
                result.put("code", String.valueOf(HttpStatus.TOO_MANY_REQUESTS.value()));
                result.put("message", HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());
                result.put("x","xx");
                return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                        .contentType(MediaType.APPLICATION_JSON)
//                        .body(BodyInserters.fromValue(result));
                        .body(BodyInserters.fromObject(result));
            }
        };

        // 加载自定义限流异常处理器
        GatewayCallbackManager.setBlockHandler(blockRequestHandler);
    }
}
java

4.发几个请求看看效果啦。

上面是ip端口是gateway的,整个URL被路由到了一个叫web-server的服务的验证码接口。

服务的名字被识别到了。

流控的规则定义的就和上面的一样了。更多了控制台使用方式还要看下面的参考文档。

美中不足的这样做是对整个服务进行限流,如果某个服务的某个接口想自定义限流逻辑的话还是要为那个单独的服务配置资源集成sentinel的。

Sentinel流控规则持久化

上面一顿操作之后,你改了改代码重启了下应用,你就会发现,what‘s up 辛辛苦苦配置的流控规则无啦,是真的无啦,这是为什么呢?因为sentinel的流控规则默认保存在客户端的内存中,内存这种东西吗,你的客户端一重启,当然直接就无了。不过没关系这么不人性化的配置,Sentinel当然有他的其他准备。不信你看。

姜同学目前使用的配置中心是Nacos,所以接下来将使用Nacos配置sentinel的限流规则。

客户端添加依赖

代码语言:javascript复制
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-datasource-nacos</artifactId>
  <version>1.8.0</version>
</dependency>
xml

配置文件添加配置信息

代码语言:javascript复制
spring:
  cloud:
    nacos:
      config:
        server-addr: 192.168.1.94:8848
        group: DEFAULT_GROUP
        namespace: pins-service-dev
      discovery:
        server-addr: 192.168.1.94:8848
        namespace: pins-service-dev
    sentinel:
      transport:
        port: 8719
        dashboard: 127.0.0.1:8888
      filter:
        enabled: false
      eager: true
      datasource:
        ds:
          nacos:
            ### nacos连接地址
            server-addr: 192.168.1.94:8848
            namespace: pins-service-dev
            ### nacos连接的分组
            group-id: DEFAULT_GROUP
            ### 路由存储规则
            rule-type: flow
            ### 读取配置文件的 data-id
            data-id: gateway-sentinel
            ### 配置文件类型
            data-type: json
yaml

重点看下面加备注的部分,上面多余的懒得删了。

Nacos添加限流配置

客户端一启动,Nacos上的配置就会被sentienl控制台同步了,遗憾的是这种流控规则开源版本的Sentinel并不支持在控制台做了修改之后同步到Nacos。到头来还是生意呀。

参考文档

网关流量控制-官方文档

网关支持

注解支持

0 人点赞