beego 優雅重啓

前言

最近在寫 go 的項目, http 用的 beego 框架. 因爲 go 不想 php, 每次代碼改動都需要重啓服務, 所以代碼發上線之後, 如何重啓服務就成了一個問題. 如果強行重啓的話, 不光在重啓期間的所有訪問都被拒絕了, 而且在殺掉進程的時候處理中的請求也掛了. 對於一個向用戶正常提供服務的服務器來說, 這種情況自然是無法容忍的.

在我的設想中, 服務的重啓應該是啓動進程處理新的請求, 而老進程則等待將現有請求處理完再退出, 這樣就可以無縫重啓了.

想法是好的, 結果網上搜了半天, 都是針對 http 系統模塊的, 沒有找到 beego 的優雅重啓. 但是我還很納悶, 這麼流行的框架, 竟然沒有人寫過? (當然, 後面完美的證明了我的愚蠢)

嘗試

在我搜了半天沒有找到的時候, 機智的我自然就要動手自己搞了.在我的設想中, 大概分爲以下三步:

  1. 接收服務重啓的命令
  2. 老進程停止接收請求並在現有請求處理完後退出
  3. 啓動新進程處理新的請求

想法是好的, 接下來就是如何實現了, 一步一步來.

第一步很簡單, 說白了就是如何向進程發送消息, 我嘗試了修改本地文件, 也想過用消息隊列, 不過最終還是選擇了大多數人的選擇, kill命令發送信號量.

準備開始第二步了, 這個時候就坑了. 首先, beego的運行只有一條命令beego.run(). 很顯然, 它將http封裝了起來, 所以要想在停止端口監聽的同時, 進程繼續處理現有請求, 只有兩條路走. 一是beego有暴露的方法支持停止端口監聽的操作. 二就是重寫beego源碼. 而重寫源碼就意味着之後就不能跟着版本進行更新了, 所以是下下策.

不管怎麼說吧, 先對beego的啓動機制有個瞭解是必要的. 就從run方法進去. 而就在我進入方法走了沒兩步, 看到了這樣的代碼:

image-20200824225931977

看註釋. 啓動優雅模式. 這這這這, 這不就是我要的麼?????? 這我整半天整了個毛啊, 人家一開始就支持. 嘗試一下, 將值置爲 true 試一下:

beego.BConfig.Listen.Graceful = true

那麼問題來了, beego是如何接收信號的呢? 從下面調用的ListenAndServe 方法走進去. 找到啓動信號監聽的地方, 然後看一下監聽的是哪個信號就可以了. 結果, 往裏走了兩個方法就找到了:

image-20200824230912629

顯然, 通過HUP信號會啓動子進程來實現優雅重啓, 而INT信號會令進程停止. 然後我驗證了一下.

  1. beego運行前修改其配置: beego.BConfig.Listen.Graceful = true
  2. 通過kill -HUP pid命令重啓.

image-20200824231324850

簡單試了一下, 確實實現了優雅重啓. 原進程會在請求處理完之後停止.

另外, 也可以在app.conf中通過配置來啓動優雅重啓:

Graceful=false

總結

最後, 我到google重新搜了一下: beego graceful. 結果發下其赫然躺在搜索結果的第一條. 我???

所以, 之後要儘量使用英文關鍵詞搜索, 中文搜索有時定位不到準確的結果, 反而浪費了大量時間. 就比如這次, 如果最開始搜到了這條, 可能十幾分鍾就搞出來了. 偏偏最後我翻源碼翻了幾個小時, 得出的結論和那十幾分鐘的還是一樣的. 好氣呀.

謹以此記錄我這被自己坑的一次.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章