Spring Cloud 注册 Nacos2.x 版本RPC客户端连接抛 Server check fail, please check server ** 异常解决方案

编程入门 行业动态 更新时间:2024-10-28 19:20:11

Spring Cloud 注册 Nacos2.x 版本RPC<a href=https://www.elefans.com/category/jswz/34/1771403.html style=客户端连接抛 Server check fail, please check server ** 异常解决方案"/>

Spring Cloud 注册 Nacos2.x 版本RPC客户端连接抛 Server check fail, please check server ** 异常解决方案

在 nacos-client:2.x 中,如果启动了naocs2.x的服务不修改任何端口的情况下是可以正常连接的。

在docker下运行了 nacos 并且指定跟主机绑定 “8848:8848” 端口

cloud 中配置

spring.cloud.nacos.discovery.server-addr=http://172.1.6.41:8848
spring.cloud.nacos.config.server-addr=http://172.1.6.41:8848

在nacos服务启动正常下,Spring Cloud 连接会抛出一个异常为:

c.a.n.c.remote.client.grpc.GrpcClient    :Server check fail, please check server 172.1.6.41 ,port 9848 is available , error ={}java.util.concurrent.ExecutionException: com.alibaba.nacos.shaded.io.grpc.StatusRuntimeException: UNAVAILABLE: io exception

那是因为Nacos2.x版本相比1.X新增了gRPC的通信方式,因此需要增加2个端口。新增端口是在配置的主端口(server.port)基础上,进行一定偏移量自动生成

端口与主端口的偏移量描述
98481000客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求
98491001服务端gRPC请求服务端端口,用于服务间同步等

那只是因为docker映射的端口缺少了,把剩下两个也补齐就正常了

    ports:- "8848:8848"- "9848:9848"- "9849:9849"

如果需要修改 8848 的端口,比如尝试把 8848修改成38848

ports:- "38848:8848"- "39848:9848"- "39849:9849"

修改成这样之后连接配置就变成了38848 也是没有问题的

spring.cloud.nacos.discovery.server-addr=http://172.1.6.41:38848
spring.cloud.nacos.config.server-addr=http://172.1.6.41:38848

如果39848 端口被其他应用占用,则需要设置一个其他端口

ports:- "38848:8848"- "39849:9848"- "39849:9849"

但是此时cloud连接nacos之后client 会根据 38848 进行偏移1000,而我们端口已经改成了39849,rpc是连接不上的,所以我们可以看看rpc的偏移到底是如何实现

我们可以从错误信息中获取到他是 c.a.n.c.remote.client.grpc.GrpcClient 这个类型下抛出来的错误。把这个类型名字直接放入IDEA,让智能提示帮我们找到这个类型是 import com.alibaba.nacosmon.remote.client.grpc.GrpcClient;,从结构上看一共有以下这些方法

com.alibaba.nacosmon.remote.client.grpc.GrpcClient#GrpcClient(java.lang.String)
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#GrpcClient(java.util.Properties)
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#GrpcClient(com.alibaba.nacosmon.remote.client.grpc.GrpcClientConfig)
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#GrpcClient(com.alibaba.nacosmon.remote.client.grpc.GrpcClientConfig, com.alibaba.nacosmon.remote.client.ServerListFactory)
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#GrpcClient(java.lang.String, java.lang.Integer, java.lang.Integer, java.util.Map<java.lang.String,java.lang.String>)
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#getConnectionType
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#createGrpcExecutor
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#shutdown
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#createNewChannelStub
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#createNewManagedChannel
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#shuntDownChannel
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#serverCheck
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#bindRequestStream
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#sendResponse
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#connectToServer
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#LOGGER
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#clientConfig
com.alibaba.nacosmon.remote.client.grpc.GrpcClient#grpcExecutor

找到 public Connection connectToServer(ServerInfo serverInfo)方法

@Overridepublic Connection connectToServer(ServerInfo serverInfo) {try {if (grpcExecutor == null) {this.grpcExecutor = createGrpcExecutor(serverInfo.getServerIp());}int port = serverInfo.getServerPort() + rpcPortOffset();ManagedChannel managedChannel = createNewManagedChannel(serverInfo.getServerIp(), port);RequestGrpc.RequestFutureStub newChannelStubTemp = createNewChannelStub(managedChannel);if (newChannelStubTemp != null) {Response response = serverCheck(serverInfo.getServerIp(), port, newChannelStubTemp);if (response == null || !(response instanceof ServerCheckResponse)) {shuntDownChannel(managedChannel);return null;}BiRequestStreamGrpc.BiRequestStreamStub biRequestStreamStub = BiRequestStreamGrpc.newStub(newChannelStubTemp.getChannel());GrpcConnection grpcConn = new GrpcConnection(serverInfo, grpcExecutor);grpcConn.setConnectionId(((ServerCheckResponse) response).getConnectionId());//create stream request and bind connection event to this connection.StreamObserver<Payload> payloadStreamObserver = bindRequestStream(biRequestStreamStub, grpcConn);

可以看到 port 是通过serverInfo.getServerPort() + rpcPortOffset(); 拼接起来的,serverInfo.getServerPort()就是通过配置文件读取过来的,那就只需要知道 rpcPortOffset(); 方法是获取值就可以了,它是一个抽象方法

    public abstract int rpcPortOffset();

这个方法由 GrpcSdkClient 和 GrpcClusterClient 两个类型分别实现

GrpcClusterClient@Overridepublic int rpcPortOffset() {return Integer.parseInt(System.getProperty(GrpcConstants.NACOS_SERVER_GRPC_PORT_OFFSET_KEY,String.valueOf(Constants.CLUSTER_GRPC_PORT_DEFAULT_OFFSET)));}
GrpcSdkClient@Overridepublic int rpcPortOffset() {return Integer.parseInt(System.getProperty(GrpcConstants.NACOS_SERVER_GRPC_PORT_OFFSET_KEY,String.valueOf(Constants.SDK_GRPC_PORT_DEFAULT_OFFSET)));}

两个类型实现都是先从环境变量的 GrpcConstants.NACOS_SERVER_GRPC_PORT_OFFSET_KEY = nacos.server.grpc.port.offset 进行获取偏移量,如果获取不到则设置成常量Constants.SDK_GRPC_PORT_DEFAULT_OFFSET =1000

public static final Integer SDK_GRPC_PORT_DEFAULT_OFFSET = 1000;

所以只需要设置一下nacos.server.grpc.port.offset 配置即可,偏移量就是RPC端口 39849- 38848 的出来的数值,nacos.server.grpc.port.offset = RPC端口 - Nacos端口

更多推荐

Spring Cloud 注册 Nacos2.x 版本RPC客户端连接抛 Server check fail, please check server ** 异

本文发布于:2024-03-06 06:11:31,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1714571.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:客户端   异常   解决方案   版本   Spring

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!