0

Mcrypt响应慢的一个原因

 2 years ago
source link: https://www.laruence.com/2012/09/24/2810.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Mcrypt响应慢的一个原因

上午的时候, 有同事来找我说上周新上线的一个使用mcrypt的脚本, 响应非常慢, 但是服务器的各项指标都正常, 不知道是什么原因.
经过了解, 一个简单的可重现的脚本如下:

  1. <?php
  2. $dmcryptText = "dummy";
  3. $key = "foobar";
  4. $size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);
  5. $iv = mcrypt_create_iv($size); //注意这里
  6. $m = mcrypt_ecb(MCRYPT_BLOWFISH, $key, $dmcryptText, MCRYPT_DECRYPT, $iv);
  7. var_dump($m);

当20个并发请求这个脚本的时候, 我们会发现Apache的响应时间急剧上升...
考虑到这个问题可能具有一定的普遍性, 于是我想我还是写一篇文章来介绍下这个坑, 防止后来人再次踩到.
PHP的Mcrypt扩展的mcrypt_create_iv, 如果你不指定的话, 默认使用/dev/random(Linux上), 作为随机数产生器. (也许有的同学已经知道原因了, 呵呵, 那就可以略过了)
这里的问题就在于/dev/random, 它的random pool依赖于系统的中断来产生. 当系统的中断数不足, 不够产生足够的随机数, 那么尝试读取的进程就会等待, 也就是会hang住, 来看一个简单的例子:

  1. $ dd if=/dev/random bs=1024k count=1

当你的机器不够繁忙的时候, 你会发现, 输出的速度很慢, 偶尔还有停顿...
问题就出在了这里, 当你20个并发请求的时候, 服务器的中断数不够, 产生不了足够的随机数给mcrypt, 继而导致PHP进程等待, 从而表现出, 响应时间变长
解决的办法就是, 改用/dev/urandom, /dev/urandom也是一个产生随机数的设备, 但是它不依赖于系统中断.

  1. <?php
  2. $dmcryptText = "dummy";
  3. $key = "foobar";
  4. $size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);
  5. $iv = mcrypt_create_iv($size, MCRYPT_DEV_URANDOM); //注意这里
  6. $m = mcrypt_ecb(MCRYPT_BLOWFISH, $key, $dmcryptText, MCRYPT_DECRYPT, $iv);
  7. var_dump($m);

修改后测试, 问题解决, 一切正常....
Weibo上SAE的同学 @胥昕ops提供了一个不需要修改PHP代码的解决方案:

胥昕ops: SAE 二三月份遇到的这个问题,一条命令秒杀此问题,

  1. $ rngd -r /dev/urandom -o /dev/random -t 1

用urandom的结果填充entropy池子,这样既保证了entropy池的数量,也保证了随机性

然而, 为什么PHP使用/dev/random作为默认, 这是因为理论上来说, /dev/urandom在一定的情况下, 可能会被可预测(参看: /dev/random), 所以一般上认为, /dev/urandom不如/dev/random安全.
后记, 大家看手册, 一定也要看手册下面的评论, 呵呵, 有很多东西在评论中, 是有提到的, 如下面这条评论, 来自mcrypt_create_iv:

If you use /dev/random you need a well filled entropy pool or the application will block until enough good entropy comes available


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK