成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

記一次PHP并發(fā)性能調(diào)優(yōu)實(shí)戰(zhàn) -- 性能提升104%

xeblog / 2979人閱讀

摘要:這是多處理器系統(tǒng)中,調(diào)度器用來(lái)分散任務(wù)到不同的機(jī)制,通常也被稱(chēng)為處理器間中斷,。

文章編寫(xiě)計(jì)劃

待完成: 詳細(xì)介紹用到的各個(gè)工具

作者: 萬(wàn)千鈞(祝星)

適合閱讀人群

文中的調(diào)優(yōu)思路無(wú)論是php, java, 還是其他任何語(yǔ)言都是用. 如果你有php使用經(jīng)驗(yàn), 那肯定就更好了

業(yè)務(wù)背景

框架及相應(yīng)環(huán)境

    laravel5.7, mysql5.7, redis5, nginx1.15

    centos 7.5 bbr

    docker, docker-compose

    阿里云 4C和8G

問(wèn)題背景

php已經(jīng)開(kāi)啟opcache, laravel也運(yùn)行了optimize命令進(jìn)行優(yōu)化, composer也進(jìn)行過(guò)dump-autoload命令.

首先需要聲明的是, 系統(tǒng)的環(huán)境中是一定有小問(wèn)題的(沒(méi)有問(wèn)題也不可能能夠提升如此大的性能), 但是這些問(wèn)題, 如果不通過(guò)使用合適的工具, 可能一輩子也發(fā)現(xiàn)不出來(lái).

本文關(guān)注的就是如何發(fā)現(xiàn)這些問(wèn)題, 以及發(fā)現(xiàn)問(wèn)題的思路.

我們首先找到系統(tǒng)中一個(gè)合適的API或函數(shù), 用來(lái)放大問(wèn)題.

這個(gè)api設(shè)計(jì)之初是給nginx負(fù)載均衡做健康檢查的. 使用ab -n 100000 -c 1000 進(jìn)行壓測(cè), 發(fā)現(xiàn)qps只能到140個(gè)每秒.

我們知道Laravel的性能是出了名的不好, 但是也不至于到這個(gè)程度, 從api的編寫(xiě)來(lái)看不應(yīng)該這么低. 所以決定一探究竟.

 public function getActivateStatus()
    {
        try {
            $result = DB::select("select 1");
            $key = 1;
            if ($result[0]->$key !== 1) {
                throw new Exception("mysql 檢查失敗");
            }
        } catch (Exception $exception) {
            Log::critical("數(shù)據(jù)庫(kù)連接失敗: {$exception->getMessage()}", $exception->getTrace());
            return 
esponse(null, 500);
        }
        try {
            Cache::getRedis()->connection()->exists("1");
        } catch (Exception $exception) {
            Log::critical("緩存連接失敗: {$exception->getMessage()}", $exception->getTrace());
            return 
esponse(null, 500);
        }
        return 
esponse(null, 204);
    }

問(wèn)題表現(xiàn)以及排查思路

top

top命令發(fā)現(xiàn)系統(tǒng)CPU占用100% 其中用戶態(tài)占80%, 內(nèi)核態(tài)占20%, 看起來(lái)沒(méi)什么大問(wèn)題. 有一個(gè)地方看起來(lái)很奇怪, top命令的運(yùn)行結(jié)果

就是有一部分php-fpm進(jìn)程處在Sleep狀態(tài), 但CPU占用還是達(dá)到了近30%. 當(dāng)一個(gè)進(jìn)程處于Sleep狀態(tài)的時(shí)候, 任然占用了不少CPU, 先不要懷疑是不是進(jìn)程的問(wèn)題, 我們看一下Ttop命令的man page.

%CPU -- CPU usage

The task"s share of the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time.

大致意思是這個(gè)占用是最后一次屏幕刷新的時(shí)候, 進(jìn)程CPU的占用. 由于top命令收集信息的時(shí)候, 可能linux把這個(gè)進(jìn)程強(qiáng)制調(diào)度了 ( 比如用于top收集進(jìn)程信息 ), 所以在這一瞬間(屏幕刷新的這一瞬間)某些php-fpm進(jìn)程處于sleep狀態(tài), 可以理解, 所以應(yīng)該不是php-fpm的問(wèn)題.

pidstat

首先選出一個(gè)php-fpm進(jìn)程, 然后使用pidstat查看進(jìn)程詳細(xì)的運(yùn)行情況

過(guò)程中也沒(méi)發(fā)現(xiàn)什么異樣, 并且和top命令的運(yùn)行結(jié)果也基本一致.

vmstat

