谷粒商城-高级-79 -高并发监控-Sentinel 限流、熔断降级
一、什么是Sentinel?
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 的主要特性:
二、整合Sentinel
Spring Cloud Alibaba整合Sentinel文档:https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
1、导入依赖
因为Sentinel在所有微服务都要使用,所以,该依赖直接放在 gulimall-common
通用服务下。gulimall-common/pom.xml
<!--alibaba cloud Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2、下载控制台
您可以从 release 页面 下载最新版本的控制台 jar 包。这里我们可以根据自己安装的Sentinel依赖包的版本来下载对应版本的控制台。
可以看到我这里依赖包的核心版本为 sentinel-core:1.6.3
,所以,应该下载该版本的控制台,其他版本可能会有冲突或兼容性问题。
jar包下载到本地,放到我们服务路径,然后启动服务:
> cd /Users/kaiyiwang/javaweb/guli/develop/sentinel
> java -jar sentinel-dashboard-1.6.3.jar --server.port=8333
启动打印:
ype [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-09-17 15:46:26.711 INFO 48509 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2020-09-17 15:46:26.881 INFO 48509 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8333 (http) with context path ''
2020-09-17 15:46:26.949 INFO 48509 --- [ main] c.a.c.s.dashboard.DashboardApplication : Started DashboardApplication in 29.367 seconds (JVM running for 46.812)
可以看到已经启动成功了,然后访问这个服务: http://localhost:8333/#/dashboard/home
默认账号和密码都是 sentinel。
3、配置控制台地址信息
这里我们以gulimall-order
订单微服务为例,在该微服务下配置Sentinel:gulimall-order/src/main/resources/application.yml
spring:
datasource:
username: root
password: root
url: jdbc:mysql://192.168.10.10:3306/gulimall_oms
driver-class-name: com.mysql.cj.jdbc.Driver
# 配置nacos注册中心
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
# sentinel控制台地址配置
sentinel:
transport:
port: 8719
dashboard: localhost:8333
application:
name: gulimall-order
thymeleaf:
cache: false # 测试期间关掉缓存
redis:
host: 192.168.10.10
prot: 6379
session:
store-type: redis # Session store type,SpringSession整合,使用redis作为session存储
mybatis-plus:
mapper-location: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto # id主键自增
server:
port: 9000
servlet:
session:
timeout: 30m # Session timeout,SpringSession整合
然后重启订单服务,访问订单列表,就可以看到订单服务已经注册到sentinel了:
http://order.gulimall.com/order/order/list
Sentinel 功能非常强大,有各种监控数据提供。
4、在控制台调整参数
在控制台调整参数,默认所有的流控设置保存在内存中,重启失效。
设置QPS,每秒查询3次。
三、导入信息审计模块actuator
导入actuator依赖
actuator 审计模块,可以实时统计Springboot健康状态,包括整个请求的调用信息等,Sentinel通过统计拿到的这些信息最终做整个数据的监控功能能。
gulimall-order/pom.xml
<!-- 审计信息模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
暴露端口:
每一个微服务都导入 actuator,并配合 management.endpoints.web.exposure.include=*
,暴露端口之后别人就能访问了。
gulimall-order/src/main/resources/application.properties
# === Sentinel ===
# 暴露端口,别人就可以访问了
management.endpoints.web.exposure.include=*
Sentinel Endpoint 里暴露的信息非常有用。包括当前应用的所有规则信息、日志目录、当前实例的 IP,Sentinel Dashboard 地址,Block Page,应用与 Sentinel Dashboard 的心跳频率等等信息。
IDEA编辑器可以实时统计springboot健康及请求信息:
四、自定义 Sentinel流控返回数据
gulimall-order/xxx/order/config/GulimallOrderSentinelConfig.java
package com.atguigu.gulimall.order.config;
import com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler;
/**
* Sentinel自定义阻塞返回方法
*
* @author: kaiyi
* @createTime: 2020-09-17 16:05
**/
@Configuration
public class GulimallOrderSentinelConfig {
public GulimallOrderSentinelConfig() {
WebCallbackManager.setUrlBlockHandler(new UrlBlockHandler() {
@Override
public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws IOException {
R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(), BizCodeEnum.TO_MANY_REQUEST.getMsg());
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
response.getWriter().write(JSON.toJSONString(error));
}
});
}
}
设置流控:
QPS设置为3,即每秒最多请求3个,如果超过会由Sentinel直接返回流量过大信息:
狂刷页面:
实时监控图:
五、全服务引入Sentinel
按照上边的步骤,给剩下的几个微服务也引入 Sentinel监控。
ok,已经将我们的所有微服务加入到 Sentinel监控了。
六、熔断降级
熔断
使用sentinel来保护feign远程调用,熔断:
1)、调用方的熔断保护,feign.sentinel.enabled=true
2)、调用方手动指定远程服务的降级策略(在 sentinel管理后台配置),远程服务被降级处理,触发我们的熔断回调方法。
3)、超大流量的时候,必须牺牲一些远程服务,在服务的提供方(远程服务)指定降级策略。
提供方是在运行,但是不运行自己的业务逻辑,返回的是默认的降级数据(限流的数据)。
给我们每个服务都开启 feign远程调用的熔断功能:application.properties
feign.sentinel.enabled=true
七、网关流控
Sentinel允许在网关层进行流控。
网关服务引入网关控流依赖:gulimall-gateway/pom.xml
<!-- sentinel网关流控 -->
<!-- https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
由于1.6.3版本的控制台对路由区分控制不够明显,所以,下载1.7.2这个新版本,然后启动:
> cd /Users/kaiyiwang/javaweb/guli/develop/sentinel
> java -jar sentinel-dashboard-1.7.2.jar --server.port=8333
我们可以看到1.7.2版本多了一个API管理。
在请求链路看以看到相关的服务路由:
然后对这个网关进行流量控制规则设置:
定制网关流控配置:gulimall-gateway/xxx/gateway/config/SentinelGatewayConfig.java
package com.atguigu.gulimall.gateway.config;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.fastjson.JSON;
import com.atguigu.common.exception.BizCodeEnum;
import com.atguigu.common.utils.R;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* Sentinel网关限流回调配置
*
* @author: kaiyi
* @create: 2020-09-18 00:21
*/
@Configuration
public class SentinelGatewayConfig {
public SentinelGatewayConfig(){
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
/**
* 网关限流了请求,就会调用此回调
* Mono Flux
* @param serverWebExchange
* @param throwable
* @return
*/
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
R error = R.error(BizCodeEnum.TOO_MANY_REQUEST.getCode(), BizCodeEnum.TOO_MANY_REQUEST.getMsg());
String errJson = JSON.toJSONString(error);
Mono<ServerResponse> body = ServerResponse.ok().body(Mono.just(errJson), String.class);
return body;
}
});
}
}
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)