Mcrypt响应慢的一个缘由

上午的时候, 有同事来找我说上周新上线的一个使用mcrypt的脚本, 响应很是慢, 可是服务器的各项指标都正常, 不知道是什么缘由.php

通过了解, 一个简单的可重现的脚本以下:html

 
 
 

  
  
  
  

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

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

考虑到这个问题可能具备必定的广泛性, 因而我想我仍是写一篇文章来介绍下这个坑, 防止后来人再次踩到.bash

PHP的Mcrypt扩展的mcrypt_create_iv, 若是你不指定的话, 默认使用/dev/random(Linux上), 做为随机数产生器. (也许有的同窗已经知道缘由了, 呵呵, 那就能够略过了)服务器

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

 
 
 

  
  
  
  

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

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

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

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

 
 
 

  
  
  
  

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

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

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:

相关文章
相关标签/搜索