一行代码导致Sentinel控制台,API管理/网关流控菜单不显示

  |   0 评论   |   0 浏览

正常菜单情况,pom.xml 相关依赖

<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-nacos-config</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
	<groupId>com.alibaba.csp</groupId>
	<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

application.properties 相关配置项

spring.cloud.nacos.discovery.server-addr=192.168.1.6:8848

spring.cloud.gateway.enabled=true
spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.lower-case-service-id=true

spring.cloud.gateway.routes[0].id=book-service
spring.cloud.gateway.routes[0].uri=lb://book-service
spring.cloud.gateway.routes[0].predicates[0]=Path=/book/**

spring.main.allow-bean-definition-overriding=true

spring.cloud.sentinel.transport.dashboard=192.168.1.6:8080
spring.cloud.sentinel.transport.port=8719

spring.cloud.sentinel.filter.enabled=true
spring.cloud.sentinel.eager=false
spring.cloud.sentinel.datasource.ds.nacos.server-addr=192.168.1.6:8848
spring.cloud.sentinel.datasource.ds.nacos.namespace=c51764ea-936b-42a9-a169-8b78ca9ea93e
spring.cloud.sentinel.datasource.ds.nacos.data-id=gateway-sentinel-flow.json
spring.cloud.sentinel.datasource.ds.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds.nacos.rule-type=gw-flow

注意项

  • spring.cloud.sentinel.eager=false 懒加载Sentinel Dashboard菜单
  • spring.cloud.sentinel.datasource.ds.nacos.namespace=xxxyyyzzz 如果配置放Nacos命名空间,要加上
  • spring.cloud.sentinel.transport.port=8719 应用与Sentinel Dashboard 交互端口

Nacos 增加限流配置

image.png

限流返回信息友好提示为中文

编码实现,添加 Bean,实现 BlockRequestHandler 接口

import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;

@Slf4j
@Component
public class CustomBlockRequestHandler implements BlockRequestHandler {
    @Autowired
    private InetUtils inetUtils;

    @PostConstruct
    public void doInit() {
        System.setProperty(TransportConfig.HEARTBEAT_CLIENT_IP, inetUtils.findFirstNonLoopbackAddress().getHostAddress());
    }

    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable ex) {
        String resultString = "{\"code\":403,\"message\":\"服务开启限流保护,请稍后再试!\"}";
        return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS).contentType(MediaType.APPLICATION_JSON_UTF8).body(BodyInserters.fromObject(resultString));
    }

}

要注意,放在能被Spring boot 启动类能扫描到 @Component 注解的地方,被识别。

配置实现

配置 com.alibaba.cloud.sentinel.gateway.FallbackProperties 属性

  • responseStatus 默认为 HttpStatus.TOO_MANY_REQUESTS.value()
  • contentType 默认为 MediaType.APPLICATION_JSON.toString()
spring.cloud.sentinel.scg.fallback.response-body={"code":403,"msg":"服务开启限流保护,请稍后再试!"}
spring.cloud.sentinel.scg.fallback.mode=response

启动 Sentinel Dashboard 控制台,运行应用程序,

image.png

访问 Sentinel Dashboard,看 spring.cloud.sentinel.eager=false 懒加载

image.png

访问网关接口,触发菜单显示,并且手速快点触发限流阀值

image.png

刚手速有点慢,点了很多次,才触发限流,还是用压力测试 Jmeter,Apache ab等软件好点。

看 Sentinel 控制台,限流配置

image.png

在Sentinel 控制台编辑修改的限流设置是不会自动同步到Nacos的,而在Nacos修改的持久化配置,Sentinel是可以获取到的。一般解决方式是,把Sentinel源码下载下来,加Bean,Controller来同步Sentinel配置到Nacos。这里提供另外一种复杂问题简单化处理方式手动添加,首先在Sentinel控制台编辑好限流设置,然后访问交互端口对应接口获取配置内容,复制粘贴到Nacos添加即可。

    //http://ip:port/getRules?type=flow
    //http://ip:port/gateway/getRules

在Sentinel修改阀值为6,访问 http://192.168.1.5:8719/gateway/getRules 获取数据

image.png

问题主题来了,是什么代码导致控制台API管理/网关菜单不显示呢,

SentinelConfig.setConfig(TransportConfig.HEARTBEAT_CLIENT_IP, inetUtils.findFirstNonLoopbackAddress().getHostAddress());//有毒代码不显示菜单
System.setProperty(TransportConfig.HEARTBEAT_CLIENT_IP, inetUtils.findFirstNonLoopbackAddress().getHostAddress());//正常显示代码

停掉控制台和网关应用程序,用有毒代码重新启动试试

image.png

这个问题和Alibaba Sentinel管理人员沟通过,提交Issue给官方,待解决。


标题:一行代码导致Sentinel控制台,API管理/网关流控菜单不显示
作者:shuikan95
地址:http://javadaily.cn/articles/2020/04/01/1585710559721.html