目录
MQ(mybatis-plus)
有三个重要注解
@TableName
@TableId
@TableField :成员变量与字段名不一致,且是is开头,如ismarried在数据库里是is_married则需要是由该注解
iservice批处理
在yml配置中的连接mysql的配置的url中加上开启rewriteBatchedStatements=true参数,配置jdbc参数,批处理默认是关闭的,由mybatis管控。
代码生成器:
iservice中DB的静态方法
可以解决循环依赖,注入问题,但要考虑MP的版本问题,版本低的
增删改查:
查:List,select,
删:delete,remove
增:save,insert
MP提供的逻辑删除配置
枚举处理器:
用于解决数据库中不同数字对应的状态的简易处理操作。
实现枚举类型变量与数据库类型字段的转换步骤:
1.将数据库中的字段用枚举封装起来。
@Getter//使用该注解,方便我们去取值
public enum UserStatus {
NORMAL(1,"正常"),
FROZEN(2,"冻结"),
;
@EnumValue
//加上该注解后,数据库知道该值往数据库中写
@JsonValue
//返回的值是1或2
private final int value;
private final String desc;
UserStatus(int value, String desc) {
this.value = value;
this.desc = desc;
}
}
2,在配置文件中配置同一的枚举处理器,实现类型转换。
json处理器
Docker:
Docker部署数据库mysql:
在finalshell中:
如果要root管理员权限的话:输入us 回车
在输入虚拟环境的密码,即可。
部署MySQL
先停掉虚拟机中的MySQL,确保你的虚拟机已经安装Docker,且网络开通的情况下,执行下面命令即可安装MySQL:
在finalshell中先:
然后创建一个通用网络:
docker network create hm-net
使用下面的命令来安装MySQL:
docker run
-d \ --name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-v /root/mysql/init:/docker-entrypoint-initdb.d \
--network hm-net\
mysql
docker run
-d \ --name mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123 \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-v /root/mysql/init:/docker-entrypoint-initdb.d \
--network hm-net\
mysql
进入mysql内部:
根据docker容器中的mysql的容器id进入mysql,可进行mysql的数据库相关操作。
docker exec -it e8421f7bf834 bash
注意:docker run:创建并运行一个容器,-d是让容器在后台运行
docker run:创建并运行一个容器,-d是让容器在后台运行
-name mysql:给容器起个名字,必须唯一
-p3306:3306:设置端口映射
-eKEY=VALUE:是设置环境变量
注意:mysql是镜像名,并且正确的写法是,镜像名:版本号,如果不写版本号,默认是最新的版本
此时,通过命令查看mysql容器:
docker ps
设置mysql开机自启:
docker update --restart=always mysql(容器名,也可以是容器id)
使用docker查看mysql的版本:
镜像仓库:
存储和管理镜像的平台,Docker'官方维护了一个公共仓库:Docker Hub。
在finallshell中输入 docker inspect mysql 查询MySQL内置的IP地址(电脑终端不允许访问)
docker pull:将远程镜像下载到本地镜像
docker images 查看本地镜像
docker rmi删除本地镜像
docker run运行docker
拉取nginx为例
容器内:
docker stop将正在运行的进程停掉
docker start 将停止的进程开启
docker ps 查看容器中运行中的镜像,
docker ps -a 查看容器内所有的镜像
docker rm 删除的是容器
docker logs 查看运行的日志
docker exec 进入容器的内部
docker logs -f nginx:日志一直进行下去(若没加-f则不会一直生成日志)
docker exec -it nginx bash进入nginx容器内部
exit退出容器
进入mysql容器(上面有)后
mysql客户端命令:
mysql -uroot -p
非强制删除(前提是要将容器停掉)
docker rm mysql
强制删除:(不管是否在运行)
docker rm mysql -f
默认情况下,每次重启虚拟机我们都需要手动启动Docker和Docker中的容器。通过命令可以实现开机自启:
# Docker开机自启
systemctl enable docker
# Docker容器开机自启
docker update --restart=always [容器名/容器id]
我们以Nginx为例给大家演示上述命令。
# 第1步,去DockerHub查看nginx镜像仓库及相关信息
# 第2步,拉取Nginx镜像
docker pull nginx
# 第3步,查看镜像
docker images
# 结果如下:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 16 months ago 141MB
mysql latest 3218b38490ce 17 months ago 516MB
# 第4步,创建并允许Nginx容器
docker run -d --name nginx -p 80:80 nginx
# 第5步,查看运行中容器
docker ps
# 也可以加格式化方式访问,格式会更加清爽
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 第6步,访问网页,
地址:http://虚拟机地址
# 第7步,停止容器
docker stop nginx
# 第8步,查看所有容器
docker ps -a --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 第9步,再次启动nginx容器
docker start nginx
# 第10步,再次查看容器
docker ps -format"table{{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"
# 第11步,查看容器详细信息
docker inspect nginx
# 第12步,进入容器,查看容器内目录
docker exec -it nginx bash
# 或者,可以进入MySQL
docker exec -it mysql mysql -uroot -p
# 第13步,删除容器
docker rm nginx
# 发现无法删除,因为容器运行中,强制删除容器
docker rm -f nginx
电脑开机让停止运行的docker运行起来:
如何解决开机启动docker出现
“Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the d”
的问题
检查 Docker 是否正在运行
首先,我们需要检查 Docker 是否正在运行。可以通过以下命令来检查 Docker 服务的状态:
登录后复制
systemctl status docker
如果 Docker 正在运行,你会看到类似下面的输出:
docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2021-01-01 00:00:00 UTC; 1h ago Docs: Main PID: 12345 (dockerd) Tasks: 27 CGroup: /system.slice/docker.service └─12345 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
相反,你会发现里面出现:
Active: inactive (dead)
启动docker:
sudo systemctl start docker
重器docker
sudo systemctl restart docker
数据卷挂载:
前提是nginx正在运行:进入nginx
docker exec -it nginx bash
进入html目录,(cd和/之间有空格)
cd /usr/share/nginx/html
进入成功之后显示
root@c1e01e4d2d8a:/usr/share/nginx/html#
数据卷基本命令:
查看volume的一些基础命令,和作用。
docker volume --help
在执行docker runi命令时,使用-v数据卷:容器内目录可以完成数据卷挂载
当创建容器时,如果挂载了数据卷且数据卷不存在,会自动创建数据卷
创建一个数据卷,名字为html
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
查询卷内详细信息:
进入卷内:
docker volume inspect html
查看详细信息:
ll
修改html内容:(也可以在MobaXterm中更方便修改)
vi index.html
自定义镜像:
部署一个Java应用的步骤:
准备一个Linux服务器
安装JRE并配置环境变量
拷贝jar包
运行jar包
Dockerfile:
就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。将来Docker可以根据Dockerfile帮我们构建镜像。常见指令如下:
容器网络连接:
查询网卡:
ip addr
查看网络:
docker network ls
一旦两个容器在同一网桥中,另一个容器可以通过ping容器名直接访问
网桥为hm-net
使nginx进入hm-net网桥
docker network connect hm-net nginx
查询容器网络连接情况
docker inspect nginx
docker compose:
其命令格式如下:
在MobaXterm中
先su输入密码
后再
cd~
删除root目录中的mysql文件
rm -r -f mysql
到达根目录root,将wzx198012目录中的mysql文件复制到root下
cp -r /home/wzx198012/mysql mysql
在mysql目录中创建data文件夹
mkdir data
然后再创建mysql容器
docker拉去rabbitmq报错:
[root@localhost ~]# docker pull rabbitmq:3.12.0-management
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
第一种方式:
查看DNS客户机的配置文件:
发现我的nameserver 是 8.8.8.8了,说明我的DNS出了问题
需要新增DNS:nameserver 114.114.114.114
cat /etc/resolv.conf
vim /etc/resolv.conf
添加了8.8.8.8ip
第二种方式:
第一步:
进入vi /etc/docker/daemon.json文件中进行如下配置;
下面这个是原来的阿里云配置,(已删,记录以下!)
"https://m0x7j7ky.mirror.aliyuncs.com",
新的配置如下:
{
"registry-mirrors": ["https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"]
}
{
"registry-mirrors": ["https://docker.registry.cyou",
"https://docker-cf.registry.cyou",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn",
"https://docker.mirrors.ustc.edu.cn",
"https://mirror.iscas.ac.cn",
"https://docker.rainbond.cc"]
}
第二步:
重启docker!
systemctl daemon-reload
systemctl restart docker
systemctl daemon-reload
systemctl restart docker
docker给rabbitmq安装插件:
第一步:拉取镜像
docker pull rabbitmq:3.12.0-management
第二步:启动
docker run -d --name=rabbitmq --restart=always -p 5672:5672 -p 15672:15672 rabbitmq:3.12.0-management
docker run -d --name=rabbitmq --restart=always -p 5672:5672 -p 15672:15672 rabbitmq:3.12.0-management
安装插件的步骤:
第三步:安装延迟队列插件
首先下载rabbitmq_delayed_message_exchange-3.12.0.ez文件上传到RabbitMQ所在服务器,下载地址:Community Plugins | RabbitMQ
切换到插件所在目录,执行 docker cp rabbitmq_delayed_message_exchange-3.12.0.ez rabbitmq:/plugins 命令,将刚插件拷贝到容器内plugins目录下
执行 docker exec -it rabbitmq /bin/bash 命令进入到容器内部,并 cd plugins 进入plugins目录
执行 ls -l|grep delay 命令查看插件是否copy成功
在容器内plugins目录下,执行 rabbitmq-plugins enable rabbitmq_delayed_message_exchange 命令启用插件
exit命令退出RabbitMQ容器内部,然后执行 docker restart rabbitmq 命令重启RabbitMQ容器
安装插件遇到的问题:
将消息延迟队列的插件安装到配置到rabbitmq的容器中的plugins目录下。
该命令冒号前后没有空格!
docker cp rabbitmq_delayed_message_exchange-3.12.0.ez rabbitmq:/plugins
微服务:
目前以灰色的版本为主
什么时候拆分微服务?
初创型公司或项目尽量采用单体项目,快速试错。随着项目发展到达
一定规模再做拆分
如何拆分微服务?
目标:高内聚、低耦合。
方式:纵向拆分、横向拆分
拆分后碰到的第一个问题是什么,如何解决?
拆分后,某些数据在不同服务,无法直接调用本地方法查询数据
利用RestTemplate发送Http请求,实现远程调用
Nacos注册中心:
设置开机自启
docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim
docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim
注意:启动完成后,访问下面地址:http://192.168.150.101:8848/nacos/,注意将192.168.150.101
替换为你自己的虚拟机IP地址。
模拟多个启动类:
右键启动类:点击复制配置
在其中更改启动类的端口
服务发现:
消费者需要连接nacos以拉去和订阅服务,因此服务发现的前两步与服务注册是一样,后面再加上服务调用即可:
1,引入nacos的依赖
<!--nacos 服务注册发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
2,配置nacos地址
# 给微服务起一个名字
spring:
application:
name: cart-service #微服务名称
profiles:
active: dev
datasource:
url: jdbc:mysql://${hm.db.host}:3306/hm-cart?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: ${hm.db.pw}
cloud:
nacos:
server-addr: 192.168.47.130:8848
3,服务发现
private void handleCartItems(List<CartVO> vos) { // TODO 1.获取商品id Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet()); // 2.查询商品 //2.1根据服务名称获取服务的实力列表 List<ServiceInstance> instances = discoveryClient.getInstances("item-service"); if(CollUtil.isEmpty(instances)){ return; } //2.2手写负载均衡,从服务列表中挑选一个实例 ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size())); //2.3利用ResTemplate发起http请求,得到http的相应 /** * 因为使用nacos注册后,有多个端口共调用,所以不能把url写死; */ ResponseEntity<List<ItemDTO>> response = restTemplate.exchange( instance.getUri()+"/items?ids={ids}", HttpMethod.GET, null, new ParameterizedTypeReference<List<ItemDTO>>() { }, Map.of("ids", CollUtil.join(itemIds, ",")) ); //判断相应是否成功 if(!response.getStatusCode().is2xxSuccessful()){ return; } List<ItemDTO> items =response.getBody(); if (CollUtils.isEmpty(items)) { return; } // 3.转为 id 到 item的map Map<Long, ItemDTO> itemMap = items.stream().collect(Collectors.toMap(ItemDTO::getId, Function.identity())); // 4.写入vo for (CartVO v : vos) { ItemDTO item = itemMap.get(v.getItemId()); if (item == null) { continue; } v.setNewPrice(item.getPrice()); v.setStatus(item.getStatus()); v.setStock(item.getStock()); } }
OpenFeign简化注册中心代码:
使用步骤OpenFeign
1,导入依赖
<!--openFeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--负载均衡器--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency>
2,在引导类中添加一个注解
@EnableFeignClients
3,编写FeignClient
获取商品的id集合
@FeignClient("item-service") public interface ItemClient { @GetMapping("/items") List<ItemDTO>queryItemByIds(@RequestParam("ids") Collection<Long> ids); }
连接池: OpenFeign整合OKHttp步骤:
第一:
<!--OK http 的依赖 支持连接池--> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency>
第二:
做配置
#允许使用okhttp:Enables the use of the OK HTTP Client by Feign
feign:
okhttp:
enabled: true
这样就可以使用了!
OpenFeign.只会在FeignClient所在包的日志级别为DEBUG时,才会输出日志。而且其日志级别有4级:
●NONE:不记录任何日志信息,这是默认值。
●
BAS引C:仅记录请求的方法,URL以及响应状态码和执行时间
●
HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
●FU儿L:记录所有请求和响应的明细,包括头信息、请求体、元数据。
由于Feign默认的日志级别就是NONE,所以默认我们看不到请求日志。
OpenFeign日志输出:
网关路由:
用户信息从网关传递给微服务的SpringMVC的拦截器
在hmall-common中配置
配置拦截器:
/**
* springMVC拦截器,不做登录校验,只做用户信息的获取,不做拦截!
*/
public class UserInfoInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1,获取登录用户信息
String userInfo = request.getHeader("user-info");
//2.判断是否获取了用户,如果有,存入ThreadLocal
if (StrUtil.isNotBlank(userInfo)){
UserContext.setUser(Long.valueOf(userInfo));
}
//3.放行
return true;
//return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
//使用完后删除用户信息
UserContext.removeUser();
}
}
添加为拦截器 (MvcConfig包下)
注意条件@ConditionalOnClass(DispatcherServlet.class)为了不再网关中生效
@Configuration
@ConditionalOnClass(DispatcherServlet.class)
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserInfoInterceptor());
}
}
在路径src/main/resources/META-INF/spring.factories中添加中键的一个配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.hmall.common.config.MyBatisConfig,\
com.hmall.common.config.MvcConfig,\
com.hmall.common.config.JsonConfig
OpenFeign中提供了一个拦截器接口,所有由OpenFeign.发起的请求都会先调用拦截器处理请求:
实现远程调用时,用户信息的传递:
public class DefaultFeignConfig { //定义日志级别 @Bean public Logger.Level feignLoggrLevel(){ return Logger.Level.FULL; } //配置微服务之间的请求头传递 @Bean public RequestInterceptor userInfoRequestInterceptor(){ return new RequestInterceptor() { @Override public void apply(RequestTemplate Template) { Long userId = UserContext.getUser(); if (userId!=null){ Template.header("user-info",userId.toString()); } } }; } }
路由断言:
spring: application: name: gateway cloud: nacos: server-addr: 192.168.47.130:8848 gateway: routes: - id: item-service uri: lb://item-service predicates: - Path=/items/**,/search/** # 默认对所有的服务都生效 default-filters: - AddRequestHeader=truth,anyone long-press like button will be rich
spring: application: name: gateway cloud: nacos: server-addr: 192.168.150.101:8848 gateway: routes: - id: item # 路由规则id,自定义,唯一 uri: lb://item-service # 路由的目标服务,lb代表负载均衡,会从注册中心拉取服务列表 predicates: # 路由断言,判断当前请求是否符合当前规则,符合则路由到目标服务 - Path=/items/**,/search/** # 这里是以请求路径作为判断规则
路由过滤器:
网关登录校验请求处理流程:
自定义过滤器:
在nacos中做的全局配置
spring: datasource: url: jdbc:mysql://${hm.db.host:192.168.150.101}:${hm.db.port:3306}/${hm.db.database}?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: ${hm.db.un:root} password: ${hm.db.pw:123} mybatis-plus: configuration: default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler global-config: db-config: update-strategy: not_null id-type: auto
logging: level: com.hmall: debug pattern: dateformat: HH:mm:ss:SSS file: path: "logs/${spring.application.name}"
knife4j: enable: true openapi: title: ${hm.swagger.title:黑马商城接口文档} description: ${hm.swagger.description:黑马商城接口文档} email: ${hm.swagger.email:zhanghuyi@itcast.cn} concat: ${hm.swagger.concat:虎哥} url: https://www.itcast.cn version: v1.0.0 group: default: group-name: default api-rule: package api-rule-resources: - ${hm.swagger.package}
引依赖:
<!--nacos配置管理--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--读取bootstrap文件--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency>
拉取共享配置:
配置热更新:
当修改配置文件中的配置时,微服务无需重启即可使配置生效。
第一:在bootstrap.yaml中已经配置过了,不用特别关注!
第二:
微服务中要以特定方式读取需要热更新的配置属性
推荐第一种方式:
雪崩问题:
雪崩问题产生的原因是什么?
1.微服务相互调用,服务提供者出现故障或阻塞。
2.服务调用者没有做好异常处理,导致自身故障。
3.调用链中的所有服务级联失败,导致整个集群故障
解决问题的思路有哪些?
尽量避免服务出现故障或阻塞。
一、保证代码的健壮性;
二、保证网络畅通;
三、能应对较高的并发请求;
服务调用者做好远程调用异常的后备方案,避免故障扩散
解决雪崩问题的常见方案有哪些?
请求限流:限制流量在服务可以处理的范围,避免因突发流量而故障
线程隔离:控制业务可用的线程数量,将故障隔离在一定范围
服务熔断:将异常比例过高的接口断开,拒绝所有请求,直接走fallback
失败处理:定义fallback逻辑,让业务失败时不再抛出异常,而是返
回默认数据或友好提示
服务熔断:
Docshttps://b11et3un53m.feishu.cn/wiki/QfVrw3sZvihmnPkmALYcUHIDnff#B8m1djLmQohLpixhcQscVrFwnmY安装完Sentinel后在控制台输入以下命令便可启动sentinel
java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
端口时8090
访问http://localhost:8090出现用户和密码都是sentinel
<!--sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
进行如下配置:
Restful风格的API请求路径一般都相同,这会导致簇点资源名称重复。因此我们要修改配置,把请求方式+请求路径作
为簇点资源名称:
spring: cloud: sentinel: transport: dashboard: localhost:8090 http-method-specify: true # 开启请求方式前缀
OpenFeign整合Sentinel
修改cart-service模块的application.yml文件,开启Feign的sentinel功能:
feign: sentinel: enabled: true # 开启feign对sentinel的支持
注意:默认情况下SpringBoot项目的tomcat最大线程数是200,允许的最大连接是8492,单机测试很难打满。
所以我们需要配置一下cart-service模块的application.yml文件,修改tomcat连接:
server: port: 8082 tomcat: threads: max: 50 # 允许的最大线程数 accept-count: 50 # 最大排队等待数量 max-connections: 100 # 允许的最大连接
Fallback:
FeignClient的Fallback有两种配置方式:
方式一:FallbackClass,无法对远程调用的异常做处理
方式二:FallbackFactory,可以对远程调用的异常做处理,通常都会选择这种
步骤一:自定义类,实现FallbackFactory,编写对某个FeignClient的fallback;逻辑:
步骤二:将刚刚定义的UserClientFallbackFactory注册为一个Bean:
步骤三:在UserClient接口中使用UserClientFallbackFactory:
分布式事务:
认识Seata
Seata事务管理中有三个重要的角色:
TC(Transaction Coordinator)-事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
TM(Transaction Manager)~事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
RM(Resource Manager)~资源管理器:管理分支事务,与TC交谈以注册分支事务和报告分支事务的状态
在项目中引入Seata依赖:
配置TC服务地址