Laravist群友雜談 談笑風(fēng)生篇

這幾天群里來(lái)了安正超大神,一下子群情'波'濤洶涌呀,什么?你不知道超神是誰(shuí),這是他的個(gè)人網(wǎng)站可以去瞧一瞧.

.......對(duì)了,差點(diǎn)忘了,群里也來(lái)了一個(gè)'似乎'沒(méi)有存在感的仁兄 - Drupal獵人(QQ號(hào):打上馬賽克),為什么說(shuō)他呢,因?yàn)槁?tīng)說(shuō)他技術(shù)也很厲害,不過(guò)在某些方面比他的技術(shù)還要那啥,你懂得(嗶嗶,學(xué)生卡)。

名言篇

留下 1/3 的時(shí)間學(xué)習(xí),留下 1/3 的時(shí)間思考,剩下 1/3 才是寫(xiě)代碼 --- Little

干正事吧,好好學(xué)習(xí),也可以跟大神一樣溜 --- Jellybool?

人生如此短暫,我花費(fèi)了打炮的時(shí)間來(lái)學(xué)門(mén)技術(shù),我容易嗎我? --- Drupal獵人


Js事件的冒泡用法 --- Little

js推薦這種把事件綁定在body上,用冒泡來(lái)做,不要直接在每個(gè)元素上都綁事件。

寫(xiě)js,也是寫(xiě)php面向?qū)ο箢?lèi)似。前面定義各種類(lèi)、方法、屬性,最后把事件綁定在body上,通過(guò)冒泡找id或者找元素。這樣你哪怕?lián)Q了模板,只要流程不是有大變化,js也不用大改的。



比如:開(kāi)始音樂(lè)和暫停音樂(lè)。只不過(guò)是click觸發(fā)的,如果加一個(gè) ESC按鍵觸發(fā),只需要改個(gè)觸發(fā)事件即可。


很少在 js 里會(huì)注冊(cè) window. 下的全局變量,一切都是私有變量。內(nèi)部的用 _,注冊(cè)到外面,一般只用 APP. 這樣的大寫(xiě)類(lèi)。$ 開(kāi)頭的表示 jquery selector,閉包?return?出去了。


PHP opcache --- Little

群友問(wèn):php 開(kāi)啟了 opcache, 如果在命令行執(zhí)行 opcache_reset(), 會(huì)重置 包括 php-pfm 的緩存么

答:不會(huì),每個(gè)php-cli進(jìn)程都有自己的opcache空間,所有php-fpm進(jìn)程是一個(gè)opcache空間,

生產(chǎn)環(huán)境opcache的timestamp檢查關(guān)掉,發(fā)布代碼的時(shí)候再更新下opcache,可以避免很多stat系統(tǒng)調(diào)用

※ 深入淺出FastCGI/php-fpm --- Little

這一個(gè)話題包括Little講解php-fpm和PHP與Mysql連接的整合,方方覺(jué)得兩個(gè)丟在一起可以更能理解

先看個(gè)圖,標(biāo)準(zhǔn)的PHP單進(jìn)程CLI和CGI生命周期。php進(jìn)程啟動(dòng),需要zend core、加載擴(kuò)展(MINIT)、接收請(qǐng)求(RINIT) 這樣的。一個(gè)進(jìn)程只服務(wù)一次命令行或HTTP請(qǐng)求,就退出。


而FastCGI/php-fpm 就是改造后的多進(jìn)程的 CGI,類(lèi)似于資源池,預(yù)先啟動(dòng) 100個(gè) php-fpm 進(jìn)程,提前MINT,nginx的請(qǐng)求來(lái)了,直接進(jìn)入 RINIT -> RSHUTDOWN 循環(huán)。請(qǐng)求結(jié)束,進(jìn)程不退出,一個(gè)進(jìn)程至少服務(wù)上萬(wàn)次請(qǐng)求才退出。

為什么一定要退出?怕RINIT->RSHUTDOWN循環(huán),有哪個(gè)代碼寫(xiě)的不好,變量一直沒(méi)釋放,內(nèi)存泄露GC又回收不了。php-fpm里的pm.max_requests配置就是設(shè)置RINT循環(huán)多少次,退出進(jìn)程。