保持壓測(cè)壓力, 運(yùn)行vmstate查看, 除了context switch (上下文切換)有點(diǎn)高之外, 并沒(méi)有看到太多異常. 由于我們使用的docker, redis, mysql都運(yùn)行在同一臺(tái)機(jī)器上, 7000左右的CS還是一個(gè)合理的范圍, 但是這個(gè)IN(中斷)就有點(diǎn)太高了, 達(dá)到了1.4萬(wàn)左右. 一定有什么東西觸發(fā)了中斷.

我們知道中斷有硬中斷和軟中斷, 硬中斷是由網(wǎng)卡, 鼠標(biāo)等硬件發(fā)出中斷信號(hào), cpu馬上停下在做的事情, 處理中斷信號(hào). 軟中斷是由操作系統(tǒng)發(fā)出的, 常用于進(jìn)程的強(qiáng)制調(diào)度.

不管是vmstat還是pidstat都只是新能探測(cè)工具, 我們無(wú)法看到具體的中斷是由誰(shuí)發(fā)出的. 我們通過(guò)/proc/interrupts 這個(gè)只讀文件中讀取系統(tǒng)的中斷信息, 獲取到底是什么導(dǎo)致的中斷升高. 通過(guò)watch -d命令, 判斷變化最頻繁的中斷.

watch -d cat /proc/interrupts

我們發(fā)現(xiàn)其中Rescheduling interrupts變化的最快, 這個(gè)是重調(diào)度中斷(RES),這個(gè)中斷類(lèi)型表示,喚醒空閑狀態(tài)的CPU 來(lái)調(diào)度新的任務(wù)運(yùn)行。這是多處理器系統(tǒng)(SMP)中,調(diào)度器用來(lái)分散任務(wù)到不同 CPU的機(jī)制,通常也被稱(chēng)為處理器間中斷(Inter-Processor Interrupts,IPI)。 結(jié)合vmstat中的命令, 我們可以確定造成qps不高的原因之一是過(guò)多的進(jìn)程爭(zhēng)搶CPU導(dǎo)致的, 我們現(xiàn)在還不能確定具體是什么, 所以還需要進(jìn)一步的排查.

strace

strace可以查看系統(tǒng)調(diào)用, 我們知道, 當(dāng)使用系統(tǒng)調(diào)用的時(shí)候, 系統(tǒng)陷入內(nèi)核態(tài), 這個(gè)過(guò)程是會(huì)產(chǎn)生軟中斷的, 通過(guò)查看php-fpm的系統(tǒng)調(diào)用, 驗(yàn)證我們的猜想

果然, 發(fā)現(xiàn)大量的stat系統(tǒng)調(diào)用, 我們猜想, 是opcache在檢查文件是否過(guò)期導(dǎo)致的. 我們通過(guò)修改opcache的配置, 讓opcache更少的檢查文件timestamp, 減少這種系統(tǒng)調(diào)用

    opcache.validate_timestamps="60"
    opcache.revalidate_freq="0"

再次執(zhí)行ab命令進(jìn)行壓測(cè)

果然qps直接漲到了205, 提升非常明顯, 有接近 46% 的提升

perf

現(xiàn)在任然不滿足這個(gè)性能, 希望在更多地方找到突破口. 通過(guò)

perf record -g
perf report -g

看到系統(tǒng)的分析報(bào)告

我們看到, 好像這里面有太多tcp建立相關(guān)的系統(tǒng)調(diào)用(具體是不是我還不清楚, 請(qǐng)大神指正, 但是看到send, ip, tcp啥的我就懷疑可能是tcp/ip相關(guān)的問(wèn)題). 我們懷疑兩種情況

    與mysql, redis重復(fù)大量的建立TCP連接, 消耗資源

    大量請(qǐng)求帶來(lái)的tcp連接

先說(shuō)第一個(gè), 經(jīng)過(guò)檢查, 發(fā)現(xiàn)數(shù)據(jù)庫(kù)連接使用了php-fpm的連接池, 但是redis連接沒(méi)有, redis用的predis, 這個(gè)是一個(gè)純PHP實(shí)現(xiàn), 性能不高, 換成了phpredis:

打開(kāi)laravel的config/database.php文件, 修改redis的driver為phpredis, 確保本機(jī)已安裝php的redis擴(kuò)展. 另外由于Laravel自己封裝了一個(gè)Redis門(mén)面, 而恰好redis擴(kuò)展帶來(lái)的對(duì)象名也叫Redis. 所以需要修改Laravel的Redis門(mén)面為其他名字, 如RedisL5.

再次進(jìn)行壓測(cè)

達(dá)到了喜人的286qps, 雖然和其他主打高性能的框架或者原生php比, 還有很高的提升空間(比如Swoole), 但是最終達(dá)到了104%的提升, 還是很有意義的

總結(jié)

我們通過(guò)top, 發(fā)現(xiàn)系統(tǒng)CPU占用高, 且發(fā)現(xiàn)確實(shí)是php-fpm進(jìn)程占用了CPU資源, 判斷系統(tǒng)瓶頸來(lái)自于PHP.

