4、消息中间件部署:RabbitMQ 3.x 安装与集群配置、Kafka 2.8 安装与Topic管理、Nginx 1.20 反向代理配置

消息中间件,说白了就是系统的「高速公路」。没有它,微服务之间就是鸡同鸭讲。我这些年经手的项目,十有八九都栽在消息队列的坑里。今天咱们就把 RabbitMQ、Kafka 和 Nginx 反向代理这三板斧,一次性讲透。

消息中间件部署核心逻辑 RabbitMQ 3.x 安装 + 集群 + 镜像队列 Kafka 2.8 安装 + Topic + 分区管理 Nginx 1.20 反向代理 + 负载均衡 统一目标:高可用、高吞吐、低延迟 运维要点:监控 + 日志 + 容灾

4.1 RabbitMQ 3.x 安装与集群配置

RabbitMQ 这东西,我最早接触是在 2016 年。当时公司要做异步订单处理,选型时在 ActiveMQ 和 RabbitMQ 之间纠结了好久。后来发现 RabbitMQ 的 Erlang 生态虽然有点怪,但稳定性确实没得说。

4.1.1 单机安装

先装 Erlang,再装 RabbitMQ。顺序别搞反了,不然你会看到一堆莫名其妙的依赖错误。

# 安装 Erlang(CentOS 7 示例)
rpm -Uvh https://packages.erlang-solutions.com/erlang/rpm/centos/7/x86_64/esl-erlang-23.3.4.11-1.x86_64.rpm

# 安装 RabbitMQ
rpm --import https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
yum install rabbitmq-server-3.9.13-1.el7.noarch.rpm -y

# 启动并设置开机自启
systemctl start rabbitmq-server
systemctl enable rabbitmq-server
我的习惯:装完后第一件事就是启用管理插件。没有 Web 界面,排查问题全靠猜,太痛苦了。
rabbitmq-plugins enable rabbitmq_management

默认端口 15672,用 guest/guest 登录。不过要注意——远程访问必须新建用户,guest 只能在 localhost 用。这个坑我踩过,当时在测试环境配了半天连不上,最后发现是安全限制。

4.1.2 集群配置

集群部署,说白了就是让多台机器共享同一个「虚拟主机」和「队列」信息。我建议至少 3 台,形成镜像队列模式。

注意:集群节点之间必须能互相解析主机名。我习惯在 /etc/hosts 里写死,省得 DNS 出幺蛾子。
# 假设三台机器:node1、node2、node3
# 在每台机器上执行
echo "192.168.1.10 node1" >> /etc/hosts
echo "192.168.1.11 node2" >> /etc/hosts
echo "192.168.1.12 node3" >> /etc/hosts

# 停止所有节点
rabbitmqctl stop_app

# 在 node2 和 node3 上加入集群
rabbitmqctl join_cluster rabbit@node1

# 启动所有节点
rabbitmqctl start_app

# 查看集群状态
rabbitmqctl cluster_status

集群建好后,记得配镜像队列。不然队列只存在一个节点上,节点挂了数据就丢了。

# 设置镜像策略,匹配所有队列,自动同步到所有节点
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
避坑指南:我曾经在生产环境忘记配镜像策略,结果一个节点宕机,所有消息全部丢失。从那以后,我每次建集群第一件事就是配策略。

4.2 Kafka 2.8 安装与 Topic 管理

Kafka 和 RabbitMQ 不一样。RabbitMQ 是「邮递员」,把信送到你手上;Kafka 是「公告板」,消息写上去,谁想看谁来看。吞吐量不是一个量级。

4.2.1 安装 Kafka 2.8

Kafka 依赖 Zookeeper,不过 2.8 版本已经支持 KRaft 模式了。但我个人建议,生产环境还是用 Zookeeper 稳一点。新特性嘛,等社区再磨一磨。

# 下载解压
wget https://archive.apache.org/dist/kafka/2.8.0/kafka_2.13-2.8.0.tgz
tar -xzf kafka_2.13-2.8.0.tgz
cd kafka_2.13-2.8.0

# 启动 Zookeeper(单机测试)
bin/zookeeper-server-start.sh config/zookeeper.properties &

