Docker 安装
创建自定义镜像
构建本地镜像
mkdir /tmp/aaa
cd /tmp/aaa
touch Dockerfile # 文件内容见后面
docker build -t btpka3/my-mq:1.0 .
docker images
Dockerfile 文件内容
FROM rabbitmq
RUN rabbitmq-plugins enable --offline rabbitmq_management
EXPOSE 15671 15672
RUN rabbitmq-plugins enable --offline rabbitmq_mqtt
EXPOSE 1883 8883
RUN echo =====RABBITMQ_VERSION: ${RABBITMQ_VERSION}
ADD https://dl.bintray.com/rabbitmq/community-plugins/rabbitmq_web_mqtt-3.6.x-14dae543.ez \
/usr/lib/rabbitmq/lib/rabbitmq_server-$RABBITMQ_VERSION/plugins/
RUN chmod go+r /usr/lib/rabbitmq/lib/rabbitmq_server-$RABBITMQ_VERSION/plugins/rabbitmq_web_mqtt-3.6.x-14dae543.ez
EXPOSE 15675
RUN rabbitmq-plugins enable --offline rabbitmq_web_mqtt
/var/lib/rabbitmq
mkdir -p ~/tmp/mq/conf/
mkdir -p ~/tmp/mq/data/
echo '[ { rabbit, [ { loopback_users, [ ] } ] } ].' > ~/tmp/mq/conf/rabbitmq.config
touch ~/tmp/mq/conf/rabbitmq-env.conf
docker run -d \
--name mq \
-p 4369:4369 \
-p 5671:5671 \
-p 5672:5672 \
-p 25672:25672 \
-p 15671:15671 \
-p 15672:15672 \
-p 1883:1883 \
-p 8883:8883 \
-p 15675:15675 \
-v /Users/zll/tmp/mq/data/:/var/lib/rabbitmq/:rw \
-v /Users/zll/tmp/mq/conf/rabbitmq.config:/etc/rabbitmq/rabbitmq.config \
-v /Users/zll/tmp/mq/conf/rabbitmq-env.conf:/etc/rabbitmq/rabbitmq-env.conf \
btpka3/my-mq:1.0
docker exec -it mq bash
# 启用 MQTT 插件
rabbitmq-plugins enable rabbitmq_mqtt
# 显示默认配置
cat /etc/rabbitmq/rabbitmq.config
cat /etc/rabbitmq/enabled_plugins
# 通过浏览器访问
# http://localhost:15672
# nginx
docker run \
--name my-nginx \
-d \
--link mq:mq \
-p 80:80 \
-p 443:443 \
-v ~/tmp/my-nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
-v ~/tmp/my-nginx/conf/conf.d:/etc/nginx/conf.d:ro \
nginx:1.11.8
TLS
[
{ssl, [
{versions, ['tlsv1.2', 'tlsv1.1']}
]},
{rabbit, [
{loopback_users, []},
{ssl_listeners, [5671]},
{ssl_options, [
{cacertfile, "/var/lib/rabbitmq/myca.pem.cer"},
{certfile, "/var/lib/rabbitmq/server.pem.cer"},
{keyfile, "/var/lib/rabbitmq/server.pem.key"},
{versions, ['tlsv1.2', 'tlsv1.1']},
{verify, verify_peer},
{fail_if_no_peer_cert, false}
]}
]},
{rabbitmq_mqtt, [
{default_user, "guest"},
{default_pass, "guest"},
{allow_anonymous, false},
{vhost, "/"},
{exchange, "amq.topic"},
{subscription_ttl, 1800000},
{prefetch, 10},
{ssl_listeners, [8883]},
{tcp_listeners, [1883]},
{tcp_listen_options, [
{backlog, 128},
{nodelay, true}
]}
]}
].
RabbitMQ常用命令
# 启停命令等
[me@localhost:~] sudo service rabbitmq-server xxx
# 重置(即清除所有queue,binding,message等)
[me@localhost:~] sudo rabbitmqctl stop_app
[me@localhost:~] sudo rabbitmqctl force_reset
[me@localhost:~] sudo rabbitmqctl start_app
# 列出给定的 queues
sudo rabbitmqctl list_queues
安装Erlang
RabbitMQ是使用Erlang开发,因此需要先安装Erlang。具体要使用哪个版本。则需要看一下这里了。最低需要 R13B03。
PRM 安装请参考这里。提示:请确 CentOS 上已经安装了 EPEL.
虽然测试环境的都是 CentOs 6.x系列,而生产环境则还有 CentOs 5.x 系列。 通过这里可以得知,CentOS 5.x下的EPEL只支持到 R12B-5,版本太低了。 如果要使用RabbitMq集群,则使用的RabbitMQ、Erlang需要一致。因此,为了方便起见,Erlang还是使用源码编译安装。
从这里下载 otp_src_17.1.tar.gz。解压后需要先阅读一下 README.md
和 HOWTO/INSTALL.md
# 依赖检查
yum install unixODBC unixODBC-dev openssl openssl-devel
make -v # 确保有GNU Make
gcc --version # 确保有GNU gcc
perl -v # 确保 perl 的版本 >= 5
m4 --version # 确保有GNU M4
rpm -q ncurses-devel # 确保 ncurses-devel 已经安装。若未安装可以使用 yum install ncurses-devel 安装。
sed --version # 确保已经安装了 sed
rpm -q openssl # (可选)检查openssl已经安装,如有必要,升级一下版本
java -version # (可选)检查已经安装了Oracle JDK
rpm -q flex # (可选)
# skip X Windows、wxWidgets check
# 解压
tar zxvf otp_src_17.1.tar.gz
cd otp_src_17.1
export ERL_TOP=`pwd`
export LANG=C
# 配置
# 默认是安装到 `/usr/local/{bin,lib/erlang}` 下的, 这里我们可以不指定PREFIX。
./configure --enable-threads --enable-smp-support --enable-kernel-poll --enable-hipe
# 编译
make
# (可选)测试。 FIXME: 在测试环境上是有几个testcase没通过的,暂不知会造成何种影响
make release_tests
cd release/tests/test_server
$ERL_TOP/bin/erl -s ts install -s ts smoke_test batch -s init stop
# 运行完testcase之后,可以scp -r [email protected]:$ERL_TOP/release/tests/test_server /tmp/1 ,在本地浏览器查看结果
# 安装
cd $ERL_TOP
make install
# 简单测试
erl
A=12.
A.
压缩包安装RabbitMq
参考这里,安装 Installing on Generic Unix, 基本上解压后就可以直接运行了。
tar zxvf rabbitmq-server-generic-unix-3.3.5.tar.gz -C /usr/local/
# 修改配置 rabbitmq.config
cd /usr/local/rabbitmq_server-3.3.5
vi ./etc/rabbitmq/rabbitmq.config # 可以使guest账户远程主机登录
[{rabbit, [{loopback_users, []}]}].
useradd rabbitmq
chown -R rabbitmq:rabbitmq /usr/local/rabbitmq_server-3.3.5
vi /etc/profile.d/lizi.sh
export RABBITMQ_HOME=/usr/local/rabbitmq_server-3.3.5
export PATH=$RABBITMQ_HOME/sbin:$PATH
yum/rpm 安装
使用yum/rpm 安装,请参考这里。
systemctl is-enabled rabbitmq-server
systemctl status rabbitmq-server
systemctl restart rabbitmq-server
创建集群
参考官方文档clustering 和HA。非官方总结可以参考这里。 下面以服务器 s83 和 s85 创建集群为例,进行步骤介绍
# 分别在 s83、s85 修改hosts
vi /etc/hosts
192.168.101.83 s83
192.168.101.85 s85
# 先启动 s83
[root@s83 ~]# su - rabbitmq
[rabbitmq@s83 ~]$ rabbitmq-server -detached # 以 rabbitmq 用户启动
[rabbitmq@s83 ~]$ scp /home/rabbitmq/.erlang.cookie rabbitmq@s85:/home/rabbitmq/ # 使集群用的cookie相同
# 再启动 s85
[root@s85 ~]# su - rabbitmq
[rabbitmq@s85 ~]$ rabbitmq-server -detached
[rabbitmq@s85 ~]$ rabbitmqctl stop_app
[rabbitmq@s85 ~]$ rabbitmqctl join_cluster rabbit@s83 # 加入、创建集群
[rabbitmq@s85 ~]$ rabbitmqctl start_app
rabbitmqctl cluster_status # 分别确认集群状态
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' # 设置HA模式:所有消息都会两个节点上copy
rabbitmqctl set_policy TTL ".*" '{"message-ttl":60000}' # 设置消息过期时间:60秒
# (可选)安装一些插件
rabbitmq-plugins enable rabbitmq_management
rabbitmq-plugins enable rabbitmq_federation
rabbitmq-plugins enable rabbitmq_federation_management
# 之后重启RabbitMQ,并访问 http://xxxx:15672
# 用户管理
rabbitmq默认的用户和密码均为:guest
rabbitmqctl delete_user guest # 删除guest用户
rabbitmqctl add_user lizi lizi_mq # 添加用户,用户名:lizi;密码:lizi_mq
rabbitmqctl set_user_tags lizi administrator # 为lizi用户设置administrator权限,可选的
# 权限有:administrator,monitoring, management
rabbimqctl change_password lizi {newpassword} # 为lizi用户修改密码
修改 /etc/hosts
192.168.101.83 s83
192.168.101.85 s85
集群配置参考
开启相关插件. Management、 federation
设置所有资源都使用HA模式
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
启停命令
# 1. 先到所有集群节点的电脑上执行以下命令
su - rabbitmq
rabbitmq-server -detached
# 2. 在到任一集群节点上确认
su - rabbitmq
rabbitmqctl cluster_status
XXX:不要使用以下init.d脚本。/etc/init.d/rabbitmq-server
以下示例文件是从rpm包中提取的。
#!/bin/sh
#
# rabbitmq-server RabbitMQ broker
#
# chkconfig: - 80 05
# description: Enable AMQP service provided by RabbitMQ
#
### BEGIN INIT INFO
# Provides: rabbitmq-server
# Required-Start: $remote_fs $network
# Required-Stop: $remote_fs $network
# Description: RabbitMQ broker
# Short-Description: Enable AMQP service provided by RabbitMQ broker
### END INIT INFO
# Source function library.
. /etc/init.d/functions
. /etc/profile.d/lizi.sh
#PATH=/sbin:/usr/sbin:/bin:/usr/bin
export HOME=/home/rabbitmq
NAME=rabbitmq-server
DAEMON=${RABBITMQ_HOME}/sbin/${NAME}
CONTROL=${RABBITMQ_HOME}/sbin/rabbitmqctl
DESC=rabbitmq-server
USER=rabbitmq
ROTATE_SUFFIX=
INIT_LOG_DIR=/var/log/rabbitmq
PID_FILE=/var/run/rabbitmq/pid
START_PROG="daemon"
LOCK_FILE=/var/lock/subsys/$NAME
test -x $DAEMON || exit 0
test -x $CONTROL || exit 0
RETVAL=0
set -e
[ -f /etc/default/${NAME} ] && . /etc/default/${NAME}
ensure_pid_dir () {
PID_DIR=`dirname ${PID_FILE}`
if [ ! -d ${PID_DIR} ] ; then
mkdir -p ${PID_DIR}
chown -R ${USER}:${USER} ${PID_DIR}
chmod 755 ${PID_DIR}
fi
}
remove_pid () {
rm -f ${PID_FILE}
rmdir `dirname ${PID_FILE}` || :
}
start_rabbitmq () {
status_rabbitmq quiet
if [ $RETVAL = 0 ] ; then
echo RabbitMQ is currently running
else
RETVAL=0
ensure_pid_dir
set +e
RABBITMQ_PID_FILE=$PID_FILE $START_PROG $DAEMON \
> "${INIT_LOG_DIR}/startup_log" \
2> "${INIT_LOG_DIR}/startup_err" \
0<&- &
$CONTROL wait $PID_FILE >/dev/null 2>&1
RETVAL=$?
set -e
case "$RETVAL" in
0)
echo SUCCESS
if [ -n "$LOCK_FILE" ] ; then
touch $LOCK_FILE
fi
;;
*)
remove_pid
echo FAILED - check ${INIT_LOG_DIR}/startup_\{log, _err\}
RETVAL=1
;;
esac
fi
}
stop_rabbitmq () {
status_rabbitmq quiet
if [ $RETVAL = 0 ] ; then
set +e
$CONTROL stop ${PID_FILE} > ${INIT_LOG_DIR}/shutdown_log 2> ${INIT_LOG_DIR}/shutdown_err
RETVAL=$?
set -e
if [ $RETVAL = 0 ] ; then
remove_pid
if [ -n "$LOCK_FILE" ] ; then
rm -f $LOCK_FILE
fi
else
echo FAILED - check ${INIT_LOG_DIR}/shutdown_log, _err
fi
else
echo RabbitMQ is not running
RETVAL=0
fi
}
status_rabbitmq() {
set +e
if [ "$1" != "quiet" ] ; then
$CONTROL status 2>&1
else
$CONTROL status > /dev/null 2>&1
fi
if [ $? != 0 ] ; then
RETVAL=3
fi
set -e
}
rotate_logs_rabbitmq() {
set +e
$CONTROL rotate_logs ${ROTATE_SUFFIX}
if [ $? != 0 ] ; then
RETVAL=1
fi
set -e
}
restart_running_rabbitmq () {
status_rabbitmq quiet
if [ $RETVAL = 0 ] ; then
restart_rabbitmq
else
echo RabbitMQ is not runnning
RETVAL=0
fi
}
restart_rabbitmq() {
stop_rabbitmq
start_rabbitmq
}
case "$1" in
start)
echo -n "Starting $DESC: "
start_rabbitmq
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
stop_rabbitmq
echo "$NAME."
;;
status)
status_rabbitmq
;;
rotate-logs)
echo -n "Rotating log files for $DESC: "
rotate_logs_rabbitmq
;;
force-reload|reload|restart)
echo -n "Restarting $DESC: "
restart_rabbitmq
echo "$NAME."
;;
try-restart)
echo -n "Restarting $DESC: "
restart_running_rabbitmq
echo "$NAME."
;;
*)
echo "Usage: $0 {start|stop|status|rotate-logs|restart|condrestart|try-restart|reload|force-reload}" >&2
RETVAL=1
;;
esac
exit $RETVAL
Nginx 反向代理
修改 nginx.conf
# 最后追加以下配置
stream {
include /etc/nginx/conf.d/*.conf.stream;
}
创建 /etc/nginx/conf.d/mq.conf.stream
upstream mqtt_1883 {
server mq:1883;
}
upstream mqtts_8883 {
server mq:8883;
}
# 完全 tcp 转发
server {
listen 11883;
proxy_connect_timeout 20s;
proxy_timeout 5m;
proxy_pass mqtt_1883;
}
server {
listen 18883;
proxy_connect_timeout 20s;
proxy_timeout 5m;
proxy_pass mqtts_8883;
}
# 代为TSL
server {
listen 19883 ssl;
ssl_certificate conf.d/mq/server.pem.cer;
ssl_certificate_key conf.d/mq/server.pem.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
#ssl_ciphers HIGH:!aNULL:!MD5;
#ssl_prefer_server_ciphers on;
proxy_connect_timeout 20s;
proxy_timeout 5m;
proxy_pass mqtt_1883;
}