【发布时间】:2023-03-12 07:11:01
【问题描述】:
(查询部分下方朝向中间) 发帖于https://developer.jboss.org/message/982355
环境: 英菲尼斯潘 9.13, 带有 jgroups 的集群中的嵌入式缓存, 单一文件存储, 在单个 docker 主机/守护进程中使用 Docker 服务中的 JGroups(还没有在 AWS 中)。
Infinispan.xml 如下:
<jgroups><stack-file name="external-file" path="${path.to.jgroups.xml}"/></jgroups>
应用程序 = 2 个网络应用程序 + 数据库
问题:
当我将 单独的 tomcats 中的 2 个 webapps 直接部署在一台机器上(还不是 docker)时,初始化缓存的 Infinispan 管理器(在每个 webapp 中)使用 jgroups 形成一个集群(即它有效)。但是使用完全相同的配置(和 jgroups 中的相同通道名称),当 在 docker 中将 webapps 部署为服务时,它们不会加入同一个集群(而是它们是独立的,并且只有一个成员查看 - 下面的日志)。
服务是来自 images = linux + tomcat + webapp 的 docker 容器,并使用 docker compose v3 启动。
我已经尝试了https://github.com/belaban/jgroups-docker 的说明,用于包含 JGroups 的容器和几个演示,其中建议 为 docker 使用 --network=host 模式服务(这确实有效,但我们不能这样做,因为如果我们扩展配置文件需要有单独的端口),或在 jgroups.xml 中传递 external_addr=docker_host_IP_address 字段(这不起作用,查询是如何使它起作用)。
它不是时间问题,因为我也尝试过显着延迟启动部署在堆栈中的第二个服务,但 2 个应用程序的 Infinispan 集群仍然只有一个成员(该容器本身)。调用 cacheManager.getMembers() 也会在每个应用程序中显示一个条目(应该显示 2)。
第一个应用中只显示一个成员的日志:
org.infinispan.remoting.transport.jgroups.JGroupsTransport.receiveClusterView ISPN000094: Received new cluster view for channel CHANNEL_NAME: [FirstContainerId-6292|0] (1) [FirstContainerId-6292].
org.infinispan.remoting.transport.jgroups.JGroupsTransport.startJGroupsChannelIfNeeded ISPN000079: Channel CHANNEL_NAME local address is FirstContainerId-6292, physical addresses are [10.xx.yy.zz:7800]
日志仅显示第二个应用中的一个成员:
org.infinispan.remoting.transport.jgroups.JGroupsTransport.receiveClusterView ISPN000094: Received new cluster view for channel CHANNEL_NAME: [SecondContainerId-3502|0] (1) [SecondContainerId-3502]
29-Apr-2018 11:47:42.357 INFO [localhost-startStop-1] org.infinispan.remoting.transport.jgroups.JGroupsTransport.startJGroupsChannelIfNeeded ISPN000079: Channel CHANNEL_NAME local address is 58cfa4b95c16-3502, physical addresses are [10.xx.yy.zz:7800]
docker compose V3 如下并显示覆盖网络:
version: "3"
services:
app1:
image: app1:version
ports:
- "fooPort1:barPort"
volumes:
- "foo:bar"
networks:
- webnet
app2:
image: app2:version
ports:
- "fooPort2:barPort"
volumes:
- "foo:bar"
networks:
- webnet
volumes:
dbdata:
networks:
webnet:
部署使用 $docker stack deploy --compose-file docker-compose.yml OurStack
JGroups.xml 有下面的相关配置部分:
<TCP
external_addr="${ext-addr:docker.host.ip.address}"
bind_addr="${jgroups.tcp.address:127.0.0.1}"
bind_port="${jgroups.tcp.port:7800}"
enable_diagnostics="false"
thread_naming_pattern="pl"
send_buf_size="640k"
sock_conn_timeout="300"
bundler_type="sender-sends-with-timer"
thread_pool.min_threads="${jgroups.thread_pool.min_threads:1}"
thread_pool.max_threads="${jgroups.thread_pool.max_threads:10}"
thread_pool.keep_alive_time="60000"/>
<MPING bind_addr="${jgroups.tcp.address:127.0.0.1}"
mcast_addr="${jgroups.mping.mcast_addr:228.2.4.6}"
mcast_port="${jgroups.mping.mcast_port:43366}"
ip_ttl="${jgroups.udp.ip_ttl:2}"/>
代码类似:
DefaultCacheManager manager = new DefaultCacheManager(jgroupsConfigFile.getAbsolutePath());
Cache someCache = new Cache(manager.getCache("SOME_CACHE").getAdvancedCache().withFlags(Flag.IGNORE_RETURN_VALUES));
查询: 我们如何使用上面的 docker-compose(作为 docker 容器中的两个服务)和 jgroups.xml 进行部署,以便两个 webapps 中的每个 webapps 中的 Infinispan 缓存加入并形成一个集群 - 这样两个应用程序就可以访问彼此读取的相同数据/写入缓存。现在它们连接到相同的通道名称,并且每个都成为一个具有一个成员的集群,即使我们将 jgroups 指向 external_addr。
到目前为止尝试过:
- 延迟第二个服务的启动,以便第一个有足够的时间来做广告。
- JGroups - 在 Docker 中运行 JGroups 可以使用 docker compose 将 belaban/jgroups 容器部署为堆栈中的两个服务,并且它们能够形成一个集群(容器内的 chat.sh 显示 2 个成员视图)。
- 尝试过 --net=host 可行但不可行。在 jgroups.xml 中尝试了 external_addr=docker.host.ip,这是理想的解决方案,但它不起作用(上面的日志来自于此)。
谢谢!如果需要,将尝试提供任何具体信息。
【问题讨论】:
标签: docker cluster-computing docker-swarm infinispan jgroups