在 Kubernetes 上使用Spring Boot+ActiveMQ

banq發表於2022-07-27

本文將教您如何在 Kubernetes 上執行 ActiveMQ,並透過 Spring Boot 將其與您的應用程式整合。我們將使用專門的操作員部署一個叢集的 ActiveMQ 代理。然後我們將構建並執行兩個 Spring Boot 應用程式:
  1. 第一個在多個例項中執行並從佇列接收訊息,
  2. 而第二個是向該佇列傳送訊息。

為了測試 ActiveMQ 叢集,我們將使用Kind。消費者應用程式使用幾種不同的模式連線到叢集。

ActiveMQ 也是一個非常流行的訊息代理。例如,它支援最新版本的 AMQP 協議,而 Rabbit 則是基於它們對 AMQP 0.9 的擴充套件。

原始碼:
GitHub 儲存庫。然後進入messaging目錄。您將找到三個 Spring Boot 應用程式simple-producer:simple-consumer和simple-counter. 

ActiveMQ Artemis 是 Red Hat 提供的名為AMQ Broker的商業產品的基礎。Red Hat 積極開發了一個用於 ActiveMQ 的 Spring Boot 啟動器和一個在 Kubernetes 上執行它的運算子。為了訪問 Spring Boot,您需要在pom.xml檔案中包含 Red Hat Maven 儲存庫:

<repository>
  <id>red-hat-ga</id>
  <url>https://maven.repository.redhat.com/ga</url>
</repository>


之後,您可以在 Maven 中包含一個啟動器pom.xml:

<dependency>
  <groupId>org.amqphub.spring</groupId>
  <artifactId>amqp-10-jms-spring-boot-starter</artifactId>
  <version>2.5.6</version>
  <exclusions>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>log4j-over-slf4j</artifactId>
    </exclusion>
  </exclusions>
</dependency>


然後,我們只需要使用@EnableJMS註解為我們的應用程式啟用 JMS:

@SpringBootApplication
@EnableJms
public class SimpleConsumer {

   public static void main(String[] args) {
      SpringApplication.run(SimpleConsumer.class, args);
   }

}

我們的應用程式非常簡單。它只是接收並列印傳入的訊息。接收訊息的方法應該用 註釋@JmsListener。該destination欄位包含目標佇列的名稱。

@Service
public class Listener {

   private static final Logger LOG = LoggerFactory
      .getLogger(Listener.class);

   @JmsListener(destination = "test-1")
   public void processMsg(SimpleMessage message) {
      LOG.info("============= Received: " + message);
   }

}

這是代表我們資訊的類:

public class SimpleMessage implements Serializable {

   private Long id;
   private String source;
   private String content;

   public SimpleMessage() {
   }

   public SimpleMessage(Long id, String source, String content) {
      this.id = id;
      this.source = source;
      this.content = content;
   }

   // ... GETTERS AND SETTERS

   @Override
   public String toString() {
      return "SimpleMessage{" +
              "id=" + id +
              ", source='" + source + '\'' +
              ", content='" + content + '\'' +
              '}';
   }
}

最後,我們需要設定連線配置設定。使用 AMQP Spring Boot 啟動器非常簡單。我們只需要設定屬性amqphub.amqp10jms.remoteUrl。現在,我們將基於在 Kubernetes 級別設定的環境變數Deployment。

amqphub.amqp10jms.remoteUrl = ${ARTEMIS_URL}
生產者應用程式非常相似。我們使用 SpringJmsTemplate生成訊息並將訊息傳送到目標佇列,而不是用於接收訊息的註解。傳送訊息的方法公開為 HTTPPOST /producer/send端點。

@RestController
@RequestMapping("/producer")
public class ProducerController {

   private static long id = 1;
   private final JmsTemplate jmsTemplate;
   @Value("${DESTINATION}")
   private String destination;

   public ProducerController(JmsTemplate jmsTemplate) {
      this.jmsTemplate = jmsTemplate;
   }

   @PostMapping("/send")
   public SimpleMessage send(@RequestBody SimpleMessage message) {
      if (message.getId() == null) {
          message.setId(id++);
      }
      jmsTemplate.convertAndSend(destination, message);
      return message;
   }
}


