Mcrypt響應慢的乙個原因

2021-06-16 23:14:56 字數 1622 閱讀 8787

上午的時候, 有同事來找我說上週新上線的乙個使用mcrypt的指令碼, 響應非常慢, 但是伺服器的各項指標都正常, 不知道是什麼原因.

經過了解, 乙個簡單的可重現的指令碼如下:

<?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);

修改後測試, 問題解決, 一切正常….

weibo上sae的同學 @胥昕ops提供了乙個不需要修改php**的解決方案:

胥昕ops: sae 二三月份遇到的這個問題,一條命令秒殺此問題,

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

用urandom的結果填充entropy池子,這樣既保證了entropy池的數量,也保證了隨機性

然而, 為什麼php使用/dev/random作為預設, 這是因為理論上來說, /dev/urandom在一定的情況下, 可能會被可**(參看: /dev/random), 所以一般上認為, /dev/urandom不如/dev/random安全.

PHP Mcrypt響應慢的原因解決備註

上午的時候,有同事來找我說上週新上線的乙個使用mcrypt的指令碼,響應非常慢,但是伺服器的各項指標都正常,不知道是什麼原因.經過了解,乙個簡單的可重現的指令碼如下 當20個併發請求這個指令碼的時候,我們會發現apache的響應時間急劇上公升 考慮到這個問題可能具有一定的普遍性,於是我想我還是寫一篇...

php Mcrypt響應慢的原因解決備註

上午的時候,有同事來找我說上週新上線的乙個使用mcrypt的指令碼,響應非常慢,但是伺服器的各項指標都正常,不知道是什麼原因.經過了解,乙個簡單的可重現的指令碼如下 當20個併發請求這個指令碼的時候,我們會發現apache的響應時間急劇上公升 考慮到這個問題可能具有一定的普遍性,於是我想我還是寫一篇...

php Mcrypt響應慢的原因解決備註

上午的時候,有同事來找我說上週新上線的乙個使用mcrypt的指令碼,響應非常慢,但是伺服器的各項指標都正常,不知道是什麼原因.經過了解,乙個簡單的可重現的指令碼如下 當20個併發請求這個指令碼的時候,我們會發現apache的響應時間急劇上公升 考慮到這個問題可能具有一定的普遍性,於是我想我還是寫一篇...