Docker容器运行DUBBO服务
在使用Docker容器运行dubbo服务的时候遇到一个麻烦的问题,docker服务安装时会自动生成一个独立的网卡docker0,默认网段为172.17.0.1,和宿主机隔离并不互通,Docker会使用容器内的IP注册到注册中心,这样其他的dubbo服务就无法连接这个应用
DUBBO主机绑定规则:
主机绑定表示的是 Dubbo 服务对外发布的 IP 地址,默认情况下 Dubbo 会按照以下顺序来查找并绑定主机 IP 地址
1、查找环境变量中 DUBBO_IP_TO_BIND 属性配置的 IP 地址;
2、查找 dubbo.protocol.host 属性配置的 IP 地址,默认是空,如果没有配置或者IP地址不合法,则继续往下查找;
3、通过 LocalHost.getHostAddress 获取本机 IP 地址,如果获取失败,则继续往下查找;
4、如果配置了注册中心的地址,则使用 Socket 通信连接到注册中心的地址后,使用 for 循环通过 socket.getLocalAddress().getHostAddress() 扫描各个网卡获取网卡 IP 地址;
获取的 IP 地址并不是写入注册中心的地址。默认情况下,写入注册中心的 IP 地址优先选择环境变量中 DUBBO_IP_TO_REGISTRY 属性配置的 IP 地址。在这个属性没有配置的情况下,才会选取前面获得的 IP 地址并写入注册中心;
问题:使用默认的主机绑定规则,可能会存在获取的 IP 地址不正确的情况;
原因:Dubbo 检测本地 IP 地址的策略是先调用 LocalHost.getHostAddress,I这个方法的原理是通过获取本机的 hostname 映射 IP 地址,如果它指向的是一个错误的 IP 地址,那么这个错误的地址将会作为服务发布的地址注册到 ZooKeeper 节点上;
解决方案:
1、在 /etc/hosts 中配置机器名对应正确的 IP 地址映射;
2、在环境变量中添加 DUBBO_IP_TO_BIND 或者 DUBBO_IP_TO_REGISTRY 属性,Value 值为绑定的主机地址;
3、通过 dubbo.protocolhost 设置主机地址;
一、通过绑定hosts方式配置IP映射:
点击查看代码
HOST_IP=宿主机IP
cp /etc/hosts /tmp/hosts
sed -i '$d' /tmp/hosts #替换IP为宿主机IP
echo "$HOST_IP $HOSTNAME" >> /tmp/hosts
cat /tmp/hosts > /etc/hosts
二、设置 DUBBO_IP_TO_BIND 方式配置IP映射
点击查看代码
version: "3"
services:
server1:
image: IMAGEHUB
deploy:
resources:
limits:
cpus: "1"
memory: "512M"
reservations:
cpus: "0.2"
memory: "256M"
container_name: SERVICE
environment:
- DUBBO_IP_TO_REGISTRY= #注册到注册中心的IP地址
- DUBBO_PORT_TO_REGISTRY= #注册到注册中心的端口
- DUBBO_PORT_TO_BIND=30934 #监听端口
- ZK_INSTANCE_IP= #监听IP地址
restart: always
ports:
- "30934:30934"
- "22222:22222"
volumes:
- /data/logs/SERVICE/:/var/log/ompc/