前情
环境版本:
jdk 1.8
springboot 2.2.2
springcloud Hoxton.SR1
seata 1.1.0
nacos 1.3.1
环境配置:
seata1.1.0注册进nacos1.3.1 整合springcloud微服务 全流程
1. 修改seata server端的配置文件,记得先备份(安装位置)
1.1 file.conf
关于vgroup_mapping关键字更改为vgroupMapping,在官网中有所说明,conf均更改为驼峰命名。
存储方式改为db,并将数据库配置改为自己的。
1.2 registry.conf
将注册类型改为nacos,注意namespace若是public则保留空值即可。
1.3 使用db_store.sql中的语句建库seata,并执行脚本建表。
2. 先启动nacos,再启动seata
至此为止,seata服务启动正常且注册到nacos,如下图:
3. 编写微服务,修改seata client端的配置文件(IDEA的微服务配置中)
编写微服务的部分省略。将server的两个conf文件复制到resources中,并修改yml文件配置。
修改yml,注意这里黄色写错了,有大坑...看了源码就知道。
tx-service-group: my_test_tx_group
启动微服务:
发现问题:启动后,服务已经注册进nacos,但一直弹error- 无可用服务。
明明有服务却得到null,只能推断是配置问题没有读取到,但是又找不到配置问题在哪,参考他人的源码分析,查看获取host的url,设置clusters=default,竟然可以获取到hosts:
http://localhost:8848/nacos/v1/ns/instance/list?app=unknown&healthyOnly=false&namespaceId=public&clientIP=192.168.1.1&serviceName=DEFAULT_GROUP%40%40serverAddr&udpPort=52734&encoding=UTF-8&clusters=default
又看了看get的url,定位在最后的clusters=default,难道是程序中没有get到clusters的值?索性将url中的clusters=default去掉,竟然也可以获取到hosts:
http://localhost:8848/nacos/v1/ns/instance/list?app=unknown&healthyOnly=false&namespaceId=public&clientIP=192.168.1.1&serviceName=DEFAULT_GROUP%40%40serverAddr&udpPort=52734&encoding=UTF-8
这就让人迷惑了,get请求能获取到,但程序中就是获取不到,猜想是我的程序没有走到这一步就跳转了。带着这样的疑问去看源码,最终找到了答案...果然,因为之前就已经获得了null值,所以并没有发送请求。
先给个结论:yml和file.conf对应关系应该如下图!(建议大家学习时也要多思考,不要一味复制),default才是clusters的名称。
源码分析过程:
- 看错误日志
ERROR 8132 --- [ main] i.s.c.r.netty.NettyClientChannelManager : no available service 'null' found, please make sure registry config correct
- 由此首先找到这个类 NettyClientChannelManager ,定位到availList打断点
- 查看getAvailServerList方法
- 查看lookup方法
- 查看getServiceGroup方法
这里已经可以发现传递的String为service.vgroupMapping.default,不太对劲了!注意这里也能看出1.1.0已修改为驼峰命名规则。
- 给getConfig的接口和方法层层加断点,找到执行的getConfig方法
我理解两次是分别去本地和nacos中寻找配置
但都找不到service.vgroupMapping.default,因为你配的是service.vgroupMapping.my_text_tx_group = "default" ,所以层层return后,会得到空的availList,报错。
那么问题出在哪里呢?
正确执行时:(想看看怎么获得host的)
- 可以得到clusterName,并会继续向下执行
- 进入getAllInstances方法
- 进入getServiceInfo方法
- 进入getServiceInfo0方法
此时return serviceInfoMap.get(key),那肯定有put吧(参考他人)
- 查找 serviceInfoMap.put
执行到这时切换了线程
- 可以看到已经获得了正确的host值。
那么在哪里调用的url?
- 在刚刚的方法页
- 依次寻找调用方法
- 最终定位到url:
http://localhost:8848/nacos/v1/ns/instance/list?healthyOnly=false&namespaceId=public&clientIP=192.168.79.1&serviceName=DEFAULT_GROUP%40%40serverAddr&udpPort=51357&encoding=UTF-8&clusters=default
正是在末尾加上了clusters=default,得以请求到数据。
总结
学习的时候要多思考,多较真,配置可以参照官网,但也要小心。
虽然问题是小问题,但是这波学到了很多,还是很值得的。
参考:虽然我的问题和他们的不一致,但是源码分析部分给了我启发。
SpringCloud整合Seata启动报no available server to connect源码分析 - 灰信网(软件开发博客聚合) (freesion.com)https://www.freesion.com/article/7552502508/(31条消息) 关于springcloud-alibaba+nacos(注册中心、配置中心)之seata1.1.0版本之坑_weixin_46123910的博客-CSDN博客_seata 无法注册到nacos
https://blog.csdn.net/weixin_46123910/article/details/106748873
启动微服务之后又遇到了新问题
参考他人如下,记录
1.Feign调用服务报错:Load balancer does not have available server for client:xxx
2. feign.FeignException$InternalServerError: status 500 reading CartFeignService#getSelectedCartItems()
(31条消息) feign.FeignException$InternalServerError: status 500 reading CartFeignService#getSelectedCartItems()_明快de玄米61的博客-CSDN博客https://blog.csdn.net/qq_42449963/article/details/112913592Feign接口中是否有诡异的返回值类型,比如
BigDecimal
,你可以换一个类型
3. Seata报错: 0101 can not connect to 169.254.0.1:8091 cause:can not register RM,err:regis(33条消息) [已解决]Seata报错: 0101 can not connect to 169.254.0.1:8091 cause:can not register RM,err:regis_AsajuHuishi的博客-CSDN博客https://blog.csdn.net/qq_36937684/article/details/120582962?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_ecpm_v1~rank_v31_ecpm-3-120582962.pc_agg_new_rank&utm_term=RM%2C+can+not+register+seata&spm=1000.2123.3001.4430可能启动时加上 -p 8091