再來(lái)看幾個(gè) TSF、swoole、workerman、php-pm,都是 php 啟動(dòng)cli進(jìn)程,用php管理子進(jìn)程,php解析HTTP協(xié)議。

生命周期連?RINIT?->?MINIT?循環(huán)都省了,沒(méi)寫(xiě)在?類(lèi)屬性里的變量,裸寫(xiě)的變量都是?進(jìn)程級(jí)全局變量,比?php-fpm?下的?$_GET、$_POST、$_SERVER、$_SESSION、$_COOKIE?這些全局變量范圍還大,是進(jìn)程級(jí)的。意味著你?寫(xiě)了個(gè)?a.php,里面定義了?$a?=?1;?賦值之后,下次請(qǐng)求過(guò)來(lái),只要正好分配到了這個(gè)進(jìn)程,依然還能取到普通定義的?$a?變量。

這意味著什么?像?Laravel?里的?$app?這些變量,只要寫(xiě)在最外面,因?yàn)闆](méi)有觸發(fā)?RSHUTDOWN,又沒(méi)有主動(dòng)?unset,GC引用計(jì)數(shù)器一直大于?0,變量不會(huì)消失。

那怎么解決每次請(qǐng)求?$_GET?和?$_POST?不一樣的問(wèn)題?這些?swoole、workerman?進(jìn)程管理器自己實(shí)現(xiàn)了小型化的?INIT?->?SHUTDOWN?過(guò)程,維護(hù)一些引用計(jì)數(shù)唄,自己的?a.php?完成后,這種框架幫你?unset($_GET)。

問(wèn)題來(lái)了,穩(wěn)定不穩(wěn)定?swoole、workman框架本身穩(wěn)定,但因?yàn)橥耆淖兞藀hp生命周期,業(yè)務(wù)開(kāi)發(fā)人員不熟悉,一不小心寫(xiě)了?global、static?這樣的變量,全局用了,內(nèi)存越占越大,崩潰。又或者?寫(xiě)了個(gè)?exit,把整個(gè)進(jìn)程?exit?而不是?request?ext?了。

舉個(gè)例子來(lái)理解,用 swoole、php-pm 這種進(jìn)程模式,假設(shè)只啟動(dòng)一個(gè)進(jìn)程,可能會(huì)出現(xiàn)以下情況。

1、寫(xiě)個(gè)頁(yè)面 http://www.xxx.com/a.php,內(nèi)容是 $a = 1,而到一個(gè)完全不相關(guān)的頁(yè)面 http://www.xxx.com/b.php,內(nèi)容就是var_dump($a); 居然能輸出 int(1); 很神奇

2、寫(xiě)個(gè)頁(yè)面 http://www.xxx.com/c.php,里面執(zhí)行完一段邏輯后,exit('error'),本以為頁(yè)面輸出個(gè) error,是正常的拒絕訪問(wèn)。再刷新,502了,什么情況。

那哪種情況比較適合使用swoole

Little答:

特別繁忙的某個(gè)接口、業(yè)務(wù)邏輯簡(jiǎn)單、依賴較少的情況,可以用。有良好的編碼習(xí)慣,不用全局變量,不寫(xiě) exit 只用 return 不會(huì)有問(wèn)題。但是無(wú)法保證用到的哪個(gè) vendor 不出現(xiàn)這些東西,所以不能大規(guī)模使用。

Abraham因?yàn)樯婕拜^多框架,深切表示很多 vendor 里面 的寫(xiě)法真是千奇百怪,有的根本都沒(méi)見(jiàn)過(guò),

比如解析 var_dump 去判斷對(duì)象

當(dāng)然我只是看了這些進(jìn)程早期版本的實(shí)現(xiàn),現(xiàn)在php不是有某種注入技術(shù),可以改寫(xiě)原生函數(shù)么。說(shuō)不定啟動(dòng)swoole的時(shí)候,已經(jīng)用某種方法把 exit 改寫(xiě)了呢。

這里是Little對(duì)于的一些理解,讀者還是需要與現(xiàn)在版本進(jìn)行比較

對(duì)于swoole、workman等框架本身穩(wěn)定,但因?yàn)橥耆淖兞藀hp生命周期是否意味著更適合做一些微框架,寫(xiě)純Restful API?

