nacos注册服务及集成seata踩坑记录(No available service)

nacos注册服务及集成seata踩坑记录

概述

这一段时间一直在学习阿里微服务的全家桶套餐。功能挺好用的,就是文档太少了,遇到问题太难排查。今天在玩Seata的启动的时候遇到很多坑,在这里通过nacos集成seata来简单阐述一下基于nacos注册服务及配置中心联调排查问题的思路。针对我遇到的问题,暂时讲问题主要归结为4类:

  • 注册服务及获取服务的问题
  • 配置文件读取的问题
  • Alibaba全家桶依赖问题
  • 网路链路的问题

问题复现

因为目前网上提供的demo,大多数是在本地或是windows上进行的集成,这次我的集成是基于一个小项目在Linux环境上的集成。借由这次nacos集成seata我们逐步来分析问题的原因:

1.还原情景

1.引入Alibaba全家桶的依赖
nacos注册服务及集成seata踩坑记录(No available service)

2.引入nacos服务注册中心及配置中心依赖
nacos注册服务及集成seata踩坑记录(No available service)

3.引入seata依赖

nacos注册服务及集成seata踩坑记录(No available service)

4.在服务的配置文件中集成seata

nacos注册服务及集成seata踩坑记录(No available service)

5.服务器启动nacos服务端及seata服务端

这里我们使用的是1.1.4版本的nacos以及1.4版本的seata

nacos注册服务及集成seata踩坑记录(No available service)

nacos注册服务及集成seata踩坑记录(No available service)

6.启动项目,发现错误
nacos注册服务及集成seata踩坑记录(No available service)

错误详情:
io.seata.common.exception.FrameworkException: No available service

这时我们猜测服务并没有连接到seata服务

解决问题1(读取配置文件的问题)

我们进入seata源码打断点,进入源码 RegistryService 类,找到getServiceGroup方法,发现问题:
nacos注册服务及集成seata踩坑记录(No available service)

这时我们根据调用链 getConfig 找到从nacos读取配置的方法
nacos注册服务及集成seata踩坑记录(No available service)

继续跟进getConfig方法,找到getConfigInner方法,忽略使用本地配置,找到获取nacos配置的代码:
nacos注册服务及集成seata踩坑记录(No available service)

最终,我们获取到seata向nacos发送读取配置的get请求,我们找到url和参数,放入postman模拟请求:
nacos注册服务及集成seata踩坑记录(No available service)

放入postman进行验证,这里给出GET请求的详细地址,方便大家调试:
http://xxx:8848/nacos/v1/cs/configs?dataId=service.vgroupMapping.my_ums_tx_group&group=DEFAULT_GROUP

找到问题:
nacos注册服务及集成seata踩坑记录(No available service)

经过几次参数组合的尝试,最终确定不传入namespace时,可以获得正确的配置数据:
nacos注册服务及集成seata踩坑记录(No available service)

验证修改是否生效

修改ums的ums-application-dev.yml配置文件,删除配置中的namespace,并再次启动项目查看
nacos注册服务及集成seata踩坑记录(No available service)

nacos注册服务及集成seata踩坑记录(No available service)

7.发现问题仍然没有解决:
nacos注册服务及集成seata踩坑记录(No available service)

解决问题2(获取seata服务的问题)

在问题1的基础上,我们跟踪原来来到NettyClientChannelManager中的reconnect方法,发现获取到的服务实例为null:
nacos注册服务及集成seata踩坑记录(No available service)

跟踪源码到getAvailServerList方法,进入nacos服务获取方法:
nacos注册服务及集成seata踩坑记录(No available service)

继续向下跟踪代码。发现端倪:
nacos注册服务及集成seata踩坑记录(No available service)

对于这个常量值我们意外发现与nacos上注册的seata服务名称不一样:
nacos注册服务及集成seata踩坑记录(No available service)

反复分析导致这个情况产生的原因,是nacos源码写错了嘛?这时我们突然发现服务端的seata版本与我们项目中的seata版本存在较大的差异,之前我们看到服务器上我们使用的时1.4版本的seata,而项目中的seata版本则为1.1版本:
nacos注册服务及集成seata踩坑记录(No available service)
这里也向大家提供nacos获取服务的GET请求
http://XXXX:8848/nacos/v1/ns/instance/list?app=ums-application&healthyOnly=false&namespaceId=public&clientIP=XXXXXX&[email protected]@seata-server&udpPort=58795&clusters=default

经过在官网的查询,我决定使用最新的Alibaba全家桶版本,及2.2.3版本:
nacos注册服务及集成seata踩坑记录(No available service)

这时我们发现,seata-all的版本已经提高到了1.3版本,随后我们启动项目并查看源码:
nacos注册服务及集成seata踩坑记录(No available service)

8.这次我们打上 @GlobalTransactional 标签进行分布式事务验证。发现现在错误解决
nacos注册服务及集成seata踩坑记录(No available service)

这里我在第二个insert语句中加入了sql错误,在第一句insert后打入断点验证,发现ums表插入了数据,在ums表的相同数据库中的undo_log表中发现有数据记录。
nacos注册服务及集成seata踩坑记录(No available service)

nacos注册服务及集成seata踩坑记录(No available service)

放开断点,代码抛出SQL异常.后再观察两个表数据:

  • user表刚刚插入的数据被擦除
  • undo_log表刚刚插入的数据被擦除:
    nacos注册服务及集成seata踩坑记录(No available service)

9.至此nacos集成seata问题解决,验证生效

总计

这次只时阐述了nacos集成seata相关的问题,因为每个人使用的Alibaba全家桶,nacos服务端及seata服务端的版本都不尽相同,且现在Alibaba全家桶项目更新很快,对代码的修改也比较频繁,很多代码仅仅一个小版本都会带来很多问题,所以阅读nacos相关源码变得尤为重要,笔者这里只时提供一个排除问题,解决异常的思路。也希望大家在使用中遇到的问题相互交流。