文章目录
-
- 1.微服务基本环境调整
- 2.使用OpenFeign实现微服务模块间的远程调用
-
-
- 1.消费者的pom.xml,引入OpenFeign和Nacos的服务发现
- 2.消费者的application.yml(配置nacos服务注册)
- 3.消费者的启动类(开启nacos的服务发现,以及启动OpenFeign)
- [4.com/sun/springcloud/service/MemberOpenfeignService.java 编写与远程调用的方法匹配的接口](#4.com/sun/springcloud/service/MemberOpenfeignService.java 编写与远程调用的方法匹配的接口)
- 5.编写一个controller进行远程调用
- 6.测试
-
- 1.启动nacos,81模块,10004,10006模块
- 2.访问nacos查看注册情况
- [3.浏览器输入 http://localhost:81/member/openfeign/get/1 (必须加上http:// )](#3.浏览器输入 http://localhost:81/member/openfeign/get/1 (必须加上http:// ))
- 7.切换负载均衡算法
-
- 1.编写配置类,注入一个负载均衡算法的bean
- 2.重新启动,报错,bean已经被定义了,说明之前可能定义了同样id的负载均衡算法的bean
- 3.换一个id即可,然后重新启动
- 4.测试,浏览器访问几次,有时会出现超时的情况(OpenFeign默认超时时间为1s)
- [5.设置超时时间 application.yml](#5.设置超时时间 application.yml)
- 6.又检查了一下,远程调用的方法,之前设置了休眠时间,删除即可。。。
-
- 3.服务消费者整合Sentinel进行服务保护
-
-
- 1.pom.xml引入Sentinel
- [2.application.yml 配置Sentinel的客户端和服务端](#2.application.yml 配置Sentinel的客户端和服务端)
- 3.测试
-
- 1.启动nacos,sentinel
- 2.启动81,10004,10006模块
- [3.浏览器输入http://localhost:8080/ 进入Sentinel的服务端](#3.浏览器输入http://localhost:8080/ 进入Sentinel的服务端)
- 4.浏览器输入http://192.168.137.1:8848/nacos/index.html进入nacos查看注册情况
- [5.浏览器访问 http://localhost:81/member/openfeign/get/1 然后查看Sentinel控制台](#5.浏览器访问 http://localhost:81/member/openfeign/get/1 然后查看Sentinel控制台)
- 4.需求分析
- 5.开始配置之前进行测试
-
- 当10004和10006都down掉时,不断请求会发生什么?
-
- 1.首先关闭10004和10006微服务
- [2.浏览器发送请求 http://localhost:81/member/openfeign/get/1,发现是超时](#2.浏览器发送请求 http://localhost:81/member/openfeign/get/1,发现是超时)
- [3.浏览器发送请求 http://localhost:81/member/openfeign/get/1, 可以发现服务不可用](#3.浏览器发送请求 http://localhost:81/member/openfeign/get/1, 可以发现服务不可用)
- [6. 81模块配置如果远程调用的服务出现异常,则立即返回结果](#6. 81模块配置如果远程调用的服务出现异常,则立即返回结果)
-
- [1.MemberFeignFallbackService.java 实现 MemberOpenfeignService.java 并注入容器](#1.MemberFeignFallbackService.java 实现 MemberOpenfeignService.java 并注入容器)
- 2.在application.yml配置启用openfeign和sentinel的整合
- [3.MemberOpenfeignService 添加fallback属性,指定出现异常要处理的类](#3.MemberOpenfeignService 添加fallback属性,指定出现异常要处理的类)
- [4.重新启动81模块,浏览器输入 http://localhost:81/member/openfeign/get/1测试](#4.重新启动81模块,浏览器输入 http://localhost:81/member/openfeign/get/1测试)
- 5.关闭10004和10006,再次进行测试,成功处理异常!
-
- 4.消费者使用OpenFeign整合Sentinel进行服务保护小结
- 5.规则持久化
-
-
- 1.规则持久化方案
- 2.规则持久化原理
- 3.需求分析
- 4.具体配置
-
- 1.在Nacos配置中心增加Sentinel的流控规则
- 2.pom.xml引入nacos和sentinel持久化的依赖
- [3.application.yml 拉取Nacos的配置信息并同步到Sentinel](#3.application.yml 拉取Nacos的配置信息并同步到Sentinel)
- 4.测试
-
- 1.启动Nacos、Sentinel、81、10004、10006
- 2.查看Nacos注册情况
- [3.浏览器快速请求 http://localhost:81/member/openfeign/get/1, 流控规则生效!](#3.浏览器快速请求 http://localhost:81/member/openfeign/get/1, 流控规则生效!)
- 4.查看同步到Sentinel的流控规则
- 5.其他规则配置
-
1.微服务基本环境调整
1.对10004模块的application.yml调整
2.启动nacos以及一个消费者两个提供者
目前的消费者是Ribbon+restTemplate形式进行远程调用的
3.测试
1.输入http://localhost:8848/nacos/index.html 来查看注册情况
2.浏览器访问 http://localhost:81/member/nacos/consumer/get/1
3.结果
2.使用OpenFeign实现微服务模块间的远程调用
1.消费者的pom.xml,引入OpenFeign和Nacos的服务发现
xml
<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 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.example</groupId>
<artifactId>e-commerce-center</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>member-service-nacos-consumer-81</artifactId>
<name>Archetype - member-service-nacos-consumer-81</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- 引入openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--引入nacos的服务发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- springboot web starter 用来监听端口-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 如果在子工程/模块指定了 version,则以指定为准 -->
</dependency>
<!--
1. starter-actuator 是 springboot 程序的监控系统,可以实现健康检查,info 信息
等
2. 访问 http://localhost:10000/actuator 可以看到相关链接, 还可以做相关设置. -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 公共模块的jar包 -->
<dependency>
<groupId>org.example</groupId>
<artifactId>e_commerce_center-common-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
2.消费者的application.yml(配置nacos服务注册)
yaml
server:
port: 81
spring:
application:
name: member-service-nacos-consumer-81
# 配置nacos的服务注册
cloud:
nacos:
discovery:
server-addr: localhost:8848 # 配置要注册到的nacos地址,根据实际情况填写
3.消费者的启动类(开启nacos的服务发现,以及启动OpenFeign)
java
package com.sun.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author 孙显圣
* @version 1.0
*/
@SpringBootApplication // springboot启动类
@EnableDiscoveryClient // 开启nacos服务发现
@EnableFeignClients // 开启feign远程调用
public class MemberNacosCostomerApplication81 {
public static void main(String[] args) {
SpringApplication.run(MemberNacosCostomerApplication81.class, args);
}
}
4.com/sun/springcloud/service/MemberOpenfeignService.java 编写与远程调用的方法匹配的接口
1.将要远程调用的方法整个复制到这个接口,然后去掉方法体
java
package com.sun.springcloud.service;
import com.sun.springcloud.util.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* Description:
*
* @Author sun
* @Create 2024/3/30 10:39
* @Version 1.0
*/
public interface MemberOpenfeignService {
/**
* 根据id来获取某个会员的信息
*
* @param id 使用路径参数的形式传入参数
* @return 返回json格式的数据
*/
@GetMapping("/memberget/{id}") // 这里使用的路径参数
public Result getMemberById(@PathVariable("id") Long id);
}
2.在接口上添加@FeignClient注解,指定远程调用的服务在nacos中的名字
- 这样这个接口中就具备了所有远程调用微服务的信息
- 后面在注入的时候就会注入针对这个接口的代理对象,远程调用方法的时候通过@FeignClient注解中的信息进行服务发现ip + 端口 + 上下文路径,并在前面加上http://,最后再拼接上这个@GetMapping注解中的资源路径,完成远程调用
- 简单来说,这个接口需要包含要远程调用的服务发现和资源路径的信息,这样才能够进行远程调用
java
package com.sun.springcloud.service;
import com.sun.springcloud.util.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* Description:
*
* @Author sun
* @Create 2024/3/30 10:39
* @Version 1.0
*/
@FeignClient("member-service-nacos-provider") // 会进行服务的发现,发现服务的ip+端口+上下文路径
public interface MemberOpenfeignService {
/**
* 根据id来获取某个会员的信息
*
* @param id 使用路径参数的形式传入参数
* @return 返回json格式的数据
*/
@GetMapping("/member/get/{id}") // 这里使用的路径参数
public Result getMemberById(@PathVariable("id") Long id);
}
5.编写一个controller进行远程调用
1.创建一个MemberOpenFeignController的controller并将要远程调用的controller上面的注解复制过来(不能改)
java
package com.sun.springcloud.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
/**
* Description:
*
* @Author sun
* @Create 2024/3/30 10:53
* @Version 1.0
*/
// 这两个注解是要远程调用的controller的注解
@RestController
@Slf4j
public class MemberOpenFeignController {
}
2.依赖注入刚才编写的远程调用的接口的动态代理对象
java
package com.sun.springcloud.controller;
import com.sun.springcloud.service.MemberOpenfeignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* Description:
*
* @Author sun
* @Create 2024/3/30 10:53
* @Version 1.0
*/
// 这两个注解是要远程调用的controller的注解
@RestController
@Slf4j
public class MemberOpenFeignController {
@Resource
private MemberOpenfeignService memberOpenFeignService; // 注入远程调用的接口
}
3.将要远程调用的接口再复制过来,按Tab,使用copilot来自动补全远程调用的代码
- 这里的url,方法名,参数,都是可以修改的
- 传入getMemberById的参数必须符合这个controller的要求
- getMemberById的返回类型也要匹配,比如这里就必须使用@RestController
- 牢记接口三要素 url 参数 返回值
- 建议:如果只是想要远程调用一下的话,就没必要修改了,直接粘贴过来远程调用即可
java
package com.sun.springcloud.controller;
import com.sun.springcloud.service.MemberOpenfeignService;
import com.sun.springcloud.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* Description:
*
* @Author sun
* @Create 2024/3/30 10:53
* @Version 1.0
*/
// 这两个注解是要远程调用的controller的注解
@RestController
@Slf4j
public class MemberOpenFeignController {
@Resource
private MemberOpenfeignService memberOpenFeignService; // 注入远程调用的接口
/**
* 根据id来获取某个会员的信息
*
* @param id 使用路径参数的形式传入参数
* @return 返回json格式的数据
*/
@GetMapping("/member/openfeign/get/{id}") // 1.这里的url是可以改的
public Result getMemberById(@PathVariable("id") Long id) { // 2.这里的参数和方法名是可以改的
// 远程调用member-service-nacos-provider的getMemberById方法
return memberOpenFeignService.getMemberById(id); // 这里的参数和返回值是要远程调用的接口的参数和返回值
}
}
6.测试
1.启动nacos,81模块,10004,10006模块
2.访问nacos查看注册情况
3.浏览器输入 http://localhost:81/member/openfeign/get/1 (必须加上http:// )
7.切换负载均衡算法
1.编写配置类,注入一个负载均衡算法的bean
java
package com.sun.springcloud.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/** 配置类,用于配置Ribbon的负载均衡策略
* @author 孙显圣
* @version 1.0
*/
@Configuration
public class RibbonRule {
@Bean
public IRule ribbonRule() {
// 随机策略
return new RandomRule();
}
}
2.重新启动,报错,bean已经被定义了,说明之前可能定义了同样id的负载均衡算法的bean
3.换一个id即可,然后重新启动
4.测试,浏览器访问几次,有时会出现超时的情况(OpenFeign默认超时时间为1s)
5.设置超时时间 application.yml
1.全局配置
yaml
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 10000
2.单个Feign客户端配置
yaml
feign:
client:
config:
客户端的application-name:
connectTimeout: 5000
readTimeout: 10000
6.又检查了一下,远程调用的方法,之前设置了休眠时间,删除即可。。。
3.服务消费者整合Sentinel进行服务保护
1.pom.xml引入Sentinel
xml
<!-- 引入Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.application.yml 配置Sentinel的客户端和服务端
yaml
sentinel:
transport:
dashboard: localhost:8080 # 配置sentinel服务端的地址,根据实际情况填写
port: 8719 # 配置sentinel客户端的端口,根据实际情况填写,如果冲突,会自动+1,直到找到可用的端口
3.测试
1.启动nacos,sentinel
2.启动81,10004,10006模块
3.浏览器输入http://localhost:8080/ 进入Sentinel的服务端
4.浏览器输入http://192.168.137.1:8848/nacos/index.html进入nacos查看注册情况
5.浏览器访问 http://localhost:81/member/openfeign/get/1 然后查看Sentinel控制台
4.需求分析
5.开始配置之前进行测试
当10004和10006都down掉时,不断请求会发生什么?
1.首先关闭10004和10006微服务
2.浏览器发送请求 http://localhost:81/member/openfeign/get/1,发现是超时
- 原因是OpenFeign会根据接口的信息来通过服务发现和资源路径,找到要远程调用的接口,并缓存在本地,所以只要缓存还在,就不会是服务不可用
3.浏览器发送请求 http://localhost:81/member/openfeign/get/1, 可以发现服务不可用
- 此时的缓存已经不在,OpenFeign重新从nacos获取服务信息,但是获取不到所以会出现服务不可用的错误
6. 81模块配置如果远程调用的服务出现异常,则立即返回结果
1.MemberFeignFallbackService.java 实现 MemberOpenfeignService.java 并注入容器
java
package com.sun.springcloud.service;
import com.sun.springcloud.util.Result;
import org.springframework.stereotype.Component;
/**
* Description: 会员服务的降级处理, 当服务不可用时,立即返回一个默认的结果
*
* @Author sun
* @Create 2024/3/30 14:32
* @Version 1.0
*/
@Component // 注入到spring容器中
public class MemberFeignFallbackService implements MemberOpenfeignService{
@Override
public Result getMemberById(Long id) {
return Result.error("503", "服务降级返回, 服务不可用");
}
}
2.在application.yml配置启用openfeign和sentinel的整合
yaml
# 配置openfeign和sentinel的整合
feign:
sentinel:
enabled: true
3.MemberOpenfeignService 添加fallback属性,指定出现异常要处理的类
4.重新启动81模块,浏览器输入 http://localhost:81/member/openfeign/get/1测试
5.关闭10004和10006,再次进行测试,成功处理异常!
4.消费者使用OpenFeign整合Sentinel进行服务保护小结
1.服务消费者OpenFeign远程调用流程
1.配置Nacos的服务发现和服务注册功能
- 服务发现:配置pom.xml,和启动类开启服务发现的注解
- 服务注册:配置application.yml
2.配置OpenFeign远程调用
1.pom.xml引入OpenFeign依赖
2.编写service接口存放服务发现和资源路径的信息
- 将要远程调用的方法整个复制到这个接口,然后去掉方法体
- 在接口上添加@FeignClient注解,指定远程调用的服务在nacos中的名字
3.编写controller进行远程调用
- 将要远程调用的controller上面的注解复制过来(不能改)
- 依赖注入刚才编写的远程调用的接口的动态代理对象
- 将要远程调用的接口再复制过来去掉方法体,按Tab,使用copilot来自动补全远程调用的代码
2.整合Sentinel进行服务保护流程
1.配置Sentinel监控服务
- pom.xml引入Sentinel依赖
- application.yml 配置Sentinel的客户端和服务端
2.配置OpenFeign整合Sentinel,使得远程调用出现异常集中处理
- 编写一个类实现存放服务发现和资源路径的信息的service,并实现其方法,然后注入容器
- 在application.yml配置启用openfeign和sentinel的整合
- 在service中的@FeignClient注解,添加fallback属性,指定出现处理异常的类
3.服务消费者OpenFeign远程调用整合Sentinel进行服务保护原理
4.Sentinel仍然可以对这个controller进行流量控制,熔断降级,热点限流
设置QPS为1
5.规则持久化
1.规则持久化方案
2.规则持久化原理
- 简单来说就是在Nacos配置Sentinel的规则
- 然后在通过Sentinel监控的微服务通过底层通信,同步到Sentinel上
3.需求分析
4.具体配置
1.在Nacos配置中心增加Sentinel的流控规则
2.pom.xml引入nacos和sentinel持久化的依赖
xml
<!-- 引入nacos和sentinel持久化的依赖 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
3.application.yml 拉取Nacos的配置信息并同步到Sentinel
yaml
datasource:
ds1: # 从Nacos中读取sentinel的规则配置
nacos:
server-addr: localhost:8848 # 配置要注册到的nacos地址,根据实际情况填写
dataId: member-service-nacos-consumer-81 # 配置要读取的配置的dataId
groupId: DEFAULT_GROUP # 配置要读取的配置的groupId
data-type: json # 配置要读取的配置的类型
rule-type: flow # 配置要读取的配置的规则类型为流控规则