You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCP环境Docker Swarm部署Selenium Grid节点数量波动故障

Docker Swarm下Selenium Grid在GCP环境节点丢失问题排查与解决

问题详情

同一Docker Compose配置的Selenium Grid,在Azure虚拟机的Docker Swarm环境可正常运行,但在GCP环境中出现以下异常:

  • 部署时所有节点能正常启动,但测试运行后节点数量持续减少,最终导致测试失败
  • 测试报错(会话丢失):
01:17:29.140 WARN [SeleniumSpanExporter$1.lambda$export$1] - Unable to execute request for an existing session: Unable to find session with ID: 438df7f8fbf108115a19cdee31d96494
Build info: version: '4.2.2', revision: '683ccb65d6'
System info: host: '8fb32b33e907', ip: '10.0.1.8', os.name: 'Linux', os.arch: 'amd64', os.version: '5.15.0-1031-gcp', java.version: '11.0.15'
Driver info: driver.version: unknown
01:17:29.140 WARN [SeleniumSpanExporter$1.lambda$export$1] - org.openqa.selenium.NoSuchSessionException: Unable to find session with ID: 438df7f8fbf108115a19cdee31d96494
Build info: version: '4.2.2', revision: '683ccb65d6'
System info: host: '8fb32b33e907', ip: '10.0.1.8', os.name: 'Linux', os.arch: 'amd64', os.version: '5.15.0-1031-gcp', java.version: '11.0.15'
Driver info: driver.version: unknown
        at org.openqa.selenium.grid.sessionmap.local.LocalSessionMap.get(LocalSessionMap.java:129)
        at org.openqa.selenium.grid.router.HandleSession.lambda$loadSessionId$4(HandleSession.java:159)
        at io.opentelemetry.context.Context.lambda$wrap$2(Context.java:224)
        at org.openqa.selenium.grid.router.HandleSession.execute(HandleSession.java:122)
        at org.openqa.selenium.remote.http.Route$PredicatedRoute.handle(Route.java:373)
        at org.openqa.selenium.remote.http.Route.execute(Route.java:68)
        at org.openqa.selenium.remote.http.Route$CombinedRoute.handle(Route.java:336)
        at org.openqa.selenium.remote.http.Route.execute(Route.java:68)
        at org.openqa.selenium.grid.router.Router.execute(Router.java:91)
        at org.openqa.selenium.grid.web.EnsureSpecCompliantResponseHeaders.lambda$apply$0(EnsureSpecCompliantResponseHeaders.java:34)
        at org.openqa.selenium.remote.http.Filter$1.execute(Filter.java:64)
        at org.openqa.selenium.remote.http.Route$CombinedRoute.handle(Route.java:336)
        at org.openqa.selenium.remote.http.Route.execute(Route.java:68)
        at org.openqa.selenium.remote.http.Route$CombinedRoute.handle(Route.java:336)
        at org.openqa.selenium.remote.http.Route.execute(Route.java:68)
        at org.openqa.selenium.remote.AddWebDriverSpecHeaders.lambda$apply$0(AddWebDriverSpecHeaders.java:35)
        at org.openqa.selenium.remote.ErrorFilter.lambda$apply$0(ErrorFilter.java:44)
        at org.openqa.selenium.remote.http.Filter$1.execute(Filter.java:64)
        at org.openqa.selenium.remote.ErrorFilter.lambda$apply$0(ErrorFilter.java:44)
        at org.openqa.selenium.remote.http.Filter$1.execute(Filter.java:64)
        at org.openqa.selenium.netty.server.SeleniumHandler.lambda$channelRead0$0(SeleniumHandler.java:44)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)
  • 节点日志报错(主机名解析失败):
