特别申明!
本文仅讨论openvpn的隧道转发。一般适用于lan联机加速,异地内网办公用途。不涉及任何其它功能。
起因
最新在和朋友开黑玩raft,星露谷,overcooked等游戏。因为国内运营商大量采用nat技术(特别是移动)。导致p2p联机即便地理位置十分相近,也会十分卡顿,延迟极高,丢包极高。很多情况甚至无法加入房间。
之前有篇文章介绍采用UsbEAm_LAN_Party来进行组建lan。即可通过局域网联机。即便通过steam api进行联机中继,大部分游戏也会切换到lan联机。
所以通过组建lan,对大部分p2p游戏加速效果非常棒!(该功能也可用于异地内网办公,本质上模拟所有设备处于一个虚拟局域网,lan内网有的功能都有)
深度研究
通过openvpn,组建一个虚拟的lan非常容易。有需要可看另一篇博文一键部署lan
但我就想研究的深入一点,之前的lan部署,只能有一台服务器。假设现在需要和香港,澳门的小伙伴联机。那么单一的服务器,很可能因为跨国线路的不同,导致小伙伴完全难以连上该服务器,延迟丢包都会很高。
此时,我就在想,是否可以部署多台服务器。一台在国内,用于国内用户。一台在香港,用于跨国联机。两台服务器之间走GIA专线,并处于相互衔接lan。
实操解决方案
两台以上的服务器组建共享的lan,难度比一台大很多。好在我解决了。思路如下:
服务器A:位于国内杭州,所有连接他的用户,分配内网10.251.0.0/16 10.250.0.0/16
服务器B:位于香港,所有连接他的用户,分配内网10.249.0.0/16 10.248.0.0/16
服务器B通过配置openvpn,作为客户端,连接服务器A。获得内网地址 10.251.0.2 两个服务器都必须启用IP转发。
设置服务器A的出站路由:
出站:10.249.0.0/16 10.248.0.0/16 路由至 10.251.0.2
设置服务器B的出站路由:
出站:10.251.0.0/16 10.250.0.0/16 路由至10.251.0.1(也就是服务器A的内网地址)
中间配置非常麻烦,需要逐个分析,linux有几个常用命令:
route 查看当前路由表
ip a 查看当前所有网络接口
netstat -an 查看当前网络连接
同时不要忘记在服务器A和B作为服务器的配置中,push 路由表给用户。
至此无论你连接服务器A还是服务器B,都能处于同一个大的10.0.0.0/8 下面。双方可以随便ping通,且假如用户端采用tun模式,甚至可以在网络第二层,也就是链路层进行更多的操作。这里不再深入
杂谈
假设我们把问题更加复杂一点,我想有几百台服务器,组建一个超大的内网。要怎么做?该怎么架构?
上面的解决方案仅仅是服务器B作为客户端和服务器A通讯,如果有服务器C,D,E等等。那么这些服务器之间又要如何?
本质上也就两种情况。
情况1:把某个服务器作为主服务器,其他都作为从服务器。所有从服务器只和主服务器沟通。由主服务器来进行从服务器的之间的转发。
很容易看出,这样做虽然配置起来简单,但主服务器一挂,大家都得拜拜。而且从服务器之间不能互相沟通,必须由主服务器转发,大大降低了网络资源的利用率,并且集群的网络瓶颈为主服务器的最大吞吐量。甚至还会出现绕远路的情况。所有有了下面这个情况。
情况2:所有服务器之间,两两互通,通过不断维护路由表,实现一个超大的复杂的网状集群。
这其实也有问题,每个服务器都要同时和所有其他服务器保持通讯。当服务器量级增长,这部分资源也会白白消耗。而且该情况配置十分麻烦,每个服务器的路由表完全不同,都需要维护。(当然,可以通过写脚本来自动化)
两种情况各有优缺,在真实场景中,应该是两个并用。在某个地域一台为主服务器,下面配一些从服务器。世界范围内跨地域由主服务器来沟通,并逐级向下。上层的从服务器,在下层为主服务器。依次嵌套。
我也没做过如此庞大集群,我猜测我的思路应该非常原始,但核心思路八九不离十。真实情况应该比这复杂很多很多。
话又说回来,对于我们游戏开发者,一般情况是按国家分服。即便是超高并发redis,也都是在机房里的内网沟通。。可能有一些数据需要跨国家通讯。。但大多数情况,应该是用不到的。但从cloudflare tunnel等等技术来看,这种思路是的确有人用的。
改天再起一问,讨论一下游戏中超高并发redis的种种情况。