版本
springboot : 2.2.7.RELEASEspring-cloud-starter-alibaba-sentinel : 2.2.2.RELEASEsentinel-transport-simple-http : 1.7.2sentinel-datasource-nacos : 1.8.0nacos : 1.3.2
dependency
<dependency>
<groupId>com.alibaba.cloud
</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel
</artifactId>
<version>2.2.2.RELEASE
</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp
</groupId>
<artifactId>sentinel-transport-simple-http
</artifactId>
<version>1.7.2
</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp
</groupId>
<artifactId>sentinel-datasource-nacos
</artifactId>
<version>1.8.0
</version>
</dependency>
sentinel控制台相关的规则,直接在内存中操作,无法直接持久化保存,项目重新启动后,配置的规则会丢失,所以选择了nacos进行规则的持久化保存。在nacos配置后,项目重启后仍能从nacos获取到配置的规则数据。
application.yml
application:
name: xxxxx
cloud:
sentinel:
eager: true
transport:
dashboard: 172.16.2.2
:8083
port: 8721
heartbeat-interval-ms: 1000
datasource:
ds1:
nacos:
server-addr: 172.16.2.2
:8848
namespace: xxxxx
username: nacos
password: nacos
dataId: xxxxx
group: DEFAULT_GROUP
data-type: json
rule-type: flow
ds2:
nacos:
server-addr: 172.16.2.2
:8848
namespace: xxxxx
username: nacos
password: nacos
dataId: xxxxx
group: DEFAULT_GROUP
data-type: json
rule-type: degrade
log:
dir: /home/xxx/csp
一些教程中配置nacos时,没有设置spring.cloud.sentinel.datasource.ds1.nacos.username和spring.cloud.sentinel.datasource.ds1.nacos.password 会在启动时由于npe问题而创建bean出错。高版本需要设置这个两个值才可以。
监听熔断器状态变化事件
@Component
public class SentinelUtil {
public static final Logger logger
= LoggerFactory
.getLogger(SentinelUtil
.class);
private static CircuitBreakerStateChangeObserver
getCircuitBreakerStateChangeObserver() {
return (prevState
, newState
, rule
, snapshotValue
) -> {
if (newState
== CircuitBreaker
.State
.OPEN
) {
final String content
= String
.format("%s -> OPEN at %s, snapshotValue=%.2f, resource=%s",
prevState
.name(),
DateTimes
.formatTemporal("yyyy-MM-dd HH:mm:ss",
LocalDateTime
.now()),
snapshotValue
, rule
.getResource());
final boolean send
= MailUtil
.sendNotifyFailedMail("接口状态变化通知", content
);
if (!send
) {
logger
.error("接口状态变化通知 发送失败");
}
} else {
final String content
= String
.format("%s -> %s at %s, snapshotValue=%.2f,resource=%s",
prevState
.name(), newState
.name(),
DateTimes
.formatTemporal("yyyy-MM-dd HH:mm:ss",
LocalDateTime
.now()),
snapshotValue
, rule
.getResource());
final boolean send
= MailUtil
.sendNotifyFailedMail("接口状态变化通知", content
);
if (!send
) {
logger
.error("接口状态变化通知 发送失败");
}
}
};
}
@PostConstruct
public void registerStateChangeObserver() {
EventObserverRegistry
.getInstance()
.addStateChangeObserver("logging", getCircuitBreakerStateChangeObserver());
}
}
这里做了简单的特定的处理,在状态变化时进行邮件通知。也可以记录到数据库中。
注意点
@SentinelResource注解 不支持private方法,也需要spring托管的类中的方法才可以。使用fallbackClass时,fallback方法必须是public static方法。多个项目实例连接至sentinel控制台,不需要更改spring.cloud.sentinel.sentinel.port=xxxx(默认8719)端口,sentinel会自动尝试探测使用后面的端口。