4.24. 为高可用性配置领导优先部署
leader-follower 配置都有单独的部署,每个部署都有一个代理实例。每个部署中的代理必须配置为将消息持久化到同一目标,可以是 JDBC 数据库或共享卷上的日志。
与为数据库或共享卷获取锁定的代理可实现高可用性。获取锁定的代理会成为为客户端请求服务的领导代理。无法获取锁定的代理会变为 follower。后续是一个被动代理,持续尝试获取数据库或共享卷的锁定。如果后续者获取锁定,它会立即成为领导,并开始为客户端提供服务。
领导(leader-follower 部署)为节点故障提供一个更快的修复时间(MTTR),而不是 OpenShift 为单个部署提供的节点故障。在 leader-follower 部署中,代理可以在单独的集群中,以防止集群故障。这些集群可以位于不同的数据中心中,以便代理服务对数据中心中断具有弹性,只要用于在数据中心之间持久保留消息的存储可用。
4.24.1. 配置使用共享 Java 数据库连接(JDBC)数据库的 leader-follower 代理部署 复制链接链接已复制到粘贴板!
您可以配置 leader-follower 代理部署,将消息保留到共享 JDBC 数据库。
前提条件
您有一个容器镜像,其中包含您要用于 AMQ Broker 的 JDBC 数据库的 JAR 文件。有关创建容器镜像的详情,请参考 OpenShift 文档中的创建镜像。https://docs.openshift.com/container-platform/latest/openshift_images/create-images.html在每个代理的配置中,您可以指定 init 容器,将容器镜像中的 JAR 文件复制到运行时可用于代理的位置。
流程
配置两个
ActiveMQArtemis
自定义资源实例,以创建单独的代理部署。在每个自定义资源中,指定一个唯一名称,并确保
cluster
和persistenceEnabled
属性设置为false
。将size
属性设置为1
,以便在每个部署中创建一个代理。例如:apiVersion: broker.amq.io/v1beta1 kind: ActiveMQArtemis metadata: name: peer-broker-a spec: deploymentPlan: size: 1 clustered: false persistenceEnabled: false
apiVersion: broker.amq.io/v1beta1 kind: ActiveMQArtemis metadata: name: peer-broker-a spec: deploymentPlan: size: 1 clustered: false persistenceEnabled: false
Copy to Clipboard Copied! Toggle word wrap Toggle overflow apiVersion: broker.amq.io/v1beta1 kind: ActiveMQArtemis metadata: name: peer-broker-b spec: deploymentPlan: size: 1 clustered: false persistenceEnabled: false
apiVersion: broker.amq.io/v1beta1 kind: ActiveMQArtemis metadata: name: peer-broker-b spec: deploymentPlan: size: 1 clustered: false persistenceEnabled: false
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意如果两个代理部署在同一 OpenShift 集群中,请确保在单独的节点上置备代理 pod,以避免在节点出现故障时同时出现这两个代理中断。有关控制节点上 pod 放置的更多信息,请参阅 第 4.17 节 “控制 OpenShift Container Platform 节点上的代理 pod 放置”。
为每个 CR 添加新的存活度探测。
如果没有配置存活度探测,则会启用默认探测来检查代理的健康状况。默认探测检查 AMQ 管理控制台是否可访问。在 leader-follower 配置中,AMQ Management Console 在任何给定时间无法在代理中访问,这会导致存活度探测在该代理上失败。每次存活度探测失败时,它会重启代理,该代理会将代理置于持久重启循环中。因此,后续代理进入
CrashLoopBackOff
状态,如果当前领导失败则不可用。要防止默认存活度探测运行,您必须配置一个新的存活度探测,该探测可以在代理是领导或后续时成功运行。以下是满足此要求的存活度探测示例。在本例中,存活度探测会检查运行代理的命令是否已执行,这通过存在
cli.lock
锁定文件来表示。spec: .. livenessProbe: exec: command: - test - -f - /home/jboss/amq-broker/lock/cli.lock ..
spec: .. livenessProbe: exec: command: - test - -f - /home/jboss/amq-broker/lock/cli.lock ..
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 有关配置存活度探测的更多信息,请参阅 第 4.15.2 节 “配置存活度和就绪度探测”。
在每个代理配置中,使用
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
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 Copied! Toggle word wrap Toggle overflow 有关启用 JDBC 数据库持久性的更多信息,请参阅 第 4.5.2 节 “配置数据库持久性”。
在每个代理配置中,配置代理以加载连接到 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"
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 Copied! Toggle word wrap Toggle overflow 有关自定义 Operator 创建的 OpenShift 资源的更多信息,请参阅 第 4.21 节 “自定义 Operator 创建的 Openshift 资源”。
-
使用
保存每个自定义资源。
- 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"
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 Copied! Toggle word wrap Toggle overflow 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"
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 Copied! Toggle word wrap Toggle overflow
4.24.2. 配置使用共享日志的 leader-follower 代理部署 复制链接链接已复制到粘贴板!
您可以配置 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
oc apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-volume
namespace: activemq
spec:
accessModes:
- ReadWriteMany
volumeMode: Filesystem
resources:
requests:
storage: 2Gi
EOF
创建 PVC 后,oc get pvc
命令的输出会显示共享卷具有 待处理状态
,直到代理部署并绑定到卷。例如:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE shared-volume Pending gp3-csi <unset> 7s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
shared-volume Pending gp3-csi <unset> 7s
流程
准备并应用 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
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 Copied! Toggle word wrap Toggle overflow 注意如果两个代理部署在同一 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
- 用于存储大型消息的文件系统位置。
-
使用
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
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