2015-11-11 23 views
0

我需要開發一種機制來將生產環境中運行的守護程序升級到新版本,而不會丟失客戶端(TCP)連接。這與nginx在升級到新版本時的作用類似。我需要這個去除錯誤或發佈次要版本更改,這可能是一天一次。守護進程是用C語言爲Linux平臺開發的。升級服務器可執行文件而不會丟失用戶的連接

的升級的過程會是這樣的:

  1. 的new_daemon將在命令行中指定的old_daemon
  2. 進程ID new_daemon將通過插座連接到舊的守護進程來運行發送/接收數據和消息。
  3. new_daemon會向old_daemon發送一條消息,以停止偵聽用於接收客戶端連接的PORT。在確認監聽服務被扣留後,new_daemon將開始監聽端口
  4. new_daemon會將消息發送到old_daemon以發送當前用戶連接的打開文件描述符。使用系統調用sendmsg(),old_daemon會傳遞new_daemon向內核分配的所有資源,不僅包括連接,還包括所有打開的文件。
  5. new_daemon會將消息發送到old_daemon以傳遞所有全局內存變量,old_daemon會通過兩個進程之間的套接字連接發送它。

這個過程非常複雜,所以我想問一下,如果有人可以提出一個更好的過程,或者有一些方法可以輕鬆地做到這一點?目標是在升級過程中停機時間最少。

TIA

回答

0

一種選擇是寫你最妖的共享庫,並使用dlopen的新功能融入到正在運行的進程。這意味着某些部分無法更改,並且您可能會遇到併發問題,但它不再需要IPC。

+0

我同意,這是最便宜的(在開發時間)替代方案。也許我會去的。但是這隻適用於數據結構(變量)不變的情況。所以,你的建議非常好,我沒有想到,但它仍然是解決方案的50%。 – Nulik

1

另一種替代方法是強制old_daemonfork()/exec()new_daemon立即停止接受。 new_daemon將自動繼承偵聽套接字,現有連接和打開文件(除非它們是fcntl'd到FD_CLOEXEC)。

這就是說,我不認爲有一個乾淨的方式來交出不完整的工作(正如我理解的步驟4和5試圖完成)。如果可能的話,讓old_daemon完成它們。

+0

謝謝,這是複製文件描述符的好方法。 +1。 – Nulik

相關問題