在部署一个开源项目时,本地调试遇到seata的服务一直没有找到,于是开始排查。
首先是将所有组件docker-compose发布到云服务器,接下来本地启动应用,控制台一直报错。
ERROR 2968 --- [eoutChecker_1_1] i.s.c.r.netty.NettyClientChannelManager : no available service found in cluster 'default', please make sure registry config correct and keep your seata server running
这个问题就是seata服务端没有正确启动,随即到服务器上查看启动日志,排查问题。
在部署时发现seata一直注册不到nacos上,然后导致了本地应用检测不到SEATA_GROUP而产生报错。
那首先定位问题就是服务端发布的有问题
然后就重新部署发布,使用命令
docker-compose up --build
查看启动日志,首先发现mysql的问题,Operation not permitted
,经过一番google,这个问题大概是因为mysql8的版本在docker上部署,会有安全校验,具体解决方法就是在docker-compose.yaml
中mysql服务添加参数
security_opt:
- seccomp:unconfined
重新启动后正常,但是这不是造成seata启动错误的原因,根本问题仍未解决
seata在启动之后,根据registry.conf的配置注册到nacos
mall4cloud-seata | 02:25:03.680 INFO --- [ main] i.s.core.rpc.netty.NettyServerBootstrap : Server started, listen port: 8091
mall4cloud-seata | 02:25:03.804 ERROR --- [ main] io.seata.server.Server : nettyServer init error:ErrCode:500, ErrMsg:failed to req API:/nacos/v1/ns/instance after all servers([10.0.4.14:8848]) tried: java.net.SocketException: Connection reset
mall4cloud-seata | ==>
mall4cloud-seata | java.lang.RuntimeException: ErrCode:500, ErrMsg:failed to req API:/nacos/v1/ns/instance after all servers([10.0.4.14:8848]) tried: java.net.SocketException: Connection reset
mall4cloud-seata | at io.seata.core.rpc.netty.NettyServerBootstrap.start(NettyServerBootstrap.java:157) ~[seata-core-1.4.2.jar:na]
mall4cloud-seata | at io.seata.core.rpc.netty.AbstractNettyRemotingServer.init(AbstractNettyRemotingServer.java:55) ~[seata-core-1.4.2.jar:na]
mall4cloud-seata | at io.seata.core.rpc.netty.NettyRemotingServer.init(NettyRemotingServer.java:52) ~[seata-core-1.4.2.jar:na]
mall4cloud-seata | at io.seata.server.Server.main(Server.java:98) ~[classes/:na]
mall4cloud-seata | Caused by: com.alibaba.nacos.api.exception.NacosException: failed to req API:/nacos/v1/ns/instance after all servers([10.0.4.14:8848]) tried: java.net.SocketException: Connection reset
mall4cloud-seata | at com.alibaba.nacos.client.naming.net.NamingProxy.reqApi(NamingProxy.java:552) ~[nacos-client-1.3.3.jar:na]
mall4cloud-seata | at com.alibaba.nacos.client.naming.net.NamingProxy.reqApi(NamingProxy.java:491) ~[nacos-client-1.3.3.jar:na]
mall4cloud-seata | at com.alibaba.nacos.client.naming.net.NamingProxy.reqApi(NamingProxy.java:486) ~[nacos-client-1.3.3.jar:na]
mall4cloud-seata | at com.alibaba.nacos.client.naming.net.NamingProxy.registerService(NamingProxy.java:239) ~[nacos-client-1.3.3.jar:na]
mall4cloud-seata | at com.alibaba.nacos.client.naming.NacosNamingService.registerInstance(NacosNamingService.java:200) ~[nacos-client-1.3.3.jar:na]
mall4cloud-seata | at com.alibaba.nacos.client.naming.NacosNamingService.registerInstance(NacosNamingService.java:185) ~[nacos-client-1.3.3.jar:na]
mall4cloud-seata | at io.seata.discovery.registry.nacos.NacosRegistryServiceImpl.register(NacosRegistryServiceImpl.java:86) ~[seata-discovery-nacos-1.4.2.jar:na]
mall4cloud-seata | at io.seata.core.rpc.netty.NettyServerBootstrap.start(NettyServerBootstrap.java:153) ~[seata-core-1.4.2.jar:na]
mall4cloud-seata | ... 3 common frames omitted
mall4cloud-seata | <==
mall4cloud-seata |
但是遇到问题,这里,就是nacos的serverAddr配置的不对了,这里的ip应该是nacos的docker容器IP地址,那通过下面命令,查看对应IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mall4cloud-nacos
然后更改seata的registry.conf文件中的serverAddr为容器IP:8848
registry {
type = "nacos"
nacos {
application = "seata-server"
serverAddr = "nacos容器ip:8848"
group = "SEATA_GROUP"
namespace = "dsafawefwf"
cluster = "default"
username = "nacos"
password = "nacos"
}
}
config {
type = "nacos"
nacos {
serverAddr = "nacos容器ip:8848"
namespace = "dsafawefwf"
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
}
}
再次重新启动,连接正常了,但是这还没结束,因为SEATA_GROUP的配置项是保存在mysql的,而在seata初始化数据源的时候报错,这里也是因为需要配置数据源url为服务器上mysql所在容器的IP
如上面的方法,更改数据源url,再次重启seata。终于,seata服务端正常启动了!
到这里,服务端的组件正常启动了,再回到本地项目,启动之后
这个问题是出在docker-compose.yaml
中,seata的配置SEATA_IP应该是对外暴露服务的IP,那么就是服务器的外网地址,重新修改后再次构建启动
我们可以看到注册成功了,至此,项目可以正常启动和调试了。
最后总结一下seata部署在远程服务器,本地访问的配置。此项目的seata是依赖于nacos和mysql,nacos是用于seata的服务注册,seata的配置则是通过nacos来读取配置,nacos的配置是保存在mysql,本地远程连接时需要注意的配置项:
- 首先在部署docker时,有两个文件要配置,
registry.conf
和file.conf
。registry.conf是将seata服务注册到nacos的配置,所以这里nacos的serverAddr
设置为nacos容器的IP;file.conf
是seata服务端参数的配置,如果选择store.db的,seata服务端配置数据源,参数store.db.url
要指定mysql容器的地址,所有的seata相关参数都保存在mysql中; - seata服务端配置好之后,在编排配置文件
docker-compose.yaml
中,seata的environment
参数需要配置成你的服务器外网IP,这样确保你的客户端能够访问到seata,这一点也比较好理解,因为我们需要从nacos找到seata的注册配置然后去访问seata,所以这里如果配置成内网地址的话是访问不通的。
更多推荐