最近在项目中使用到Docker和Dubbo,想在Docker中运行一个服务并把该服务自身的信息发布到Dubbo注册中心。
刚开始测试时候将所有容器都放在同一台主机中,测试过程很顺利,但是当进行Docker主机扩展,将容器部署在不同的主机时候,就发现一个奇怪的现象:应用之间调试不通了。
这里对具体问题解释一下:Dubbo提供了一个方便的服务发现机制,每个服务(这里称为提供者)只要向Dubbo注册中心注册过,注册中心就会将服务的地址发送给同样在注册中心注册的服务调用方(这里称为消费者),之后即使Dubbo注册中心挂了也不影响服务的调用。
当服务提供者部署在容器中时,这时候发现其在Dubbo中心注册的是容器的IP地址,而对于另外一台主机上的消费者来说这个IP是不可访问的,当时我在网上找了很多相关的资料,最后得出几种解决方案。
解决方案
设置容器的IP与主机IP在同一网段内,使容器IP可直接访问(会占用大量的IP地址,且IP会限制在同一网段,在生产环境中往往不可能)。
通过复杂的iptables路由规则,通过多层桥接方式打通网络(此法是可行的,也是今后要考虑的,但是操作起来略麻烦)。
对Dubbo进行扩展,扩展dubbo protocol配置,增加配置项publish host、 publish port,对应主机的ip和port,并且在注册服务时将主机的ip和port写到注册中心。(这种方法需要对Dubbo进行扩展,不太建议)
以上三种方法都有一定的局限性和复杂性,我就想能否有更加简单便捷的方法可以解决这个问题。
最后查阅资料时发现Dubbo是先通过hostname(通过ping hostname)来得到本机的IP地址的,换句话说也就是dubbo是读取/etc/hosts文件得到主机的IP的,又因为Docker在重启时候IP地址会重置,即/etc/hosts文件在Docker重启时候会被重置,所以考虑在Docker启动的脚本中动态修改/etc/hosts文件,从而改变Docker主机的IP。
实施
在Docker启动时候将运行一个脚本文件(该脚本将通过另外一个脚本运行服务,将服务注册到Dubbo中心),在脚本文件中运行下面命令:
start.sh
#!/bin/sh
sed -i "s/.*$(hostname)/$DOCKER_IP $(hostname)/" /etc/hosts
/data/app/bin/start.sh
在启动Docker时候将宿主机的IP作为一个环境变量传递给Docker主机,然后Docker主机中将运行上面的start.sh脚本,该脚本的作用是在启动服务之前,通过查找/etc/hosts文件把现有的Docker主机名对应的IP修改为宿主机的IP,从而使得注册到Dubbo中心的是宿主机的IP和端口。
一切都似乎没问题,然后在运行的时候却出现一个意想不到的错误:
sed: cannot rename /etc/sed8DbrGm: Device or resource busy
原来/etc/hosts文件是在宿主机挂载到Docker中,所以使用sed/awk等命令时候将导致设备或者资源忙的错误。
既然不能直接修改原来的文件,那么就变通一下,把原来的文件复制一份,通过修改复制后的文件,然后通过cat复制文件重定向到/etc/hosts去,问题得到解决!
新的脚本如下:
start.sh
#!/bin/sh
cp /etc/hosts /etc/hosts.temp
sed -i "s/.*$(hostname)/$DOCKER_IP $(hostname)/" /etc/hosts.temp
cat /etc/hosts.temp > /etc/hosts
/data/app/bin/start.sh
摘自:http://blog.csdn.net/liu306487103/article/details/52221986
分享到:
相关推荐
在dubbo中,默认使用的是多播机制,也就是说,dubbo服务在启动时会通过网络多播的方式将自己的信息广播到局域网内的所有主机上。不过,这种机制可能会受到网络配置的限制。因此,在某些情况下,也可以使用单播机制,...
Dubbo正是为了解决这种复杂环境下服务间的高效通信问题而设计的。 - **单一体应用架构**:初期阶段,网站流量较小,可将所有功能部署在一个应用中以降低成本。 - **垂直应用架构**:随着流量增长,单一应用通过增加...
- **服务容器**:Dubbo内置了多种服务容器,如Spring Container、Jetty Container和Log4j Container等,这些容器主要用于暴露服务。 - **缺点**:尽管Dubbo具有许多优势,但也存在一些局限性,例如性能受网络延迟和...
总的来说,Dubbo协议模块的源码解析涵盖了RPC协议的原理、Dubbo框架对各种协议的支持以及配置方法,对于理解Dubbo的网络通信机制和优化服务调用具有重要作用。通过深入学习这部分内容,开发者可以更好地定制和优化...
本文档详细讲解了Dubbo的使用方法和主要功能特性,适用于依赖Dubbo作为业务工程RPC通信框架的开发者,作为参考手册。 首先,文档介绍了互联网发展带来的背景需求,网站应用规模的扩大促使传统垂直应用架构转向...
例如,在容器环境下,服务可能需要绑定到容器的内部IP地址而非宿主机的IP地址。 #### 集群容错 在分布式环境中,任何组件都可能出现故障,这可能导致整个系统的不可用。为了解决这一问题,Dubbo提供了一种集群容错...
- **服务提供者** 必需依赖 `dubbo` 以及远程通信协议的实现,比如 `dubbo-rpc`。 - **服务消费者** 则需要引入 `dubbo` 以及配置服务消费者的行为。 - 在配置中可以设置缺省依赖与可选依赖,缺省依赖是必须配置的,...
当前微服务框架,如 SpringCloud、Dubbo 等,也仅作为过渡模型的事实。这些问题主要有: 1. 不适于高度组织化的容器集群,微服务实体运行于容器中同外部隔离,不知道自己的服务地址等环境信息。 2. 现有微服务框架...
4. **容器网络**(第29章):随着Docker和Kubernetes等容器技术的普及,容器网络允许容器在不同主机间通信。这些章节可能会讨论如何实现容器的网络连接,比如使用Docker的桥接网络或通过CNI(Container Network ...
Dubbo是阿里巴巴开源的RPC框架,可以与SpringCloud集成,实现微服务间的高效通信。 3.3 消息总线与事件驱动 3.3.1 Spring Cloud Bus Spring Cloud Bus用于连接SpringCloud的应用实例,可以通过消息代理(如...
本篇文章将围绕Dubbo容器资源库中的Zookeeper配置进行详细介绍。 #### 一、Zookeeper配置概述 Zookeeper的配置主要通过`zoo.cfg`文件来完成,该文件通常位于Zookeeper安装目录下的`conf`文件夹中。`zoo.cfg`文件...
对于小型项目,可以优先考虑使用轻量级的解决方案,如使用Docker容器化部署,配合Kubernetes或Docker Compose进行服务编排,以降低复杂性。同时,采用如Spring Cloud或Dubbo等成熟的微服务框架,可以快速搭建起基本...
消息驱动Bean必须实现两个接口MessageDrivenBean和MessageListener 在对象创建的过程中将被容器调用,onMessage函数方法接收消息参数,将其强制转型为合适的消息类型,同时打印出消息的内容。同时一个mail note将被...