CDN加速小水管动态应用技巧

不得不说现在大陆和HK的云主机都是小水管模式,由于硬件的快速发展在这种小水管的情况下很难发挥出用户硬件资源的能力,当然可以加水管但费用很高,更多时候会浪费带宽;这个时候我们想到CDN加速,这种资源的好处就是可以把瞬间流量分担出去,让小水管可以应对更多的请求。但CDN在我们印象中都是加速静态资源,更新慢对于动态不怎好用,但办法总是用的接下来介绍一下如何用CDN加速动态应用。

需求

最近在做一个在线讨论的服务,由于涉及到比较多的内容如发送图片,附件和历史记录等,对于这样的动态信息展示的确不适合小水管;对于3Mb的小水管来说一张图片就可以把小水管给卡住了。。更不要说记录中有大量的图片和附件存在!接下来想到了CDN,经过一些时间的思考把发送消息和历史信息的资源都落地到CDN上,但这些消息都是动态如果每次变更去刷CDN那基本就没法用了!为了实现这些想到了一种新的思路并落地到group.beetlex.io

接下来就把这思路介绍给大家。

CDN配置

现有的云服务商都提供CDN服务,费用也不高对于500G的年包也就一百块不到。CDN配置很简单,以下以百度为例(虽然百度搜索很烂,但这个CDN服务还是挺稳的)。在CDN中添加你的域名

里面的CNAME就是你原域名的DNS指向值,添加完成后可以根据自己的需要制定访问控件,最好配置一下主要防止其他网站直接利用网站的资源来进行流量输出。

使用

当有了CDN后第一步就可以把你的静态资源直接挂载的CDN中,主要是网站固定的HTML,CSS,JS和图片等。可以直接在页面中添加域引用的资源如:

<script src="http://group.tomap.me/js/comm.js"></script>

如果你的网站是HTTPS访问,则资源连接也必须是HTTPS。

动态数据使用

对于动态数据的应用则因为应用的情况不同来进行不同的设计,不过方式差别不大;以下是针对group.beetlex.io应用做的一些处理。在这个应用中主要有两类动态信息主要是实时发送消息和历史记录;实时消息并不需要走CDN但消息内图片和附件则无法由小水管来保障!还有每次进入房间获取历史聊天记录都有着比较高的瞬间流量,这种流量小水管也应付不来。

  • 消息图片和附件资源

由于group.beetlex.io以 Markdown 的方式进行消息输入,所以可以上传图片或附件进行一个消息展示。虽然可以把这些资源先存到云服务商中然后获取相关访问URL再输出,但这种设计的方式有着一定的依赖性,以后 相 关URL切换并不方便,最终还是选择存储到本地服务中; 但这种存储方式存在一个问题就是小水管输出比 较麻烦,既然有CDN只需要在 Markdown 输出的时候更换一下URL地址即可; 更换代码如下:

msg.Message = msg.Message.replace(/<img.*?src="(.*?)">/gi, (data) => {

var regex = /<img.*?src="(.*?)"/;

var src = regex.exec(data.toString())[1];

if (src[0] == '/')

src = 'http://group.tomap.me' + src;

var html = '';

if (insert == true) {

if (src.indexOf('faces') >= 0) {

html = '<img src="/images/imgloading.gif" _src="' + src + '">'

}

else {

html = '<img src="/images/imgloading.gif" _src="' + src + '" onclick="page.imgViewSrc=\'' + src + '\'">'

}

}

else {

if (src.indexOf('faces') >= 0) {

html = '<img src="' + src + '">'

}

else {

html = '<img src="' + src + '" onclick="page.imgViewSrc=\'' + src + '\'">'

}

}

return html

});

只需要简单地匹配一下相关图片标签替换即可,如果是站外图片则不代替;对于下载的文件的连接也可以使         用这种处理方式。这样这些图片的展示和文件下载都由CDN来输出处理。

  • 历史记录

在group.beetlex.io中每个用户进讨论组都要重新拉取历史记录信息,如果消息量太大的情况一个就把小水管

的小水管拉完了。为了解决这一问题也使用了CDN来加载历史记录,但房间的历史记录是经常变的如果变更 后自动去 刷新 CDN可能很难达到有效性。 为了解决这一问题采用了URL重写机制来解决这一问题,原 理很简当讨论组每次有消息的时候都变更讨论组的版本号,然后在进这个讨论组时都访问这样一个版本的URL 来处理,重写代码如下:

"/rooms/{room}-{version}.html" => "/GetRoomHistory?room={room}"

这样每次获取讨论历史信息的时候都访问一个房间ID+版本的静态页面,而后台则根据这个URL重写到获取信 息的控制器上,这样只要信息有变更每次加载新的都能从CDN中获取。 不过这种做法就是当第一个访问的用 户大概延时 1秒左右 这延时完全可以接受,但后面访问的速度就快多了; 通过这样做法即使 小水管也能支撑 很多历史记录加载而不影响服务效率。 以下是调用的代码

this.enterRoom.asyncget({ room: id, password: password })

.then((result) => {

var url = 'http://group.tomap.me/rooms/' + id + '-' + result + '.html';

this.getRoomHistory.loading = true;

axios.get(url).then((r) => {

r.data.forEach(v => { this.addMessage(v, true); });

this.imgs = null;

setTimeout(this.loadImg, 1000);

this.hasNewMessage = true;

this.getRoomHistory.loading = false;

}).catch((error) => {

this.$errorMsg(error);

this.getRoomHistory.loading = false;

});

rooms_password[id] = password;

}).catch((err) => {

this.selectItem = {};

rooms_password[id] = null;

});

技巧总结

其实动态数据使用CDN也是比较简单事情,主要利用更改请求的URL或重写来把静态资源切换到动态数据接口上;为了让CDN更快速地获取到新数据,通过数据变更的版本号来定位到新的URL来让CDN加载新的数据。通过这种方式就可以把很多动态接口做成CDN静态化。

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章