4.24. 为高可用性配置领导优先部署


leader-follower 配置都有单独的部署,每个部署都有一个代理实例。每个部署中的代理必须配置为将消息持久化到同一目标,可以是 JDBC 数据库或共享卷上的日志。

与为数据库或共享卷获取锁定的代理可实现高可用性。获取锁定的代理会成为为客户端请求服务的领导代理。无法获取锁定的代理会变为 follower。后续是一个被动代理,持续尝试获取数据库或共享卷的锁定。如果后续者获取锁定,它会立即成为领导,并开始为客户端提供服务。

领导(leader-follower 部署)为节点故障提供一个更快的修复时间(MTTR),而不是 OpenShift 为单个部署提供的节点故障。在 leader-follower 部署中,代理可以在单独的集群中,以防止集群故障。这些集群可以位于不同的数据中心中,以便代理服务对数据中心中断具有弹性,只要用于在数据中心之间持久保留消息的存储可用。

您可以配置 leader-follower 代理部署,将消息保留到共享 JDBC 数据库。

前提条件

您有一个容器镜像,其中包含您要用于 AMQ Broker 的 JDBC 数据库的 JAR 文件。有关创建容器镜像的详情,请参考 OpenShift 文档中的创建镜像。https://docs.openshift.com/container-platform/latest/openshift_images/create-images.html在每个代理的配置中,您可以指定 init 容器,将容器镜像中的 JAR 文件复制到运行时可用于代理的位置。

