【发布时间】:2021-08-24 20:56:49
【问题描述】:
我们有一堆微服务在共享 AWS EC2 实例的自己的 Docker 容器中运行。 鉴于在本地运行时获得的出色结果,现在我们正在尝试使用 Chronicle 队列作为我们在 AWS 中的微服务之间进行通信的一种方式。
MS1 收到一个 API 请求并进行一些内部处理并向 CH2 Chronicle 队列发送一个事件。 MS2 正在侦听 CH2 编年史队列,当事件到达那里时,它会拾取它并进行一些内部处理并将事件发送到 CH3 编年史队列。
API --> MS1 --> CH2 --> MS2 --> CH3 --> ...
在每个容器中,我们都有/tmp/my_app_data 一个应用程序根文件夹和一个与微服务交互的每个 Chronicle 队列的子文件夹。
例如,在 MS1 容器中,我们有 /tmp/my_app_data/ch2,在 MS2 容器中,我们有 /tmp/my_app_data/ch2 和 /tmp/my_app_data/ch3
所有这些文件夹都以类似的结构映射到 EC2 主机:
/tmp/my_app_data
|_ch2
|_ch3
|_...
现在,在尝试运行我们的系统时,我们遇到了各种访问数据的问题,这些数据是由一个微服务编写的,旨在用于工作流程中的下一个微服务。在上面的示例中,我们可以进一步让 MS2 从 ch2 读取 MS1 发送给您的数据,但我们仍然无法将数据标记为已处理,这意味着 MS2 正在写入 ch2 文件夹下的文件。
我无法列出我们尝试过的全部排列组合,甚至试图破解容器内和 EC2 主机上的文件权限;看来我缺少一些特定于 Docker/AWS 的基本设置。
这是我们来自 MS1 Dockerfile 的 Docker 配置:
RUN mkdir -p /tmp/my_app_data && chown nobody:nobody /tmp/my_app_data
RUN mkdir -p /tmp/my_app_data/ch2 && chown nobody:nobody /tmp/my_app_data/ch2
USER nobody
VOLUME ["/tmp/my_app_data"]
类似地,我们在 MS1 Dockerfile 中拥有相同的 Docker 配置:
RUN mkdir -p /tmp/my_app_data && chown nobody:nobody /tmp/my_app_data
RUN mkdir -p /tmp/my_app_data/ch2 && chown nobody:nobody /tmp/my_app_data/ch2
RUN mkdir -p /tmp/my_app_data/ch3 && chown nobody:nobody /tmp/my_app_data/ch3
USER nobody
VOLUME ["/tmp/my_app_data"]
在 AWS 方面,我们拥有 MS1 和 MS2 任务定义的部分:
"mountPoints": [
{
"readOnly": null,
"containerPath": "/tmp/my_app_data",
"sourceVolume": "chronicle"
}
],
....
"volumes": [
{
"fsxWindowsFileServerVolumeConfiguration": null,
"efsVolumeConfiguration": null,
"name": "chronicle",
"host": {
"sourcePath": "/tmp/my_app_data"
},
"dockerVolumeConfiguration": null
}
]
所以这是我的问题:我做错了什么,我该如何解决?
理想情况下,对于我们来说,这应该在以用户 nobody 运行时工作,但因为这是一个 POC,所以无论如何我都会很感激让它运行,包括 root。对我们来说,这个 POC 的目的是确认我们在云中使用 Chronicle 是否获得与在本地运行时相同的良好结果。
提前感谢您的意见。
【问题讨论】:
-
您能否使用不依赖共享文件的不同排队解决方案(RabbitMQ 是一种流行的开源选项)?
-
是的,我可以,而且我们已经使用 solace 和 IBM MQ 创建了 POC,而且性能也非常好。然而,Chronicle 有一个优势,即除了类路径中的 jar 之外,不需要任何基础设施设置。这表示尚未做出离开 Kafka 的决定。
-
我正试图解决这个问题,我想知道问题是否在于尝试在不同的任务中绑定挂载相同的文件夹。看起来像single task you are doing the right thing。
-
话虽如此,您是否考虑过在您的设计中使用 EFS 来托管您的队列文件?我看到了一些优点:它允许将 EC2 的短暂性与队列的持久性分离,它允许使用超过 1 个 EC2(用于 HA 并在需要时进行扩展),它还可以绕过完成的 POSIX 混乱通过 IAM 通过任务角色将 r/w 权限分配给 EC2。如果您想更深入地了解这一点,请查看this blog series的第 1 部分和第 2 部分
-
EFS 是我尝试的第一件事。不幸的是,Chronicle-queue 开源不支持在不同主机之间移动数据。只要所有数据都移动到同一个硬盘上而不涉及任何网络,它就可以正常工作。看起来你需要chronicle-queue-enterprise,这对我们都有好处,只是为了一个POC,我想让它在单个EC2上工作
标签: java amazon-web-services docker amazon-ecs chronicle-queue