解决dubbo无法连接访问远程服务提供者
问题由来:在本地写了一个服务提供者用dubbo将服务暴露出去(即注册到服务中心zookeeper),再在服务消费者用dubbo发现服务,结果没有出现问题。但当服务提供者放在云服务器上后,消费者不能发现远程服务导致RPC失败。
一. dubbo的工作原理
首先要理解dubbo的工作原理,才能找到问题根源。
1.暴露服务.
springboot结合dubbo的服务提供者配置
通过这个配置,会将服务暴露给zookeeper注册中心,注册的信息为各个接口的ip、端口、接口名称、参数、通信协议等。
2.发现服务
服务消费者的配置基本一样。发现流程为扫描使用@Reference
的接口,根据配置的注册中心地址去寻找服务,将服务的所有信息保存并生成一个代理以供调用。这里要保证RPC接口和用到的实体类信息在同一个包目录下才能成功发现服务
3.服务调用
在消费者使用远程接口调用函数时,底层的代理就根据从注册中心得到的服务提供者的ip和端口发送数据给服务提供者,数据使用dubbo协议封装了 调用接口、调用函数、函数各个参数等信息 最后再序列化发送。服务提供者收到信息后,定位的具体的接口和函数,发起调用,然后将结果封装后在发送给消费者。消费者拿到后返回。以上就RPC的调用过程。
二. 查看注册中心
有了理论基础就可以解决问题了。因为服务的信息都在注册中心zookeeper里,不能调用可能是注册中心出问题,所以进入zookeeper查看服务提供者到底有没有把服务器写入。
进入zookeeper后发现暴露的服务信息不对劲,注册的是局域网ip,这就导致消费者获取到这个ip无法连接服务提供者。
解决方法:
1.进入云服务器,输入hostname
获取本机名
2.然后vim /etc/hosts
在末尾加入 主机名 公网ip
3.重新启动服务提供者暴露服务
三.调用失败的其他原因
- 远程接口和实体类没在同一个包目录下。这样会导致底层反射创建类失败。最好是把接口和实体抽取放在一个模块。
- 云服务器端口未开放。像阿里云的服务器,首先要到控制台将服务器的安全组加入需要用到的端口,如dubbo协议的20880端口,zookeeper的2181端口等。然后还要在防火墙里开启端口
firewall-cmd --add-port=20880/tcp --permanent
且刷新一下firewall-cmd --reload
或者直接将防火墙关闭(不建议)。 - 服务者和提供者用的注册中心地址和通信协议不一致,这里需要统一配置。