官网:https://sentinelguard.io/zh-cn/index.html
项目介绍:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
钉钉讨论群2:30150716
下载:https://github.com/alibaba/Sentinel/releases
启动:(全部使用默认配置)
java -jar sentinel-dashboard-1.7.2.jar
默认的访问端口为:8080,默认的登录帐号和密码都是:sentinel
启动时指定端口,是否监控自己,项目名称,登录的帐号和密码:
java -Dserver.port=8480 -Dcsp.sentinel.dashboard.server=localhost:8480 -Dproject.name=sentinel-dashboard -Dsentinel.dashboard.auth.username=sentinel -Dsentinel.dashboard.auth.password=123456 -jar sentinel-dashboard-1.7.2.jar
参数说明:(注意:参数要放到 -jar的前边)
-Dserver.port=8480 # 指定控制台的端口为8480
-Dcsp.sentinel.dashboard.server=localhost:8480 # 指定要被哪个控制台监控(这里指定的是自己监控自己)
-Dproject.name=sentinel-dashboard # 指定实例名称(名称会在控制台左侧以菜单显示)
-Dsentinel.dashboard.auth.username=sentinel # 设置登录的帐号为:sentinel
-Dsentinel.dashboard.auth.password=123456 # 设置登录的密码为:123456
重启后访问:http://localhost:8480/
更多的参数参考:
启动配置:https://github.com/alibaba/Sentinel/wiki/%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E9%A1%B9
登录鉴权:https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0#%E9%89%B4%E6%9D%83
新建项目:https://start.spring.io/
添加配置:application.yml
server:
port: 8321
spring:
application:
name: alibaba-sentinel # 项目名称,如果不写Sentinel会自己产生一个有端口号的名称
cloud:
sentinel:
transport:
# 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互
port: 8719
# sentinel控制台地址
dashboard: localhost:8480
添加一个Service类:.
package com.example.service;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Service;
@Service
public class TestService {
@SentinelResource(value = "sayHello")
public String sayHello(String name) {
return "Hello, " + name;
}
}
添加一个控制器添加访问端口:
package com.example.controller;
import com.example.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {
@Autowired
private TestService service;
@GetMapping(value = "/hello/{name}")
public String apiHello(@PathVariable String name) {
return service.sayHello(name);
}
}
启动。
必须先访问一下:http://localhost:8321/hello/abc123,Sentinel中才会有监控项出现。
先对访问路径做下限流
1秒内刷新超过1次,就被限制掉了
换成对资源进行限流
1秒内多次刷新:
抛出异常,所以这里要在代码里做一下限流的处理了。
给Service添加一个限流时的方法:
package com.example.service;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;
@Service
public class TestService {
@SentinelResource(value = "sayHello", blockHandler = "blockHandler")
public String sayHello(String name) {
return "Hello, " + name;
}
/**
* 被限流时调用的方法
* @param str 被限流的方法的参数
* @param ex 限流异常
* @return String
*/
public String blockHandler(String str, BlockException ex){
return "被限流了。。。"+str;
}
}
超出流量时的提示:
代码整理:TestService.java
package com.example.service;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;
@Service
public class TestService {
@SentinelResource(value = "sayHello", blockHandler = "blockHandler", fallback = "fallBack")
public String sayHello(String name) {
if (name.equals("1")) {
throw new ExceptionInInitializerError("出异常了,参数不能是:" + name);
}
return "Hello, " + name;
}
/**
* 处理java代码中的异常,不管有没有达到Sentinel中的配置
* 只要java代码中出现异常就会调用,如果断流的方法被调用,则这个方法不被调用
*
* @param name 被控制的方法的参数
* @param e 代码中抛出的异常,这个参数是可选的
* @return
*/
public String fallBack(String name, Throwable e) {
System.err.println("Java代码有异常:"+e.getMessage());
return "业务方法中出现异常: " + name + " -> " + e.getMessage();
}
/**
* 根据Sentinel中(对资源名)的配置(流控/降级)来进行处理
* 当达到Sentinel中配置的条件阈值时将会调用(如:单位时间内超过流量限制,单位时间内超过异常数量的限制)
*
* @param name 被控制的方法的参数
* @param e 断流的异常,参数必须加,不加这个参数即使达到了断流条件也不会执行
* @return
*/
public String blockHandler(String name, BlockException e) {
return "超过了Sentinel中的设置,被断流了。。。" + name + " " + e.getMessage();
}
}
Sentinel一个比较显著的问题,就是随着项目的重启,原来做好的配置就都没有了,还需要再配置。这点如果是在生产环境是不能发生的。做一个瘸腿的持久化(使用Nacos)。这个持久化的配置是用Nacos+微服务端实现的,在Sentinel的控制台修改后无法同步给Nacos。也就是在Nacos上配置后,由微服务端读取配置,然后同步给Sentinel。
首先,先启动好Nacos,在Nacos的public命名空间中添加一个配置项:
[
{
"resource": "sayHello",
"limitApp": "default",
"grade": 1,
"count": 5,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
然后,给微服务的项目引入nacos的数据源jar包。这个包去maven库里找:
https://mvnrepository.com/search?q=nacos+datasource
com.alibaba.csp
sentinel-datasource-nacos
最后,在微服务这边的application.yml中添加数据源的配置:
server:
port: 8321
spring:
application:
name: alibaba-sentinel # 项目名称,如果不写Sentinel会自己产生一个有端口号的名称
cloud:
sentinel:
transport:
# 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互
port: 8719
# sentinel控制台地址
dashboard: localhost:8480
datasource:
ds1:
nacos:
server-addr: localhost:8848 # nacos 地址(数据源地址)
data-id: sentinel-config # 配置项名称
data-type: json # 数据格式
rule-type: flow
启动项目,访问下然后去Sentinel查看下
不知道阿里为啥不把持久化这块做完整,难道是为了卖阿里云? (还有种方式是在微服务端存文件)
完毕。