# 启动 Kafka
bin/kafka-server-start.sh config/server.properties &

配置文件里,有几个参数我每次都会改:

参数 默认值 我建议的值 说明
log.dirs /tmp/kafka-logs /data/kafka/logs 别放 /tmp,重启就没了
num.partitions 1 3 分区数太少,并发上不去
default.replication.factor 1 2 至少 2 副本,防止丢数据

4.2.2 Topic 管理

Topic 是 Kafka 的核心概念。我见过不少新手,Topic 建得乱七八糟,最后消费端都不知道该读哪个分区。

# 创建 Topic
bin/kafka-topics.sh --create \
  --bootstrap-server localhost:9092 \
  --replication-factor 2 \
  --partitions 3 \
  --topic order-events

# 查看所有 Topic
bin/kafka-topics.sh --list --bootstrap-server localhost:9092

# 查看 Topic 详情
bin/kafka-topics.sh --describe \
  --bootstrap-server localhost:9092 \
  --topic order-events
我的经验:Topic 命名要有规范。比如「业务-环境-事件类型」,order-prod-created、payment-test-refund。不然半年后你自己都看不懂。

生产消息和消费消息,我习惯用控制台先测一把:

# 生产者
bin/kafka-console-producer.sh \
  --bootstrap-server localhost:9092 \
  --topic order-events

# 消费者(从最早开始读)
bin/kafka-console-consumer.sh \
  --bootstrap-server localhost:9092 \
  --topic order-events \
  --from-beginning

为什么会建议先测一把?因为配置错了,比如 broker 地址写错、Topic 不存在,这时候就能发现,而不是等到上线后日志刷屏。

4.3 Nginx 1.20 反向代理配置

Nginx 反向代理,说白了就是「前台接待」。客户端找它,它帮你转到后面的真实服务。我习惯用 Nginx 统一管理所有中间件的入口,方便做限流和日志。

4.3.1 安装 Nginx 1.20

# CentOS 7 安装
yum install epel-release -y
yum install nginx-1.20.1 -y

# 启动
systemctl start nginx
systemctl enable nginx

4.3.2 反向代理配置

假设我们要把 RabbitMQ 的管理界面和 Kafka 的 REST 代理都通过 Nginx 暴露出去。

# /etc/nginx/conf.d/message-proxy.conf

upstream rabbitmq_cluster {
    server 192.168.1.10:15672 weight=3;
    server 192.168.1.11:15672 weight=2;
    server 192.168.1.12:15672 weight=1;
}

upstream kafka_rest {
    server 192.168.1.10:8082;
    server 192.168.1.11:8082;
}

server {
    listen 80;
    server_name msg.internal.company.com;

    # RabbitMQ 管理界面
    location /rabbitmq/ {
        proxy_pass http://rabbitmq_cluster/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # Kafka REST 代理
    location /kafka/ {
        proxy_pass http://kafka_rest/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 限流配置,防止突发流量打垮后端
    limit_req_zone $binary_remote_addr zone=msg_limit:10m rate=10r/s;
    location /api/ {
        limit_req zone=msg_limit burst=20 nodelay;
        proxy_pass http://kafka_rest;
    }
}
注意:proxy_pass 后面的 URL 末尾有没有斜杠,行为完全不同。有斜杠会去掉匹配的 location 前缀,没有斜杠则原样转发。这个细节我调试过整整一个下午。

4.3.3 负载均衡策略

Nginx 默认是轮询。但我建议根据实际情况调整:

策略 配置方式 适用场景
轮询 默认 各节点性能一致
权重 weight=3 节点性能差异大
IP Hash ip_hash 需要会话保持
最少连接 least_conn 请求处理时间不均
避坑指南:我曾经在生产环境用轮询,结果一台老机器被活活压垮。后来改成权重策略,新机器 weight=5,老机器 weight=1,问题解决。你想想看,运维有时候就是这点小细节。

配置完记得检查语法:

nginx -t
systemctl reload nginx

嗯,到这里消息中间件的部署就讲完了。RabbitMQ 重可靠性,Kafka 重吞吐量,Nginx 做统一入口。这三者配合好了,你的在线学习投资系统才能扛得住高并发。