专栏首页三言两语应对LeanCloud对于处理性能的限制

应对LeanCloud对于处理性能的限制

最近一直想如何才能统计资源分享页面里的资源的下载次数,由于是直接放的资源链接,即点击即可获取,所以没有所谓的拦截页面进行统计,同时作为静态博客也几乎没有带数据存储的动态扩展能力,这时想到了用LeanCloud来实现下载的计数,最后基本实现了这个想法,有兴趣的可以去资源分享里看看效果。

更广泛的应用场景

其实上面说的对下载次数进行统计实际上就是统计点击的计数,这就可以应用到更多的场景,比如给文章添加喜欢数、顶数、踩数等等,这是可以直接用的,处理逻辑都不变。 还有就是类似淘宝五颗星打分数的这种评分机制,也是可以稍作改变就可以。 总之,只要是由点击后触发数据更新的场景都可以用此来实现。

这里,对如何实现整个需求暂不细说,主要说一下遇到的主要问题。

LeanCloud查询处理的性能局限

QPS 因特网上,经常用每秒查询率来衡量域名系统服务器的机器的性能,其即为QPS。 对应fetches/sec,即每秒的响应请求数,也即是最大吞吐能力。 计算关系: QPS = 并发量 / 平均响应时间 并发量 = QPS * 平均响应时间

这里,LeanCloud对免费实例的QPS做了限制,可以理解,如果同时的查询发送的过多,则会使Lean返回错误代码,如下图所示:

错误码详解

429 信息 - Too many requests. 含义 - 超过应用的流控限制,即超过每个应用同一时刻最多可使用的工作线程数,或者说同一时刻最多可以同时处理的数据请求。通过 控制台 > 存储 > API 统计 > API 性能 > 总览 可以查看应用产生的请求统计数据,如平均工作线程、平均响应时间等。使用 LeanCloud 商用版或企业版 的用户,如有需要,可以联系我们来调整工作线程数。

原因分析

第一遍打开时需要循环发一遍查询来查询每个资源已有的下载数。

这里注意,为什么要循环每次发一次查询呢,因为在LeanCloud中创建的实例场景是广义的计数实例,即我只发一次查询然后处理返回结果,这种方式理论上是可行的,但是在实现上需要附加查询条件,还要考虑在库中的实例不一定只是一个地方的计数统计,总之较为复杂。

更简单的处理方式就是一一对应,一个计数实例(表中的一行记录)就是对应页面某处的一个计数器,只是在这里,由于分享下载的资源有点多,大概200元素,所以如果不加处理的发送查询请求,那几乎算是同时对LeanCloud发起这200次查询请求,由于其访问性能有限,所以需要对请求的发送做一定调整。

$(tar).each(function(index, item) {
    var url = $(this).attr("id");
    var texts = $(this).parent().find(sp).eq(cnt);
    var url = $(this).attr("id");
    query.equalTo("url", url);
    query.find({
    	success: function(results) {
    		if (results.length == 0) {
    			texts.text("0"); //初始是 0
    			return;
    		}
    		for (var i = 0; i < results.length; i++) {
    			var object = results[i];
    			texts.text(object.get('time'));
    		}
    	}
    });
});

我们主要关注QPS的变化,上图中较高的曲线是未经处理时发送查询请求的QPS曲线,这时由于并发的查询数过多,导致LeanCloud达到瞬时的负载上限而出现429错误。官方的错误代码解释为:

429 信息 - Too many requests. 含义 - 超过应用的流控限制,即超过每个应用同一时刻最多可使用的工作线程数,或者说同一时刻最多可以同时处理的数据请求。通过 控制台 > 存储 > API 统计 > API 性能 > 总览 可以查看应用产生的请求统计数据,如平均工作线程、平均响应时间等。使用 LeanCloud 商用版或企业版 的用户,如有需要,可以联系我们来调整工作线程数。

解决方法

解决此问题自然的会想到使用降低同时请求的查询数量,进而想到可以使用延迟执行来实现,这里可以使用setTimeout来针对循环内的每一次查询都进行延时操作。

这里又引出一个问题,那就是如何在each循环中进行延时操作

each循环中进行延时操作