接著我們通過(guò)pidstat, vmstat發(fā)現(xiàn)壓測(cè)過(guò)程中, 出現(xiàn)了大量的系統(tǒng)中斷, 并通過(guò) watch -d cat /proc/interrupts 發(fā)現(xiàn)主要的中斷來(lái)自于重調(diào)度中斷(RES)

通過(guò)strace查看具體的系統(tǒng)調(diào)用, 發(fā)現(xiàn)大量的系統(tǒng)調(diào)用來(lái)自于stat, 猜測(cè)可能是opcache頻繁的檢查時(shí)間戳, 判斷文件修改. 通過(guò)修改配置項(xiàng), 達(dá)到了46%的性能提升

最后再通過(guò)perf, 查看函數(shù)調(diào)用棧, 分析得到, 可能是大量的與redis的TCP連接帶來(lái)不必要的資源消耗. 通過(guò)安裝redis擴(kuò)展, 以及使用phpredis來(lái)驅(qū)動(dòng)Laravel的redis緩存, 提升性能, 達(dá)到了又一次近50%的性能提升.

最終我們完成了我們的性能提升104%的目標(biāo)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/7022.html

相關(guān)文章

  • 一次PHP并發(fā)性能調(diào)優(yōu)實(shí)戰(zhàn) -- 性能提升104%

    摘要:這是多處理器系統(tǒng)中,調(diào)度器用來(lái)分散任務(wù)到不同的機(jī)制,通常也被稱(chēng)為處理器間中斷,。文章編寫(xiě)計(jì)劃 待完成: 詳細(xì)介紹用到的各個(gè)工具 作者: 萬(wàn)千鈞(祝星) 適合閱讀人群 文中的調(diào)優(yōu)思路無(wú)論是php, java, 還是其他任何語(yǔ)言都是用. 如果你有php使用經(jīng)驗(yàn), 那肯定就更好了 業(yè)務(wù)背景 框架及相應(yīng)環(huán)境 laravel5.7, mysql5.7, redis5, nginx1.15 cento...

    番茄西紅柿 評(píng)論0 收藏0
  • 一次 Laravel 應(yīng)用性能調(diào)優(yōu)經(jīng)歷

    摘要:為了一探究竟,于是開(kāi)啟了這次應(yīng)用性能調(diào)優(yōu)之旅。使用即時(shí)編譯器和都能輕輕松松的讓你的應(yīng)用程序在不用做任何修改的情況下,直接提高或者更高的性能。 這是一份事后的總結(jié)。在經(jīng)歷了調(diào)優(yōu)過(guò)程踩的很多坑之后,我們最終完善并實(shí)施了初步的性能測(cè)試方案,通過(guò)真實(shí)的測(cè)試數(shù)據(jù)歸納出了 Laravel 開(kāi)發(fā)過(guò)程中的一些實(shí)踐技巧。 0x00 源起 最近有同事反饋 Laravel 寫(xiě)的應(yīng)用程序響應(yīng)有點(diǎn)慢、20幾個(gè)并...

    warkiz 評(píng)論0 收藏0
  • PHP 性能分析第三篇: 性能調(diào)優(yōu)實(shí)戰(zhàn)

    摘要:注意本文是我們的性能分析系列的第三篇,點(diǎn)此閱讀性能分析第一篇介紹,或性能分析第二篇深入研究。小的性能提升很可能來(lái)自優(yōu)化,而非緩存。注意此更改已提交到并已獲更新。目前,兩者具備相同的特性,只有一些部分重命名了。 注意:本文是我們的 PHP 性能分析系列的第三篇,點(diǎn)此閱讀?PHP 性能分析第一篇: XHProf & XHGui 介紹?,或??PHP 性能分析第二篇: 深入研究 XHGui...

    cnsworder 評(píng)論0 收藏0
  • Java架構(gòu)體系學(xué)習(xí)路線圖,第六點(diǎn)尤為重要!

    摘要:有不少朋友問(wèn),除了掌握語(yǔ)法,還要系統(tǒng)學(xué)習(xí)哪些相關(guān)的技術(shù),今天分享一個(gè),互聯(lián)網(wǎng)技術(shù)學(xué)習(xí)路線圖。群內(nèi)已經(jīng)有小伙伴將知識(shí)體系整理好源碼,筆記,學(xué)習(xí)視頻,歡迎加群免費(fèi)取。 showImg(https://segmentfault.com/img/remote/1460000015926035); 我們都知道android依賴于Java,五六年后進(jìn)入瓶頸期,很多人都學(xué)習(xí)了后臺(tái)業(yè)務(wù)關(guān)的知識(shí)。當(dāng)然我...

    hufeng 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<