使用 Nginx Ingress 建立 Kind 叢集
我們的示例應用程式已準備就緒。在部署它們之前,我們需要準備本地 Kubernetes 叢集。我們將在那裡部署由三個代理組成的 ActiveMQ 叢集。因此,我們的 Kubernetes 叢集也將由三個節點組成。因此,在 Kubernetes 上執行了三個消費者應用程式例項。它們透過 AMQP 協議連線到 ActiveMQ 代理。還有一個生產者應用程式例項可以按需傳送訊息。

為了在本地執行多節點 Kubernetes 叢集,我們將使用 Kind。我們不僅會測試透過 AMQP 協議的通訊,還會透過 HTTP 公開 ActiveMQ 管理控制檯。因為 ActiveMQ 使用無頭服務來公開 Web 控制檯,所以我們必須在 Kind 上建立和配置 Ingress 才能訪問它。讓我們開始。

第一步,我們將建立一個 Kind 叢集。它由一個控制平面和三個工作人員組成。必須正確準備配置才能執行 Nginx 入口控制器。我們應該將ingress-ready標籤新增到單個工作節點並公開埠80和443. 這是 Kind 配置檔案的最終版本:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
    kubeadmConfigPatches:
    - |
      kind: JoinConfiguration
      nodeRegistration:
        kubeletExtraArgs:
          node-labels: "ingress-ready=true"
    extraPortMappings:
    - containerPort: 80
      hostPort: 80
      protocol: TCP
    - containerPort: 443
      hostPort: 443
      protocol: TCP  
  - role: worker
  - role: worker

現在,讓我們透過執行以下命令建立一個 Kind 叢集:

$ kind create cluster --config kind-config.yaml
如果您的叢集已成功建立。

之後,讓我們安裝 Nginx Ingress Controller。它只是一個命令:

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml


在 Kubernetes 上安裝 ActiveMQ Artemis
最後,我們可以繼續安裝 ActiveMQ Artemis。首先,讓我們安裝所需的 CRD。您可以在 GitHub 上的操作員儲存庫中找到所有 YAML 清單。

$ git clone https://github.com/artemiscloud/activemq-artemis-operator.git
$ cd activemq-artemis-operator

帶有 CRD 的清單位於deploy/crds目錄中:

$ kubectl create -f ./deploy/crds

之後,我們可以安裝運算子:

$ kubectl create -f ./deploy/service_account.yaml
$ kubectl create -f ./deploy/role.yaml
$ kubectl create -f ./deploy/role_binding.yaml
$ kubectl create -f ./deploy/election_role.yaml
$ kubectl create -f ./deploy/election_role_binding.yaml
$ kubectl create -f ./deploy/operator_config.yaml
$ kubectl create -f ./deploy/operator.yaml

為了建立叢集,我們必須建立ActiveMQArtemis物件。它包含許多作為叢集(1)一部分的代理。我們還應該設定訪問器,以在每個代理 pod (2)之外公開 AMQP 埠。當然,我們也會暴露管理控制檯(3)。

apiVersion: broker.amq.io/v1beta1
kind: ActiveMQArtemis
metadata:
  name: ex-aao
spec:
  deploymentPlan:
    size: 3 # (1)
    image: placeholder
    messageMigration: true
    resources:
      limits:
        cpu: "500m"
        memory: "1024Mi"
      requests:
        cpu: "250m"
        memory: "512Mi"
  acceptors: # (2)
    - name: amqp
      protocols: amqp
      port: 5672
      connectionsAllowed: 5
  console: # (3)
    expose: true

建立完成ActiveMQArtemis後,操作員將開始部署過程。它建立StatefulSet物件:

$ kubectl get statefulset
NAME        READY   AGE
ex-aao-ss   3/3     1m

它按順序使用代理啟動所有三個 pod:

$ kubectl get pod -l application=ex-aao-app
NAME          READY   STATUS    RESTARTS    AGE
ex-aao-ss-0   1/1     Running   0           5m
ex-aao-ss-1   1/1     Running   0           3m
ex-aao-ss-2   1/1     Running   0           1m


後面更詳細步驟點選標題

相關文章