【问题标题】:Infinispan's JGroups not joining the same cluster in Docker servicesInfinispan 的 JGroups 没有加入 Docker 服务中的同一个集群
【发布时间】: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


    【解决方案1】:

    显然external_addr="${ext-addr:docker.host.ip.address}" 无法解析(或解析为null),因此使用bind_addr127.0.0.1docker.host.ip.address 是您设置的吗(例如作为环境变量)?

    external_addr 属性应该指向一个有效的 IP 地址。

    【讨论】:

    • 我更正了日志(对不起,我想我没有添加 external_addr 就拿走了它们)。当 external_addr="10.xx.yy.zz" 被添加到 jgroups.xml 时(现在在上面的问题日志中更正了),即使这样也看到了问题。两个应用程序都显示他们加入了集群,其中一个视图成员具有逻辑地址 containerId-something 和物理地址 10.xx.yy.zz:7800(我相信 Docker 的内部路由应该解析到不同的容器)。
    • 还有一个更新——我今天用 infinispan-core-9.1.3.Final.jar/default-configs/default-jgroups-udp.xml (没有改变)和容器进行了测试能够形成一个集群(有 2 个视图成员)。尽管有这个解决方法,我们希望让它通过 TCP 工作以提高可靠性,而 default-jgroups-tcp.xml 仍然显示相同的问题。感谢您的回复,顺便说一句!
    • MPING 是负责初始发现的协议;你能仔细检查一下它的 bind_addr 是否设置正确吗?例如。除非两个进程在同一个物理盒子上运行,否则 127.0.0.1 将无法工作...
    • 这是我用来在同一个物理机上成功运行多个实例的 TCP 配置:
    • Docker swarm (尚)不支持 IP 多播,详见github.com/docker/libnetwork/issues/552。我建议使用支持多播的 docker 插件,例如 weave,或将传输/发现切换到(例如)TCP:TCPGOSSIP、TCP:TCPPING 或其他基于云的发现协议,例如 NATIVE_S3_PING、FILE_PING、GOOGLE_PING 等
    猜你喜欢
    • 2017-11-09
    • 2015-01-18
    • 2018-05-25
    • 2014-11-21
    • 2013-02-22
    • 2019-01-21
    • 2018-11-08
    • 1970-01-01
    • 2018-10-24
    相关资源
    最近更新 更多