GoFrame 高級(jí)特性-平滑重啟特性

2023-05-18 15:12 更新

平滑重啟(熱重啟)是指?WebServer?在重啟的時(shí)候不會(huì)中斷已有請(qǐng)求的執(zhí)行。該特性在不同的項(xiàng)目版本發(fā)布的時(shí)候特別有用,例如,當(dāng)需要先后發(fā)布兩個(gè)版本:A、B,那么在A執(zhí)行的過(guò)程當(dāng)中,我們可以將B的程序發(fā)布直接覆蓋A的程序,并使用平滑重啟特性(使用Web或者命令行)無(wú)縫地將請(qǐng)求過(guò)渡到新版本的服務(wù)中。

需要注意的是,該特性?xún)H限于?*nix?系統(tǒng)(?Linux/Unix/FreeBSD?等等),在Windows下僅支持完整重啟功能(請(qǐng)求無(wú)法平滑過(guò)渡)。

目前平滑重啟特性需要在本地打開(kāi)一個(gè)?10000?端口的?tcp?監(jiān)聽(tīng)服務(wù)(如果端口被占用,會(huì)遞加端口)。

默認(rèn)情況下平滑重啟特性是關(guān)閉的,可以通過(guò)配置選項(xiàng)打開(kāi)。

?gf?框架支持非常方便的?Web?管理功能,也就是說(shuō)我們可以通過(guò)?Web?頁(yè)面/接口直接進(jìn)行?WebServer?的重啟/關(guān)閉等管理操作。同時(shí),?gf?框架也支持通過(guò)命令行終端指令(僅限?*nix?系統(tǒng))的形式進(jìn)行?WebServer?的重啟/關(guān)閉等管理操作。

Web管理

我們先來(lái)看一下?WebServer?中涉及到管理操作方法有哪些:

func (s *Server) Restart(newExeFilePath...string) error
func (s *Server) Shutdown() error

func (s *Server) EnableAdmin(pattern ...string)

?Restart?用于重啟服務(wù)(?*nix?系統(tǒng)下為平滑重啟,windows下為完整重啟),?Shutdown?用于關(guān)閉服務(wù),?EnableAdmin?用于將管理頁(yè)面注冊(cè)到指定的路由規(guī)則上,默認(rèn)地址是?/debug/admin?(我們可以指定一個(gè)私密的管理地址,也可以使用中間件來(lái)對(duì)該頁(yè)面進(jìn)行鑒權(quán))。

以下對(duì)其中兩個(gè)方法做詳細(xì)說(shuō)明。

  • ?Restart ?

?Restart?的參數(shù)可指定自定義重啟的可執(zhí)行文件路徑(?newExeFilePath?),不傳遞時(shí)默認(rèn)為原可執(zhí)行文件路徑。特別是在windows系統(tǒng)下,當(dāng)可執(zhí)行文件正在使用時(shí),無(wú)法對(duì)其進(jìn)行文件替換更新(新版本文件替換老版本文件)。當(dāng)指定自定義的可執(zhí)行文件路徑后,?WebServer?重啟時(shí)將會(huì)執(zhí)行新版本的可執(zhí)行文件,不再使用老版本文件,這種特性簡(jiǎn)化了在某些系統(tǒng)上的版本更新流程。

  • ?EnableAdmin ?

首先,該方法為用戶(hù)管理?WebServer?提供了簡(jiǎn)便的頁(yè)面和接口,在單?WebServer?下管理非常方便,直接訪問(wèn)管理頁(yè)面點(diǎn)擊對(duì)應(yīng)鏈接即可。需要注意的是,由于帶有管理功能,如果是在生產(chǎn)環(huán)境上,建議自定義該管理地址為一個(gè)私密地址。

同時(shí),?EnableaAdmim?提供的?restart?接口也支持自定義可執(zhí)行文件路徑,直接通過(guò)?GET?參數(shù)往?restart?接口傳遞?newExeFilePath?變量即可,例如: http://127.0.0.1/debug/admin/restart?newExeFilePath=xxxxxxx

此外,在大多數(shù)時(shí)候,?WebServer?往往不只有1個(gè)節(jié)點(diǎn),因此大多數(shù)服務(wù)管理運(yùn)維中,例如:重啟操作,當(dāng)然不是直接訪問(wèn)每個(gè)?WebServer?的?admin?頁(yè)面手動(dòng)執(zhí)行重啟操作。而是充分利用?admin?頁(yè)面提供的功能接口,通過(guò)接口控制來(lái)實(shí)現(xiàn)統(tǒng)一的?WebServer?管理控制。

示例1:基本使用

package main

import (
    "time"
    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/os/gproc"
    "github.com/gogf/gf/v2/net/ghttp"
)

func main() {
    s := g.Server()
    s.BindHandler("/", func(r *ghttp.Request){
        r.Response.Writeln("哈嘍!")
    })
    s.BindHandler("/pid", func(r *ghttp.Request){
        r.Response.Writeln(gproc.Pid())
    })
    s.BindHandler("/sleep", func(r *ghttp.Request){
        r.Response.Writeln(gproc.Pid())
        time.Sleep(10*time.Second)
        r.Response.Writeln(gproc.Pid())
    })
    s.EnableAdmin()
    s.SetPort(8199)
    s.Run()
}

我們通過(guò)以下幾個(gè)步驟來(lái)測(cè)試平滑重啟:


  • 訪問(wèn) http://127.0.0.1:8199/sleep ,這個(gè)頁(yè)面將會(huì)執(zhí)行10秒,用于測(cè)試重啟時(shí)該頁(yè)面請(qǐng)求執(zhí)行是否會(huì)斷掉



  • 隨后我們點(diǎn)擊?restart?管理鏈接,?WebServer?將會(huì)立即平滑重啟(?*nix?系統(tǒng)下)


