【流量控制系列7】Sentinel实践

sentinel的使用

架构方式

图片

Sentinel dashboard改造

默认是支持单机,现在需要改造成集群配置方式。

页面controller改造

将test下的nacos文件夹复制到包rule下
启用类:FlowControllerV2
provider注入

1
2
3
4
5
6
@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

前端页面sidebar替换
app.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.state('dashboard.flow', {
templateUrl: 'app/views/flow_v2.html',
url: '/v2/flow/:app',
controller: 'FlowControllerV2',
resolve: {
loadMyFiles: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({
name: 'sentinelDashboardApp',
files: [
'app/scripts/controllers/flow_v2.js',
]
});
}]
}
})

配置改造

追加nacos配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server.port=8091
#spring settings
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true

#logging settings
logging.level.org.springframework.web=INFO
logging.file=${user.home}/logs/csp/sentinel-dashboard.log
logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
#logging.pattern.console= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n

#auth settings
auth.filter.exclude-urls=/,/auth/login,/auth/logout,/registry/machine
auth.filter.exclude-url-suffixes=htm,html,js,css,map,ico,ttf,woff,png
auth.username=sentinel
auth.password=sentinel

nacos.server=10.5.117.217

nacos集群部署

  • 追加配置

distribution 下的resource配置

1
2
3
4
db.num=1
db.url.0=jdbc:mysql://10.59.118.120:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=prog_admin
db.password=prog_nacos

cluster.conf

1
2
3
10.59.118.126:8848
10.59.118.127:8848
10.59.118.121:8848
  • 编译

    1
    $ mvn -Prelease-nacos -DskipTests clean install -
  • 启动

1
$NACOS_HOME/bin/startup.sh

支付平台配置改造

Web项目

引入包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>${sentinel-version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-cluster-client-default</artifactId>
<version>${sentinel-version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>${sentinel-version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-web-servlet</artifactId>
</dependency>
  • 追加nacos配置
1
2
###限流配置###
nexos.host=@filter.nexos.host@
  • 追加拦截器
    SentinelFilter
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
    HttpServletRequest sRequest = (HttpServletRequest)request;
    Entry entry = null;
    try {

    // 根据请求生成的资源
    String target = FilterUtil.filterTarget(sRequest);
    if (!target.startsWith("/admin")) {
    target = WebCallbackManager.getUrlCleaner().clean(target);
    entry = SphU.entry(target, EntryType.IN, 1);
    }
    // 如果能成功“申请”到资源,则说明未被限流
    // 则将请求放行
    chain.doFilter(request, response);
    } catch (BlockException e) {
    // 否则如果捕获了BlockException异常,说明请求被限流了
    // 则将请求重定向到一个默认的页面
    //System.out.println("触发限流规则");
    throw new RuntimeException("触发限流规则");
    } catch (IOException e2) {
    // 省略部分代码
    } finally {
    if (entry != null) {
    entry.exit();
    }
    }
    }

监听 nacos配置变更

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void initSentinalClusterClientConfig() {
String REMOTE_ADDRESS = propertyPlaceholderConfigurer.getCtxProp("nexos.host");
//初始化一个配置ClusterClientConfig的 Nacos 数据源
ReadableDataSource<String, ClusterClientAssignConfig> ds =
new NacosDataSource<>(REMOTE_ADDRESS, GROUP_ID, CLIENT_CONFIG_DATA,
source -> JSON.parseObject(source, new TypeReference<ClusterClientAssignConfig>() {}));
ClusterClientConfigManager.registerServerAssignProperty(ds.getProperty());
}

private void initClientFlow() {
String REMOTE_ADDRESS = propertyPlaceholderConfigurer.getCtxProp("nexos.host");
//使用 Nacos 数据源作为配置中心,需要在 REMOTE_ADDRESS 上启动一个 Nacos 的服务
ReadableDataSource<String, List<FlowRule>> ds =
new NacosDataSource<>(REMOTE_ADDRESS, GROUP_ID, APP_NAME + FLOW_POSTFIX,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
//为集群客户端注册动态规则源
FlowRuleManager.register2Property(ds.getProperty());
}

启动

启动加入:

1
-Dcsp.sentinel.dashboard.server=10.5.32.97:8091 -Dproject.name=littlehui-17pay

遇到的坑

  1. sentinel配置的限流规则。来源app字段limitApp指的是请求来源,常用default,如果指定app那么非app来源的请求获取不到rule列表。

  2. sentinel客户端不支持nacos的命名空间配置,所以用的是默认的public空间。

附件

源码

nacos-1.0.0-RC3源码
sentinel-1.6.0源码

文档索引

【流量控制系列1】引言和索引
【流量控制系列2】流量控制的基础方法和算法
【流量控制系列3】Semaphore信号量介绍
【流量控制系列4】Sentinel和Hystrix对比
【流量控制系列5】Sentinel 详细介绍
【流量控制系列6】Sentinel 详细介绍-SlotChain源码解析
【流量控制系列7】Sentinel实践

Like 1 Comments Issue Page