技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> PHP --> Mcrypt响应慢的一个原因

Mcrypt响应慢的一个原因

浏览:4374次  出处信息

       经过了解, 一个简单的可重现的脚本如下:

<?php
$dmcryptText = "dummy";
$key = "foobar";
$size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);

$iv = mcrypt_create_iv($size);  //注意这里

$m = mcrypt_ecb(MCRYPT_BLOWFISH, $key, $dmcryptText, MCRYPT_DECRYPT, $iv);
var_dump($m);

        当20个并发请求这个脚本的时候, 我们会发现Apache的响应时间急剧上升…

        考虑到这个问题可能具有一定的普遍性, 于是我想我还是写一篇文章来介绍下这个坑, 防止后来人再次踩到.

        PHP的Mcrypt扩展的mcrypt_create_iv, 如果你不指定的话, 默认使用/dev/random(Linux上), 作为随机数产生器.  (也许有的同学已经知道原因了, 呵呵, 那就可以略过了)

        这里的问题就在于/dev/random,  它的random pool依赖于系统的中断来产生.  当系统的中断数不足, 不够产生足够的随机数, 那么尝试读取的进程就会等待, 也就是会hang住, 来看一个简单的例子:

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

        当你的机器不够繁忙的时候, 你会发现, 输出的速度很慢, 偶尔还有停顿…

        问题就出在了这里,  当你20个并发请求的时候,  服务器的中断数不够, 产生不了足够的随机数给mcrypt, 继而导致PHP进程等待,  从而表现出,  响应时间变长

        解决的办法就是, 改用/dev/urandom,  /dev/urandom也是一个产生随机数的设备,  但是它不依赖于系统中断.

<?php
$dmcryptText = "dummy";
$key = "foobar";
$size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);

$iv = mcrypt_create_iv($size, MCRYPT_DEV_URANDOM);  //注意这里

$m = mcrypt_ecb(MCRYPT_BLOWFISH, $key, $dmcryptText, MCRYPT_DECRYPT, $iv);
var_dump($m);

        修改后测试,  问题解决,  一切正常….

        然而, 为什么PHP使用/dev/random作为默认,  这是因为理论上来说,   /dev/urandom在一定的情况下, 是会被可预测的, 所以大家一般认为, /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

建议继续学习:

  1. 可恶,被 PHP-Mcrypt 的官方 Example 误导了    (阅读:1545)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1