同時(shí)在終端也會(huì)輸出以下信息:

 2018-05-18 11:02:04.812 11511: http server started listening on [:8199]
 2018-05-18 11:02:09.172 11511: server reloading
 2018-05-18 11:02:09.172 11511: all servers shutdown
 2018-05-18 11:02:09.176 16358: http server restarted listening on [:8199]
  • 我們可以發(fā)現(xiàn)在整個(gè)操作中,?sleep?頁(yè)面的執(zhí)行并沒(méi)有被中斷,繼續(xù)等待幾秒,當(dāng)?sleep?執(zhí)行完成后,頁(yè)面輸出內(nèi)容為:


  • 可以發(fā)現(xiàn),?sleep?頁(yè)面輸出的進(jìn)程?pid?和之前的不一樣了,代表請(qǐng)求的執(zhí)行被新的進(jìn)程平滑接管,舊的服務(wù)進(jìn)程也隨之銷(xiāo)毀;

示例2:HTTPS支持

package main

import (
    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/net/ghttp"
)

func main() {
    s := g.Server()
    s.BindHandler("/", func(r *ghttp.Request){
        r.Response.Writeln("哈羅!")
    })
    s.EnableHTTPS("/home/john/temp/server.crt", "/home/john/temp/server.key")
    s.EnableAdmin()
    s.SetPort(8200)
    s.Run()
}

?gf?框架的平滑重啟特性對(duì)于?HTTPS?的支持也是相當(dāng)友好和簡(jiǎn)便,操作步驟如下:

  1. 訪問(wèn) https://127.0.0.1:8200/debug/admin/restart 平滑重啟?HTTPS?服務(wù);
  2. 訪問(wèn) https://127.0.0.1:8200/debug/admin/shutdown 平滑關(guān)閉?WebServer?服務(wù);

在命令行終端可以看到以下輸出信息:

2018-05-18 11:13:05.554 17278: https server started listening on [:8200]
2018-05-18 11:13:21.270 17278: server reloading
2018-05-18 11:13:21.270 17278: all servers shutdown
2018-05-18 11:13:21.278 17319: https server reloaded listening on [:8200]
2018-05-18 11:13:34.895 17319: server shutting down
2018-05-18 11:13:34.895 17269: all servers shutdown

示例3:多服務(wù)及多端口

?gf?框架的平滑重啟特性相當(dāng)強(qiáng)大及穩(wěn)定,不僅僅支持單一服務(wù)單一端口監(jiān)聽(tīng)管理,同時(shí)也支持多服務(wù)多端口等復(fù)雜場(chǎng)景的監(jiān)聽(tīng)管理。

package main

import (
    "github.com/gogf/gf/v2/frame/g"
)

func main() {
    s1 := g.Server("s1")
    s1.EnableAdmin()
    s1.SetPort(8100, 8200)
    s1.Start()

    s2 := g.Server("s2")
    s2.EnableAdmin()
    s2.SetPort(8300, 8400)
    s2.Start()

    g.Wait()
}

以上示例演示的是兩個(gè)?WebServer? s1及s2,分別監(jiān)聽(tīng)8100,8200及8300,8400。我們隨后訪問(wèn) http://127.0.0.1:8100/debug/admin/reload 平滑重啟服務(wù),然后再通過(guò) http://127.0.0.1:8100/debug/admin/shutdown 平滑關(guān)閉服務(wù),最終在終端打印出的信息如下:

2018-05-18 11:26:54.729 18111: http server started listening on [:8400]
2018-05-18 11:26:54.729 18111: http server started listening on [:8100]
2018-05-18 11:26:54.729 18111: http server started listening on [:8300]
2018-05-18 11:26:54.729 18111: http server started listening on [:8200]
2018-05-18 11:27:08.203 18111: server reloading
2018-05-18 11:27:08.203 18111: all servers shutdown
2018-05-18 11:27:08.207 18124: http server reloaded listening on [:8300]
2018-05-18 11:27:08.207 18124: http server reloaded listening on [:8400]
2018-05-18 11:27:08.207 18124: http server reloaded listening on [:8200]
2018-05-18 11:27:08.207 18124: http server reloaded listening on [:8100]
2018-05-18 11:27:19.379 18124: server shutting down
2018-05-18 11:27:19.380 18102: all servers shutdown

命令行管理

?gf?框架除了提供?Web?方式的管理能力以外,也支持命令行方式來(lái)進(jìn)行管理,由于命令行采用了信號(hào)量進(jìn)行管理,因此僅支持?*nix?系統(tǒng)。

重啟服務(wù)

使用?SIGUSR1?信號(hào)量實(shí)現(xiàn),使用方式:

kill -SIGUSR1 進(jìn)程ID

關(guān)閉服務(wù)

使用?SIGINT/SIGQUIT/SIGKILL/SIGHUP/SIGTERM?其中任意一個(gè)信號(hào)量來(lái)實(shí)現(xiàn),使用方式:

kill -SIGTERM 進(jìn)程ID

其他管理方式

由于?gf?框架的?WebServer?采用了單例設(shè)計(jì),因此任何地方都可以通過(guò)?g.Server(名稱(chēng))?或者?ghttp.GetServer(名稱(chēng))?來(lái)獲得對(duì)應(yīng)?WebServer?的單例對(duì)象,隨后通過(guò)?Restart?和?Shutdown?方法可以實(shí)現(xiàn)對(duì)該?WebServer?的管理。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)