一、介绍
本实例分为消费者和生产者:生产者查询数据库,消费者调用生产者接口。
引入了Nacos
注册中心、Ribbon
负载均衡、Sentinel
流量控制,服务调用使用RestTemplate
、持久层使用JPA
。
SpringCloudAlibaba——Sentinel分布式系统的流量防卫兵
SpringCloudAlibaba——Nacos注册中心、配置中心的使用
消费者目录结构:
生产者目录结构:
二、pom依赖
2.1 消费者POM
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!--引入 Sentinel 依赖-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.1</version>
</dependency>
<!--Sentinel注解支持 @SentinelResource 注解,注解方式埋点不支持 private 方法。-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.1</version>
</dependency>
<!--客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.1</version>
</dependency>
<!-- sentinel整合Spring -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<!--SpringBootweb-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--SpringBoot测试类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<!-- springcloud alibaba nacos discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<!-- springcloud alibaba nacos config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<!-- Ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
</dependencies>
2.2 生产者POM
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!--引入 Sentinel 依赖-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.1</version>
</dependency>
<!--Sentinel注解支持 @SentinelResource 注解,注解方式埋点不支持 private 方法。-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.1</version>
</dependency>
<!--客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.1</version>
</dependency>
<!--SpringDataJPA-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<!-- sentinel整合Spring -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<!--SpringBootweb-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--SpringBoot测试类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<!-- springcloud alibaba nacos discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<!-- springcloud alibaba nacos config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
</dependencies>
三、源码分析
3.1 生产者
控制层直接查数据库(省略了业务层)
表结构:
表映射实体类:
数据访问层:
3.2 消费者(注解方式定义资源)
控制层:
Sentinel 支持通过 @SentinelResource
注解定义资源并配置 blockHandler
和 fallback
函数来进行限流之后的处理。
消费者启动类:
注入RestTemplate
,使用Ribbon的@LoadBalanced
注解开启负载均衡。
注意使用了@LoadBalanced注解,在RestTemplate调用的时候URL需要使用Nacos注册中心注册的服务名:
3.3 配置文件
sentinel配置文件:
project.name=SentinelDemo2021-06-1715:02:51
#单个监控日志文件的大小 long 52428800 (50MB)
csp.sentinel.metric.file.single.size=52428800
#监控日志文件的总数上限 默认6
csp.sentinel.metric.file.total.count=2
# 日志默认${user.home}/logs/csp/
csp.sentinel.log.dir=/Users/LiuShihao/IdeaProjects/sentinel-demo/logs
#日志文件名中是否加入进程号,用于单机部署多个应用的情况 默认 boolean false
csp.sentinel.log.use.pid=false
#Record 日志输出的类型,file 代表输出至文件,console 代表输出至终端
csp.sentinel.log.output.type=console
#控制台的地址,指定控制台后客户端会自动向该地址发送心跳包。地址格式为:hostIp:port
csp.sentinel.dashboard.server=localhost:8080
#心跳包发送周期,单位毫秒 long
csp.sentinel.heartbeat.interval.ms=30000
#本地启动 HTTP API Server 的端口号 int 默认为 8719 若端口冲突会自动向下探测可用的端口。
csp.sentinel.api.port=8719
#指定心跳包中本机的 IP
#csp.sentinel.heartbeat.client.ip
消费者application.yml
server:
port: 8081
spring:
application:
name: sentinel-consumer
cloud:
nacos:
config:
# Nacos配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
生产者application.yml
server:
port: 8082
spring:
application:
name: sentinel-provider
jpa:
show-sql: true
hibernate:
naming:
# 取消小驼峰到下划线映射(加上这个)
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
datasource:
url: jdbc:mysql://localhost:3306/day27?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
cloud:
nacos:
config:
# Nacos配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
四、启动测试
在浏览器地址访问:http://localhost:8081/consumer/getDept/1
可以在Sentinel仪表盘上看到服务的监控信息。
给消费者添加流控规则
:
QPS:每秒访问量。
当我们连续刷新的时候就会报错:
从而达到流量控制
的目的。