因为代理服务商的有些线路偶尔会出现连接不稳定的情况,而且一般都会有多条线路供用户选择,所以就选用 Haproxy 作为负载均衡器。

安装Haproxy

yay -S haproxy

修改配置

global
    log     /dev/log local0 info
    user    haproxy
    pidfile /run/haproxy.pid
    daemon

defaults
    mode tcp 

    log global
    option tcplog
    log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"

    option redispatch
    retries 3

    timeout connect 5s
    timeout client 30s
    timeout client-fin 30s
    timeout server 30s
    timeout tunnel  1h

frontend stats
    mode http
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 10s
    stats admin if TRUE
    stats auth admin:admin

frontend  main
    bind	:13170
    default_backend	ss           

backend ss
    balance     roundrobin
    server  ss1 c1.com:13170 check
    server  ss2 c2.com:13170 check backup

默认使用 server1,当 server1 出现故障时,请求转发到 server2,可以设置多个 backup,提高可用性。

20230806 更新

默认的 Haproxy systemd unit 的依赖配置是下面这样:

After=network-online.target
Wants=network-online.target

正常来讲没有问题,需要网络连接准备就绪以后才开启 Haproxy,但是这个配置里面backend里面配置了域名,而且我用了 dnsmasq 作为dns解析器,上游又配置了 dnscrypt-proxy 作为dns解析加密,dnsmasq 是作为 NetworkManager 的一部分启动,也就是包含在了 network-online.target 里面了,但是 dnsmasq 还依赖了 dnscrypt-proxy,所有如果要能够(能够的含义为进程启动成功)解析域名,需要在这个服务启动以后再启动,修改 unit 里面的配置:

[Unit]
After=network-online.target dnscrypt-proxy.service
Wants=network-online.target dnscrypt-proxy.service
[Service]
RestartSec=2

RestartSec 默认值为 0.1s,但是由于 dnscrypt-proxy 启动需要几秒时间,即使配置了 After 参数,在 systemd 默认10s内重试5次的条件下,Haproxy 在启动后 0.5 秒就结束尝试,所以要配置为2秒。即 Haproxy 在 dnscrypt-proxy 启动后启动,并且启动失败2秒后再次尝试5次,直到成功。 Wants 和 Requires 的区别在于,Wants 的服务启动失败也不会影响对应服务的状态,而 Requires 的话,如果服务启动失败,则对应的服务一定失败,是强依赖关系。