月度归档:2018年01月

一次活动的防刷实践

前段时间公司做了个投票活动,前30名即可领取奖品。为防止刷票制定了以下规则。

  1. 用户3票/天,每票须投给不同的用户不得重复投票。
  2. 被投票用户每小时最高可获票数位100票/小时
  3. 每IP投票100票/小时
  4. 每fingerprint 投票100票/小时

规则的实现也很简单,我们采用Redis来存储用户投票的状态信息。
用户3票/天
采用set集合存储。如 user_id:9527 {1223,2334,2555}
校验时先判断set集合成员是否大于等于3,再验证是否已经存在投票的用户防止重复投票。

其余均采用key:value方式,默认值为0,自增到100。TTL按规定时间设置即可。

通过实践发现,前端生成的fingerprint重复率比较高(一个公司的都有重复)。取消了这条限制。

开启OPcache加速你的PHP应用

什么是OPcache?

Zend OPcache 通过 opcode 缓存和优化提供更快的php执行过程。它将预编译的脚本文件存储在共享内存中供以后使用,从而避免了从磁盘读取代码并进行编译的时间消耗。同时,它还应用了一些代码优化模式,使得代码执行更快。

为什么要用?

如下图php的执行的生命周期,第一部分是没有opcode缓存的情况。第二部分则是缓存了opcode的情况。

从图中我们可以清楚的看到,PHP开始执行请求->读文件->词法分析->语法分析->生成opcode->再由Zend引擎执行opcode返回执行结果。

聪明如你肯定发现在php文件没有更改的情况下,每次都要经过词法分析、语法分析、生成opcode有点浪费。那在代码没有更改的时候能不能把要执行代码的opcode缓存起来用于下次使用呢?这样不就提高了速度么。

OPcache就是来管理opcode缓存的,如上图下半部分。

是共享内存么?

PHP官方文档:
PHP processes with opcode cache enabled use shared memory for opcode caching. Yet, PHP processes will be able to “share” that shared memory, only if they were all created (forked) from the same, original PHP process, that allocated that shared memory.

据笔者的实验,开启OPcache后php-fpm的主进程内存占用会增加,即是把生成的opcode放在主进程里了。

补充一条查看php进程内存使用命令:

  1. 查看php-fpm的进程个数
    ps -fe |grep “php-fpm”|grep “pool”|wc -l
  2. 查看单个进程内存占用大小
    ps -ylC php-fpm –sort:rss
    RSS 为内存大小,单位K

性能有多大提升?

笔者在Ubuntu php7.0下开启OPcache的情况下速度可以提升13%左右,目前用在测试环境中,还在观察。

如何配置?

官方文档讲的很清楚,这里不作赘述。
http://php.net/manual/zh/opcache.configuration.php#ini.opcache.max-wasted-percentage

如何发布?

  • 手动重置:
    如果validate_timestamps 选项设置很久的话,就需要手工重置opcode。PHP提供了两个方法:
    opcode_reset() 重置整个字节码缓存内容
    opcache_invalidate 废除指定文件opcode缓存
  • 自动更新:
    validate_timestamps 设置5秒的话,在代码更新好后等个5秒就好了。
  • 重启php-fpm,不太建议这么做。

相关工具

OPcache Status
https://github.com/rlerdorf/opcache-status
CacheTool – Manage cache in the CLI
https://github.com/gordalina/cachetool