php swoole 心跳,聊聊swoole的心跳
來自:桶哥的一篇關(guān)于swoole的心跳的文章,作為Swoole顧問(顧得上就問,是為「顧問」)得推一下這篇文章,最后只留下一配置,其實(shí)我也不是太明白原理,我在想如果是局域網(wǎng)里還需要心跳?
——————————————————————————————————————————————————————————————————————
swoole提供了一個(gè)心跳的功能,很多朋友感到困惑。
心跳是什么?
顧名思義,心跳是判斷一個(gè)事物生還是死的一個(gè)標(biāo)準(zhǔn),在swoole里,心跳是指用來判斷一個(gè)連接是正常還是斷開的。
從TCP協(xié)議說起
我們都知道一個(gè)五元組標(biāo)識(shí)一個(gè)網(wǎng)絡(luò)連接,創(chuàng)建一個(gè)連接有三次握手,而斷開一個(gè)連接有四次揮手。不管是服務(wù)器還是客戶端
發(fā)起連接的關(guān)閉,都會(huì)完整的走完四次揮手的過程,這樣,一切很完美,系統(tǒng)回收這個(gè)fd,應(yīng)用層也可以通過onClose回調(diào)處理相關(guān)的事情.
fd是什么?
fd學(xué)名是文件描述符,在unix的哲學(xué)就是一切皆文件中,這個(gè)fd就是系統(tǒng)層暴露給業(yè)務(wù)層的用來表示一個(gè)五元組網(wǎng)絡(luò)連接的標(biāo)識(shí)。你可以簡單的理解為一個(gè)索引,通過對這個(gè)fd的操作,系統(tǒng)層可以找到相應(yīng)的連接而且進(jìn)行的一系列操作,如發(fā)送數(shù)據(jù)到網(wǎng)瞳,進(jìn)行連接關(guān)閉等等。
為什么要心跳?
剛才提到,如果我們要關(guān)閉某個(gè)連接,我們可以在業(yè)務(wù)層對fd發(fā)起關(guān)閉連接的操作,以swoole為例:
$server->close($fd);
正常情況下,都會(huì)走完整個(gè)四次揮手,(swoole會(huì)有onClose回調(diào)),系統(tǒng)回收fd,以待分配給其他的連接。
那系統(tǒng)為什么要回收fd,因?yàn)閒d資源是有限的,所以必需重復(fù)利用。
但在某些情況下,如突然拔掉網(wǎng)線或藍(lán)翔演習(xí)挖斷光纜,服務(wù)端并不能感知到這個(gè)連接的異常,但實(shí)際上是這個(gè)連接已經(jīng)失效了,如果沒有一個(gè)回收機(jī)制,這類連接將用光所有的fd,導(dǎo)致系統(tǒng)不再能接受新的連接請求,所以就有了心跳機(jī)制。
什么是心跳機(jī)制?
心跳機(jī)制就是業(yè)務(wù)層來提供一個(gè)連接是否存活的一個(gè)方法,讓系統(tǒng)能判定一個(gè)連接是否失效。一般有兩種實(shí)現(xiàn)方式:
1: 客戶端定時(shí)發(fā)送一個(gè)心跳包,告訴服務(wù)器我還活著,服務(wù)器定時(shí)檢測所有客戶端列表,看他們最后一個(gè)心跳包的時(shí)間是否過長,如果過長,則認(rèn)為已無心跳,判定為死連接,主動(dòng)關(guān)閉這個(gè)連接。
2: 服務(wù)器定時(shí)詢問所有的客戶端,你們還活著么?如果活著,給我個(gè)回饋,沒得到回饋的客戶端,格殺勿論。
兩種心跳方案有什么區(qū)別?
第一種方案,對服務(wù)器和網(wǎng)絡(luò)的壓力更小,而且更具有靈活性,但需要客戶端配合定時(shí)發(fā)送心跳包。
第二種方案,對服務(wù)器和網(wǎng)絡(luò)壓力更大,不建議使用。
心跳在swoole里的實(shí)現(xiàn)
swoole采用的是第一種方案
swoole會(huì)在主進(jìn)程獨(dú)立起一個(gè)心跳線程,通過定時(shí)輪詢所有的連接,來判斷連接的生死,所以swoole的心跳不會(huì)堵塞任何業(yè)務(wù)邏輯。
那怎么判斷連接的生死了?swoole在connection結(jié)構(gòu)體中有 time_t last_time 字段,用來存放最后一次收包的時(shí)間戳,進(jìn)而通過與這個(gè)時(shí)間對比來判定是否存活
于是,swoole有兩個(gè)配置:
heartbeat_check_interval: 服務(wù)器定時(shí)檢測在線列表的時(shí)間
heartbeat_idle_time: 連接最大的空閑時(shí)間 (如果最后一個(gè)心跳包的時(shí)間與當(dāng)前時(shí)間之差超過這個(gè)值,則認(rèn)為該連接失效)
配置建議
建議 heartbeat_idle_time 為 heartbeat_check_interval 的兩倍多一點(diǎn)。
這個(gè)兩倍是為了進(jìn)行容錯(cuò),允許丟一個(gè)包
而多一點(diǎn)是考慮到網(wǎng)絡(luò)的延時(shí)。
你可以跟據(jù)實(shí)際的業(yè)務(wù)來調(diào)整這個(gè)容錯(cuò)率(允許丟幾個(gè)包)。
補(bǔ)充
1、系統(tǒng)層面也提供心跳機(jī)制,只不過粒度相對比較粗,而且時(shí)間稍長,沒有應(yīng)用層靈活
2、swoole還提供ping的功能,通過配置ping值,swoole內(nèi)核可以判斷只是一個(gè)心跳包,而不會(huì),也沒必要把數(shù)據(jù)包轉(zhuǎn)發(fā)應(yīng)用層(onReceive)。
3、心跳不只是swoole獨(dú)有,大多數(shù)tcp的網(wǎng)絡(luò)服務(wù)都會(huì)考慮到這個(gè)問題
本文原創(chuàng)發(fā)布php中文網(wǎng),轉(zhuǎn)載請注明出處,感謝您的尊重!
總結(jié)
以上是生活随笔為你收集整理的php swoole 心跳,聊聊swoole的心跳的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java编写一个集合类_Java集合类
- 下一篇: 农业农村银行贷款2000元24天多少利息