目录
1. 安装sentinel管理后台
1. 下载sentinel 1.8.6最新版本
wget https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar
2. 启动sentinel控制后台
java -Dserver.port=6003 -Dcsp.sentinel.dashboard.server=localhost:6003 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
其中,6003是控制后台的端口,启动后,通过网页访问:http://127.0.0.1:6003
默认的登录名和密码:sentinel
2. 网关集成sentinel
1. 修改pom.xml, 添加依赖:
<!-- 引入sentinel进行服务降级熔断 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- gateway网关整合sentinel进行限流降级 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
2. 修改网关的nacos配置,添加以下配置项:
spring:
cloud:
sentinel:
filter:
enabled: false
eager: true ## 立即加载
transport:
port: 7101 ## sentinel规则通过此端口通知网关
dashboard: localhost:6003 ## sentinel控制台地址
#配置限流之后的响应内容
scg:
fallback:
# 两种模式:一种是response返回文字提示信息,一种是redirect,重定向跳转,需要同时配置redirect(跳转的uri)
mode: response
# 响应的状态
response-status: 426
# 响应体
response-body: '{"code": 426,"message": "限流了,稍后重试!"}'
启动网关节点,登录sentinel, 则可看到新加的网关服务:
3. sentinel常用的规则
Sentinel支持基于网关路由的Rule ID和网关访问的API路径的限流和熔断规则,临时的限流和熔断规则可以通过Sentinel的管理后台进行添加,但后台添加的规则在网关重启后会丢失,因此常规的规则需要硬代码方式编写,具体是实现一个Sentinel相关的配置,在配置类里初始化相关规则,示例代码如下:
package com.cloudservice.gateway_service.sentinel;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.result.view.ViewResolver;
import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
import jakarta.annotation.PostConstruct;
@Configuration
public class GatewaySentinelConfig {
private final List<ViewResolver> viewResolverList;
private final ServerCodecConfigurer serverCodecConfigurer;
public GatewaySentinelConfig(ObjectProvider<List<ViewResolver>> viewObjectProvider,
ServerCodecConfigurer serverCodecConfigurer)
{
this.viewResolverList = viewObjectProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
return new SentinelGatewayBlockExceptionHandler(viewResolverList, serverCodecConfigurer);
}
@Bean
@Order(-1)
public GlobalFilter sentinelGlobalFilter() {
return new SentinelGatewayFilter();
}
// 配置对象初始化时执行,初始化Route和API的过滤规则
@PostConstruct
public void doInit() {
initCustomizedApis();
initGatewayRules();
}
// 初始化API的规则
// SentinelGatewayConstants.URL_MATCH_STRATEGY_EXACT 精确匹配
// SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX 前缀匹配
// SentinelGatewayConstants.URL_MATCH_STRATEGY_REGEX 正则表达式匹配
private void initCustomizedApis() {
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api = new ApiDefinition("自定义api规则")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem()
.setPattern("/test")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
definitions.add(api);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
// 初始化Route的规则
private void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("order-service")
.setCount(2)
.setIntervalSec(1));
GatewayRuleManager.loadRules(rules);
}
}
[上一篇]从零开始搭建高负载java架构(05)——gateway网关节点(权限验证篇)