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

如何在多台服务器上扩展Selenoid集群?

问题描述

我有三台服务器,计划在其中两台部署Selenoid,从第三台服务器调用这个集群。目前我用以下代码随机指定服务器:

if randint(0, 1) == 1:
    host = "HOST_1"
else:
    host = "HOST_2"

请问在webdriver.Remote / Selenoid中,有没有更优的指定最优服务器的方案?

当前调用代码如下:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options as ChromeOptions
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from random import randint

def get_chrome():
    options = ChromeOptions()
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.add_argument('--headless')
    options.set_capability("browserName", "chrome")
    options.set_capability("browserVersion", "80.0_VNC")
    options.set_capability("selenoid:options", {
        "enableVNC": True,
        "enableVideo": True
    })
    if randint(0, 1) == 1:
        host = "HOST_1"
    else:
        host = "HOST_2"
    driver = webdriver.Remote(command_executor='http://{}:4444/wd/hub'.format(host), options=options)
    return driver

我当前的Selenoid基础设施配置(docker-compose):

version: '3'
services:
  selenoid:
    image: "aerokube/selenoid"
    network_mode: bridge
    restart: always
    shm_size: 2g
    ports:
      - "4444:4444"
    volumes:
      - "$PWD:/etc/selenoid/" # 假设当前目录包含browsers.json
      - "/var/run/docker.sock:/var/run/docker.sock"
    command: ["-limit", "12"]  # 限制并行会话总数为12
  selenoid-ui:
    image: "aerokube/selenoid-ui"
    network_mode: bridge
    restart: always
    links:
      - selenoid
    ports:
      - "8080:8080"
    command: ["--selenoid-uri", "http://selenoid:4444"]
最优方案推荐

1. 使用Selenoid自带集群负载均衡(推荐)

Selenoid原生支持集群模式,你可以在第三台服务器部署Selenoid Hub,让它作为统一入口管理两台Selenoid节点,自动实现负载均衡。

配置步骤:

  1. 在第三台服务器部署Selenoid Hub:
    创建与节点一致的browsers.json文件,然后用Docker启动Hub:

    version: '3'
    services:
      selenoid-hub:
        image: "aerokube/selenoid:latest"
        network_mode: bridge
        restart: always
        ports:
          - "4444:4444"
        volumes:
          - "$PWD:/etc/selenoid/"
        command: ["-hub", "-nodes", "http://HOST_1:4444,http://HOST_2:4444"]
    

    其中-nodes参数指定两台Selenoid节点的地址。

  2. 修改调用代码:
    无需再随机选择节点,直接将command_executor指向Hub地址即可:

    def get_chrome():
        # 保持原有options配置不变
        driver = webdriver.Remote(command_executor='http://HUB_HOST:4444/wd/hub', options=options)
        return driver
    

    Hub会自动根据节点的空闲会话数分配请求,比随机选择更高效合理。

2. 基于节点负载动态选择

如果不想部署Hub,可以通过Selenoid的状态API获取节点负载,主动选择空闲会话最多的节点。

实现思路:

  • 调用Selenoid节点的/status接口,获取当前已用会话数和总限制数
  • 计算每个节点的空闲会话数,选择空闲量最大的节点
  • 若节点不可用则自动跳过,最后 fallback 到随机选择

修改后的代码示例:

import requests
from selenium import webdriver
from selenium.webdriver.chrome.options import Options as ChromeOptions
from random import randint

def get_best_selenoid_host(hosts):
    best_host = None
    max_free = -1
    for host in hosts:
        try:
            resp = requests.get(f"http://{host}:4444/status", timeout=2)
            if resp.status_code == 200:
                status = resp.json()
                used = status.get("sessions", 0)
                total = status.get("limit", 12)
                free = total - used
                if free > max_free:
                    max_free = free
                    best_host = host
        except Exception:
            # 节点不可用时跳过
            continue
    return best_host or hosts[randint(0, len(hosts)-1)]

def get_chrome():
    options = ChromeOptions()
    # 保持原有options配置不变
    hosts = ["HOST_1", "HOST_2"]
    host = get_best_selenoid_host(hosts)
    driver = webdriver.Remote(command_executor=f'http://{host}:4444/wd/hub', options=options)
    return driver

3. 用Nginx反向代理做负载均衡

在第三台服务器部署Nginx,配置反向代理和负载均衡规则,将请求转发到两台Selenoid节点。

Nginx配置示例:

http {
    upstream selenoid_cluster {
        server HOST_1:4444;
        server HOST_2:4444;
        # 采用最少连接数策略,比默认轮询更优
        least_conn;
    }

    server {
        listen 4444;
        location / {
            proxy_pass http://selenoid_cluster;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

修改调用代码:

直接将command_executor指向Nginx服务器地址即可:

driver = webdriver.Remote(command_executor='http://NGINX_HOST:4444/wd/hub', options=options)

Nginx的least_conn策略会自动把请求分配到当前连接数最少的节点,实现智能负载均衡。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 06:31:03