介绍我们的海外速度优化的实践,虽然都是琐碎的事情,但或许对大家会有所帮助。
另外,不要妄想海外线路的速度比肩国内。本文所述,也别对海外的速度太过于悲观。
格式好一点的原文:
http://ued.com.cn/post/tech/keep-the-speed-of-visiting-when-outside#content## 背景介绍
我们为什么把服务器放在国外?虽然这样做的人不少,原因也是明了的很。作为背景介绍,还是陈述几个理由。
- 我们对国外的市场,有欲望;没有打算放弃,服务器在外面,速度能够保证。
- 我们说的服务器,这里指的是类似Amazon的AWS或者Linode之类的;而这类服务,国内也有。在技术层面,让人没有安全感。
- 涉及到域名、网站的备案,这会严重影响产品本身的用户体验,甚至会扼杀。
我们选择的服务提供商是Amazon,然后,挑战就来了……
- - - - - - - - - - - - - -
## 选择线路
AWS上最便宜的区块自然是美国的本土,随便测试下ping值,一般是300+,500+也是正常的。距离中国大陆速度最快的是东京的节点,ping值在100左右,当然会有不算低的丢包率…… 据说Linode的日本节点要比Amazon的快一些。
而且,我们暂时没有考虑(在国内)使用第三方的CDN服务(除了图片资源这种速度硬伤会有所影响外,其它优化后,速度会很快);但我们又测试了下美国本土到日本的速度,并不是很理想,这方面会考虑CDN,用AWS自己的FrontCloud,而且能减少费用。呃,这个自然在国内用不了,对应的DNS被墙了。
对了,AWS日本节点上的费用,普遍比美国本土高出50%左右……
继续,我们要做到秒开!
- - - - - - - - - - - - - -
## Gzip & Cache
### 在S3上的处理
我们把Amazon的S3存储服务,直接用为静态资源WEB服务器。这个很简单,你只要在S3上创建的bucket名字用你计划启用的域名,
比如statics.yourdomain.com;然后在DNS中CNAME到<code>
s3-ap-northeast-1.amazonaws.com</code>即可。
但在上传到S3的时候,我们要对文件(css、js、html)进行GZIP压缩,并做Cache-Control。Cache-Control是文件被访问时候,可以同浏览器进行通讯,告诉浏览器自行缓存,就不会每次都去请求一次。
*css、js还可以在gzip之前通过yui compressor进行进一步压缩; 另外,css中使用的所有图片,压缩为一张图,用background-postion来做。*
代码片段如下:
def gzip_content(content):
zbuf = StringIO.StringIO()
zfile = GzipFile(mode='wb', compresslevel=6, fileobj=zbuf)
zfile.write(content)
zfile.close()
return zbuf.getvalue()
#- - - - 下面的是上传的代码片段 - - - - -
with open(file,'rb') as f:
content = f.read()
key = bucket.new_key(path)
content_type = guess_type(path)[0]
headers = {
'Cache-Control':'max-age=315360000’,#这里是设置缓存的
}
policy = 'public-read'
key.set_metadata('Content-Type', content_type)
# gzip压缩
if content_type in GZIP_CONTENT_TYPES:
content = gzip_content(content)
headers.update({'Content-Encoding': 'gzip'})
key.set_contents_from_string(content, headers=headers, policy=policy)
### 在APP(网站)上的处理
你也可以用上面代码片段中的思路,直接进行GZIP压缩;但还是建议在Nginx中进行处理,因为会更高效一点。
注意输出response的时候,有些非高度动态的页面,打上Cache-Control,就算30秒也好…… 这会一定程度减少你网站的请求数。
- - - - - - - - - - - - - -
## 数据库索引
不管如何,你必须要一定程度上了解数据库索引优化的知识。比如常用explain去看看,数据查询的效率,比如前匹配和后匹配的效率区别,比如索引端中要避免使用NULL值, .etc
如果你用django,则可以用debug-toolbar这类的第三方效率工具库。
如果使用NoSQL之类的,要建立必要的索引;比如mongodb中,如果使用正则查询的时候,只要什么时候索引是有效的,何种情况会直接产生接近死循环的loop。
如果有些数据任务因为花销比较大,如有必要驻后台跑的,就不要放在Web服务中嵌入!
尽自己所学,让所有WEB过来的请求,都是读、读、读;快速的读、快速的读、快速的读!避开所有可能的,程序内部的阻塞!
- - - - - - - - - - - - - -
其实经过上面几步之后,东京的节点上服务器上页面访问,到完全渲染成功,估计1秒多一些。
- - - - - - - - - - - - - -
## 但还不够!
我们要做DNS的优化。
你应该知道怎么去查看一个页面在渲染过程中各个时间的耗费,比如使用Chrome浏览器自带的开发者工具;或者使用
http://17ce.com http://alibench.com 这些在线的工具。
这里需要补充的是,我们使用的DNS服务是Amazon的Route53,我们发现,国内各个网络节点,平均的解析时间在400-500毫秒之间,这个速度成了瓶颈了。虽然DNS的记录本身会缓存,其实帮助并不大,别人仍会有这种感觉的,“访问有时滞”……
但我们不会因此就弃用Route53的,因为,它在海外的解析速度是有保证的;另外,它的费用真的是物美价廉……
而国内最好的DNS托管服务,无疑就是
http://dnspod.cn- - - - - - - - - - - - - -
## DNS优化
在优化DNS之前,先介绍下dig,通过命令行运行<code>dig
google.com +trace</code>, 这个会成为你自己本机、服务器上评价国内外DNS速度的重要参考依据。
我们的想法就是把DNSPOD和Route53合用…… 但如果只是简单地在域名设置的地方,把它们分别提供的DNS合在一起,是没有用的;当然,这第一步是你应该做的。
在这部分开始之前,我们有必要了解下DNS,首先,它是松散的、分布式的、端口在53。
DNS中有一项设定,叫SOA,简单的可以理解就是指定哪个解析服务是最优先的,格式如下, 中间是空格隔开。
> [authority-domain] [domain-of-zone-admin]
[zone-serial-number] [refresh-time] [retry-time]
[expire-time] [minimum TTL]
DNSPOD中没有SOA的设置,因为它已经默认设定好了,无法更改,所以,在Route53中,需要与它保持一致。
>
f1g1ns1.dnspod.net.
freednsadmin.dnspod.com. 1354421554 3600 180 1209600 180
并且在Route53中的NS记录上,把DNSPOD的服务地址补上。
等这些记录都生效之后,可以测一下DNS是否正常了。可以到这里测试,
http://www.intodns.com/另外非常重要的一点是,你在Route53和DNSPOD上的记录应该是完全一致的,包括TTL;另外,一般情况下,No Glue,这个可以不用考虑去优化。它的意思,比如
test.com 跑去
ns-88.awsdns-31.co.uk 解析,只会返回NS记录,而不是直接IP地址;因为 .com 和 .co.uk 的顶级解析,归属并不是一致的。
f1g1ns1.dnspod.net. ['119.167.195.11', '122.225.217.192', '180.153.10.150', '183.60.52.217'] [TTL=172800]
f1g1ns2.dnspod.net. ['112.90.143.29', '122.225.217.191', '180.153.10.151', '180.153.162.150'] [TTL=172800]
ns-2.awsdns-61.com. ['205.251.93.236'] [TTL=172800]
ns-6.awsdns-36.net. ['25.251.15.28'] [TTL=172800]
**
ns-94.awsdns-08.org. ['205.251.136.10'] (NO GLUE) [TTL=172800] **
**
ns-88.awsdns-31.co.uk. ['205.251.18.52'] (NO GLUE) [TTL=172800]**
- - - - - - - - - -
如此一来,一个页面从发起请求到最终渲染,国内各省市节点的时间平均值基本上控制在700ms左右;如果服务器在国内,其中的连接时间,也会被大幅降低。
**但如论如何,让服务在墙外,会有所受损,也会有所得,各自平衡;只是漂泊在外,别对速度抱太大的恐惧就好……**