流程

  1. 配置两个 ActiveMQArtemis 自定义资源实例,以创建单独的代理部署。

    在每个自定义资源中,指定一个唯一名称,并确保 clusterpersistenceEnabled 属性设置为 false。将 size 属性设置为 1,以便在每个部署中创建一个代理。例如:

    apiVersion: broker.amq.io/v1beta1
    kind: ActiveMQArtemis
    metadata:
      name: peer-broker-a
    spec:
      deploymentPlan:
        size: 1
        clustered: false
        persistenceEnabled: false
    Copy to Clipboard Toggle word wrap
    apiVersion: broker.amq.io/v1beta1
    kind: ActiveMQArtemis
    metadata:
      name: peer-broker-b
    spec:
      deploymentPlan:
        size: 1
        clustered: false
        persistenceEnabled: false
    Copy to Clipboard Toggle word wrap
    注意

    如果两个代理部署在同一 OpenShift 集群中,请确保在单独的节点上置备代理 pod,以避免在节点出现故障时同时出现这两个代理中断。有关控制节点上 pod 放置的更多信息,请参阅 第 4.17 节 “控制 OpenShift Container Platform 节点上的代理 pod 放置”

  2. 为每个 CR 添加新的存活度探测。

    如果没有配置存活度探测,则会启用默认探测来检查代理的健康状况。默认探测检查 AMQ 管理控制台是否可访问。在 leader-follower 配置中,AMQ Management Console 在任何给定时间无法在代理中访问,这会导致存活度探测在该代理上失败。每次存活度探测失败时,它会重启代理,该代理会将代理置于持久重启循环中。因此,后续代理进入 CrashLoopBackOff 状态,如果当前领导失败则不可用。

    要防止默认存活度探测运行,您必须配置一个新的存活度探测,该探测可以在代理是领导或后续时成功运行。以下是满足此要求的存活度探测示例。在本例中,存活度探测会检查运行代理的命令是否已执行,这通过存在 cli.lock 锁定文件来表示。

    spec:
      ..
      livenessProbe:
        exec:
          command:
          - test
          - -f
          - /home/jboss/amq-broker/lock/cli.lock
      ..
    Copy to Clipboard Toggle word wrap

    有关配置存活度探测的更多信息,请参阅 第 4.15.2 节 “配置存活度和就绪度探测”

  3. 在每个代理配置中,使用 brokerProperties 属性启用 JDBC 数据库持久性。例如:

    spec:
      ..
      brokerProperties:
      - storeConfiguration=DATABASE
      - storeConfiguration.jdbcDriverClassName=<class name>
      - storeConfiguration.jdbcConnectionUrl=jdbc:<Database URL>
      - HAPolicyConfiguration=SHARED_STORE_PRIMARY
      - storeConfiguration.jdbcLockRenewPeriodMillis=2000
      - storeConfiguration.jdbcLockExpirationMillis=6000
    Copy to Clipboard Toggle word wrap

    有关启用 JDBC 数据库持久性的更多信息,请参阅 第 4.5.2 节 “配置数据库持久性”

  4. 在每个代理配置中,配置代理以加载连接到 JDBC 数据库所需的 JAR 文件。

    • 使用 resourceTemplates 属性自定义每个代理的 StatefulSet 资源。在自定义中,使用 patch 属性指定一个 init 容器,该容器将 JAR 文件从您准备的自定义容器镜像复制到代理 Pod。
    • 使用 env 属性创建 ARTEMIS_EXTRA_LIBS 环境变量,以扩展代理的 Java 类路径,使其包含将 JDBC 数据库复制到的目录。通过扩展 Java 类路径,代理可以在运行时从 pod 上的指定目录中加载 JAR 文件。

      spec:
        ..
        env:
        - name: ARTEMIS_EXTRA_LIBS
          value: '/amq/init/config/extra-libs'
        resourceTemplates:
        - selector:
            kind: StatefulSet
          patch:
            kind: StatefulSet
            spec:
              template:
                spec:
                  initContainers:
                  - name: jdbc-driver-init
                    image: <custom container image with JAR>
                    volumeMounts:
                    - name: amq-cfg-dir
                      mountPath: /amq/init/config
                    command:
                    - "bash"
                    - "-c"
                    - "mkdir -p /amq/init/config/extra-libs && cp <__JAR file_> /amq/init/config/extra-libs"
      Copy to Clipboard Toggle word wrap

      有关自定义 Operator 创建的 OpenShift 资源的更多信息,请参阅 第 4.21 节 “自定义 Operator 创建的 Openshift 资源”

  5. 保存每个自定义资源。

    Example

    以下示例显示了使用 Oracle 数据库的 leader-follower 代理部署的配置。

    apiVersion: broker.amq.io/v1beta1
    kind: ActiveMQArtemis
    metadata:
      name: peer-broker-a
    spec:
      deploymentPlan:
        size: 1
        clustered: false
        persistenceEnabled: false
        livenessProbe:
          exec:
            command:
            - test
            - -f
            - /home/jboss/amq-broker/lock/cli.lock
      env:
        - name: ARTEMIS_EXTRA_LIBS
          value: '/amq/init/config/extra-libs'
      brokerProperties:
        - criticalAnalyser=false
        - storeConfiguration=DATABASE
        - storeConfiguration.jdbcDriverClassName=oracle.jdbc.OracleDriver
        - storeConfiguration.jdbcConnectionUrl=jdbc:<Database URL>
        - storeConfiguration.jdbcLockRenewPeriodMillis=2000
        - storeConfiguration.jdbcLockExpirationMillis=6000
        - HAPolicyConfiguration=SHARED_STORE_PRIMARY
      acceptors:
      - name: ext-acceptor
        protocols: CORE
        port: 61626
        expose: true
        sslEnabled: true
        sslSecret: ext-acceptor-ssl-secret
      console:
        expose: true
      resourceTemplates:
      - selector:
          kind: StatefulSet
        patch:
          kind: StatefulSet
          spec:
            template:
              spec:
                initContainers:
                - name: oracle-database-jdbc-driver-init
                  image: <custom container image with JAR>
                  volumeMounts:
                  - name: amq-cfg-dir
                    mountPath: /amq/init/config
                  command:
                  - "bash"
                  - "-c"
                  - "mkdir -p /amq/init/config/extra-libs && cp <JAR file> /amq/init/config/extra-libs"
    Copy to Clipboard Toggle word wrap
    apiVersion: broker.amq.io/v1beta1
    kind: ActiveMQArtemis
    metadata:
      name: peer-broker-b
    spec:
      deploymentPlan:
        size: 1
        clustered: false
        persistenceEnabled: false
        livenessProbe:
          exec:
            command:
            - test
            - -f
            - /home/jboss/amq-broker/lock/cli.lock
      env:
        - name: ARTEMIS_EXTRA_LIBS
          value: '/amq/init/config/extra-libs'
      brokerProperties:
        - criticalAnalyser=false
        - storeConfiguration=DATABASE
        - storeConfiguration.jdbcDriverClassName=oracle.jdbc.OracleDriver
        - storeConfiguration.jdbcConnectionUrl=jdbc:<Database URL>
        - storeConfiguration.jdbcLockRenewPeriodMillis=2000
        - storeConfiguration.jdbcLockExpirationMillis=6000
        - HAPolicyConfiguration=SHARED_STORE_PRIMARY
      acceptors:
      - name: ext-acceptor
        protocols: CORE
        port: 61626
        expose: true
        sslEnabled: true
        sslSecret: ext-acceptor-ssl-secret
      console:
        expose: true
      resourceTemplates:
      - selector:
          kind: StatefulSet
        patch:
          kind: StatefulSet
          spec:
            template:
              spec:
                initContainers:
                - name: oracle-database-jdbc-driver-init
                  image: <custom container image with JAR>
                  volumeMounts:
                  - name: amq-cfg-dir
                    mountPath: /amq/init/config
                  command:
                  - "bash"
                  - "-c"
                  - "mkdir -p /amq/init/config/extra-libs && cp <JAR file> /amq/init/config/extra-libs"
    Copy to Clipboard Toggle word wrap

