Spring Cloud及其常用组件
1. Spring Cloud简介
Spring Cloud是实现分布式的一套微服务基础框架。它包含了一系列解决分布式问题的组件,主要有:服务发现注册中心、统一配置中心、消息总线、远程服务调用、负载均衡、网关、断路器、数据监控等。
2. 常用组件
- 服务发现注册中心:eurekaserver、consul、nacos
- 统一配置中心:config、nacos
- 远程服务调用及负载均衡:rabbion & openfeign
- 网关:zuul、gateway
- 消息总线:bus
- 断路器及数据监控:hystrix、sentinel
3. Nacos
3.1 简介
- Nacos是微服务架构中的服务发现注册中心及统一配置中心,为Spring Cloud Alibaba提供的组件。
- Nacos名称由"na"和"cos"组成。其中,"na"表示Name Server(命名服务),"cos"表示Configrations Server(配置服务)。
3.2 安装Nacos(Linux下的安装)
- 下载nacos
wget https://github.com/alibaba/nacos/releases/download/1.3.1/nacos-server-1.3.1.tar.gz
或
curl -O https://github.com/alibaba/nacos/releases/download/1.3.1/nacos-server-1.3.1.tar.gz
- 在指定目录下解压
mv nacos-server-1.3.1.tar.gz /usr/local/
tar -zxvf nacos-server-1.3.0.tar.gz
- 启动nacos服务
# 进入nacos的bin目录
cd /usr/local/nacos/bin/
# 启动nacos服务
./startup.sh -m standalone
- 查看日志
tail -f /usr/local/nacos/logs/start.out
- 访问nacos的web管理界面:http://ip:8848/nacos (用户名及密码:nacos)
3.3 Nacos发现注册中心服务
3.3.1 Spring Boot集成配置
- pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mo</groupId>
<artifactId>nacos</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>nacos</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.2.5.RELEASE</spring-boot.version>
<!--springcloud alibaba版本-->
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencies>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入nacos client依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--监控检查依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!--全局引用下载依赖地址,不会引入依赖-->
<dependencyManagement>
<dependencies>
<!--springcloud下载依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud alibaba下载依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.mo.NacosApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
- application.yaml配置
server:
port: 8100 # 服务端口
spring:
application:
name: nacosclient01 # 服务名称
cloud:
nacos:
server-addr: 192.168.150.128:8848 # nacos服务器地址
discovery:
server-addr: ${spring.cloud.nacos.server-addr} # 注册中心地址(默认为nacos服务器地址)
management:
endpoints:
web:
exposure:
include: "*" # 暴露所有web端点(用于健康检查)
- NacosApplication.java启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // 开启服务的注册与发现(新版本默认开启,可以不需要该注解)
public class NacosApplication {
public static void main(String[] args) {
SpringApplication.run(NacosApplication.class, args);
}
}
3.3.2 web端管理
- 访问nacos的web管理界面:http://ip:8848/nacos (用户名及密码:nacos)
- 服务管理 --> 服务列表
3.4 Nacos统一配置中心服务
3.4.1 web端配置文件管理
- 新建命名空间
- 新建配置文件
3.4.2 Spring Boot集成配置
- pom.xml配置依赖
<!--引入nacos client依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--监控检查依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--引入nacos config依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
- bootstrap.yaml预启动配置文件
spring:
application:
name: nacosclient # 服务名称(文件前缀名)
cloud:
nacos:
server-addr: 192.168.150.128:8848 # nacos服务器地址
config:
server-addr: ${spring.cloud.nacos.server-addr} # 配置中心地址(默认为nacos服务器地址)
namespace: dc4c0654-8bdd-45c4-b382-9bc9c56c7471 # 命名空间ID(默认为public)
prefix: ${spring.application.name} # 文件前缀名(默认为服务名称)
group: TEST_GROUP # 读取配置的分组(默认为DEFAULT_GROUP)
file-extension: yaml # 读取文件的后缀名(注意:yaml不能简写为yml)
profiles:
active: prod # 文件的环境名(指定后会在文件名后加"-${环境名}",不指定则省略)
-
配置文件自动刷新
- nacos默认已经实现了自动刷新
- 使用自动刷新只需要在控制器上添加@RefreshScope注解
import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RefreshScope // 自动刷新配置标识注解 public class TestController { @Value("${myname}") // 获取配置文件的值 private String myName; @GetMapping("/test/test") public String test() { return myName; } }
4. OpenFeign
4.1 简介
- OpenFeign是一种声明式、模板化的伪HTTP客户端。在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。
4.2 Spring Boot集成配置
- pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mo</groupId>
<artifactId>openfeignclient1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>openfeignclient1</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<!--springcloud版本-->
<spring.cloud.version>Hoxton.SR6</spring.cloud.version>
<!--springcloud alibaba版本-->
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencies>
<!--web 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入nacos client依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--监控检查依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--openfeign 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!--全局引用下载依赖地址,不会引入依赖-->
<dependencyManagement>
<dependencies>
<!--springcloud下载依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud alibaba下载依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- application.yaml配置
server:
port: 8201 # 服务端口
spring:
application:
name: openfeignclient1 # 服务名称
cloud:
nacos:
server-addr: 192.168.150.128:8848 # nacos服务器地址
discovery:
server-addr: ${spring.cloud.nacos.server-addr} # 注册中心地址(默认为nacos服务器地址)
feign:
client:
config:
openfeignclient2:
connectTimeout: 5000 # openfeignclient2服务连接超时配置(微秒)
readTimeout: 5000 # openfeignclient2服务等待超时配置(微秒)
loggerLevel: full # 开启openfeignclient2服务日志展示
# default:
#
# connectTimeout: 5000 # 所有服务连接超时配置(微秒)
# readTimeout: 5000 # 所有服务等待超时配置(微秒)
#
# loggerLevel: full # 开启所有服务日志展示
management:
endpoints:
web:
exposure:
include: "*" # 暴露所有web端点(用于健康检查)
logging:
level:
com.mo.openfeignclients: debug # 指定openfeign客户端日志为debug级别(必须为debug级别 )
- Openfeignclient1Application.java启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient // 开启服务的注册与发现(新版本默认开启,可以不需要该注解)
@EnableFeignClients // 开启OpenFeign客户端
public class Openfeignclient1Application {
public static void main(String[] args) {
SpringApplication.run(Openfeignclient1Application.class, args);
}
}
- OpenfeignClient2.java客户端接口
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient("openfeignclient2") // 标识当前接口是一个feign组件,value为服务ID
public interface OpenfeignClient2 {
}
4.3 OpenFeign使用案例
- Person实体类
public class Person {
private String name;
private Integer age;
public Person() {
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- api提供方测试控制器
import com.mo.dao.Person;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
public class TestController {
@GetMapping("/test/getname")
public String getName() {
return "张三";
}
@GetMapping("/test/print")
public String print(@RequestParam("content") String content) {
return content;
}
@PostMapping("/test/print2")
public String print2(@RequestParam("content") String content) {
return content;
}
@PostMapping("/test/personinfo")
public String personInfo(@RequestBody Person person) {
return person.toString();
}
@PostMapping(value = "/test/uploadfile")
public String uploadFile(@RequestPart("file") MultipartFile file) {
return file.getOriginalFilename();
}
}
- api调用方OpenFeign客户端接口
import com.mo.dao.Person;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@FeignClient("openfeignclient2") // 标识当前接口是一个feign组件,value为服务ID
public interface OpenfeignClient2 {
@GetMapping("/test/getname")
String getName();
/**
* get传参时@RequestParam注解必须存在
*/
@GetMapping("/test/print")
String print(@RequestParam("content") String content);
/**
* post传一个参数时@RequestParam注解必须存在
*/
@PostMapping("/test/print2")
String print2(@RequestParam("content") String content);
/**
* post传一个对象时@RequestBody注解必须存在
*/
@PostMapping("/test/personinfo")
String personInfo(@RequestBody Person person);
/**
* 传递文件时@RequestPart注解必须存在
* 传递文件时需在映射中加上consumes = MediaType.MULTIPART_FORM_DATA_VALUE
*/
@PostMapping(value = "/test/uploadfile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
String uploadFile(@RequestPart("file") MultipartFile file);
}
- api调用方测试控制器
import com.mo.dao.Person;
import com.mo.openfeignclients.OpenfeignClient2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
public class TestController {
@Autowired
private OpenfeignClient2 openfeignClient2;
@GetMapping("/test/testgetname")
public String testGetName() {
return openfeignClient2.getName();
}
@GetMapping("/test/testprint")
public String testPrint(@RequestParam("content") String content) {
return openfeignClient2.print(content);
}
@GetMapping("/test/testprint2")
public String testPrint2(@RequestParam("content") String content) {
return openfeignClient2.print2(content);
}
@GetMapping("/test/testpersoninfo")
public String testPersonInfo() {
Person person = new Person();
person.setName("张三");
person.setAge(20);
return openfeignClient2.personInfo(person);
}
@PostMapping(value = "/test/testuploadfile")
public String testUploadFile(MultipartFile file) {
return file.getOriginalFilename();
}
}
5. Gateway
5.1 简介
- Gateway是Spring Cloud官方推出的 API 网关框架,用于取代之前的Zuul网关。网关在微服务系统中有着非常作用,常见的有路由转发、权限校验、限流控制等功能。
5.2 Spring Boot集成配置
- pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mo</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<!--springcloud版本-->
<spring.cloud.version>Hoxton.SR6</spring.cloud.version>
<!--springcloud alibaba版本-->
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencies>
<!--引入nacos client依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--监控检查依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--引入gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!--全局引用下载依赖地址,不会引入依赖-->
<dependencyManagement>
<dependencies>
<!--springcloud下载依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud alibaba下载依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- application.yaml配置
server:
port: 8300 # 服务端口
spring:
application:
name: gateway # 服务名称
cloud:
nacos:
server-addr: 192.168.150.128:8848 # nacos服务器地址
discovery:
server-addr: ${spring.cloud.nacos.server-addr} # 注册中心地址(默认为nacos服务器地址)
gateway:
routes:
- id: routes1 # 指定路由唯一标识
#uri: http://localhost:8201/ # 指定路由服务的地址
uri: lb://client1 # 使用负载均衡策略,client1为服务ID
predicates:
- Path=/client1/** # 指定路由匹配规则
# - After=2021-04-10T10:30:30.544+08:00[Asia/Shanghai] # 指定时间之后才能访问
# - Before=2021-04-10T10:30:30.544+08:00[Asia/Shanghai] # 指定时间之前才能访问
# - Between=2021-04-10T10:30:30.544+08:00[Asia/Shanghai], 2021-04-10T11:30:30.544+08:00[Asia/Shanghai] # 指定时间之间才能访问
# - Cookie=username,chen # 带指定cookie值(可用正则表达式)才能访问
# - Header=H-Request-Id, \d+ # 指定请求值(可用正则表达式)才能访问
# - Method=GET,POST # 指定请求方式才能访问
# filters:
# - AddRequestHeader=H-Request-red, blue # 在所有请求的请求头中添加H-Request-red: blue
# - AddRequestParameter=id,1 # 在所有请求的请求参数中添加id=1
- id: routes2
#uri: http://localhost:8202/
uri: lb://client2
predicates:
- Path=/client2/**
discovery:
locator:
enabled: true # 开启根据服务名动态获取路由地址
management:
endpoints:
web:
exposure:
include: "*" # 暴露所有web端点(用于健康检查)
- 自定义过滤器
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 自定义过滤器
*/
@Configuration
public class CustomFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("过滤操作");
ServerHttpRequest request = exchange.getRequest(); // 获取request
MultiValueMap<String, String> queryParams = request.getQueryParams(); // 获取请求参数
if (queryParams.get("username") != null) {
return chain.filter(exchange); // 路由转发
}
return exchange.getResponse().setComplete(); // 过滤返回
}
@Override
public int getOrder() { // 获取Filter的优先值,值越小越优先
return -1; // -1表示该过滤器最先执行
}
}
- GatewayApplication.java启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // 开启服务的注册与发现(新版本默认开启,可以不需要该注解)
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
6. Sentinel
6.1 简介
-
Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。
-
特性:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
6.2 安装Sentinel Dashboard
- 下载
wget https://github.com/alibaba/Sentinel/releases/download/1.7.2/sentinel-dashboard-1.7.2.jar
或
curl -O https://github.com/alibaba/Sentinel/releases/download/1.7.2/sentinel-dashboard-1.7.2.jar
- 启动(需提前安装java1.8+环境)
# 使用java -jar命令直接启动,默认端口为8080,-Dserver.port=8850将端口改为8850
java -Dserver.port=8850 -jar sentinel-dashboard-1.7.2.jar
- 访问Sentinel Dashboard的web管理界面:http://ip:8850/ (用户名及密码:sentinel)
- Sentinel Dashboard的操作详见:Sentinel介绍
6.3 Spring Boot集成配置
- pom.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mo</groupId>
<artifactId>sentinel</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sentinel</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<!--springcloud alibaba版本-->
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencies>
<!--web 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入nacos client依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--监控检查依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--Sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!--全局引用下载依赖地址,不会引入依赖-->
<dependencyManagement>
<dependencies>
<!--springcloud alibaba下载依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- application.yaml配置
server:
port: 8849 # 服务端口
spring:
application:
name: sentinel # 服务名称
cloud:
nacos:
server-addr: 192.168.150.128:8848 # nacos服务器地址
discovery:
server-addr: ${spring.cloud.nacos.server-addr} # 注册中心地址(默认为nacos服务器地址)
sentinel:
enabled: true # 开启sentinel(默认开启)
transport:
dashboard: 192.168.150.128:8850 # 连接dashboard
port: 8719 # 与dashboard的通信端口
management:
endpoints:
web:
exposure:
include: "*" # 暴露所有web端点(用于健康检查)
- SentinelApplication.java启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient // 开启服务的注册与发现(新版本默认开启,可以不需要该注解)
public class SentinelApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelApplication.class, args);
}
}
6.4 @SentinelResource注解的使用
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
/**
* 注解@SentinelResource参数:
* value: 操作资源名(可自定义)
* fallback: 抛除降级/流控之类的异常时的自定义处理函数(自定义函数需在同一类中)
* blockHandler: 抛降级/流控之类的异常的自定义处理函数(自定义函数需在同一类中)
*/
@SentinelResource(value = "test", fallback = "testFallBack", blockHandler = "testBlockHandler")
@GetMapping("/test/test")
public String test() {
if (Math.random() > 0.5) {
throw new RuntimeException("服务器出错");
}
return "1111";
}
public String testFallBack() {
return "服务器出错";
}
public String testBlockHandler(BlockException blockException) {
if (blockException instanceof FlowException) {
return "当前服务已被限流";
} else if (blockException instanceof DegradeException) {
return "当前服务已被降级";
}
return "当前服务不可用";
}
}