最近接触到关于海外图片服务器国内访问提速的操作,记录一下我的过程吧,其中涉及到了nginx代理
、nginx重定向
、cloudflare的CDN服务
、DNS轮询
。
众所周知,pixiv是一个不存在(被墙)的插画网站,属于日本的一家公司。现在想从国内直接访问pixiv的图片,所以有了以下的操作。
Nginx - 代理
pixiv的图片服务器域名是i.pximg.net
,但图片服务器做了防盗链措施,根据header里的Referer值判断是否合法,只有从pixiv相关的网站发出的请求才能被接受。
利用pixiv的代理可以解决这个问题,具体配置看这里:Nginx代理pixiv图片服务器配置,Nginx开启缓存后能加快访问过的资源的速度。
服务器选择国内带宽较大,且延迟较低的。最合适的应该就是阿里云或腾讯云香港地区的轻量应用服务器
了,最低配置一个月24元,包含30M带宽峰值和1T流量,国内到香港的延迟一般都不会太高。
架构图如下:
瓶颈
此时服务器瓶颈有三个:
Nginx服务器连接到pixiv服务器的速度
我用的是香港节点的服务器,pixiv服务器应该是存放在日本的。尝试在Nginx服务器上通过wget
命令下载pixiv图片,非高峰期基本不超过5MB/s,一到晚上则慢得可怜,仅30多KB/s。ping到pixiv服务器的延迟大概54 ms。
wget https://i.pximg.net/img-original/img/2019/07/29/01/04/24/75962623_p0.jpg --header="Referer: https://www.pixiv.net/"
Nginx服务器的带宽
毕竟服务器只有30M带宽峰值,图片往往较大,一张原图往往有好几M大小,例如上面wget下载的原图大小为4.5M。若用户一多,达到了峰值后图片的加载会变慢。
用户到服务器的线路问题
腾讯云的轻量应用服务器,测了下对于电信运营商的网络比较友好,但到了晚上高峰期服务器的网络就会变差,即便是电信网也可能会扑街。
突破点
上述提到的三个瓶颈,第一点和第二点都找到了解决的方案。至于第三点,可能要更换线路更好的服务器了,成本较高。目前pixiv小程序还处于用爱发电状态,只能尽量节省成本,所以重点解决前两点吧~
cloudflare - CDN服务
图片属于静态数据,很适合利用CDN服务来加速,国内的云厂商大多数都有CDN服务,能对国内的用户访问进行优化。
但看了下价格,最低的应该是腾讯云的0.21元/GB,目前小程序图片每天消耗大概70GB流量,算下来一天需要额外14元的支出,小程序一天的收入也才3元,妥妥的入不敷出鸭,于是放弃。
目前国际上最有名的免费CDN服务商就是cloudflare了,如果是国外的业务很适合使用这个,但听说国内访问的话反而成了“CDN减速”。但白嫖怪此时跃跃欲试。
接入cloudflare
前往官网cloudflare,将自己的域名托管在cloudflare,按照流程配置后,需要去域名商控制台,将DNS服务器设置为cloudflare提供的,并前往cloudflare添加解析,这样就完成了接入。
此时架构图为:
如果是以前的架构,图片加载速度与并发相关,若访问用户少,则加载快,若访问用户多,则加载慢,甚至可能无法加载图片。
如今则是无论用户多少都能够提供服务,因为请求的目标是cloudflare,仅在CDN节点上没缓存的时候才会回源,带宽峰值没了限制,但缺点也是稳定的慢,毕竟cloudflare的CDN在国内是没有节点的。
给CDN前再套一层
搭好了cloudflare的CDN后,突发奇想,既然我最开始的方案Nginx代理pixiv服务器比较慢,那是不是可以代理cloudflare的CDN呢?
于是尝试用Nginx服务器执行命令:wget cloudflare域名/图片uri
,wow发现居然速度可以飙到18MB/s。
注1:代理cloudflare相比代理pixiv还需要加个proxy_ssl_server_name on;
的配置,否则会报502之类的错误。
注2:还需要加proxy_ignore_headers Set-Cookie Cache-Control;
,否则nginx不会缓存。
于是架构进阶为:
这里的Nginx服务器是同一台,只不过配置了两个不同的域名,域名A对用户开放,域名B是托管在cloudflard有CDN的域名。
实际上这幅图和最开始的架构很像,域名A后面的所有部分都可以当成一个整体,也就说只要访问过一次某张图片,下次再访问这张服务器因为缓存所以能直接从cloudflare取到了。相比之下直接代理pixiv服务器速度不超过5MB/s,而现在这种架构代理能跑到18MB/s。
DNS轮询或Nginx重定向
原本接入cloudflare的CDN是为了解决Nginx服务器的带宽瓶颈,但现在的套娃操作却成了解决Nginx服务器连接到pixiv服务器的速度的问题。
所以现在的瓶颈还在与Nginx服务器30M带宽上。但轻量应用服务器最高带宽也就30M无法升级配置,所以大概只能加机器了。
DNS轮询
最低所需资源:域名2个,服务器2个。
这种办法可以很容易扩展图片服务器,只需要将Nginx配置文件拷贝到另一台,再分别到A、B域名服务商添加新服务器的解析即可。
也就是A解析记录为2个服务器ip,B的解析记录也是为2个服务器的ip。
架构图为:
但这种方式存在缺点,因为DNS解析也是有缓存的,倘若其中一个服务器挂了,则需要将解析删去。但由于缓存的原因,域名的解析在删掉后的一段时间内还是会解析到不可用的服务器ip去。
Nginx重定向
最低所需资源:域名4个,服务器3个。
重定向的话除了需要新增一个图片服务器,还需要一个服务器单独做Nginx重定向。用Nginx重定向的方法扩容或者删减都很方便,即时生效。
架构图为:
服务器A配置大概如下,先内部做负载均衡再重定向,重定向需要用302(临时重定向)而不是301(永久重定向):
# 负载均衡,用uri_hash策略能提高缓存命中率
# 负载均衡到内部端口,再由端口重定向域名
upstream pixivs {
hash $request_uri;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
# 对外域名
server {
listen 80;
server_name 域名A;
location / {
proxy_pass http://pixivs;
}
}
# 重定向到域名B
server {
listen 8082;
server_name localhost;
location / {
rewrite ^/(.*) https://域名B/$1 redirect;
}
}
# 重定向到域名C
server {
listen 8081;
server_name localhost;
location / {
rewrite ^/(.*) https://域名C/$1 redirect;
}
}
关于服务器D,如果有条件可以买台日本地域的服务器,回源pixiv服务器速度较快。若无条件可以搭建在B或者C上。毕竟仅在未访问过的情况下才会到这一步。
缺点就是这个Nginx重定向服务器可能会成为新的瓶颈(如果到那时可以用DNS轮询 + Nginx重定向),并且客户端请求的话,需要请求两次才能拿到图片,一次是访问Nginx重定向服务器,一次是去真正的服务器取图片。
最后
Nginx重定向的方式会比较好控制,随时都可以进行增减,并且可以根据策略负载均衡。DNS配置起来相对简单,成本也低一些。如果有条件的话优先考虑Nginx重定向的方式,毕竟DNS生效时间非常不可控。
我尝试用了DNS轮询的方式,后来撤掉了一个服务器,一天之后还有部分请求会进入到撤走的服务器里,并且DNS轮询的方式并不能将流量完全均匀分配在两台服务器,因为客户端访问DNS解析过一次域名后就会缓存,所以对于用户来说只进一台服务器。
鉴于上述,我换成了Nginx重定向的方案,好处是即时生效。对于静态文件服务器,缓存十分重要,我们可以配合nginx的uri_hash负载均衡策略,让A图片去A服务器,B图片去B服务器。若是DNS轮询的方式则A图片会从两台服务器随机获取,降低了缓存命中率。
2020-09-28日更新
前前后后折腾了一周多,结果一到晚上服务器炸的真是离谱。这种配置白天图片加载速度能起飞,一到晚上还不如直连Cloudflare。
另外到了晚上,回源pixiv图片服务器也是慢的可怜,竟然不超过100KB/s,白天好歹还能上5MB/s。轻量服务器毕竟便宜,基本上只能靠超售赚钱了。
我放弃了,大概只有钞能力才能解决服务器线路的问题了。。。
2020-10-24日更新
最终的方案是让用户直连cloudflare,但做了CNAME接入,自选ip选了个香港地区的IP,ping的延迟大概是160ms,还算是能接受吧。至少这样即便再多用户也不用担心卡(虽然用户少的时候也不会变快)。
本文由 visionki 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Mar 17, 2021 at 03:56 pm