Little答:

這種完全改寫(xiě)生命周期的事情,就有點(diǎn)像 HHVM 對(duì) PHP做成預(yù)定義變量類(lèi)型的改變,性能提升很大,但是用起來(lái)要謹(jǐn)慎,并不是全兼容的。

Little在這里并沒(méi)有直接回答此問(wèn)題,因?yàn)樵谥熬徒榻B了,Little對(duì)于項(xiàng)目是超越框架的,不局限于框架之類(lèi)的東西.所以方方感覺(jué)也是蠻正常的

websocket最好不要php直接來(lái)做,目前php的websocket包,都是啟動(dòng)一個(gè)獨(dú)立的進(jìn)程監(jiān)聽(tīng)端口解析協(xié)議,跟 swoole、workerman 這些東西同一種性質(zhì),不能確保100%好用及可用。

推薦 借助 openresty(nginx) + lua + redis 來(lái)做。

openresty(nginx) 通過(guò) redis 插件 監(jiān)聽(tīng)websocket,同時(shí)掛起一個(gè)到 redis 的連接,用 redis 的 sub 方法,訂閱某個(gè) key。php 這邊只需要 調(diào)用 Redis 的 pub 方法,寫(xiě)入 redis 的 key 即可。

一個(gè)由TIME_WAIT 引起的話題 --- Little


TIME_WAIT多了


Abraham回答

fpm?每個(gè)進(jìn)程結(jié)束都銷(xiāo)毀連接,無(wú)法利用持久連接,持久連接指的是請(qǐng)求內(nèi)的吧,你的情況可以減小?mysql?的等待超時(shí)時(shí)間,或者直接更改操作系統(tǒng)維護(hù)的?tcp?連接數(shù)

little最后解答

我剛那個(gè) TIME_WAIT 問(wèn)題改成php-fpm 連接 mysql 用 persistent 是可以解決的。剛剛只是改錯(cuò)了文件,沒(méi)想到有個(gè)老項(xiàng)目的代碼還在這臺(tái)機(jī)器上跑。

雖然php并沒(méi)有mysql連接池,但是 PDO 的persistent參數(shù)是基于單個(gè)php-fpm進(jìn)程,仔細(xì)看了下php-fpm的生命周期,我配置了 204800 個(gè)request請(qǐng)求才會(huì)重啟這個(gè)php-fpm進(jìn)程,所以連接復(fù)用的情況還是很大,單機(jī)400個(gè)php-fpm進(jìn)程,單個(gè)進(jìn)程要跑滿20萬(wàn)次請(qǐng)求等重啟,怎么都要一兩天才行。

Abraham的理解

以前一直以為持久連接是基于 fpm 子進(jìn)程中處理 request 的線程。

為什么上面要放Abraham最開(kāi)始的回復(fù)以及后來(lái)的理解,一來(lái)是Abraham對(duì)于很多人而言其實(shí)已經(jīng)技術(shù)很好了,但是仍然對(duì)某些深層的不能正確理解,拿出來(lái)讓其他人看看是否自己也有這種理解失誤;二來(lái)嘛,嘿嘿嘿,拖出去,彈雞雞彈到死

Little

關(guān)掉持久連接,會(huì)在request shutdown 階段close mysql連接。而打開(kāi)持久連接,并不會(huì)每次請(qǐng)求都關(guān)閉,是同一個(gè)php-fpm進(jìn)程中復(fù)用連接,直到這個(gè)php-fpm進(jìn)程結(jié)束了。

然而php-fpm的mysql并沒(méi)有連接池,比如開(kāi)了400個(gè)php-fpm進(jìn)程,那就會(huì)和mysql保持400個(gè)連接,無(wú)論現(xiàn)在訪問(wèn)量高還是低。如果前端機(jī)器太多,mysql服務(wù)器會(huì)保持太多的連接數(shù),mysql服務(wù)器并不能承受太多個(gè)連接,哪怕這個(gè)連接什么事都沒(méi)干,所以并不是一個(gè)很好的解決辦法,只能再加一層mysql?proxy。而java的實(shí)現(xiàn)就有連接池,好很多,果當(dāng)前并發(fā)請(qǐng)求量只有100,那么只會(huì)有100個(gè)java到mysql的連接。這100個(gè)連接在所有java線程中復(fù)用。

