nacos2.x临时实例默认使用grpc通信引发的问题解决

nacos2.x临时实例默认使用grpc通信引发的问题解决

现象

微服务项目启动出现com.alibaba.nacos.api.exception.NacosException: Client not connected, current status:STARTING异常

原因

临时实例使用GrpcClient进行注册和心跳检测,通过看报错信息打印,可以看到nacos使用了GrpcClient,提示连接失败,查阅资料发现nacos从2.x版本开始,对于临时实例注册使用GrpcClient,通过grpc方式进行通信,区别于1.x版本的HttpClient,通过http接口的方式进行通信
在这里插入图片描述
其中grpc通信端口默认设置是与主端口偏移1000和1001
查看nacos-client2.2.0的源码,在GrpcClient.java中的connectToServer方法定义了端口,端口为在主端口的基础上进行偏移得到
在这里插入图片描述
查看rpcPortOffset方法,发现是RpcClient.java这一个抽象类的抽象方法。其中GrpcClient类继承于RpcClient类,RpcClient类中有rpcPortOffset抽象方法,GrpcClient中也继承了rpcPortOffset抽象方法,GrpcClient抽象类的实现类有两个,分别是GrpcSdkClient和GrpcClusterClient
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以看到GrpcSdkClient默认端口偏移为1000,GrpcClusterClient默认端口偏移1001,通过配置项nacos.server.grpc.port.offset可以设置端口偏移,需要注意这里的配置没法根据不同的GrpcClient实现进行区分

GrpcClient的不同实现类使用工厂模式进行创建,RpcClientFactory为工厂类,其中存在createClient和createClusterClient两个静态方法分别用于创建GrpcSdkClient和GrpcClusterClient对象,在nacos-client2.2.0的源码中没有看到使用创建GrpcClusterClient对象方法的地方,就是说RpcClient使用的就是GrpcSdkClient
在这里插入图片描述

nacos注册分析

在这里插入图片描述
在nacos进行注册时,使用了NamingClientProxy接口中的registerService方法进行注册,具体注册操作在两个实现类NamingGrpcClientProxy和NamingHttpClientProxy中定义,这里用到了静态代理模式,代理类NamingClientProxyDelegate对registerService方法进行代理,根据是否临时实例选择不同的实现,临时实例使用NamingGrpcClientProxy,非临时实例使用NamingHttpClientProxy
在这里插入图片描述
在这里插入图片描述
配置类中ephemeral定义了是否是临时实例,对应配置spring.cloud.nacos.discovery.ephemeral,默认为true
在这里插入图片描述
在这里插入图片描述
NamingGrpcClientProxy中根据前面提到的方式使用工厂模式对RpcClient进行创建

解决

通过上面的分析,知道可以有两种解决思路
1.开放grpc通信端口,端口号为nacos主端口+1000。我是因为docker容器启动的nacos,导致开放端口缺失
2.修改服务配置,spring.cloud.nacos.discovery.ephemeral = false,将实例改为持久化实例,这样使用HttpClient进行注册和心跳,无需额外开放rpc端口

  • 16
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值