JQuery中的循环each的工作原理,其并不是类似Java那样的顺序循环,即第一次循环代码的执行总是先于第二次循环中代码的执行,这里要特别注意,each中循环的的代码的执行理论上是同时进行的(异步执行),即没有严格的先后执行顺序,对于这一问题,可以统一归类为 JQuery异步执行的代码如何顺序执行 的问题。可以看看这篇文章,JQuery回调、递延对象总结,注意,使用then等对逻辑进行严格控制是正确的,但不是唯一的方法,如果你想完成的按顺序执行仅仅是时间上的先后而没有逻辑上的先后,那么还是用延时来实现比较容易理解。

$(tar).each(function(index, item) {
    send.leancloud.query(item); // 伪代码
});

上述执行后几乎是同时发送循环总数的查询请求,这样就容易导致429错误;

$(tar).each(function(index, item) {
    setTimeout(function(){ 
    	 send.leancloud.query(item); // 伪代码
    },1000);
});

上述延时的代码是经典的错误做法,误认为each是同步的顺序的循环,但其实不是,这样添加之后的效果是,全部查询同时在延时1000ms后发出,其结果还是几乎同时发向了LeanCloud。

$(tar).each(function(index, item) {
    setTimeout(function(){ 
    	 send.leancloud.query(item); // 伪代码	 
    },100*index);
});

上述为正确的写法,注意100*index,这是利用了其异步执行的特点来进行延时,每次循环后的查询请求还是跟之前叙述一样会几乎同时被执行,但是这里执行时的延时时间不一样了,这里变成了0,100,200...,即查询请求会在0ms,100ms,200ms...后被发送给LeanCloud,显然的,达到了控制QPS的要求。

上图是查询发送处理后的QPS曲线,可以看出其值下降了很多,但仍有时很尖锐,可以通过加大查询的发送间隙来降低,当然,图示状态已经可以正常查询且不触发429错误。

最终效果

对于时间间隔来说,要综合查询的数量考虑,但总体上不能过大,这样会在前端显示过慢而损失交互性。

其他

偶发的断线异常,非本地错误!:

0 信息 - (无) 含义 - WebSocket 正常关闭,可能发生在服务器重启,或本地网络异常的情况。SDK 会自动重连,无需人工干预。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 构建CUDA项目二周目翻车记录

    继上次的翻车之后,我算是有了些经验,同时机器上也装了些共通的依赖库,由于上项目最后的错误解决不了就放那里了,开始搞一下这个项目,这和上一个项目的目的是一样的,都...

    ZONGLYN
  • 快速建站“新玩具”—glitch.me

    今天在 YouTube 看了一个谷歌的开发视频,里面主讲者用 Glitch.me 做了代码的演示平台,所以自然地通过视频下方的演示链接,接触到了 Glitch,...

    ZONGLYN
  • 可视化布局算法的框架设计

    原项目是一个Web项目,采用传统的Servlet方式,后台主要完成的工作是计算节点的坐标,将节点的坐标封装成json格式由与前台进行交互。前期阶段,从前后台的数...

    ZONGLYN
  • [android] 实现返回键操作思路

    记录用户点击的操作历史,使用栈数据结构,频繁的操作栈顶(添加,获取,删除),使用LinkedList

    陶士涵
  • Godot3游戏引擎入门之五:上下左右移动动画(上)

    2018-10-10 by Liuqingwen | Tags: Godot | Hits

    IT自学不成才
  • tf.compat.v1.global_variables

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    于小勇
  • 自2015年起,大型电信运营商总计裁员10.7万人

    据Lightreading跟踪的20家主要电信运营商的过去两个财年里,超过10.7万个职位被裁减,相当于这些公司总职位的6%。

    SDNLAB
  • 初学Python语言者必须理解的下划线

    在大多数编程语言中,下划线是命名变量或者函数名称时的连字符,但是,在Python语言中,不仅如此。如果你是一名Python程序员,对于诸如 _ in range...

    老齐
  • MySQL数据延迟跳动的问题分析

    今天分析了另外一个关于数据库延迟跳动的问题,也算是比较典型,这个过程中也有一些分析问题的方法和技巧工参考。

    jeanron100
  • 【难度越大,优势越大】腾讯AI Lab刷新人脸识别与人脸检测国际记录

    编辑:闻菲 【新智元导读】日前,腾讯AI Lab在国际最大、最难的人脸检测平台WIDER FACE与热门人脸识别平台MegaFace多项评测指标获得第一,刷新了...

    新智元

扫码关注云+社区

领取腾讯云代金券