irpas技术客

进击的码农(二)seata之no available service ‘default‘ found_孤帆远影碧空尽

网络 4883

版本 seata:1.3.0spring-boot:2.2.9.RELEASEspring-cloud:Hoxton.SR6spring-cloud-alibaba:2.2.1.RELEASENacos:1.3 seata配置

seata server的配置文件如下:

分别设置file.conf de mode为db,registry.config为nacos, 其他不变, 之后启动。

然后配置客户端:

seata: application-id: ${spring.application.name} tx-service-group: ${spring.application.name}-group registry: nacos: namespace: ff2a1399-d3a6-48f5-80a9-18d67b35e383 server-addr: 1.1.11.15:8848 type: nacos service: vgroup-mapping: seata-product-group: default

启动客户端, 会出现如下的错误:

no available service 'default' found, please make sure registry config correct

网上很多都会提到default大小写之类的,依然没有解决问题,通过跟踪代码可知在NettyClientChannelManager的reconnect方法中getAvailServerList获取不到服务,再跟踪到NacosRegistryServiceImpl的lookup中,发现最终调用NamingService去获取nacos中的实例

@Override public List<InetSocketAddress> lookup(String key) throws Exception { String clusterName = getServiceGroup(key); if (null == clusterName) { return null; } if (!LISTENER_SERVICE_MAP.containsKey(clusterName)) { synchronized (LOCK_OBJ) { if (!LISTENER_SERVICE_MAP.containsKey(clusterName)) { List<String> clusters = new ArrayList<>(); clusters.add(clusterName); List<Instance> firstAllInstances = getNamingInstance().getAllInstances(PRO_SERVER_ADDR_KEY, clusters); if (null != firstAllInstances) { List<InetSocketAddress> newAddressList = firstAllInstances.stream() .filter(instance -> instance.isEnabled() && instance.isHealthy()) .map(instance -> new InetSocketAddress(instance.getIp(), instance.getPort())) .collect(Collectors.toList()); CLUSTER_ADDRESS_MAP.put(clusterName, newAddressList); } subscribe(clusterName, event -> { List<Instance> instances = ((NamingEvent)event).getInstances(); if (null == instances && null != CLUSTER_ADDRESS_MAP.get(clusterName)) { CLUSTER_ADDRESS_MAP.remove(clusterName); } else if (!CollectionUtils.isEmpty(instances)) { List<InetSocketAddress> newAddressList = instances.stream() .filter(instance -> instance.isEnabled() && instance.isHealthy()) .map(instance -> new InetSocketAddress(instance.getIp(), instance.getPort())) .collect(Collectors.toList()); CLUSTER_ADDRESS_MAP.put(clusterName, newAddressList); } }); } } } return CLUSTER_ADDRESS_MAP.get(clusterName); }

接口中的key就是我们客户端配置的seata-product-group,getServiceGroup得到clusterName=default,这里都没有问题, 和我们的配置没有出入,再深入发现问题出在这里:

List firstAllInstances = getNamingInstance().getAllInstances(PRO_SERVER_ADDR_KEY, clusters);拿不到实例,为啥呢,因为PRO_SERVER_ADDR_KEY = “serverAddr”; 但是我们注册的服务根本没有叫serverAddr,所以就会报题目说的错误。

回头再看seata的registry.conf,

registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos" nacos { application = "seata-server" serverAddr = "" group = "SEATA_GROUP" namespace = "" cluster = "default" username = "" password = "" } eureka { serviceUrl = "http://localhost:8761/eureka" application = "default" weight = "1" } redis { serverAddr = "localhost:6379" db = 0 password = "" cluster = "default" timeout = 0 }

由于默认的application 是seata-server, 而我们引入的NacosRegistryServiceImpl中写死了服务叫serverAddr, 故一直找不到seata TC 的服务所在,还有一点是seata的group默认是"SEATA_GROUP",如果我们客户端服务的group和seata不一样,也会报题目的错误,只要把registry.conf的nacos中的application 改为serverAddr,并且把group改为和客户端一样的或者修改客户端的group,要求一致即可:

改客户端 spring: cloud: nacos: discovery: server-addr: 1.1.11.15:8848 namespace: ff2a1399-d3a6-48f5-80a9-18d67b35e383 group: SEATA_GROUP 改registry.conf registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos" nacos { application = "serverAddr" serverAddr = "XXXXXXX" group = "SEATA_GROUP" namespace = "XXXXXX" cluster = "default" username = "XXXXX" password = "XXXX" } eureka { serviceUrl = "http://localhost:8761/eureka" application = "default" weight = "1" } redis { serverAddr = "localhost:6379" db = 0 password = "" cluster = "default" timeout = 0 }

真是坑爹


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #进击的码农二seata之no #available #service #default #found #de