memcached 非法key導(dǎo)致內(nèi)存溢出

昨天晚上服務(wù)器開始報(bào)警一個(gè)內(nèi)存泄漏的錯(cuò)誤,直接導(dǎo)致頁(yè)面出現(xiàn)500錯(cuò)誤侄非,所幸出現(xiàn)頁(yè)面的地址只有一個(gè)片拍,且此頁(yè)面有做ats健康緩存,所以用戶訪問的始終是正常頁(yè)面

錯(cuò)誤描述:PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 976370274 bytes) in mc.php on line 31

出錯(cuò)的頁(yè)面最近沒有動(dòng)到昔榴,由于是PHP Fatal error:級(jí)別辛藻,無法通過debug_backtrace拿到堆棧信息,給排查問題造成很大困擾互订。

排查問題:通過在測(cè)試環(huán)境復(fù)現(xiàn)問題吱肌,一行行調(diào)試,打印輸出仰禽,最終定位到小編在錄入一個(gè)id值時(shí)多復(fù)制了一個(gè)tab符號(hào)氮墨,代碼中信任了此值

當(dāng)它為int拼接為mc的key進(jìn)行緩存獲取到的數(shù)據(jù),被緩存數(shù)據(jù)是一個(gè)數(shù)組吐葵,在set成功后get被緩存數(shù)據(jù)時(shí)內(nèi)存溢出规揪。

代碼場(chǎng)景還原

<?php

$m = new Memcached();
$host = '127.0.0.1';
$port = 11211;
$m->addServer($host, $port);
echo "=connect mc $host:$port\n";
$mcKey = "\t188883";

$mcKey2 = "test_" . $mcKey;
# 注意被設(shè)置的值一定是array才能復(fù)現(xiàn)內(nèi)存溢出
$ntest = array (
    'id' => '188883',
);

echo "=set mc\n";
var_dump($m->set($mcKey2, $ntest, 60));
echo "=set mc result\n";
var_dump($m->getResultMessage());
echo "=get mc\n";
var_dump($m->get($mcKey2));
echo "=get mc result\n";
var_dump($m->getResultMessage());

運(yùn)行程序

#php -d "display_errors=On" test.php
=connect mc 127.0.0.1:11211
=set mc
bool(true)
=set mc result
string(7) "SUCCESS"
=get mc

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 976304738 bytes) in test.php on line 20

檢查軟件版本

php 5.4.25
libmemcached 1.0.18
memcached 2.2.0

為了找出底層問題和新版本修復(fù)情況找了一個(gè)php7.x的版本測(cè)試

#php -d "display_errors=On" test.php
=connect mc 127.0.0.1:11211
=set mc
bool(false)
=set mc result
string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE"
=get mc
bool(false)
=get mc result
string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE"

相關(guān)軟件版本

php 7.0.7
libmemcached 1.0.18
memcached 3.0.3

由于是獲取mc時(shí)出現(xiàn)的內(nèi)存溢出,且從上面看由于新版本對(duì)mc的key做了增強(qiáng)的檢查而避免的温峭,所以
先下載兩個(gè)memcached版本源碼猛铅,進(jìn)行查看

  // memcached 2.2.0 可以看到對(duì)key的檢查只限于空格和長(zhǎng)度,tab是被認(rèn)為合法的
    if (key_len == 0 || strchr(key, ' ')) {
        i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
        RETURN_FROM_GET;
    }
// memcached 3.0.3 這里的key驗(yàn)證相對(duì)來說復(fù)雜了許多
#define MEMC_CHECK_KEY(intern, key)                                               \
    if (UNEXPECTED(ZSTR_LEN(key) == 0 ||                                          \
        ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH ||                             \
        (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) \
                ? !s_memc_valid_key_binary(ZSTR_VAL(key))                         \
                : !s_memc_valid_key_ascii(ZSTR_VAL(key))                          \
        ))) {                                                                     \
        intern->rescode = MEMCACHED_BAD_KEY_PROVIDED;                             \
        RETURN_FALSE;                                                             \
    }

#ifdef HAVE_MEMCACHED_PROTOCOL

小結(jié)
memcached 2.2.0 是php5使用的最高版本了诚镰,memcached 3.x是給php7 使用的奕坟,如果要在php5項(xiàng)目中避免內(nèi)存溢出只能在php代碼層面對(duì)mckey進(jìn)行檢查或是提高代碼書寫質(zhì)量,避免傳遞給擴(kuò)展一個(gè)非法的key清笨,對(duì)于有條件的用戶也可以升級(jí)到php7

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末月杉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抠艾,更是在濱河造成了極大的恐慌苛萎,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異腌歉,居然都是意外死亡蛙酪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門翘盖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桂塞,“玉大人,你說我怎么就攤上這事馍驯「笪#” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵汰瘫,是天一觀的道長(zhǎng)狂打。 經(jīng)常有香客問我,道長(zhǎng)混弥,這世上最難降的妖魔是什么趴乡? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮蝗拿,結(jié)果婚禮上晾捏,老公的妹妹穿的比我還像新娘。我一直安慰自己蛹磺,他們只是感情好粟瞬,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著萤捆,像睡著了一般裙品。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上俗或,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天市怎,我揣著相機(jī)與錄音,去河邊找鬼辛慰。 笑死区匠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的帅腌。 我是一名探鬼主播驰弄,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼速客!你這毒婦竟也來了戚篙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤溺职,失蹤者是張志新(化名)和其女友劉穎岔擂,沒想到半個(gè)月后位喂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乱灵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年塑崖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痛倚。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡规婆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出状原,到底是詐尸還是另有隱情聋呢,我是刑警寧澤苗踪,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布颠区,位于F島的核電站,受9級(jí)特大地震影響通铲,放射性物質(zhì)發(fā)生泄漏毕莱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一颅夺、第九天 我趴在偏房一處隱蔽的房頂上張望朋截。 院中可真熱鬧,春花似錦吧黄、人聲如沸部服。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)廓八。三九已至,卻和暖如春赵抢,著一層夾襖步出監(jiān)牢的瞬間剧蹂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工烦却, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宠叼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓其爵,卻偏偏與公主長(zhǎng)得像冒冬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子摩渺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 1简烤、memcache的概念? Memcache是一個(gè)高性能的分布式的內(nèi)存對(duì)象緩存系統(tǒng)证逻,通過在內(nèi)存里維護(hù)一個(gè)統(tǒng)一的巨...
    桖辶殤閱讀 2,243評(píng)論 2 12
  • 轉(zhuǎn)載自cr180大神DiscuzX2.5完整目錄結(jié)構(gòu)【source程序文件庫(kù)】 /source/admincp后臺(tái)...
    cndaqiang閱讀 860評(píng)論 1 2
  • php.ini設(shè)置,上傳大文件: post_max_size = 128Mupload_max_filesize ...
    bycall閱讀 6,778評(píng)論 3 64
  • 乾乾君子健 坤坤厚德藏 屯屯以經(jīng)綸 蒙蒙正氣養(yǎng) 需需取有度 訟訟謀始章 師師容民眾 比比建鄰邦 ...
    張蕾馥閱讀 1,973評(píng)論 0 0