大背景

说需求不讲背景就是耍流氓。 ———– by 一个被虐的码农

那么,背景是这样的,公司现有的测试业务情况如实交代:

  • 局域网自建mongo数据库,用于业务的测试环境数据(IP:192.168.2.100,电信公网IP 200.201.202.203,标记为服务器A)
  • 公网阿里云ECS(IP: 100.101.102.103,标记为服务器B),用于外网测试环境代码的运行,通过服务器A的公网IP来连接mongo数据库
  • 阿里云DNS配置A解析记录 dev.xxx.com 100.101.102.103
  • 在脱离公司的公网环境,需要能正常访问dev.xxx.com的服务

问题来了

运营人员抱怨各种测试服务反应很慢。噢?那么我们来研究下网络数据走向和对应的时间消耗咯

  • 运营人员使用测试服务->DNS解析dev.xxx.com->请求服务器B->通过服务器A的公网IP连接到mongo数据库->上传数据回服务器B->返回数据给和服务器A同一个公网出口的App(哇,这链条长的很开心)
  • 通过配置PHP fpm slowlog得知,发现实际上时间消耗都花在了mongo相关的连接上面了,为什么呢???

分析问题

我们用的电信家用宽带,100M下载带宽,上传也就那么4M,完全不能看啊,稍微查询一个大一点的数据集,传输时间够喝一壶了,而且这么4M带宽,还要服务于公司员工正常的上网需求,那么降低这里的上传带宽使用也是很有必要的。

选定方案

so,找到问题了,光说有什么用,得有解决方案啊

  • 把数据库也扔到外网去,那么对整个公司局域网来说,主要消耗只有对公网服务器B的请求下行数据,然而mongo对硬件消耗有点大,作为一个测试环境来讲,升级硬件配置或者再开一台服务器难免有点资源浪费,退而求其次,合理利用局域网服务器做mongo服务才是正路
  • 服务器A硬件配置是强于ECS好多倍的,不要浪费了,那么就在服务器A上面搞事吧
  • 通过分析上面的请求路径,那么我们可以把服务器A的公网上传拦截掉,怎么拦截呢?从DNS上面动手,于是请求路径会变成:APP->解析dev.xxx.com->请求服务器A(192.168.2.100)->服务器A的程序请求localhost的数据库->返回数据给程序->返回给同一个局域网的运营测试人员
  • 这样一来,速度提升的有点可怕,运营人员再也不腰痛了

解决问题

既然有初步方案了,那么怎么解决?

  • 那么需要使用“提速”的运营人员,可以通过配置HOST来实现 dev.xxx.com 解析成 192.168.2.100,如果只有PC平台的产品,倒也不失为一种选择
  • 移动设备怎么办?Android不root,iOS不root没法玩啊,除非这些测试机器允许以某种方式“模拟配置host”,比如Android读取sd卡某个文件,若定义了解析数据,则以解析结果为准,需要预埋代码,改起来也麻烦,一点也不优雅
  • 移动设备实在没办法改呢?那我配置代理咯,代理设备请求到能改HOST的PC设备,也是麻烦
  • 既然这么蛋疼,那我配置一个DNS服务器好了,一番搜索之后,unbound这个软件上场了,配置一个DNS服务器,使用标准端口53,将局域网所有需要”提速“的设备首选DNS改成192.168.2.100即可
  • 本着优化应该对使用者透明的原则,把上面这个配置DNS的步骤也省了,直接用DHCP服务器返回192.168.2.100作为首选DNS

断一下网,重新连接,刷新页面,一切只如初见,那么美好~

题外话

有人说,为了性价比,透明解决问题,为何不把所有服务都放在局域网的服务器A上面,连买ECS的钱都省了。。。

骚年,你还是太年轻

  • 电信运营商怎能允许家用宽带用来做服务器提供服务这种行为,那么谁购买他高贵的企业专线带宽呢?于是我们家用宽带的80端口、8080端口默认都是被封了。
  • 就算运营商不搞事,国家要求所有IDC必须只对有域名备案信息的域名才能提供正常的服务,就算配置了解析,在访问到具体的IP的时候,也是一样不能正常访问你的业务,从这个角度来讲,电信运营商封锁这两个端口也算是为了规避备案问题。
  • 改端口也不是不行,然而综合考虑,改端口方案导致各个业务都需要做额外的配置修改,还是买个ECS做外网测试业务简单粗暴

那么其实除了上面的DNS方案,还有没有其他方案?答案是有的,理论上通过配置路由表SNAT,把对服务器B(100.101.102.103)的流量请求转发到服务器A192.168.2.100,然而该方案似乎有点一刀切,不够灵活,还是留着DNS,需要这种访问链路优化的话,配置首选DNS服务器为192.168.2.100,不需要的时候或者想强行访问服务器B的逻辑,那么只需要配置其他公用DNS即可。

UPDATE 2017-09-05

由于在实际使用过程中(大概1个多月的持续时长),发现对于不甚了解原理的小伙伴来讲,有额外的理解成本,业务也准备上HTTPS访问,那么就又来搞事吧,于是改为下面的方式:

  • 仅保留局域网服务器A,全部使用Let’s Encrypt部署HTTPS访问(电信没封443端口),局域网访问可以使用HTTP或者HTTPS,而公网访问就只有HTTPS能通啦- -
  • unbound DNS配置依然保留
  • 路由表在另外一个服务器上面,暂时未变动