我已经为 Artemis ActiveMQ 主备 HA 实现了领导者选举。这将检查 ActiveMQ Pod 的可用性并更新 Pod 中的标签(服务标签固定为“主要”)。这有助于服务将流量路由到当前的“主”pod。
伪代码:
while true:
if currentPod's TCP socket 61616 is running:
change the label of the pod to 'primary' if not already 'primary'
else:
change the label of the pod to 'backup' if not already 'backup'
wait(3 sec)
Pod 的基础镜像:eclipse-temurin:17
对我来说,这工作得很好,一旦主 Pod 崩溃或重新启动,所有传入流量都会顺利转移到第二个 Pod。
在
entrypoint.sh
-
python3 $PATH/leader-election.py &
这些文件有 n 个内容,所以我不会全部添加,但这里是对这个问题很重要的一部分
# Create broker instance
FROM eclipse-temurin:17 as builder
ARG ACTIVEMQ_ARTEMIS_VERSION
ENV ACTIVEMQ_ARTEMIS_VERSION=$ACTIVEMQ_ARTEMIS_VERSION
RUN apt-get -qq -o=Dpkg::Use-Pty=0 update && apt-get -y install && apt-get -y install wget
RUN apt-get install -y python3
RUN apt-get install -y python3-pip
RUN wget https://archive.apache.org/dist/activemq/activemq-artemis/$ACTIVEMQ_ARTEMIS_VERSION/apache-artemis-$ACTIVEMQ_ARTEMIS_VERSION-bin.tar.gz
RUN tar xvfz apache-artemis-$ACTIVEMQ_ARTEMIS_VERSION-bin.tar.gz
RUN ln -s /opt/apache-artemis-${ACTIVEMQ_ARTEMIS_VERSION} /opt/apache-artemis
RUN rm -f apache-artemis-${ACTIVEMQ_ARTEMIS_VERSION}-bin.tar.gz KEYS apache-artemis-${ACTIVEMQ_ARTEMIS_VERSION}-bin.tar.gz.asc
WORKDIR /var/lib
RUN "/opt/apache-artemis-${ACTIVEMQ_ARTEMIS_VERSION}/bin/artemis" create artemis \
--home /opt/apache-artemis \
--http-host 0.0.0.0 \
--user artemis \
--password artemis \
--no-hornetq-acceptor --no-mqtt-acceptor --no-stomp-acceptor --no-amqp-acceptor \
--role amq \
--require-login ;
# some more configs
COPY assets/docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["artemis-server"]
if [ "$LEADER_ELECTION" = "true" ]; then
python3 $OVERRIDE_PATH/leader-election.py &
fi
# some more things
if [ "$1" = 'artemis-server' ]; then
exec dumb-init -- sh ./artemis run
fi
有状态集和服务
apiVersion: v1
kind: Service
metadata:
name: activemq-svc
namespace: activemq
spec:
type: ClusterIP
ports:
- port: 61616
name: netty-connector
protocol: TCP
targetPort: 61616
selector:
app: activemq
node: primary
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: activemq-statefulset
namespace: activemq
spec:
replicas: 2
serviceName: activemq-svc
selector:
matchLabels:
app: activemq
template:
metadata:
labels:
app: activemq
node: not-ready
Python 负责根据可用性将
node: not-ready
更改为 node: primary
或 node: backup
。
因此,在给定时间点,其中一个节点始终是 primary
,然后与服务匹配,从而允许流量仅流向该 pod。
这个脚本随机停止,领导者选举对我来说变成了一场灾难。我一直在寻找如何将 python 脚本作为服务运行的方法,或者 cron 是每3秒运行代码的选项吗? 另外,我发现了How to make a Python script run like a service or daemon in Linux,其中的要求有点相似。这就带来了另一个问题,这是否可以在没有无限循环的情况下完成?
我使用 supervisord 来运行 python 脚本。