SpringCloudAlibaba简单运用
这篇文章就是简单介绍一下用SpringCloudAlibaba如何搭建一个微服务项目
项目基础搭建
1.父项目搭建
- 导入依赖即可,父项目不需要有代码,只需要提供子类会用到的依赖
<parent>
<groupId> org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
<spring-boot.version>2.2.5.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
<mysql.version>5.1.47</mysql.version>
<mybatis.version>2.1.1</mybatis.version>
</properties>
<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>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
2.搭建公共模块,可以放一些公用的domain
3.User服务搭建
- user-server需要注册进Nacos中
- 第一步:导入依赖
<dependencies>
<!--nacos客户端依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringBootWeb依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--公共模块依赖-->
<dependency>
<groupId>cn.lion</groupId>
<artifactId>common-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
</dependencies>
- 第二步:编写启动类
@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("cn.lion.mapper")
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class,args);
}
}
- 第三步:编写配置文件
server:
port: 10010
spring:
application:
name: user-server # 应用名称
datasource:
url: jdbc:mysql://localhost:3306/cloud_test?useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 指定nacos注册中心地址
- 第四步:启动测试,在nacos注册中心进行查看
4.Order服务搭建
- order-server需要注册进Nacos中
- 第一步:导入依赖
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--nacos客户端依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringBootWeb依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入OpenFeign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--公共模块依赖-->
<dependency>
<groupId>cn.lion</groupId>
<artifactId>common-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
</dependencies>
- 第二步:创建启动类
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@MapperScan("cn.lion.mapper")
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
}
- 第三步:编写配置文件
server:
port: 10000
spring:
application:
name: order-server # 应用名称
datasource:
url: jdbc:mysql://localhost:3306/cloud_test?useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 指定nacos注册中心地址
sentinel:
transport:
dashboard: localhost:8090 # 指定sentinel服务端地址
user-server: # 针对user-server的服务开启随机算法的负载均衡
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
feign:
sentinel:
enabled: true #开启熔断功能
#mybatis:
# type-aliases-package: cn.lion.order.domain # 数据库别名配置
# configuration:
# map-underscore-to-camel-case: true # 数据库表字段名和Java对象属性名之间的映射
#
#logging:
# level:
# cn.lion: debug
# pattern:
# dateformat: MM-dd HH:mm:ss:SSS
- 第四步:启动测试,在nacos注册中心进行查看
6.服务通信
- 在服务调用方我们可以使用Feign、OpenFeign、Dubbo,本次我们直接使用OpenFeign
- 第一步:OrderServer中导入OpenFeign依赖
<!--引入OpenFeign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 第二步:UserServer提供被调用接口
@RestController
@RequestMapping("/user")
public class UserController {
@Value("${server.port}")
private String port;
@GetMapping("/getById/{id}")
public User getById(@PathVariable("id") Long id){
return new User(id, "HelloWorld", "你好,世界!,端口号:" + port);
}
}
- 第三步:OrderServer开启OpenFeign
@SpringBootApplication
// 开启Nacos客户端
@EnableDiscoveryClient
// 开启openfeign
@EnableFeignClients
public class OrderApp {
public static void main(String[] args) {
SpringApplication.run(OrderApp.class,args);
}
}
- 第四步:提供OpenFeign接口
@FeignClient("user-server")
public interface UserFeignClient {
@GetMapping("/user/getById/{id}")
public User getById(@PathVariable("id") Long id);
}
- 第五步:提供OrderServer调用UserServer接口
@RestController
@RequestMapping("/order")
public class OrderController {
/**
* feign调用user服务的客户端组件
*/
@Autowired
private UserFeignClient feignClient;
/**
* 调用user服务接口并返回
* @param id 用户id
* @return
*/
@GetMapping("/{id}")
public User getById(@PathVariable("id") Long id){
return feignClient.getById(id);
}
}
- 第六步:重启服务,访问OrderServer接口
7.网关模块搭建
- 第一步:导入依赖
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--引入gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos客户端依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--公共模块依赖-->
<dependency>
<groupId>cn.lion</groupId>
<artifactId>common-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--nacos配置中心客户端依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
-
第二步:编写启动类
@SpringBootApplication @EnableDiscoveryClient public class GateWayApplication { public static void main(String[] args) { SpringApplication.run(GateWayApplication.class,args); } }
-
第三步:添加配置文件
server: port: 10086 spring: application: name: gateway-server cloud: nacos: discovery: server-addr: localhost:8848 sentinel: transport: dashboard: localhost:8090 # 指定sentinel服务端地址 gateway: discovery: locator: enabled: false #禁用服务名直接访问,但是还是可以通过主机地址和端口号进行访问 lower-case-service-id: true #服务名小写 routes: #路由配置 - id: application-user #指定服务名 uri: lb://user-server #去注册中心找这个服务名 predicates: #断言,匹配访问的路径 - Path=/user-server/** #服务访问路径 filters: - StripPrefix=1 - id: application-order #指定服务名 uri: lb://order-server #去注册中心找这个服务名 predicates: #断言,匹配访问的路径 - Path=/order-server/** #服务访问路径 filters: - StripPrefix=1
SpringCloudAlibaba-Nacos做配置中心
Nacos添加配置
-
第一步:打开Nacos监控面板,进入配置列表,新增一个user服务的配置文件
-
第二步:填写配置文件参数,这里定义了一个名字为application-user-dev.yaml的配置,使用的是YAML格式
- DataID : 非常重要,可以看做是配置的文件的名字,在程序中拉取配置文件的时候需要指定Data ID。
- Group : 分组,默认 DEFAULT_GROUP , 可以针对不同的项目指定不同的配置组
客户端接入配置中心
1.导入依赖
- 修改工程 user-server ,添加配置中心依赖nacos-config
<dependencies>
<!--nacos配置中心客户端依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
2.动态刷新配置
- nacos提供了@RefreshScope注解来刷新配置文件,除了项目环境,可以使用此注解来刷新我们在配置文件中的属性值
需求:在配置文件中定义一个dynamicRefreshTest参数,在代码中通过注解获取,测试是否能够动态刷新
- 第一步:修改注册中心中UserServer服务的配置,新增一个属性值
server:
port: 1010 # user服务端口号
spring:
application:
name: user-server # 应用名称
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 指定nacos注册中心地址
username: hello!
- 第二步:在UserServer中获取dynamicRefreshTest属性值,后续动态改变配置的值,观察是否改变
/**
* @Description 用户相关接口请求处理
* @Author Raymon
* @Date 2023/4/14 11:07
* @Version 1.0
*/
@RestController
@RequestMapping("/user")
@RefreshScope // 动态刷新配置注解
public class UserController {
@Value("${server.port}")
private String port;
@Value("${username}")
private String username;
@GetMapping("/getById/{id}")
public User getById(@PathVariable("id") Long id){
return new User(id, "helloworld", "你好世界!,端口号:" + port+ ", username:" + username);
}
}
3.编写bootstrap.yml
- 跟springcloud-config一样,我们的配置也需要写在bootstrap.yml中
- 如何查找配置文件:application-user + dev + yaml=application-user-dev.yaml 正好和Nacos配置的DataId一致
spring:
cloud:
nacos:
config:
server-addr: localhost:8848
prefix: application-gateway
file-extension: yaml
group: DEFAULT_GROUP
namespace: 8b705cca-86ef-40dd-8f00-a84a19ea2e48
profiles:
active: dev
4.测试
- 启动Nacos,启动 springcloudalibaba-user-server微服务 , 修改Nacos中的配置文件内容,然后访问 http://localhost:10001/user/2,观察控制台打印的 “username”的值会发生变化
SpringCloudAlibaba-Sentinel限流
Sentinel介绍
Sentinel是阿里巴巴开源的一款微服务流量控制组件。官网地址:https://sentinelguard.io/zh-cn/index.html
Sentinel限流应用
运行
java -Dserver.port=8090 -jar sentinel-dashboard-1.8.2.jar
访问
访问http://localhost:8090页面,就可以看到sentinel的控制台了:
需要输入账号和密码,默认都是:sentinel
登录后,发现一片空白,什么都没有:
请求进来才会有东西
2.Sentinel客户端接入
2.1.导入依赖
- 在需要使用Sentinel微服务中导入依赖,本次导入在user-server服务中
<!--sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.2.配置Sentinel
- 在nacos的配置中心修改user-server微服务配置文件,指定sentinel服务端地址
如果是放入了配置中心,就去配置中心修改
server:
port: 10001 # user服务端口号
spring:
application:
name: user-server # 应用名称
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 指定nacos注册中心地址
sentinel:
transport:
dashboard: localhost:8090 # 指定sentinel服务端地址
username: helloworld
2.3.测试
- 启动user-server,访问接口,再查看sentinel控制面板
3.Sentinel设置限流策略
-
我们可以针对某个接口在控制面板处设置限流规则,比如此处我们设置QPS每秒钟只能进来一个请求
-
第一步:设置接口限流规则
-
第二步:浏览器访问user-server服务设置了限流规则的接口,疯狂刷新下是否触发限流
4.资源限流
- Sentinel为我们提供了 @SentinelResource注解标记需要限流的资源,并设置降级方法,以userserver微服务为例
4.1.本类降级方法
- 设置限流接口,并指定降级方法
- value:给当前接口取一个资源名称
- blockHandler:指定降级方法名称,blockHandler方法访问范围需要是 public,返回类型需要与接口相匹配,参数类型必须和接口一致并且最后加一个类型为 BlockException 的异常参数
@RestController
@RequestMapping("/user")
@RefreshScope // 动态刷新配置注解
public class UserController {
@Value("${server.port}")
private String port;
@Value("${dynamicRefreshTest}")
private String dynamicRefreshTest;
@GetMapping("/{id}")
@SentinelResource(value="user-server-getById", blockHandler = "degradationMethod")
public User getById(@PathVariable("id") Long id){
return new User(id, "helloworld", "你好世界!,端口号:" + port+ ", username:" + username);
}
/**
* 服务降级方法
* @param e 服务降级方法必须接收的异常参数
*/
public User degradationMethod(@PathVariable("id") Long id, BlockException e){
e.printStackTrace();
return new User(-1L, "服务降级触发!", "当前服务流量过大,请稍后重试!");
}
}
4.2.降级类
- 创建降级类、静态降级方法
public class DowngradeUtil {
public static User degradationMethod(@PathVariable("id") Long id, BlockException e){
e.printStackTrace();
return new User(-1L, "服务降级触发!", "当前服务流量过大,请稍后重试!");
}
}
- 接口指定降级类,与降级方法
- value:给当前接口取一个资源名称
- blockHandlerClass:指定降级方法类
- blockHandler:指定降级方法名称,blockHandler方法访问范围需要是 public,返回类型需要与接口相匹配,参数类型必须和接口一致并且最后加一个类型为 BlockException 的异常参数
@GetMapping("/{id}")
@SentinelResource(value="user-server-getById", blockHandler ="degradationMethod",blockHandlerClass = DowngradeUtil.class)
public User getById(@PathVariable("id") Long id){
return new User(id, "helloworld", "你好世界!,端口号:" + port+ ", dynamicRefreshTest:" + dynamicRefreshTest);
}
4.3.测试
- 设置限流规则,浏览器访问接口进行测试
Sentinel流控模式
在添加限流规则时,点击高级选项,可以选择三种流控模式:
- 直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式
- 关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流
- 链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流
Gateway使用Sentinel限流
- SpringCloudGateway作为微服务的网关,它是微服务的访问入口,当请求的流量洪峰时可以在Gateway网关层通过Sentinel对请求进行流控
1.导入依赖
<!--sentinel与gateway整合依赖包-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<!--sentinel依赖包-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.配置Sentinel地址
- 指定Sentinel地址
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8090
3.配置限流规则
- 启动Gateway,登录Sentinel控制台,对Url资源进行流控限制,配置方式和前面的配置方式一样
4.限流降级
- Gateway并没有实际的接口方法,那么就需要使用配置的形式进行限流控制
@Configuration
public class SentinelConfig {
public SentinelConfig(){
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
return ServerResponse.ok().body(Mono.just("当前流量过高,触发限流!"),String.class);
}
});
}
}
Nacos存储限流规则
- 在之前的使用中,Sentinel的限流规则在服务启动时就已经被清除,那是因为之前的限流规则是存储在内存中,这样肯定不服务实际开发,所以我们需要进行限流规则持久化
- Sentinel中支持5种持久化的方式:file、redis、nacos、zk和apollo,本片文章针对于Nacos进行持久化配置
- nacos限流规则持久化:其实就是使用配置进行限流规则存储,在微服务中指定需要读取的限流规则
1.整合Nacos持久化限流规则
- 以user-server微服务为例,使用Nacos做限流持久化
- 第一步:在user-server服务中导入依赖
<!--Sentinel使用Nacos持久化限流规则依赖包-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.5.2</version>
</dependency>
- 第二步:在Nacos中新增限流规则配置,用于服务启动时读取限流规则,要配置在public命名空间下
- resource:对那个资源进行限流
- limitApp:这个是流控的调用者,default 代表不区分调用者
- grade:限流方式0是根据并发数量限流,1表示根据QPS来限流
- count:限流阈值,达到这个阈值就被限流,触发降级。
- strategy:基于调用链的流控制策略。0 直接,1 关联 2 链路
- controlBehavior:流控效果,0 直接拒绝,1是Warm Up,2是匀速排队
- clusterMode:是否为集群
[
{
"resource": "user-server-getById",
"limitApp": "default",
"grade": 1,
"count": 10,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
- 第三步:修改微服务在Nacos中的配置文件,增加读取Nacos中刚才配置的限流规则配置
server:
port: 1010 # user服务端口号
spring:
application:
name: user-server # 应用名称
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 指定nacos注册中心地址
sentinel:
transport:
dashboard: localhost:1111 # 指定sentinel服务端地址
datasource:
flow:
nacos: #限流持久配置
server-addr: localhost:8848 #使用nacos的持久
dataId: application-user-dev #获取限流的数据源的dataId
groupId: DEFAULT_GROUP
rule-type: flow #类型:限流
- 第四步:测试
- 重启user-server微服务,访问接口,查看Sentinel中是否有刚才设置的限流规则,并且查看动态修改限流规则是否会生效
SpringCloudAlibaba-Sentinel熔断
服务熔断降级
- 修改user-server微服务,通过@SentinelResource注解的fallback 属性指定降级方法
①本类降级方法
- 设置熔断接口,并设置降级方法
- fallback:方法的返回值类型必须与接口返回值类型一致,方法参数列表需要和接口一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常
@RestController
@RefreshScope // 动态刷新配置注解
public class UserController {
@Value("${server.port}")
private String port;
@Value("${dynamicRefreshTest}")
private String dynamicRefreshTest;
@GetMapping("/getById/{id}")
@SentinelResource(value="user-server-getById", fallback = "fuseDegradation")
public User getById(@PathVariable("id") Long id){
try {
// 用于让服务慢响应
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new User(id, "源码时代", "我在源码时代学习Java!,端口号:" + port + ", dynamicRefreshTest:" + dynamicRefreshTest);
}
/*
* @Description: 熔断降级方法
* @param id:
* @param e: 降级异常
* @return: cn.itsource.domain.User
**/
public User fuseDegradation(@PathVariable("id") Long id, Throwable e){
e.printStackTrace();
return new User(-1L, "熔断服务降级触发!", "服务不可用,请稍后重试!");
}
}
②降级类
- 设置熔断接口,并设置降级方法
- fallbackClass:指定熔断类字节码
- fallback:方法的返回值类型必须与接口返回值类型一致,方法参数列表需要和接口一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常
- 熔断降级类
public class FuseDowngradeUtil {
/*
* @Description: 熔断降级方法
* @param id:
* @param e: 降级异常
* @return: cn.itsource.domain.User
**/
public static User fuseDegradation(@PathVariable("id") Long id, Throwable e){
e.printStackTrace();
return new User(-1L, "熔断服务降级触发!", "服务不可用,请稍后重试!");
}
}
- 熔断接口
@RestController
@RefreshScope // 动态刷新配置注解
public class UserController {
@Value("${server.port}")
private String port;
@Value("${dynamicRefreshTest}")
private String dynamicRefreshTest;
/*
* @Description: 提供一个根据Id返回User对象的接口,给order服务调用
* @param id:
* @return: cn.itsource.domain.User
**/
@GetMapping("/getById/{id}")
@SentinelResource(value="user-server-getById", fallback = "fuseDegradation", fallbackClass = FuseDowngradeUtil.class)
public User getById(@PathVariable("id") Long id){
try {
// 用于让服务慢响应
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new User(id, "源码时代", "我在源码时代学习Java!,端口号:" + port + ", dynamicRefreshTest:" + dynamicRefreshTest);
}
}
2.设置熔断降级规则
- 重启user-server服务后,在Sentinel中设置熔断降级规则,以慢调用比例规则为例
- 最大RT:请求平均响应时长
- 比例阈值:每秒请求次数的百分比,多少百分比触发
- 熔断时长:该熔断接口停止提供服务的时长
- 最小请求数:每秒请求数量
3.测试
- 访问user-server服务接口,疯狂刷新,就会看到触发熔断降级方法,并且10S内无法继续访问成功
OpenFeign整合Sentinel熔断
- Spring Cloud Alibaba是Spring Cloud的一个子项目,OpenFeign是Spring Cloud的客户端负载均衡器,使用Spring Cloud Alibaba依然可以很方便的集成OpenFeign,如果要使用OpenFeign作为服务客户端负载均衡,那么我们需要考虑OpenFeign开启Sentinel进行服务熔断降级
1.导入依赖
- OpenFeign整合Sentinel熔断那么就需要微服务导入OpenFeign依赖与Sentinel依赖
<!--引入OpenFeign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.开启OpenFeignSentinel熔断
server:
port: 1020 # order服务端口号
spring:
application:
name: order-server # 应用名称
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 指定nacos注册中心地址
sentinel:
transport:
dashboard: localhost:1111 # 指定sentinel服务端地址
feign:
sentinel:
enabled: true #开启熔断功能
3.OpenFeign接口降级
- 这里跟OpenFeign开启Hystrix降级一样,还是可以使用fallback属性
@FeignClient(value = "user-server", fallbackFactory = UserFeignClientFallbackFactory.class) // 表示是feign接口
public interface UserFeignClient {
@GetMapping("/getById/{id}")
User getById(@PathVariable("id") Long id);
}
4.编写降级类
@Component
public class UserFeignClientFallbackFactory implements FallbackFactory<UserFeignClient> {
/*
* @Description: 熔断托底方法
* @param throwable:
* @return: cn.itsource.feigenClients.UserFeignClient
**/
@Override
public UserFeignClient create(Throwable throwable) {
return new UserFeignClient() {
@Override
public User getById(Long id) {
return new User(-1L, "触发熔断", "服务不可用,请稍后重试!");
}
};
}
}
5.测试
- 第一步:正常启动order-server、user-server服务,访问order-server服务接口
- 第二步:关闭user-server服务,触发熔断