java.net.UnknownHostException: selenium-hub: Name or service not known
        at java.base/java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
        at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:929)
        at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1519)
        at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:848)
        at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1509)
        at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1368)
        at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1302)
        at java.base/java.net.InetAddress.getByName(InetAddress.java:1252)
        at org.openqa.selenium.events.zeromq.UnboundZmqEventBus.isSubAddressIPv6(UnboundZmqEventBus.java:170)
        at org.openqa.selenium.events.zeromq.UnboundZmqEventBus.lambda$new$6(UnboundZmqEventBus.java:125)
        at dev.failsafe.Functions.lambda$toCtxSupplier$9(Functions.java:228)
        at dev.failsafe.Functions.lambda$get$0(Functions.java:46)
        at dev.failsafe.internal.RetryPolicyExecutor.lambda$apply$0(RetryPolicyExecutor.java:74)
        at dev.failsafe.SyncExecutionImpl.executeSync(SyncExecutionImpl.java:193)
        at dev.failsafe.FailsafeExecutor.call(FailsafeExecutor.java:376)
        at dev.failsafe.FailsafeExecutor.run(FailsafeExecutor.java:220)
        at org.openqa.selenium.events.zeromq.UnboundZmqEventBus.<init>(UnboundZmqEventBus.java:122)
        at org.openqa.selenium.events.zeromq.ZeroMqEventBus.create(ZeroMqEventBus.java:53)
        at org.openqa.selenium.events.zeromq.ZeroMqEventBus.create(ZeroMqEventBus.java:79)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.openqa.selenium.grid.config.ClassCreation.callCreateMethod(ClassCreation.java:50)
        at org.openqa.selenium.grid.config.MemoizedConfig.lambda$getClass$4(MemoizedConfig.java:100)
        at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1705)
        at org.openqa.selenium.grid.config.MemoizedConfig.getClass(MemoizedConfig.java:95)
        at org.openqa.selenium.grid.server.EventBusOptions.createBus(EventBusOptions.java:51)
        at org.openqa.selenium.grid.server.EventBusOptions.getEventBus(EventBusOptions.java:41)
        at org.openqa.selenium.grid.node.httpd.NodeServer.createHandlers(NodeServer.java:117)
        at org.openqa.selenium.grid.node.httpd.NodeServer.asServer(NodeServer.java:183)
        at org.openqa.selenium.grid.node.httpd.NodeServer.execute(NodeServer.java:231)
        at org.openqa.selenium.grid.TemplateGridCommand.lambda$configure$4(TemplateGridCommand.java:129)
        at org.openqa.selenium.grid.Main.launch(Main.java:83)
        at org.openqa.selenium.grid.Main.go(Main.java:57)
        at org.openqa.selenium.grid.Main.main(Main.java:42)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.openqa.selenium.grid.Bootstrap.runMain(Bootstrap.java:77)
        at org.openqa.selenium.grid.Bootstrap.main(Bootstrap.java:70)
12:03:53.760 WARN [UnboundZmqEventBus.lambda$new$3] - Connecting to tcp://selenium-hub:4442 and tcp://selenium-hub:4443 failed
12:04:03.520 WARN [UnboundZmqEventBus.lambda$new$4] - Failure #1. Retrying.
  • 已尝试操作:更新Docker镜像、修复DNS解析、重启Grid;节点重启后仅短暂在线,随后数量逐渐减少
  • 使用配置:Docker Compose文件基于官方Swarm示例,通过docker service scale -c docker_compose sel命令扩容节点

问题根源

核心原因是GCP环境中Selenium节点无法解析selenium-hub服务名,导致节点无法连接Hub的ZeroMQ事件总线(4442/4443端口),持续重试失败后被Swarm调度移除,进而引发测试会话丢失错误。Azure与GCP的Docker Swarm网络DNS解析策略存在差异,GCP默认配置对Swarm服务名的解析支持不足。

解决步骤

1. 强制指定Overlay网络的DNS别名

在Docker Compose文件中为selenium-hub服务添加明确的网络别名,确保节点能稳定解析:

services:
  selenium-hub:
    image: selenium/hub:4.2.2
    ports:
      - "4442:4442"
      - "4443:4443"
      - "4444:4444"
    networks:
      selenium-grid:
        aliases:
          - selenium-hub
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]

  chrome-node:
    image: selenium/node-chrome:4.2.2
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
    networks:
      - selenium-grid
    deploy:
      replicas: 5

networks:
  selenium-grid:
    driver: overlay
    attachable: true

2. 配置Docker Daemon的DNS解析

在GCP虚拟机上修改Docker daemon配置,添加内置DNS服务器:

  • 编辑/etc/docker/daemon.json(不存在则创建):
{
  "dns": ["127.0.0.11", "8.8.8.8"]
}
  • 重启Docker daemon:
systemctl restart docker

127.0.0.11是Docker内置DNS服务器,负责解析Swarm服务名;8.8.8.8作为备用公共DNS。

3. 检查GCP防火墙规则

确保VPC防火墙允许以下通信:

  • UDP端口4789(Overlay网络VXLAN通信)
  • TCP端口4442、4443、4444(Selenium Grid通信)
  • Swarm节点间的内部IP段通信

4. 调整Selenium节点超时配置

延长节点注册超时时间,避免因网络延迟被判定为失败:

chrome-node:
  environment:
    - SE_EVENT_BUS_HOST=selenium-hub
    - SE_EVENT_BUS_PUBLISH_PORT=4442
    - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
    - SE_NODE_REGISTER_TIMEOUT=300000  # 5分钟注册超时
    - SE_NODE_HEARTBEAT_INTERVAL=30000  # 30秒心跳间隔

5. 验证服务名解析

在任意节点容器内执行解析测试,确认服务名能正常解析:

docker exec -it <chrome-node-container-id> nslookup selenium-hub

内容的提问来源于stack exchange,提问作者user22965033

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:17:01