您可以配置 leader-follower 代理部署,将消息保留在两个代理实例共享的卷中。

前提条件

您创建了持久性卷声明(PVC)来请求共享卷来存储两个代理的消息数据。仔细考虑,确保您请求的容量足以将消息传递数据存储在共享卷中。在以下 PVC 示例中,请求 2GB 存储容量。

oc apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared-volume
  namespace: activemq
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 2Gi
EOF
Copy to Clipboard Toggle word wrap
注意

创建 PVC 后,oc get pvc 命令的输出会显示共享卷具有 待处理状态,直到代理部署并绑定到卷。例如:

NAME            STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
shared-volume   Pending                                      gp3-csi        <unset>                 7s
Copy to Clipboard Toggle word wrap

流程

  1. 准备并应用 YAML 配置来创建 leader-follower 代理部署。例如:

    oc apply -f - <<EOF
    apiVersion: broker.amq.io/v1beta1
    kind: ActiveMQArtemis
    metadata:
      name: peer-broker-a
    spec:
      deploymentPlan:
        size: 1
        persistenceEnabled: false
        clustered: false
        extraVolumes:
        - name: extra-volume
          persistentVolumeClaim:
            claimName: shared-volume
        extraVolumeMounts:
        - name: extra-volume
          mountPath: /opt/amq-broker/data
        livenessProbe:
          exec:
            command:
            - test
            - -f
            - /home/jboss/amq-broker/lock/cli.lock
      brokerProperties:
      - HAPolicyConfiguration=SHARED_STORE_PRIMARY
      - journalDirectory=/opt/amq-broker/data/journal
      - pagingDirectory=/opt/amq-broker/data/paging,
      - bindingsDirectory=/opt/amq-broker/data/bindings
      - largeMessagesDirectory=/opt/amq-broker/data/largemessages
      acceptors:
      - name: ext-acceptor
        protocols: CORE
        port: 61626
        expose: true
        sslEnabled: true
        sslSecret: ext-acceptor-ssl-secret
    ---
    apiVersion: broker.amq.io/v1beta1
    kind: ActiveMQArtemis
    metadata:
      name: peer-broker-b
    spec:
      deploymentPlan:
        size: 1
        persistenceEnabled: false
        clustered: false
        extraVolumes:
        - name: extra-volume
          persistentVolumeClaim:
            claimName: shared-volume
        extraVolumeMounts:
        - name: extra-volume
          mountPath: /opt/amq-broker/data
        livenessProbe:
          exec:
            command:
            - test
            - -f
            - /home/jboss/amq-broker/lock/cli.lock
      brokerProperties:
      - HAPolicyConfiguration=SHARED_STORE_PRIMARY
      - journalDirectory=/opt/amq-broker/data/journal
      - pagingDirectory=/opt/amq-broker/data/paging,
      - bindingsDirectory=/opt/amq-broker/data/bindings
      - largeMessagesDirectory=/opt/amq-broker/data/largemessages
      acceptors:
      - name: ext-acceptor
        protocols: CORE
        port: 61626
        expose: true
        sslEnabled: true
        sslSecret: ext-acceptor-ssl-secret
    EOF
    Copy to Clipboard Toggle word wrap
    注意

    如果两个代理部署在同一 OpenShift 集群中,请确保在单独的节点上置备代理 pod,以避免在节点出现故障时同时出现这两个代理中断。有关控制节点上 pod 放置的更多信息,请参阅 第 4.17 节 “控制 OpenShift Container Platform 节点上的代理 pod 放置”

    下表描述了示例中特定于 leader-follower 部署的 YAML 配置。

    Expand
    表 4.8. Leader-follower 配置
    属性描述

    metadata.name

    在每个部署中为代理指定一个唯一名称。

    size

    指定一个 1 值在每次部署中创建一个代理。

    persistenceEnabled

    设置为 false,以使用临时 pod 存储来存储代理应用程序文件、配置文件、日志等。

    clustered

    设置为 false 以禁用集群。

    extraVolumes

    指定您创建的 PVC 详情,用于为代理请求额外的共享卷,这是创建 leader-follower 部署的先决条件。

    name
    使用字符串值为卷分配名称。
    claimName
    确保这与您创建的 PVC 中的 metadata.name 属性的值匹配。

    extraVolumeMounts

    指定在每个代理 pod 中挂载额外共享卷的详情。

    name
    确保这与 extraVolumes.name 值匹配。
    mountPath
    卷挂载到每个代理 pod 上的路径。

    livenessProbe

    启用默认存活度探测来检查代理的健康状况。默认探测检查 AMQ 管理控制台是否可访问。在 leader-follower 配置中,AMQ Management Console 在任何给定时间无法在代理中访问,这会导致存活度探测在该代理上失败。每次存活度探测失败时,它会重启代理,该代理会将代理置于持久重启循环中。因此,后续代理进入 CrashLoopBackOff 状态,如果当前领导失败则不可用。

    配置一个新的存活度探测,当代理是领导或后续时,可以成功运行,如示例所示。在示例中,存活度探测会检查运行代理的命令是否已执行,这通过存在 cli.lock 锁定文件来表示。

    有关配置存活度探测的更多信息,请参阅 第 4.15.2 节 “配置存活度和就绪度探测”

    brokerProperties

    指定为日志文件启用消息持久性的详细信息。

    HAPolicyConfiguration
    设置为 SHARED_STORE_PRIMARY,以确保代理使用文件锁定来防止代理被两个代理并发访问。
    journalDirectory
    用于存储消息日志的文件系统位置。
    PageDirectory
    文件系统位置,以存储页面消息。
    bindingsDirectory
    用于存储绑定日志的文件系统位置。
    largeMessagesDirectory
    用于存储大型消息的文件系统位置。
  2. 使用 oc get pods 命令来识别哪个代理是领导,这是后续代理。在以下示例中,peer-broker-a-s-0 是 leader,由 READY 列中的 1/1 条目表示。
NAME                 READY   STATUS             RESTARTS         AGE
peer-broker-a-ss-0   1/1     Running            0                72m
peer-broker-b-ss-0   0/1     Running            0                72m
Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat