VPN服务器多进程负载均衡方案

应boj大大的要求,将此次负载均衡的技术细节记录下来。本文供维护人员参考,请大家多多拍砖。

由于OpenVPN在处理数据包的校验、加解密、封装时都需要大量CPU资源,OpenVPN不支持多线程处理,导致服务器的CPU利用率率长期保持在30%以下(4核心服务器)。为了提升服务器CPU的利用率,增强数据处理能力、提升VPN总带宽,为服务器添加了4个独立的OpenVPN工作进程,使用ipvsadm做udp负载均衡。

1. 创建4个OpenVPN配置文件:/etc/openvpn/server-worker-{1..4}.conf(绑定10001~10004端口),并修改相应的路由表配置文件。

2. 启动4个工作线程
       service openvpn start server-worker-{1..4}

3. 设置ipvsadm超时参数:
       ipvsadm --set 0 0 35
三个参数代表:TCP sessions, TCP sessions after receiving a FIN packet, UDP packets 的超时时间;0表示不修改当前参数。

4. 绑定需要负载均衡的端口(以202.141.160.95:1194为例,其余类似):
       ipvsadm -A -u 202.141.160.95:1194 -s rr
其中 rr 表示采用轮询(Round Robin)策略。

5. 添加后端
       ipvsadm -a -u 202.141.160.95:1194 -r 202.141.160.95:10001 -m
类似的,可以添加端口号为10002~10004的后端。

其中 -m 表示采用地址伪装(masquerading)的方式访问后端。因为要保证从A网卡来的数据包仍然从A网卡返回,因此不能使用gatewaying和ipip的方式。(但masquerading效率相对较低)

到此,负载均衡已经部署完成。


经过观察,负载均衡的效果并不理想,依然存在某进程CPU占用率100%,而其他几个核心空闲的情况。以下是优化方式:

一、采用最小连接(Least-Connection)策略替换轮询(Round Robin)策略

由于用户可能随机断开连接,而轮询策略并不会感知这一因素,导致每个后端的连接数有一定差距。(注:使用ipvsadm -L命令可以查看分配到每个后端的连接数)

将连接策略改为Least-Connection:
       ipvsadm -E -u 202.141.160.95:1194 -s lc

P.S. 修改策略不会导致原有连接中断。

二、添加多个后端

由于每个用户的带宽使用情况并不一样,当有多个大流量用户被分配到同一个进程时,就会出现单线程CPU100%,其余空闲的情况。

假设有4个工作进程,160个用户,2个大流量用户,这两个大流量用户“撞车”的概率为:0.245。

假设有16个工作进程,其余条件不变,则撞车概率概率为 0.014。

为了减弱这类大流量用户“撞车”的影响,可以适当多添加一些工作进程。当前创建了16个工作进程,CPU利用率最高达到为83%(为什么不是100%呢?)。

以上

《VPN服务器多进程负载均衡方案》有1个想法

  1. Hi, 关于使用`-m`作为转发策略的理由,“要保证从A网卡来的数据包仍然从A网卡返回”这个理由是不是不准确?主要是因为service端口和real servers的端口不同才必须使用masquerading吧。另外,看ipvsadm手册里的描述(见”packet-forwarding-method”一节),对于本地地址,IPVS会默认使用local forwarding,貌似没用上masquerading,所以性能损失也相应会小?

    P.S. 文章思路很清晰,非常实用,感谢!

评论已关闭。