白驹过隙,这篇文章距今已有一年以上的历史。技术发展日新月异,文中的观点或代码很可能过时或失效,请自行甄别:)

问题

最开始部署 nsq 的时候是直接在云主机上直接部署的,但是作为一个牛逼的程序猿,哦不,紧跟潮流,哦不, 方便扩缩容, 怎么能不上 docker 呢? 于是我就上了 docker, 和所有玩法一样,跟着 nsq 官方文档上留的那个 docker-composer.yaml 文件copy 了一份 yaml, 然后docker-compose up -d,愉快玩耍去了,直到有一天,我想看下队列的一些数据,进入了 nsqadmin 准备看某个 nsqd 的数据时,蹦出了下面这个:

Jietu20171217-220842.jpg

啥? 找不到 host? Are u kidding me?

原因

其实想想也很简单,因为默认nsqd 的broadcast-address的地址是hostname, 而一个容器起来的时候,会随机分配一个 hostname, 而这个 hostname 并没有加入到docker 默认的路由中

解决办法

其实这个问题困扰我蛮久了,直到今天我实在忍无可忍终于找到了,而且不止一种方法, 原理很简单, 就是让 docker 找到容器的 hostname

方法一

既然找不到,那么让 nsqd 在 boardcast 的时候暴露出来的时候不要用 hostname 不就行了么,比如docker-compose.yaml 换为这个:

192.168.0.1/24

这样nsqadmin 不也可能找到了么,试了下,果然可以

Jietu20171217-222344.jpg

但是呢, 这种方法不优雅,如果做自动扩缩容就没办法了

所以, 本机搭个单机玩玩可以用这种办法

方法二

docker-compose.yaml 中新建一个网络,完整的如下:

version: '2'
services:
  nsqlookupd:
    image: nsqio/nsq
    command: /nsqlookupd
    networks:
      - nsq-network
    hostname: nsqlookupd
    ports:
      - "4161:4161"
      - "4160:4160"
  nsqd:
    image: nsqio/nsq
    command: /nsqd --lookupd-tcp-address=nsqlookupd:4160
    depends_on:
      - nsqlookupd
    hostname: nsqd
    networks:
      - nsq-network
    ports:
      - "4151:4151"
      - "4150:4150"
  nsqadmin:
    image: nsqio/nsq
    command: /nsqadmin --lookupd-http-address=nsqlookupd:4161
    depends_on:
      - nsqlookupd
    hostname: nsqadmin
    ports:
      - "4171:4171"
    networks:
      - nsq-network

networks:
  nsq-network:
    driver: bridge

方法三(针对 rancher 管理容器)

在 rancher 的应用中,给所有的服务指定网络的时候给容器名的 hostname 指定为容器,如下:

WechatIMG5347.jpeg

然后也可以很愉快地玩了