[原]关于高并发下限流用户访问

    在高并发大流量下总是有一些意想不到或者考虑不周全的事情发生。而一个网站首先是保证能够提供服务,哪怕分流或者降低速度(不得已情况下)。这就需要有一套限流的方案,在不得已的情况下启用,防止服务器停止服务。就好比小米商城抢小米时候的排队,其实就是类似的。这里我们向讨论一些简单的方案思路。

   方案1:

    直接按照用户访问数量的百分比进行限制。比如要举行大的促销。预计并发访问量是 15W,集群服务器平均打到每台机器上的并发访问量是 500,而单台机器的最大承受并发400,这时候只要限制20%的流量就可以了。(这些数据都是粗糙的举例,不要较真啊。)

    但是这种方案明显有一个弊端就是你判断不出来,当前的访问量是否需要启用限流,以为这样的限流都是针对某次大规模请求,有预估,促销之前,代码启用,促销之后,流量下降,代码就要下线。很是麻烦和不好评估统计。

   方案2:

    首先我们可以确定,一台机器的承受能力一般是固定的,可以测试出来的。如果我们能涉及一种计数机制,当QPS达到机器极限的时候限制,就可可以了。

    另外设计这种计数机制不能同步进行,也就是不能加锁,因为同步计数的话,会导致另外的进程等待。。这明显不符合初衷。比如说,我试过用memcache计数,但是很明显,链接memcache然后计数是一个同步过程,最后计数倒是一个都不差,但是很慢。但是不加锁并发惊醒的话就会导致有误差,也就是说多个进程取到同一个值,这个其实我们可以在测试过程中获得一个这种情况出现的概率。然后只要概率在接收范围之内就可以了。所以宗上,PHP的无锁共享内存就是一个可以考虑的方式。

    这里先说一下结果。

    在我自己的机器上,PHP5.4+nginx 四核 i5 nginx进程数4 模拟并发请求 200 限制用户数 100,超过计数的用户会跳转到一个等待页面。

    在这种情况下,实际数据是 进入的用户回进入 100-110左右。也就是说 会上浮 5%-10% (不过我觉得线上服务器CPU多达20多个核心,进程数也多很多,所以误差可能会更大一些

    下面看说一下实现方式:

    在共享内存当中存两个字段,一个字段用来计数,另一个字段用来计时,每一秒中,计数器从0开始重新计,如果超过预设值,就 跳出,否则进入。

    注意:PHP共享内存有两种方式,一种是 shmop系列,还有一种是 shm_attach 系列,这两种都可以完成共享内存的操作,具体区别。。请自行补脑。。我这里使用的是 shmop。 Continue reading

Code Server | wwpeng | | (0) |