Abraham再提問(wèn)

如果能保持?php-fpm?的進(jìn)程數(shù)那么多個(gè)連接。show?status?like?'%connections%',理論上應(yīng)該不變的對(duì)吧?

Little 回復(fù)

1:15 的時(shí)候,我在一臺(tái)機(jī)器上開(kāi)了持久連接。1:40左右的時(shí)候,我多開(kāi)了一臺(tái)php機(jī)器。


所以我的結(jié)論是 php-fpm 到 mysql,應(yīng)當(dāng)使用 persistent。如果機(jī)器數(shù)、php-fpm進(jìn)程數(shù)很多,后端mysql掛不了這么多空閑連接。那在 php-fpm 與 mysql 之間加一層 mysql proxy。這個(gè) mysql proxy 就是相當(dāng)于多進(jìn)程多機(jī)器的連接池。

多機(jī)器多進(jìn)程?php-fpm?(可能有5000個(gè)連接)?->?mysql?proxy?->?(可能就剩20個(gè)并發(fā)執(zhí)行mysql的活躍連接了)?mysql?server。

默認(rèn)就開(kāi)啟持久連接才好,出現(xiàn)問(wèn)題,再看看是不是考慮關(guān)掉。畢竟?php?連mysql,一個(gè)新連接會(huì)多三次?TCP握手過(guò)程,雖然是內(nèi)網(wǎng),速度感覺(jué)不出來(lái)。我這是給一個(gè)老項(xiàng)目做優(yōu)化,讓他暫時(shí)不掛。我別的項(xiàng)目都是直接上持久連接。

開(kāi)啟持久連接, 可能會(huì)導(dǎo)致那些問(wèn)題

Little答

理論上是沒(méi)有什么問(wèn)題,就是看你的mysql服務(wù)器受不受得住,受不住就要加 proxy。

另外,有空閑連接,如果你的網(wǎng)站并發(fā)量比較小,空閑連接時(shí)間長(zhǎng)了,可能會(huì)被mysql踢掉,會(huì)產(chǎn)生一個(gè)?mysql?has?gone?away?這個(gè)錯(cuò)誤,你要程序中處理,我不知道?laravel?有沒(méi)有自動(dòng)處理,理論上這種全棧框架應(yīng)該都會(huì)有個(gè)配置自動(dòng)處理這個(gè)問(wèn)題。

我全文搜了下?gone?away,發(fā)現(xiàn)?laravel?里有處理gone?away,業(yè)務(wù)層就不用關(guān)心了。

Illuminate\Databasetry\Connection? -> run() 和 tryAgainIfCausedByLostConnection()

我可不可以這樣理解,當(dāng)你的項(xiàng)目已經(jīng)需要利用 php-fpm 持久連接提供的性能福利時(shí),你同時(shí)也需要審視你的數(shù)據(jù)訪問(wèn)層架構(gòu),重新設(shè)計(jì)它

Little答

應(yīng)該這么說(shuō),持久連接應(yīng)該是在每一個(gè)環(huán)節(jié)都是盡量使用的。比如用戶瀏覽器到nginx,用HTTP/1.1,開(kāi)keepalive。nginx到php-fpm,upstream里開(kāi)keepalive,fastcgi conn 還要配個(gè)什么。php到mysql,也開(kāi)持久連接。這樣每個(gè)環(huán)節(jié)都省掉多次不必要的TCP三次握手。而MySQL性能問(wèn)題和這個(gè)連接關(guān)系并不是太大,只是mysql服務(wù)器一直以來(lái)都有個(gè)毛病,連接數(shù)超過(guò)一定的數(shù)量就受不了,哪怕這個(gè)連接是空閑的什么事都沒(méi)干,不像nginx隨便掛上十幾萬(wàn)的連接數(shù)都輕輕松松。

整理者方方小結(jié) --- 還是好好學(xué)習(xí)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評(píng)論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,414評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,169評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,722評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,465評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,823評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,000評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,554評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,513評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,722評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,125評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,430評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,237評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,482評(píng)論 2 379

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