K8s中间件上云部署rocketmq

Kafka和rocketmq应用场景选择:

  1. 选 Kafka:
  1. 需要处理海量数据流(如日志、指标)。
  2. 与大数据生态(Flink/Spark)联动。
  3. 接受较高延迟,弱事务场景。
  1. 选 RocketMQ:
  1. 强一致性需求(如支付、金融)。
  2. 需要事务消息、延迟消息、顺序消息
  3. 企业级Java应用(尤其是阿里云环境)。
  1. 举个直观例子

假设你是一家电商公司:

  1. 用 Kafka:

实时分析用户点击流(每秒百万级日志),将数据灌入 Flink 计算实时推荐。

(要的是吞吐量,允许少量延迟或重复)

  1. 用 RocketMQ:

处理订单支付后的库存扣减、短信通知,确保每笔交易可靠完成。

(要的是零丢失和事务支持)

  • rokectmq介绍

Apache RocketMQ是一个分布式消息传递和流媒体平台,具有低延迟、高性能和可靠性、万亿级别的容量和灵活的可伸缩性。

  • rocketmq角色

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 读取消息并消费 。

  • RocketMQ环境说明
  1. 提供持久存储动态供给功能(已部署)
  2. 容器镜像仓库(已部署
  3. Metallb(未部署)
  4. Ingress-nginx(未部署)

清单文件列表

[root@harbor ~]# ls /usr/local/nginx/html/metallb_ingress

  1. 准备metallb、ingress Nginx清单文件

注意:Metallb、ingress nginx负载均衡的yaml清单文件按前面课程准备

将提前准备好的清单文件metallb_ingress_yaml.tar.gz复制到本地

[root@harbor ~]# cd ~

[root@harbor ~]# tar xf metallb_ingress_yaml.tar.gz

[root@harbor ~]# mkdir /usr/local/nginx/html/metallb_ingress

[root@harbor ~]# cp /root/metallb_ingress/*  /usr/local/nginx/html/metallb_ingress/

[root@harbor ~]# ls /usr/local/nginx/html/metallb_ingress

  1. 部署metallb
  1. 修改kube-proxy代理模式

[root@master01 ~]# kubectl edit configmap kube-proxy -n kube-system

保存退出

[root@master01 ~]# kubectl rollout restart daemonset kube-proxy -n kube-system

  1. metallb部署

[root@master01 ~]# kubectl apply -f http://yaml.test.com:81/metallb_ingress/metallb-native.yaml

[root@master01 ~]# kubectl -n metallb-system get pod

  1. IP地址池准备

[root@master01 ~]# kubectl apply -f http://yaml.test.com:81/metallb_ingress/ippool.yaml

[root@master01 ~]# kubectl -n metallb-system get ipaddresspools

(4)开启二层通告

[root@master01 ~]# kubectl apply -f http://yaml.test.com:81/metallb_ingress/l2.yaml

  1. 服务代理ingress nginx部署
  1. 获取ingress nginx部署文件

[root@master01 ~]# wget http://yaml.test.com:81/metallb_ingress/deploy.yaml

  1. 修改部署文件deploy.yaml

[root@master01 ~]# vim deploy.yaml

修改:type: NodePort为 type: LoadBalancer

保存退出

  1. 部署ingress nginx
可提前将ingress.tar镜像备份文件复制到各节点,并导入镜像库

[root@worker01/02 ~]# docker load < ingress.tar

[root@worker01/02 ~]# systemctl restart docker

[root@master01 ~]# kubectl apply -f deploy.yaml

[root@master01 ~]# kubectl -n ingress-nginx get pod

  • rocketmq集群部署

我们创建一个基于k8s部署单master以及多master部署rocketmq集群,并且只需要一个broker配置文件,多个broker实例会自动基于该broker配置文件模板,自动生成不同broker实例的broker配置文件,扩容或者伸缩rocketmq集群 nameserver或者broker副本数的时候不需要理会配置文件,仅仅是调整实例的副本即可。

  1. 构建rocketmq镜像

rocketmq-namesrv和 rocketmq-broker共用同一个镜像,仅仅是启动命令和启动参数不一样,后期可灵活的通过调整启动命令和启动参数来实现不同的效果(比如通过挂载configMap的方式自定义rocketmq的配置文件,而不需要重建rocketmq的镜像)。

[root@harbor ~]# mkdir rocketmq

[root@harbor ~]# cd rocketmq

[root@harbor 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

保存退出

##  运行 MQ 应用时候可以通过环境变量设置 jvm 数值,如:JAVA_OPT="-server -Xms2g -Xmx2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

[root@harbor rocketmq]# docker build -t harbor.test.com/library/rocketmq:v1 . --no-cache

[root@harbor rocketmq]# docker images

注:刚启动的虚拟机,harbor可能没有开启,重新启动一下

[root@harbor rocketmq]# cd /usr/local/harbor/

[root@harbor harbor]# docker-compose restart

[root@harbor harbor]# docker ps  

# 数一下是不是9个容器,不是的话可能多次重启

[root@harbor harbor]# docker login harbor.test.com

[root@harbor ~]# docker push harbor.test.com/library/rocketmq:v1

Windows访问查看:http://192.168.10.14/

  1. rocketmq-namesrv部署描述文件

[root@harbor ~]# cd rocketmq/

[root@harbor rocketmq]# mkdir /usr/local/nginx/html/rocketmq

[root@harbor rocketmq]# cd /usr/local/nginx/html/rocketmq/

[root@master01 ~]# 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

保存退出

[root@master01 ~]# kubectl apply -f http://yaml.test.com:81/rocketmq/rocketmq-namesrv.yaml

提前导入镜像:

[root@worker01/02 ~]#  docker pull harbor.test.com/library/rocketmq:v1

[root@worker01/02 ~]# systemctl restart docker

[root@master01 ~]# kubectl -n rocketmq get all

[root@master01 ~]# dig -t a rocketmq-namesrv.rocketmq.svc.cluster.local. @10.96.0.10

  1. rocketmq-broker部署描述文件

[root@harbor rocketmq]# cd /usr/local/nginx/html/rocketmq

[root@harbor rocketmq]# 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

保存退出

[root@master01 ~]# kubectl apply -f http://yaml.test.com:81/rocketmq/rocketmq-broker.yaml

[root@master01 ~]# kubectl -n rocketmq get all    需等待较长时间

  1. rocketmq-dashboard部署描述文件

部署一个能实现运维监控rocketmq的可视化web应用。

部署rocketmq-dashboard应用时候重点关注部署文件里面的env环境变量参数JAVA_OPTS,该env环境变量(JAVA_OPTS)决定了应用是否能成功连接到 rocketmq-namesrv 服务。

[root@harbor rocketmq]# cd /usr/local/nginx/html/rocketmq/

[root@harbor rocketmq]# 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

保存退出

  1. rocketmq-dashboard部署

[root@master01 ~]# kubectl apply -f http://yaml.test.com:81/rocketmq/rocketmq-dashboard.yaml

提前在对应的节点下载镜像:

[root@worker02 ~]# docker pull apacherocketmq/rocketmq-dashboard:latest

[root@worker02 ~]# systemctl restart docker

[root@master01 ~]# kubectl get pods -n rocketmq

  1. 调整副本

调整rocket-namesrv副本数:

[root@master01 ~]# kubectl scale sts rocketmq-namesrv --replicas=3 -n rocketmq

[root@master01 ~]# kubectl get pods -n rocketmq

调整rocket-broker副本数:

[root@master01 ~]# kubectl scale sts rocketmq-broker --replicas=3 -n rocketmq

[root@master01 ~]# kubectl get pods -n rocketmq                         

集群节点可用内存要大于副本数中内存设置,内存不足时可使用master节点。

注:查看master01调度控制(Taints污点设置,NoSchedule不被调度)

[root@master01 ~]# kubectl describe node master01 | grep Taints

取消污点设置:

[root@master01 ~]# kubectl taint node master01 node-role.kubernetes.io/control-plane-

[root@master01 ~]# kubectl get pod -n smart -o wide

  1. 创建ingress资源对象实现域名访问dashboard

[root@harbor rocketmq]# vim rocketmq-dashboard-ingress.yaml

添加:

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

  name: ingress-rocketmq-dashboard                    #自定义ingress名称

  namespace: rocketmq

spec:

  ingressClassName: nginx

  rules:

  - host: rocketmq-dashboard.test.com                   # 自定义域名

    http:

      paths:

      - pathType: Prefix

        path: "/"

        backend:

          service:

            name: rocketmq-dashboard     # 对应上面创建的service名称

            port:

              number: 8080

保存退出

[root@master01 ~]# kubectl apply -f http://yaml.test.com:81/rocketmq/rocketmq-dashboard-ingress.yaml

[root@master01 ~]# kubectl get ingress -n rocketmq

[root@master01 ~]# kubectl -n ingress-nginx get svc

修改Windows主机etc/hosts文件:

添加:192.168.10.240 rocketmq-dashboard.test.com

保存退出

Windows浏览器访问: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分钟内,该主题没有消息产生。

更多推荐