Kafka和rocketmq应用场景选择
1、Kafka
(1)需要处理海量数据流(如日志、指标)。
(2)与大数据生态(Flink/Spark)联动。
(3)接受较高延迟,弱事务场景。
2、RocketMQ
(1)强一致性需求(如支付、金融)。
(2)需要事务消息、延迟消息、顺序消息。
(3)企业级Java应用(尤其是阿里云环境)。
3、举个直观例子
假设你是一家电商公司:
(1)用 Kafka:
实时分析用户点击流(每秒百万级日志),将数据灌入 Flink 计算实时推荐。
(要的是吞吐量,允许少量延迟或重复)
(2)用 RocketMQ:
处理订单支付后的库存扣减、短信通知,确保每笔交易可靠完成。
(要的是零丢失和事务支持)
一、RokectMQ介绍
Apache RocketMQ是一个分布式消息传递和流媒体平台,具有低延迟、高性能和可靠性、万亿级别的容量和灵活的可伸缩性。
二、RokectMQ角色
RocketMQ由四部分构成:
Producer生产者、Consumer消费者、Broker存储节点和NameServer注册中心
启动顺序:
NameServer(注册中心,用于记录消息存储位置,即Broker位置)->Broker(存储节点,用于消息存储、消息转发)
为了消除单点故障,增加可靠性或增大吞吐量,可以在多台机器上部署多个nameserver和broker,并且为每个broker部署1个或多个slave。
Topic & message queue:一个分布式消息队列中间件部署好以后,可以给很多个业务提供服务,同一个业务也有不同类型的消息要投递,这些不同类型的消息以不同的 Topic 名称来区分。所以发送和接收消息前,先创建topic,针对某个 Topic 发送和接收消息。有了 Topic 以后,还需要解决性能问题 。
如果一个Topic 要发送和接收的数据量非常大,需要能支持增加并行处理的机器来提高处理速度,这时候一个 Topic 可以根据需求设置一个或多个 Message Queue, Message Queue 类似分区或 Partition 。Topic有了多个 Message Queue 后,消息可以并行地向各个Message Queue 发送,消费者也可以并行地从多个 Message Queue 读取消息并消费 。
三、Rocket MQ环境准备
实验环境
安装好k8s集群
二十章的一到七环境
四、实验步骤
部署Metallb、Ingress Nginx
1、准备metallb、ingress Nginx清单文件(192.168.10.14)
上传metallb_ingress.tar.gz包到/root目录
tar xf metallb_ingress.tar.gz
mkdir /usr/local/nginx/html/metallb_ingress
cp /root/metallb-ingress/* /usr/local/nginx/html/metallb_ingress/
ls /usr/local/nginx/html/metallb_ingress/
2、部署metallb(master1)
(1)修改kube-proxy代理模式(master1)
编辑 Kubernetes 中 kube-proxy 的 ConfigMap
kubectl edit configmap kube-proxy -n kube-system
修改添加:
重启 Kubernetes 中 kube-proxy DaemonSet
kubectl rollout restart daemonset kube-proxy -n kube-system
(2)部署metallb
上传metallb_speaker.tar和metallb-controller.tar镜像包到/root目录并导入镜像(master1、worker1、worker2)
docker load -i metallb_speaker.tar
docker load -i metallb-controller.tar
创建资源(master1)
kubectl apply -f http://yaml.test.com:81/metallb_ingress/metallb-native.yaml
查看指定命名空间(metallb-system)中所有 Pod
kubectl get pod -n metallb-system
(3)准备IP地址池(master1)
kubectl apply -f http://yaml.test.com:81/metallb_ingress/ippool.yaml
kubectl get ipaddresspools -n metallb-system
(4)开启二层通告(master1)
kubectl apply -f http://yaml.test.com:81/metallb_ingress/l2.yaml
3、服务代理ingress nginx部署
(1)获取ingress nginx部署文件
master1:
wget http://yaml.test.com:81/metallb_ingress/deploy.yaml
master1、worker1、worker2:
上传ingress-nginx.tar包到/root目录并导入
docker load -i ingress-nginx.tar
(2)修改部署文件deploy.yaml(master1)
vim deploy.yaml
修改:
LoadBalancer
Nginx ingress controller本身也是以一个服务的方式运行在k8s群集中
改为LoadBalancer的目的是让metallb给nginx ingress分配一个群集ip
(3)部署ingress nginx(master1)
kubectl apply -f deploy.yaml
(4)查看部署状态(master1)
kubectl get pod -n ingress-nginx
五、RocketMQ集群部署
我们创建一个基于k8s部署单master以及多master部署rocketmq集群,并且只需要一个broker配置文件,多个broker实例会自动基于该broker配置文件模板,自动生成不同broker实例的broker配置文件,扩容或者伸缩rocketmq集群 nameserver或者broker副本数的时候不需要理会配置文件,仅仅是调整实例的副本即可。
1、构建RocketMQ镜像并上传到harbor(192.168.10.14)
rocketmq-namesrv和 rocketmq-broker共用同一个镜像,仅仅是启动命令和启动参数不一样,后期可灵活的通过调整启动命令和启动参数来实现不同的效果(比如通过挂载configMap的方式自定义rocketmq的配置文件,而不需要重建rocketmq的镜像)。
mkdir rocketmq
cd rocketmq/
vim Dockerfile
添加:
FROM docker.io/library/openjdk:8u102-jdk
LABEL mail=admin@test.com
RUN rm -vf /etc/localtime \
&& ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& export LANG=zh_CN.UTF-8
RUN wget -O /tmp/rocketmq-all-4.9.5-bin-release.zip \
https://mirrors.tuna.tsinghua.edu.cn/apache/rocketmq/4.9.5/rocketmq-all-4.9.5-bin-release.zip --no-check-certificate \
&& unzip /tmp/rocketmq-all-4.9.5-bin-release.zip -d /tmp/ \
&& mv /tmp/rocketmq-all-4.9.5-bin-release /opt/rocketmq \
&& rm -rf /tmp/*
RUN sed -ir '/-Xmx/c JAVA_OPT=${JAVA_OPT}' /opt/rocketmq/bin/runserver.sh \
&& sed -ir '/-Xmx/c JAVA_OPT=${JAVA_OPT}' /opt/rocketmq/bin/runbroker.sh
ENV ROCKETMQ_HOME=/opt/rocketmq
WORKDIR $ROCKETMQ_HOME
docker build -t harbor.test.com/library/rocketmq:v1 . --no-cache
参数解析:
--no-cache: 禁用缓存,强制 Docker 重新执行所有构建步骤,而不是使用缓存层
docker images
docker push harbor.test.com/library/rocketmq:v1
2、创建rocketmq-namesrv并部署描述文件
192.168.10.14:
mkdir /usr/local/nginx/html/rocketmq
cd /usr/local/nginx/html/rocketmq/
vim rocketmq-namesrv.yaml
添加:
apiVersion: v1
kind: Namespace
metadata:
name: rocketmq
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: rocketmq-namesrv
namespace: rocketmq
spec:
serviceName: rocketmq-namesrv
replicas: 2
selector:
matchLabels:
app: rocketmq-namesrv
template:
metadata:
labels:
app: rocketmq-namesrv
spec:
containers:
- name: rocketmq-namesrv-container
image: harbor.test.com/library/rocketmq:v1
imagePullPolicy: IfNotPresent
command:
- bin/mqnamesrv
env:
- name: JAVA_OPT
value: -server -Xms2g -Xmx2g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m
---
apiVersion: v1
kind: Service
metadata:
name: rocketmq-namesrv
namespace: rocketmq
labels:
app: rocketmq-namesrv
spec:
ports:
- port: 9876
protocol: TCP
targetPort: 9876
selector:
app: rocketmq-namesrv
type: ClusterIP
master1:
kubectl apply -f http://yaml.test.com:81/rocketmq/rocketmq-namesrv.yaml
kubectl -n rocketmq get all
使用 dig 工具在 Kubernetes 集群中查询 DNS 记录
kubectl get svc -n kube-system
dig -t a rocketmq-namesrv.rocketmq.svc.cluster.local. @10.96.0.10
命令解析:
-t a:指定查询类型为 A 记录,即查询域名的 IPv4 地址。
rockermq-namesrv.rocketmq.svc.cluster.local.:是要查询的域名。这是一个 Kubernetes 内部的 DNS 名称,格式为:<service-name>.<namespace>.svc.cluster.local.
3、创建rocketmq-broker并部署描述文件
192.168.10.14:
vim rocketmq-broker.yaml
添加:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: rocketmq-broker
namespace: rocketmq
spec:
serviceName: rocketmq-broker
replicas: 2
selector:
matchLabels:
app: rocketmq-broker
template:
metadata:
labels:
app: rocketmq-broker
spec:
containers:
- name: rocketmq-broker
image: harbor.test.com/library/rocketmq:v1
imagePullPolicy: IfNotPresent
command:
- bin/mqbroker
- --namesrvAddr=rocketmq-namesrv.rocketmq.svc.cluster.local.:9876
env:
- name: JAVA_OPT
value: -server -Xms512m -Xmx512m
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
terminationGracePeriodSeconds: 30
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
master1:
kubectl apply -f http://yaml.test.com:81/rocketmq/rocketmq-broker.yaml
kubectl -n rocketmq get all
4、创建rocketmq-dashboard并部署描述文件
部署一个能实现运维监控rocketmq的可视化web应用
部署rocketmq-dashboard应用时候重点关注部署文件里面的env环境变量参数JAVA_OPTS,该env环境变量(JAVA_OPTS)决定了应用是否能成功连接到 rocketmq-namesrv 服务。
192.168.10.14:
vim rocketmq-dashboard.yaml
添加:
apiVersion: apps/v1
kind: Deployment
metadata:
name: rocketmq-dashboard
namespace: rocketmq
labels:
app: rocketmq-dashboard
spec:
replicas: 1
selector:
matchLabels:
app: rocketmq-dashboard
template:
metadata:
labels:
app: rocketmq-dashboard
spec:
containers:
- name: rocketmq-dashboard
image: apacherocketmq/rocketmq-dashboard:latest
imagePullPolicy: IfNotPresent
env:
- name: JAVA_OPTS
value: -Drocketmq.namesrv.addr=rocketmq-namesrv.rocketmq.svc.cluster.local.:9876
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: rocketmq-dashboard
namespace: rocketmq
labels:
app: rocketmq-dashboard
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: rocketmq-dashboard
type: ClusterIP
worker1、worker2:
下载apacherocketmq/rocketmq-dashboard:latest或上传rocketmq-dashboard.tar镜像包到/root目录并导入
docker load -i rocketmq-dashboard.tar
master1:
kubectl apply -f http://yaml.test.com:81/rocketmq/rocketmq-dashboard.yaml
kubectl get pod -n rocketmq
5、调整副本数(master1)
调整rocket-namesrv副本数
kubectl scale sts rocketmq-namesrv --replicas=3 -n rocketmq
命令解析:
sts:表示操作的目标资源类型是 StatefulSet(StatefulSet 的缩写为 sts)
kubectl get pod -n rocketmq
调整rocket-broker副本数
kubectl scale sts rocketmq-broker --replicas=3 -n rocketmq
kubectl get pod -n rocketmq
集群节点可用内存要大于副本数中内存设置,内存不足时可使用master节点,了解即可,不用配置
查看master1调度控制(Taints污点设置,NoSchedule不被调度)
kubectl describe node master1 | grep Taints
取消污点设置:
kubectl taint node master1 node-role.kubernetes.io/control-plane-
kubectl get pod -n smart -o wide
6、创建ingress资源对象实现域名访问dashboard
192.168.10.14:
vim rocketmq-dashboard-ingress.yaml
添加:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-rocketmq-dashboard
namespace: rocketmq
spec:
ingressClassName: nginx
rules:
- host: rocketmq-dashboard.test.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: rocketmq-dashboard
port:
number: 8080
master1:
kubectl apply -f http://yaml.test.com:81/rocketmq/rocketmq-dashboard-ingress.yaml
7、项目验证
master1:
kubectl get ingress -n rocketmq
kubectl -n ingress-nginx get svc
Windows:
修改Windows主机的hosts解析文件
添加:
192.168.10.240 rocketmq-dashboard.test.com
使用浏览器访问rocketmq-dashboard.test.com
Broker TOP 10:显示了两个Broker(rocketmq-broker-1:0 和 rocketmq-broker-0:0)的总消息数(TotalMsg)。
图表中没有明显的数据变化,可能是因为数据量很小或没有变化。
主题 TOP 10:显示了两个主题(REPLY_TOPIC 和 DefaultCluster.REPLY_TOPIC)的总消息数(TotalMsg)。
同样,图表中没有明显的数据变化。
Broker 5min trend:显示了两个Broker(rocketmq-broker-1:0 和 rocketmq-broker-0:0)在最近5分钟内的消息趋势。
图表显示这两条线几乎重合,且数值在0.02左右,表明在这5分钟内,两个Broker的消息量变化不大。
主题 5min trend:显示了主题(DefaultCluster.REPLY_TOPIC)在最近5分钟内的消息趋势。
图表显示消息量为0,表明在这5分钟内,该主题没有消息产生。