十三、Axon服务器
13.1安装
本部分包括axon SE和axon EE,需要在java8或者java11的环境下安装。
13.1.1 Axon Server SE 本地安装
二进制文件:
Axon server SE-ZIP下载包含服务器本身和CLI的可执行JAR文件。复制axonserver.jar/axonserver-cli.jar到你选择的目录。
运行Axon Server SE
从文件提取的位置,运行以下命令:$ ./axonserver.jar
这将使用默认端口启动Axon SE服务器~~8024用于HTTP/8124用于gRPC。
HTTP端口用于为管理UI和Axon server SE提供的rest api提供服务。gRPC端口由Axon框架客户端应用程序用来连接到Axon服务器SE。管理界面可以在“”http://localhost:8024“打开,而REST API可在”http://localhost:8024/v1打开。
Rest api在“/v1/public/me”提供了一个操作,以获取正在运行的Axon server SE实例的配置详细信息。下面给出了响应的表示。
{
"authentication": false,
"clustered": false,
"ssl": false,
"adminNode": true,
"developmentMode": false,
"storageContextNames": [
"default"
],
"contextNames": [
"default"
],
"httpPort": 8024,
"grpcPort": 8124,
"internalHostName": null,
"grpcInternalPort": 0,
"name": ${hostname},
"hostName": ${hostname}
}
总结来说:
- 默认情况下,未启用访问控制和SSL。以下各节详细介绍了如何配置此功能。
- AxonServerSE为事件存储和消息路由提供了一个名为“default”的上下文。不可能创建任何其他上下文。
- 默认端口为8024/8124。这些值可以通过配置进行更改。
- 名称和主机名默认为运行Axon server SE的系统主机名。这些值可以通过配置更改(“axoniq.axonserver.name” / “axoniq.axonserver.hostname”).
- 群集在Axon Server SE中不可用。
- “主机名”和“内部端口”不适用于服务器
以上就完成了一个使用所有默认值的Axon服务器SE的快速设置。它现在可以作为事件存储和消息路由器使用。
访问控制
由于Axon服务器是一个事件存储,可能包含敏感数据,因此在生产环境和类似生产环境中启用访问控制始终是一个很好的实践。
访问控制部分详细介绍了在Axon服务器SE中设置访问控制所需的步骤。
SSL
Axon Server SE支持TLS/SSL(传输层安全/安全套接字层)来加密Axon Server SE的所有网络流量—从Axon框架客户端应用程序到Axon Server SE。
Axon Server SE有两个端口(HTTP/gRPC)需要为SSL启用,因此需要使用两组不同的设置,每个端口一组。
SSL部分详细介绍了在Axon服务器SE中设置SSL所需的步骤。
存储
默认情况下,Axon服务器SE将在当前目录中查找名为“data”的目录,并在其中查找“default”目录。这是存储“默认”上下文的事件和快照的位置。可以使用axoniq.axonserver.event.存储“和”axoniq.axonserver.snapshot.storage“设置。在“data”目录中还有一个小数据库,称为“ControlDB”,用于管理数据。您可以使用“…controldb path”设置自定义此位置。
配置部分详细说明了设置Axon Server SE存储所需的步骤。
开发模式
Axon Server SE可以在开发模式下启动,这使得一些特性能够为开发提供方便。
可以通过配置以下属性来启用此功能:
axoniq.axonserver.devmode.enabled=true
重置事件
在创建新特性的同时,可以方便地将Axon服务器恢复到干净的状态,而不存储任何事件。在针对系统编写和运行集成测试时,这也很有帮助。请注意,未存储在Axon服务器中的数据(例如跟踪令牌)不会从此功能中删除。必须手动删除或重置。
重置Axon服务器可以通过CLI以及UI和REST接口完成。
注意:当Axon服务器以群集模式运行时,此功能被禁用。
13.1.2 Axon server EE本地安装
13.1.2.1安装文件
Axon server EE-ZIP下载包含服务器本身和CLI的可执行JAR文件。除了存档文件,您还需要许可证才能运行它。
13.1.2.2设置Axon服务器EE
与Axon Server SE不同,Axon Server EE版本的设置和运行是一个较长的过程,涉及到群集的设置、上下文的创建和角色的分配,然后才能用于事件存储和消息路由。
在开始安装之前,我们先简单介绍一下Axon服务器EE中集群和上下文的概念。
13.1.2.2.1集群/上下文
Axon服务器节点集群将为(基于Axon框架的)客户端应用程序提供多个连接点,从而分担管理消息传递和事件存储的负载。客户端应用程序将动态连接到群集中的一个节点,并自动重新连接到另一个节点(如果它们当前连接的节点无法访问)。这确保了高可用性部署。
在单个集群中,您可以定义上下文。上下文与RDBMS中的逻辑数据库相当。它们允许强隔离,而不需要部署和管理完整实例。它们可以用于DDD意义上的“有界上下文”、多租户(每个租户有一个上下文),并且具有不同的保留策略。
集群和上下文部分提供了对这些方面的更多见解。
13.1.2.2.2集群设置
建立集群通常包括三个步骤:
- 提供“未初始化”Axon服务器EE节点
- 管理节点初始化
- 向群集添加其他节点。
提供Axon服务器EE节点
要开始设置群集,您需要设置一组未初始化的节点。在要成为集群一部分的所有节点上提取企业Zip。如果这些节点在同一台机器上运行,则需要在不同的端口上运行。
从文件提取的位置,请运行以下命令:$ ./axonserver.jar
这将使用默认端口启动Axon服务器EE,HTTP/8124使用8024端口,gRPC使用8224端口
HTTP端口用于为管理UI和Axon服务器EE提供的rest api提供服务。grpc8124端口由Axon框架客户端应用程序用来连接到Axon服务器EE,而grpc8224端口用于Axon服务器EE集群节点之间的内部通信。
管理界面可以在“打开”http://localhost:8024“而REST API可在”http://localhost:8024/v1英寸。rest api在“/v1/public/me”处提供了一个操作,以获取正在运行的Axon服务器EE实例的配置详细信息。
下面给出了响应的表示:
{
"authentication": false,
"clustered": true,
"ssl": false,
"adminNode": false,
"developmentMode": false,
"storageContextNames": [],
"contextNames": [],
"internalHostName": ${hostname},
"grpcInternalPort": 8224,
"grpcPort": 8124,
"httpPort": 8024,
"name": ${hostname},
"hostName": ${hostname}
}
对需要成为集群一部分的每个节点重复此操作。
总的来说,
- 在需要成为集群一部分的每个节点上提取Axon服务器EE-zip(以及许可证文件),并启动每个实例。
- 确保gRPC/内部gRPC端口在各个节点之间打开并可访问。
- 对位于“/v1/public/me”的每个节点的restapi调用提供了正在运行的Axon服务器EE实例的配置详细信息。可以使用系统属性文件自定义此配置“axonserver.properties“位于Axon服务器EE可分发。系统属性部分详细说明了这些值。
这就完成了设置单元化节点的过程。接下来,我们需要将其中一个节点初始化为“管理节点”
管理节点初始化
要将一组未初始化的Axon服务器EE节点转换为集群,您需要选择其中任何一个作为起点,并在其上运行“init cluster”命令。这是使用“命令行”实用程序(axonserver)完成的-命令行.jar)作为Axon服务器EE可分发的一部分提供。
$ ./axonserver-cli.jar init-cluster
一旦成功执行,将执行以下操作:,
将此节点指定为Axon服务器EE集群的管理节点
创建“admin”上下文,该上下文存储Axon服务器EE集群的配置详细信息
创建可用于客户端应用程序的事件存储/消息路由的“默认”上下文
位于“/v1/public/me”的rest api操作现在应该显示以下响应(假设axonserver-0作为管理节点的主机名)。
{
"authentication": false,
"clustered": true,
"ssl": false,
"adminNode": true,
"developmentMode": false,
"storageContextNames": [ "default" ],
"contextNames": [ "_admin", "default" ],
"name": "axonserver-1",
"hostName": "axonserver-1",
"internalHostName": "axonserver-1",
"grpcInternalPort": 8224,
"grpcPort": 8124,
"httpPort": 8024
}
}
所有管理节点都是“_admin”上下文的成员,它用于以与分发事件、命令和查询相同的方式分发集群结构数据。
UI控制台显示新初始化的管理节点,如下所示(假设axonserver-1为节点的名称)
其他节点
其他节点可以使用“register node”命令添加到集群中,并将其指向集群中已经存在的管理节点。在每个其他节点上,需要通过指向上面创建的管理节点来执行以下命令。
$ ./axonserver-cli.jar register-node -h axonserver-1
假设要添加的附加节点的主机名为“axonserver-2”,如果对第二个节点运行“/v1/public/me”处的rest api操作,将显示以下响应。{
"authentication": false,
"clustered": true,
"ssl": false,
"adminNode": true,
"developmentMode": false,
"storageContextNames": [ "default" ],
"contextNames": [ "_admin", "default" ],
"name": "axonserver-2",
"hostName": "axonserver-2",
"internalHostName": "axonserver-2",
"grpcInternalPort": 8224,
"grpcPort": 8124,
"httpPort": 8024
}
要获得集群配置的完整详细信息,请在“/v1/public/context”处对管理节点运行rest api操作。
下面显示了一个示例响应(假设管理节点和附加节点的主机名是“axonserver-1”和“axonserver-2”)
[
{
"metaData": {},
"nodes": ["axonserver-1", "axonserver-2"],
"leader": "axonserver-1",
"pendingSince": 0,
"changePending": false,
"roles": [
{ "role": "PRIMARY", "node": "axonserver-1" },
{ "role": "PRIMARY", "node": "axonserver-2" }
],
"context": "_admin"
},
{
"metaData": {},
"nodes": ["axonserver-1", "axonserver-2"],
"leader": "axonserver-1",
"pendingSince": 0,
"changePending": false,
"roles": [
{ "role": "PRIMARY", "node": "axonserver-1" },
{ "role": "PRIMARY", "node": "axonserver-2" }
],
"context": "default"
}
]
群集配置信息描述了:
- 集群的领导者
- 集群中可用的上下文(在本例中为“\u admin”和“default”)
- 群集中的节点
- 节点在特定上下文中扮演的角色(在本例中,主要角色即该上下文的完全权限)
UI控制台显示新初始化的管理节点,如下所示(假设axonserver-1作为节点的名称):
已注册其他节点。
生产级设置需要更高级的配置。例如,一个Axon服务器EE节点可以被分配在一个集群中扮演不同的角色——它可以充当一个管理节点,在“常规”事件存储和消息传递功能旁边提供配置集群并使其保持运行的服务。也可以将其配置为仅为各种角色中的特定上下文提供服务。上下文与RDBMS中的逻辑数据库相当。它们允许强隔离,而不需要部署和管理完整实例。
这在集群和上下文部分有详细说明。
这就完成了一个使用默认配置的Axon服务器EE集群的快速基本设置。
总而言之,
- 除非设置了群集,否则Axon服务器EE不可用于事件存储或消息路由。
- 默认情况下,未启用访问控制和SSL。
- 基本设置包括创建一个Axon服务器EE集群—这包括配置一个管理节点并向集群注册其他节点。
- 默认端口为8024/8124和8224。这些值可以通过配置进行更改。
- 名称和主机名默认为运行Axon服务器EE的系统主机名。这些值可以通过配置更改(“axoniq.axonserver.name” / “axoniq.axonserver.hostname”).
- “internalHostName”和“grpcInternalPort”用于Axon服务器EE集群节点之间的内部通信。这些值可以通过配置进行更改。
自动聚类
从4.3版开始,您可以使用配置设置axoniq.axonserver.autocluster.first”(在axonserver.properties文件)为其提供已知管理节点的主机名。如果该名称恰好是启动节点的主机名,它将在需要时自动在自身上执行“init cluster”命令。如果该名称不是当前主机名,它将调度一个任务来执行“register node”命令,该命令将一直尝试,直到成功为止,即第一个节点本身可用并初始化。此外,如果需要,您可以使用“axoniq.axonserver.autocluster.contexts“设置以提供要创建或联接的上下文的逗号分隔列表。(如果希望所有节点都成为管理节点,则需要显式添加“\u admin”上下文。)
存储
在一个名为“EE”的目录下创建一个名为“EE”的目录下的数据。这是存储上下文的事件和快照的位置。位置可以使用axoniq.axonserver.event.存储“和”axoniq.axonserver.snapshot.storage“设置。请注意,位置自定义适用于所有上下文,您不能针对特定上下文进行自定义。
Axon服务器EE还将在名为“log”的目录下为每个上下文创建一个文件夹。这是存储每个上下文的复制日志的位置。复制日志在上下文数据传入和分发时存储它。复制日志的存储位置可以使用axoniq.axonserver.replication.log storage folder“属性。同样,这适用于所有上下文。
在“data”目录中还有一个小数据库,称为“ControlDB”,用于管理数据。您可以使用axoniq.axonserver.controldb-“路径”设置。
设置所需的一些详细信息,包括设置aexon所需的服务器选项。
访问控制
由于Axon服务器是一个事件存储,可能包含敏感数据,因此在生产环境和类似生产环境中启用访问控制始终是一个很好的实践。
访问控制部分详细说明了在Axon服务器EE中设置访问控制所需的步骤。
SSL
Axon Server EE支持TLS/SSL(传输层安全/安全套接字层)来加密Axon Server SE的所有网络流量—从Axon Framework客户端应用程序到Axon Server EE,以及Axon Server EE群集的各个节点之间。
SSL部分详细介绍了在Axon服务器EE中设置SSL所需的步骤。
13.1.3 Docker/k8s安装Axon server SE
13.1.3.1 docker图像
Axon提供了一个随时可用的图像。该图像是使用gcr.io存储库中Google的“ distroless”基础图像(在本例中为“ gcr.io/distroless/java:11”)的紧凑图像构建的。
要运行提供的图像,可以执行以下命令。这将在Docker容器中启动Axon Server SE,并向主机公开HTTP(8024)和GRPC(8124)端口。
$ docker run -d --name -p 8024:8024 -p 8124:8124 axoniq / axonserver
通过查询可用于检索正在运行的Axon Server实例的配置信息的REST API,可以对正在运行的docker容器进行快速验证。
$ curl -s http://localhost:8024 / v1 / public / me
这将显示以下信息:
{
"authentication": false,
"clustered": false,
"ssl": false,
"adminNode": true,
"developmentMode": false,
"storageContextNames": [
"default"
],
"contextNames": [
"default"
],
"httpPort": 8024,
"grpcPort": 8124,
"internalHostName": null,
"grpcInternalPort": 0,
"name": "{axon-server-name}",
"hostName": "{axon-server-hostname}"
}
该应用程序安装在具有最小属性文件的根目录中,如下所示。“ / data”和“ / eventdata”目录创建为卷,它们的数据将在Docker临时存储树中某个位置的本地文件系统上访问。
axoniq.axonserver.snapshot.storage = / eventdata
axoniq.axonserver.controldb-path = /data
axoniq.axonserver.pid-file-location= /data
logging.file = / data / axonserver.log
logging.file.max-history = 10
logging.file.max-size = 10MB客制化
13.1.3.1.1 偏好设置
可以根据您的要求指定卷的目录位置。该映像还具有未标记为卷的第三个目录“ / config”。这使您能够拥有一个“ axonserver.properties”文件,可以将其放置在该位置以覆盖上述设置以及添加类似于本地安装的新属性。
假设您有一个目录“ axonserverse ”,它将是您的卷和配置信息的指定位置。
我们将首先为卷/配置创建子目录。我们还将在axonserver.properties文件中添加几个自定义属性(名称/主机名),该文件将放置在config子目录中。如上所述,您可以添加其他属性来控制配置。
$ mkdir -p axonserverse/data axonserverse/events axonserverse/config
$ (
> echo axoniq.axonserver.name=axonserver
> echo axoniq.axonserver.hostname=localhost
> ) > axonserverse/config/axonserver.proprties
要使用上面完成的自定义启动容器,可以执行以下命令:
docker run -d --rm --name axonserver -p 8024:8024 -p 8124:8124 -v `pwd`/axonserverse/data:/data -v `pwd`/axonserverse/events:/eventdata -v `pwd`/axonserverse/config:/config axoniq/axonserver
现在,如果您查询API(使用上面描述的“ curl”命令),它将显示它以名称“ axonserver”和主机名“ localhost”运行。数据目录还将包含ControlDB文件,PID文件以及日志输出的副本。“事件”目录将包含事件和快照数据。
通过自定义的实现,这完成了Axon Server SE Docker映像的基本设置。
13.1.3.2 Docker撰写
在docker-compose中运行Axon Server SE有助于解决围绕分布式方案的更复杂需求。以下文件将通过将“ ./data”、“./events”和“ ./config”安装为卷来启动Axon Server SE,并且config目录实际上是只读的。
再次假设您有一个目录“ axonserverse ”,它将是您的卷和配置信息的指定位置。
version: '3.3'
services:
axonserver:
image: axoniq/axonserver
hostname: axonserver
volumes:
- axonserver-data:/data
- axonserver-events:/eventdata
- axonserver-config:/config:ro
ports:
- '8024:8024'
- '8124:8124'
- '8224:8224'
networks:
- axon-demo
volumes:
axonserver-data:
driver: local
driver_opts:
o: bind
type: none
device: ${PWD}/axonserverse/data
axonserver-events:
driver: local
driver_opts:
o: bind
type: none
device: ${PWD}/axonserverse/events
axonserver-config:
driver: local
driver_opts:
o: bind
type: none
device: ${PWD}/axonserverse/config
networks:
axon-demo:
下面描述了使用docker-compose命令启动Axon Server SE。
$ docker-compose up
Creating network "docker-compose_axon-demo" with the default driver
Creating volume "docker-compose_axonserver-data" with local driver
Creating volume "docker-compose_axonserver-events" with local driver
Creating volume "docker-compose_axonserver-config" with local driver
Creating docker-compose_axonserver_1 ... done
Attaching to docker-compose_axonserver_1
axonserver_1 | _ ____
axonserver_1 | / \ __ _____ _ __ / ___| ___ _ ____ _____ _ __
axonserver_1 | / _ \ \ \/ / _ \| '_ \\___ \ / _ \ '__\ \ / / _ \ '_
axonserver_1 | / ___ \ > < (_) | | | |___) | __/ | \ V / __/ |
axonserver_1 | /_/ \_\/_/\_\___/|_| |_|____/ \___|_| \_/ \___|_|
axonserver_1 | Standard Edition Powered by AxonIQ
13.1.3.3 Kubernetes
Axon Server SE实例具有清晰持久的身份,因为它可以将有关自身的标识信息保存在controlDB中。另外,如果将其用作事件存储,则上下文的事件也将存储在磁盘上,实质上Axon Server SE是有状态的应用程序。
在Kubernetes的上下文中,这意味着我们希望将每个Axon Server部署都绑定到其自己的存储卷以及可预测的网络身份。Kubernetes为我们提供了一个StatefulSet部署类,该类仅表示StatefulSets代表一组Pod,这些Pod具有唯一的,持久的身份和稳定的主机名,无论它们在何处进行调度,都可以维护。
下面描述了一个示例YAML描述符,它为Axon服务器和两个服务(axon-server-gui / axonserver)定义了一个StatefulSet,以提供对HTTP和gRPC端口的访问。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: axonserver
labels:
app: axonserver
spec:
serviceName: axonserver
replicas: 1
selector:
matchLabels:
app: axonserver
template:
metadata:
labels:
app: axonserver
spec:
containers:
- name: axonserver
image: axoniq/axonserver
imagePullPolicy: Always
ports:
- name: grpc
containerPort: 8124
protocol: TCP
- name: gui
containerPort: 8024
protocol: TCP
volumeMounts:
- name: data
mountPath: /data
- name: events
mountPath: /eventdata
readinessProbe:
httpGet:
path: /actuator/info
port: 8024
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
failureThreshold: 30
livenessProbe:
httpGet:
path: /actuator/info
port: 8024
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
volumeClaimTemplates:
- metadata:
name: events
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 5Gi
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: axonserver-gui
labels:
app: axonserver
spec:
ports:
- name: gui
port: 8024
targetPort: 8024
selector:
app: axonserver
type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
name: axonserver
labels:
app: axonserver
spec:
ports:
- name: grpc
port: 8124
targetPort: 8124
clusterIP: None
selector:
app: axonserver
---
这里要注意的重要一点是,这是一个非常基本的描述符,因为它没有为长时间运行的部署而可能要为Axon Server SE保留的内存量和/或cpu进行任何设置。
要进行部署,您将需要一个Kubernetes集群并访问kubectl实用程序来帮助控制这些集群。对于开发Kubernetes集群,建议使用minikube或Red Hat CodeReady容器,它们会在笔记本电脑上安装Red Hat OpenShift Kubernetes集群。对于生产,建议使用托管服务,例如AWS EKS / Google的GKE或Azure的AKS。
第一步是为Axon Server SE创建一个单独的名称空间。
$ kubectl create ns ${axonserverse-ns}
namespace/running-axon-server created
下一步将是部署到群集。
$ kubectl apply -f axonserver.yml -n ${axonserverse-ns}
statefulset.apps/axonserver created
service/axonserver-gui created
service/axonserver created
这样就完成了一个基本设置,以帮助在Kubernetes上安装Axon Server SE。
13.1.4 Docker/k8s安装Axon server EE
13.1.4.1图像建构
Axon不为Axon服务器EE提供公共图像。下面提供了一个入门Dockerfile,可以根据您的要求进行定制。这将适用于OpenShift、Kubernetes以及Docker和Docker Compose。
starter文件有助于分多个阶段创建图像,该图像将基于谷歌的“distroless”基础图片gcr.io存储库,在本例则是中”gcr.io/distroless/java:11。
第一阶段创建一个名为“axonserveree”的用户和组,这样我们就可以作为非根用户运行axon server ee。它还创建将成为卷(/axonserve)的目录,并最终设置所有权。
第二阶段首先复制帐户(以“passwd”和“group”文件的形式)和主目录及其卷装入点,小心地将所有权设置为新用户。
最后的步骤复制可执行jar(axon server.jar->企业版)和一组通用属性。它标记卷装入点和公开的端口,最后指定启动Axon服务器EE的命令。
FROM busybox as source
RUN addgroup -S axonserveree \
&& adduser -S -h /axonserveree -D axonserveree \
&& mkdir -p /axonserveree/config /axonserveree/data \
/axonserveree/events /axonserveree/log \
&& chown -R axonserveree:axonserveree /axonserveree
FROM gcr.io/distroless/java:11
COPY --from=source /etc/passwd /etc/group /etc/
COPY --from=source --chown=axonserveree /axonserveree /axonserveree
COPY --chown=axonserveree axonserver.jar axonserver-cli.jar axonserver.properties /axonserveree/
USER axonserveree
WORKDIR /axonserveree
VOLUME [ "/axonserveree/config", "/axonserveree/data", "/axonserveree/events", "/axonserveree/log" ]
EXPOSE 8024/tcp 8124/tcp 8224/tcp
ENTRYPOINT [ "java", "-jar", "axonserver.jar" ]
对于公共属性(axonserver.properties),可以添加最小值集以确保装入卷并生成日志。同样,这些可以根据部署需求进行定制。
axoniq.axonserver.event.storage=/axonserveree/events
axoniq.axonserver.snapshot.storage=/axonserveree/events
axoniq.axonserver.replication.log-storage-folder=/axonserveree/log
axoniq.axonserver.controldb-path=/axonserveree/data
axoniq.axonserver.pid-file-location=/axonserveree/data
logging.file=/axonserveree/data/axonserver.log
logging.file.max-history=10
logging.file.max-size=10MB
放置Dockerfile,Axon服务器EE jar文件(axonserver.jar),Axon服务器EE客户端jar文件(axonserver-命令行.jar)以及axonserver.properties. 可以使用以下命令构造图像。
$ docker build --tag ${TAG} .
${TAG}可以是您想给Axon服务器EE Docker图像的任何标记。这就完成了Docker映像的构建。可以将映像推送到本地存储库,或者如果只想在开发计算机上运行,则可以将其保留在本地。下一步是使用dockercompose或Kubernetes来运行它。
13.1.4.2 Docker撰写
Axon Server EE旨在以分布式方式运行,即作为一个集群,其中将有多个Axon Server EE节点实例运行,所有节点都相互连接。
安装过程假设Docker Compose将用于运行一个3节点的Axon服务器EE集群,即运行我们上面构建的相同容器映像的3个服务。让我们将这些服务指定为“axonserver-1”、“axonserver-2”和“axonserver-3”。我们还将为上面构建的映像添加一个标记,名为“axon server ee:running”。
每个容器实例将为“数据”、“事件”和“日志”使用单独的卷。我们将使用“secrets”来注入许可证文件、令牌以及使用autocluster机制的集群/上下文定义。添加了一个环境变量来告诉Axon服务器许可文件的位置。
完整的docker compose文件如下所示。
version: '3.3'
services:
axonserver-1:
image: axonserver-ee:running
hostname: axonserver-1
volumes:
- axonserver-data1:/axonserver/data
- axonserver-events1:/axonserver/events
- axonserver-log1:/axonserver/log
secrets:
- source: axoniq-license
target: /axonserver/config/axoniq.license
- source: axonserver-properties
target: /axonserver/config/axonserver.properties
- source: axonserver-token
target: /axonserver/config/axonserver.token
environment:
- AXONIQ_LICENSE=/axonserver/config/axoniq.license
ports:
- '8024:8024'
- '8124:8124'
- '8224:8224'
networks:
- axon-demo
axonserver-2:
image: axonserver-ee:running
hostname: axonserver-2
volumes:
- axonserver-data2:/axonserver/data
- axonserver-events2:/axonserver/events
- axonserver-log2:/axonserver/log
secrets:
- source: axoniq-license
target: /axonserver/config/axoniq.license
- source: axonserver-properties
target: /axonserver/config/axonserver.properties
- source: axonserver-token
target: /axonserver/config/axonserver.token
environment:
- AXONIQ_LICENSE=/axonserver/config/axoniq.license
ports:
- '8025:8024'
- '8125:8124'
- '8225:8224'
networks:
- axon-demo
axonserver-3:
image: axonserver-ee:running
hostname: axonserver-3
volumes:
- axonserver-data3:/axonserver/data
- axonserver-events3:/axonserver/events
- axonserver-log3:/axonserver/log
secrets:
- source: axoniq-license
target: /axonserver/config/axoniq.license
- source: axonserver-properties
target: /axonserver/config/axonserver.properties
- source: axonserver-token
target: /axonserver/config/axonserver.token
environment:
- AXONIQ_LICENSE=/axonserver/config/axoniq.license
ports:
- '8026:8024'
- '8126:8124'
- '8226:8224'
networks:
- axon-demo
volumes:
axonserver-data1:
driver: local
driver_opts:
type: none
device: ${PWD}/data1
o: bind
axonserver-events1:
driver: local
driver_opts:
type: none
device: ${PWD}/events1
o: bind
axonserver-log1:
driver: local
driver_opts:
type: none
device: ${PWD}/log1
o: bind
axonserver-data2:
driver: local
driver_opts:
type: none
device: ${PWD}/data2
o: bind
axonserver-events2:
driver: local
driver_opts:
type: none
device: ${PWD}/events2
o: bind
axonserver-log2:
driver: local
driver_opts:
type: none
device: ${PWD}/log2
o: bind
axonserver-data3:
driver: local
driver_opts:
type: none
device: ${PWD}/data3
o: bind
axonserver-events3:
driver: local
driver_opts:
type: none
device: ${PWD}/events3
o: bind
axonserver-log3:
driver: local
driver_opts:
type: none
device: ${PWD}/log3
o: bind
networks:
axon-demo:
secrets:
axonserver-properties:
file: ./axonserver.properties
axoniq-license:
file: ./axoniq.license
axonserver-token:
file: ./axonserver.token
“axon server token”秘密用于允许CLI与节点通信。访问控制部分详细说明了这些令牌的生成。可以使用类似的方法为证书配置更多机密,从而启用SSL。
秘密定义部分中提到的axonserver.propertie属性文件如下所示:
axoniq.axonserver.autocluster.first=axonserver-1
axoniq.axonserver.autocluster.contexts=_admin,default
axoniq.axonserver.accesscontrol.enabled=true
axoniq.axonserver.accesscontrol.internal-token=${generated_token}
axoniq.axonserver.accesscontrol.systemtokenfile=/axonserver/config/axonserver.tok
使用docker compose命令启动Axon服务器EE如下所示:
$ docker-compose up
13.1.4.3 Kubernetes
在Kubernetes上部署Axon服务器EE基本上遵循与我们在Axon服务器SE上看到的相同的原则,就是使用有状态集。然而,为了满足Axon服务器EE的分布式部署拓扑,需要进行一些更改。
我们需要改变上面的文件。这是因为在Docker中,卷是作为挂载位置的所有者挂载的,而Kubernetes使用特殊的安全上下文,默认为root。因为我们的EE映像在自己的用户(axon server ee)下运行Axon服务器,所以除了“读取”之外,它对挂载的卷没有权限。可以指定上下文,但只能通过用户或组的ID来指定,而不是像我们在映像中那样使用它们的名称,因为k8s管理上下文中不存在该名称。因此,我们必须调整第一阶段以指定一个特定的数值(这里我们给出了1001),然后在有状态集的安全上下文中使用该值,我们将在下面看到。
变化描述如下。如前所述,使用docker build创建映像并给它一个标记(例如AxonServer运行)。
FROM busybox as source
RUN addgroup -S -g 1001 axonserveree \
&& adduser -S -u 1001 -h /axonserveree -D axonserveree \
&& mkdir -p /axonserveree/config /axonserveree/data \
/axonserveree/events /axonserveree/log \
&& chown -R axonserveree:axonserveree /axonserveree
我们需要通过一个axonserver.properties文件。与Docker Compose不同,Kubernetes将机密和配置映射作为目录而不是文件安装,因此我们需要将许可证和配置拆分到两个不同的位置。对于许可证密码,我们可以使用新位置“/axonserver/license”/axoniq.许可证”并调整环境变量以匹配。对于系统令牌,我们将使用“/axonserver/security”/token.txt,对于属性文件,我们将使用挂载在“/axonserver/config”目录上的ConfigMap。
可以使用“kubectl”直接从它们各自的文件中创建,如下所示。建议在创建机密和配置映射之前创建一个专用命名空间。
$ kubectl create secret generic axonserveree-license --from-file=./axoniq.license -n ${axonserveree-ns}
secret/axonserver-license created
$ kubectl create secret generic axonserveree-token --from-file=./axoniq.token -n ${axonserveree-ns}
secret/axonserver-token created
$ kubectl create configmap axonserveree-properties --from-file=./axonserver.properties -n ${axonserveree-ns}
configmap/axonserver-properties created
$
在描述符中,我们现在必须声明这个秘密,为它添加一个卷,然后将这个秘密挂载到这个卷上。然后必须添加一个卷列表来链接实际的许可证和属性。
下面给出了Axon服务器EE状态集的完整规范。这包括安全上下文、卷装载、就绪性和活动性探测,最后是卷。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: axonserveree
labels:
app: axonserveree
spec:
serviceName: axonserveree
replicas: 1
selector:
matchLabels:
app: axonserveree
template:
metadata:
labels:
app: axonserveree
spec:
securityContext:
runAsUser: 1001
fsGroup: 1001
containers:
- name: axonserveree
image: axonserver-ee:running
imagePullPolicy: IfNotPresent
ports:
- name: grpc
containerPort: 8124
protocol: TCP
- name: gui
containerPort: 8024
protocol: TCP
env:
- name: AXONIQ_LICENSE
value: "/axonserveree/license/axoniq.license"
volumeMounts:
- name: data
mountPath: /axonserveree/data
- name: events
mountPath: /axonserveree/events
- name: log
mountPath: /axonserveree/log
- name: config
mountPath: /axonserveree/config
readOnly: true
- name: system-token
mountPath: /axonserveree/security
readOnly: true
- name: license
mountPath: /axonserveree/license
readOnly: true
readinessProbe:
httpGet:
path: /actuator/info
port: 8024
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
failureThreshold: 30
livenessProbe:
httpGet:
path: /actuator/info
port: 8024
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
volumes:
- name: config
configMap:
name: axonserveree-properties
- name: system-token
secret:
secretName: axonserveree-token
- name: license
secret:
secretName: axonserveree-license
volumeClaimTemplates:
- metadata:
name: events
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 5Gi
- metadata:
name: log
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
可以使用以下命令应用StatefulSet(假设statefolset规范存储在文件“axonserver”中-sts.yml").
$ kubectl apply -f axonserver-sts.yml -n ${axonserveree-ns}
statefulset.apps/axonserveree created
下一步是创建Axon服务器EE所需的两个服务,即8024上的axonserver gui(HTTP)和8124上的axonserver(gRPC)。
apiVersion: v1
kind: Service
metadata:
name: axonserveree-gui
labels:
app: axonserveree
spec:
ports:
- name: gui
port: 8024
targetPort: 8024
selector:
app: axonserveree
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: axonserveree
labels:
app: axonserveree
spec:
ports:
- name: grpc
port: 8124
targetPort: 8124
clusterIP: None
selector:
app: axonserveree
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: axonserveree
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/affinity: cookie
nginx.ingress.kubernetes.io/affinity-mode: persistent
spec:
rules:
- host: axonserveree
http:
paths:
- backend:
serviceName: axonserveree-gui
servicePort: 8024
服务通过设置一个入口来允许被下列命令调用(假设服务标准被存储在axonserveree-ing.yml文件中)。
$ kubectl apply -f axonserveree-ing.yml -n ${axonserveree-ns}
service/axonserveree-gui created
service/axonserveree created
ingress.networking.k8s.io/axonserveree created
最后一步是扩展集群。最简单也是最正确的方法是使用1以外的比例因子,让Kubernetes负责部署多个实例。这意味着我们将获得一些Kubernetes可以根据需要动态管理和迁移的节点,同时修复名称和存储。我们将得到一个以0开头的数字作为后缀,因此比例因子为3表示“axonserver-0”到“axonserver-2”。
$ kubectl scale sts axonserveree -n ${axonserveree-ns} --replicas=3
statefulset.apps/axonserveree scaled
这就完成了一个基本设置,可以帮助在Kubernetes上安装Axon服务器EE。客户可以根据自己的需求和Kubernetes的使用情况选择定制整个设置。