dubbo提供者注册容器IP问题

dubbo架构

节点角色说明:

  • Provider: 暴露服务的服务提供方。
  • Consumer: 调用远程服务的服务消费方。
  • Registry: 服务注册与发现的注册中心(zookeeper)。
  • Monitor: 统计服务的调用次调和调用时间的监控中心。
  • Container: 服务运行容器。

调用关系说明:

0.服务容器负责启动,加载,运行服务提供者。
1.服务提供者在启动时,向注册中心注册自己提供的服务。
2.服务消费者在启动时,向注册中心订阅自己所需的服务。
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

连通性:

  • 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
  • 监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
  • 服务提供者向注册中心注册其提供的服务,并汇报调用时间到监控中心,此时间不包含网络开销
  • 服务消费者向注册中心获取服务提供者地址列表,并根据负载算法直接调用提供者,同时汇报调用时间到监控中心,此时间包含网络开销
  • 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
  • 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
  • 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
  • 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者

主机绑定

缺省主机IP查找顺序:

  • 通过LocalHost.getLocalHost()获取本机地址。
  • 如果是127.*等loopback地址,则扫描各网卡,获取网卡IP。

手动绑定IP的三种方法

  • 在/etc/hosts中指定:
    hostname 205.182.23.201
  • 在dubbo.xml中加入主机地址的配置:
    <dubbo:protocol host="205.182.23.201" name="dubbo" port="20881" />
  • 在dubbo.properties中加入主机地址的配置
    dubbo.protocol.host=205.182.23.201

Docker应用注册dubbo的问题

当docker容器部署dubbo提供者和常规部署应用混合使用一套zookeeper时,将出现Docker容器中的dubbo提供者向zookeeper注册容器IP导致常规部署应用无法访问容器IP而失败。

解决方法:

通过以上方法一手动绑定IP,可将宿主机IP绑定到/etc/hosts文件中,并将dubbo服务端口通过宿主机映射出来,这样Docker中的提供者将向zookeeper注册宿主机的IP

方法分析:

  • 启动容器时通过--add-host="hostname:host_ip"的参数向容器的/etc/hosts文件添加容器主机名和宿主机IP的映射关系;
  • 容器启动后默认会自动向/etc/hosts文件的最后一行追加”hostname”与容器IP的映射关系,因此必须删掉该行;
  • 容器的/etc/hosts文件是由宿主机挂载到Docker中,所以使用sed/awk等命令时候将导致设备或者资源忙的错误,因此通过以下方法绕过
    1
    2
    3
    cp /etc/hosts /tmp/hosts
    sed -i '$d' /tmp/hosts
    cat /tmp/hosts > /etc/hosts

优化方案:

由于在集群中容器都是通过集群动态创建的,宿主机的IP是不固定的,需要让容器自动获取宿主机的IP并添加到/etc/hosts文件中。

  • 首先在每台宿主机上创建一个/etc/ip的文件,文件内容为宿主机的IP;
  • 启动容器时通过-v /etc/ip:/etc/ip将/etc/ip文件挂载到容器中,这样容器通过/etc/ip即可获取其所对应的宿主机IP;
  • 通过以下脚本将容器hostname与宿主机IP进行绑定。
    1
    2
    3
    4
    5
    6
    7
    #!/bin/bash
    HOST_IP=`cat /etc/ip`

    cp /etc/hosts /tmp/hosts
    sed -i '$d' /tmp/hosts
    echo "$HOST_IP $HOSTNAME" >> /tmp/hosts
    cat /tmp/hosts > /etc/hosts
坚持原创技术分享,您的支持将鼓励我继续创作!
0%