最近刚开始玩Docker和ActiveMQ刚好学习到ActiveMQ集群的搭建,就将其记录了下来给有需要的人,也可以跟大家交流交流。
这里先感谢慕课网和http://blog.csdn.net/lifetragedy/article/details/51869032,在学习ActiveMQ有很大的帮助。
一、docker坏境的搭建。
这里重点不是docker,而是基于docker搭建的ActiveMQ集群,docker了解的也可以参考http://www.docker.org.cn/。
Ubuntu安装docker
Docker 要求 Ubuntu 系统的内核版本高于 3.10,可以通过uname -r来查看。
wget -qO- https://get.docker.com/ | sh
当要以非root用户可以直接运行docker时,需要执行 sudo usermod -aG docker runoob 命令,然后重新登陆,否则会报错,安装完成之后可以通过docker version来查看状态。
也可以通过curl来进行安装,which curl 命令是否安装curl,没有安装则通过 sudo apt-get update 和 sudo apt-get install curl 进行安装。
curl -sSL https://get.docker.com/ | sh
这种安装方式的好处是安装的版本是最新的,或者也可以使用sudo apt-get install docker这种安装方式比较方便,但版本不是最新的,基于你的软件源。
Linux系统
yum -y install docker
经典的安装方式,方便快捷。
Mac系统
没什么好说的,https://www.oschina.net/translate/installing-docker-on-mac-os-x
Windows系统
Docker 引擎是基于Linux 内核,所以我们需要在 Windows 上安装Boot2Docker 来安装虚拟机和运行 Docker。
最新版 Boot2Docker 下载地址: https://github.com/boot2docker/windows-installer/releases/latest
目前最新版为v1.8.0, 下载地址为: https://github.com/boot2docker/windows-installer/releases/download/v1.8.0/docker-install.exe
二、在docker中搭建activemq
首先我先从dockerhub上拉取ActiveMQ镜像,不过我网络比较慢,所以我从阿里拉取的镜像。
这是阿里云镜像仓库的地址
docker pull registry.cn-hangzhou.aliyuncs.com/daydayup/activemq
这是dockerhub
docker pull webcenter/activemq
拉取完镜像之后我们可以通过docker images来查看镜像,然后使用docker run 命令来运行(可以结合自身给出不同的命令),这里出于演示目的使用了自动分配端口映射。
这样我们的容器就运行起来了,下一步我们要做什么呢?该实例来源慕课网的 jovezhao 老师
到这里我们要来开始分析我们的工作了,我们要建立的集群是一个三个节点的集群,分别是一个master节点和一个slave以及一个中间cluster节点。
图中所表示的Node A即 cluster 节点,不进行消息的持久化,即将生产者的消息同步过来,然后发送给消费者消费。
而Node B即表示 master 节点,进行消息的生产并持久化到文件系统中,并将消息同步到 Node A(Cluster)节点。
而Node C即表示 slave 节点,属于备用节点,等待 master 释放锁,当 master 释放锁后取代Node B 称为 master节点。
这里需要注意的是master节点跟slave节点都共用一个文件系统,并且跟cluster节点可以相互通信。
而我们的集群是基于docker来搭建的,so?问题出来了,我们知道每个ActiveMQ在docker眼里就是一个运行着的容器,那么容器的文件系统跟节点访问都需要修改其配置文件,
可是配置文件在容器内部,这个问题有几个解决方案(我所知的):
1.docker commit 该命令相当于在容器上追加一层(docker每个容器都是以层来区分的)
2.dockerfile 定制镜像,就是在原有基础镜像上添加一条条指令,相当于给每一层进行配置
3.docker cp 命令修改(覆盖)容器中的配置文件(不推荐)
4.启动时进行文件映射,这也是我使用的方法,比较简单,更好的方法是使用定制镜像,不过出于测试目的也可以更加了解其内容。
我们先使用 docker cp 从容器内部复制配置文件到本地文件系统(官方给出的配置文件地址是在/opt/activemq/conf/activemq.xml)。
我们可以通过 docker exec -it 容器id /bin/bash 进入运行着的容器中(每个容器可以抽象的理解成一台虚拟机)。
而后找到我们所需要的配置文件,退出容器,通过 docker cp 命令将容器文件拷贝到本地系统中。、
docker cp 容器名:要拷贝的文件在容器里面的路径 要拷贝到宿主机的相应路径
root@ubuntu:/home/yang# docker cp 2263:/opt/apache-activemq-5.13.3/conf/activemq.xml /myConfig/activemq/activemq-master-a.xml
root@ubuntu:/myConfig/activemq# cd /myConfig/activemq/
root@ubuntu:/myConfig/activemq# ls
activemq-clusters-a.xml activemq-master-c.xml activemq-slave-c.xml
activemq-master-a.xml activemq-slave-a.xml
activemq-master-b.xml activemq-slave-b.xml
这里我复制了比较多份用于我以后的测试开发。
首先我们先来修改 Cluster 节点的配置文件,相对比较简单。
<!-- 这里是默认的端口配置,我们都需要,只留下一个61616端口即可,由于是测试所以节点机只要端口不一致即可 -->
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<!-- <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> -->
</transportConnectors>
<!-- 配置网络代理,cluster 节点需要与 master 跟 slave 进行穿透 -->
<networkConnectors>
<networkConnector uri="static:(tcp://192.168.1.106:61617,tcp://192.168.1.106:61618)" duplex="true" />
</networkConnectors>
连接到网络代理的两种方式:
静态的方法配置访问特定的网络代理 Static:(uri1,uri2,uri3,…)?key=value 或是Failover:(uri1, … , uriN)?key=value
发现中介(agents)动态的探测代理
duplex参数用来消息同步,即 master 节点生产出消息,会变成一个 sender 把消息 cluster,同理,cluster 接收到消息也会发送给 master,称为互相穿透。
下面是 master 节点的配置文件
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61617?maximumConnections=1000&wireFormat.maxFrameSize=104857600" />
<!-- <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> -->
</transportConnectors>
<networkConnectors>
<networkConnector uri="static:(tcp:192.168.1.106:61616)" duplex="true" />
</networkConnectors>
下面是 slave 节点的配置文件
<transportConnector name="openwire" uri="tcp://0.0.0.0:61618?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<!-- <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> -->
</transportConnectors>
<networkConnectors>
<networkConnector uri="static:(tcp://192.168.1.106:61616)" duplex="true" />
</networkConnectors>
这样我们的节点连接就配置好了,其实这里还有一个重要的步骤被我们忽略掉了,或者说是略过。
这个步骤就是公用文件系统,在配置文件中有这样一项配置
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>
用来指定持久化文件地址,而由于我们这里使用的是docker来运行容器,并使用文件映射的方式来指定,所以这一步骤我们可以忽略,不过cluster中需要将这项配置进行注释,
因为cluster是不作为生产者来使用的,当然如果我们生产消息时不调用该节点,这项配置也是可以省略的(理论上来说可行)。
然后我们需要要在本地文件中创建一个目录用来进行持久化(正确的做法是使用网络文件系统,我正在学习),这一步我就省略了。
接着就是启动我们的容器,slave节点是要晚于master节点的,其次两个顺序无关紧要。
root@ubuntu:~# docker run -it -d -p 61617:61616 -p 8171:8161 -v /myConfig/activemq/activemq-master-a.xml:/opt/apache-activemq-5.13.3/conf/activemq.xml -v /usr/share/activemq/kahadb:/opt/apache-activemq-5.13.3/data/kahadb registry.aliyuncs.com/daydayup/activemq
054cf0a41e5dbd08fbb268e5023f705d618f95cb679c6c665e7e8bea3b195559
root@ubuntu:~# docker run -it -d -p 61616:61616 -p 8161:8161 -v /myConfig/activemq/activemq-clusters-a.xml:/opt/apache-activemq-5.13.3/conf/activemq.xml registry.aliyuncs.com/daydayup/activemqca9534226020534e258f4ffb34c0eb0f9a97740a5ee72e390d350d2ceb0eee0d
root@ubuntu:~# docker run -it -d -p 61618:61616 -p 8181:8161 -v /myConfig/activemq/activemq-slave-a.xml:/opt/apache-activemq-5.13.3/conf/activemq.xml -v /usr/share/activemq/kahadb:/opt/apache-activemq-5.13.3/data/kahadb registry.aliyuncs.com/daydayup/activemq
327f1daba83fd56c40abac31b41f7f4435f3ee7b40e4b1719a69000248a39f0f
root@ubuntu:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
327f1daba83f registry.aliyuncs.com/daydayup/activemq "/bin/sh -c '/opt/apa" 8 seconds ago Up 4 seconds 0.0.0.0:8181->8161/tcp, 0.0.0.0:61618->61616/tcp nostalgic_ride
ca9534226020 registry.aliyuncs.com/daydayup/activemq "/bin/sh -c '/opt/apa" About a minute ago Up 58 seconds 0.0.0.0:8161->8161/tcp, 0.0.0.0:61616->61616/tcp reverent_euler
054cf0a41e5d registry.aliyuncs.com/daydayup/activemq "/bin/sh -c '/opt/apa" About a minute ago Up About a minute 0.0.0.0:8171->8161/tcp, 0.0.0.0:61617->61616/tcp tender_yalow
此时我们可以先通过查看端口来验证容器是否启动成功
root@ubuntu:/usr/share/activemq/kahadb# netstat -an | grep 61616
tcp6 0 0 :::61616 :::* LISTEN
root@ubuntu:/usr/share/activemq/kahadb# netstat -an | grep 61617
tcp6 0 0 :::61617 :::* LISTEN
root@ubuntu:/usr/share/activemq/kahadb# netstat -an | grep 61618
tcp6 0 0 :::61618 :::* LISTEN
可以看到三个端口都对外开放了,我们在使用浏览器访问管理器试试效果
可以看到slave节点已经被阻塞了,而master节点跟cluster节点都可以正常使用。
我们的集群这就搭建完成了,不过进一步的验证需要代码进行验证,还有文件系统的验证我就不一一演示了。
当我们需要更加复杂的集群都可以通过这种方式进行搭建,并在此基础上进行升级。
好了,基于docker搭建的activemq到这里就结束了,大家有什么问题可以找我交流,我也是刚接触可能有些地方误解,请及时指出,谢谢你的耐心观看。