搜了一下好像並沒有文章講這件事,網上的tcp遷移
貌似講的都是閘道器,跟upstream
直連偷偷換連線(偷改四元組,類似負載均衡);不過我說的可能跟其他人看到標題時候想的也不一樣,實際主要說的是熱更新tcp長鏈不斷。
主要也是看了mosn(螞蟻版本envoy)原始碼,這塊挺有意思的。
實際上我也沒有完全看明白它的實現,裡面**封裝太多層(抽象,也不好除錯)。比方說,conntion
遷移的時候是和reader buffer
的資料一起過去了,如何避免中間時間差的read buffer
;我只是翻懂了大致的思路,然後自己寫出來乙個(寫法上有一些差異)。
關於熱更新:類似nginx或者go http服務的熱更新,一般都比較熟知大致流程;
新程序繼承listen port(子程序繼承),並且接受新的http請求;
舊程序上面已存在的http請求正常執行至結束,舊程序在所有http請求關閉後自動退出;
所以新舊程序短時間可能會同時存在執行。
可以拿nginx和python來做個試驗。
第一步:可以看到nginx監聽了80埠,沒有任何連線過來
第二步:利用python的requests庫發http請求,注意呼叫session()是為了保持tcp暫時不斷
第三步:可以看見tcp已經保持不斷,隨後nginx -s reload
平滑重啟nginx,發現舊程序上面的長鏈tcp伺服器端主動斷了
新舊server程序切換時,如何保證client和server之間tcp長鏈不斷?
主要利用linux可以傳送 control message 格式,來傳遞fd(包括listener/tcp conntion 都是可以的)
需要注意一些細節,例如read buffer
傳過去的時機;又或者因為現在的tcp
是雙工的,所以對於write
的conntion
是不需要重複傳遞的,因為read
的conntion
已經發過一次了。
我寫了乙個極小demo,留作記錄
我的程式會指定監聽埠,當客戶端連線上來的時候,無論傳送過來,只有看到'#',就會把字串擷取加上指定的字首吐出去
舉個栗子
因為// 程式編譯、執行
go build -o main
./main -l :8081 -p hello
// 然後就不用看上面服務端的日誌,主要看下面客戶端返回
// 客戶端使用nc連線並傳送資料
nc 127.0.0.1 8081
// 傳送
123#456#789
// 收到
hello reply : 123#
hello reply : 456#
789
後面沒有'#'號,所以程式並沒有把789
返回
全流程下來 nc 與服務端的連線沒有斷鏈(可以任意中途netstat -anp檢視連線),tcp保持長鏈無感// 這個時候啟動新的程序
./main -p world
//並且把`789`後續的`#`補上發出去,你會發現nc收到了
world reply: 789#
// 最終舊程序平滑關閉
附乙份**的流程圖,防止忘了
C 關閉其他程式視窗 程序
下面介紹我所知的兩種方法,應該對大家有幫助,如果有朋友知道其他的方法,謝謝共享一下。方法1procname 需要關閉的程序名稱 private bool closeproc string procname return result 上面程式裡定義了乙個arraylist,當不知道所要關閉的程序的具...
C 關閉程序
我們可以使用getprocess方法得到當前所有程序的物件,然後遍歷這些物件通過程序名來關閉程序 注意程序名不包括字尾,如 vstesthost.exe 程序應該寫作 vstesthost 判斷時候使用 if vstesthost myprocess.processname 來做判斷即可。syste...
根據包名關閉其他應用或者程序
根據包名關閉乙個後台應用,正處於前台的應用關不了,帶通知欄的服務也屬於前台程序,關閉不了 需要許可權kill background processes param context param packagename try catch exception ex 根據包名關閉應用,已被棄用,聽說原始碼...