Smooth restart (hot reload) means the WebServer can restart without interrupting existing request execution. This feature is especially useful during different project version releases. For instance, when needing to release two versions: A and B, during the execution of A, we can directly overwrite A‘s program with B and use the graceful restart feature (using Web or command line) to seamlessly transition requests to the new version of the service.

The GoFrame framework supports very convenient web management features, which means we can directly manage Server restart/shutdown operations through a web page/API. Additionally, the framework also supports Server restart/shutdown operations through command line terminal commands (limited to *nix systems).

Feature Activation

By default, the graceful restart feature is disabled, and it can be turned on via the graceful configuration option. Please refer to the WebServer configuration management section for details: Configuration - File Template

Graceful Restart - 图1tip

Currently, the graceful restart feature requires randomly opening a TCP listening service on a local port for communication and state information exchange between new and old processes.

Notes

  • This feature is limited to *nix systems (Linux/Unix/FreeBSD, etc.), and on Windows, it only supports complete restart (requests cannot transition smoothly).
  • Please do not use IDE run (e.g., Goland) or the go run command to run processes when testing the graceful restart feature, as these methods create a parent process to manage the running Go process, which can cause failures in state exchange between child and parent processes during a graceful restart.
  • The SetGraceful configuration method in the subsequent examples is newly added after version v2.7.4. For versions below v2.7.4, please use the configuration management method to enable the graceful restart feature.

Management Methods

First, let’s look at the management methods involved in the WebServer:

  1. func (s *Server) Restart
  2. (newExeFilePath...
  3. string
  4. ) error
  5. func (s *Server) Shutdown
  6. (
  7. ) error
  8. func (s *Server) EnableAdmin
  9. (pattern ...
  10. string
  11. )

Restart is used to restart the service (graceful restart on *nix systems, complete restart on Windows), Shutdown is used to close the service, and EnableAdmin is used to register the management page with the specified routing rules. The default address is /debug/admin (we can specify a private management address or use middleware to authenticate the page).

The following details two of these methods.

Restart

The Restart parameter can specify the custom executable file path for restart (newExeFilePath). If not provided, it defaults to the original executable file path. Especially under the Windows system, when the executable file is in use, it cannot be replaced or updated (new version file replacing the old version file). By specifying a custom executable file path, when the Server restarts, it will execute the new version of the executable file instead of the old one, simplifying the version update process on some systems.

EnableAdmin

  • Firstly, this method provides users with a convenient page and API for managing the Server, which is very convenient for managing a single Server. By directly accessing and clicking the corresponding links on the management page, operations can be performed. It is important to note that, due to the management features, if used in production environments, it is recommended to customize the management address to a private address.
  • Additionally, the restart API provided by EnableAdmin also supports custom executable file paths, directly passing the newExeFilePath variable to the restart API through GET parameters, e.g., http://127.0.0.1/debug/admin/restart?newExeFilePath=xxxxxxx
  • Furthermore, in most cases, Server often has more than 1 node, so in most service management operations, such as restart operations, it is not directly accessing the admin page of each Server to manually execute the restart operation. Instead, it fully utilizes the functional APIs provided by the admin page to achieve unified Server management control through API control.

Example 1: Basic Usage

  1. package main
  2. import (
  3. "time"
  4. "github.com/gogf/gf/v2/frame/g"
  5. "github.com/gogf/gf/v2/net/ghttp"
  6. "github.com/gogf/gf/v2/os/gproc"
  7. )
  8. func main() {
  9. s := g.Server()
  10. s.BindHandler("/", func(r *ghttp.Request) {
  11. r.Response.Writeln("Hello!")
  12. })
  13. s.BindHandler("/pid", func(r *ghttp.Request) {
  14. r.Response.Writeln(gproc.Pid())
  15. })
  16. s.BindHandler("/sleep", func(r *ghttp.Request) {
  17. r.Response.Writeln(gproc.Pid())
  18. time.Sleep(10 * time.Second)
  19. r.Response.Writeln(gproc.Pid())
  20. })
  21. s.SetGraceful(true)
  22. s.EnableAdmin()
  23. s.SetPort(8199)
  24. s.Run()
  25. }

We test graceful restart through the following steps:

  1. Visit http://127.0.0.1:8199/pid to view the current process pid

Graceful Restart - 图2

  1. Visit http://127.0.0.1:8199/sleep, this page will execute for 10 seconds, used for testing whether the page request execution will be interrupted during a restart

Graceful Restart - 图3

  1. Visit http://127.0.0.1:8199/debug/admin, which is a WebServer management page registered by default after s.EnableAdmin

Graceful Restart - 图4

  1. Then we click the restart management link, and the WebServer will immediately smoothly restart (on *nix systems)

Graceful Restart - 图5

Meanwhile, the terminal will output the following information:

  1. 2018-05-18 11:02:04.812 11511: http server started listening on [:8199]
  2. 2018-05-18 11:02:09.172 11511: server reloading
  3. 2018-05-18 11:02:09.172 11511: all servers shutdown
  4. 2018-05-18 11:02:09.176 16358: http server restarted listening on [:8199]
  1. We can observe that during the entire operation, the execution of the sleep page was not interrupted, and after waiting a few seconds, when the sleep execution is finished, the page output is:

Graceful Restart - 图6

  1. It can be found that the process pid output on the sleep page is different from before, indicating that the request’s execution was smoothly taken over by the new process, and the old service process was subsequently destroyed;

Example 2: HTTPS Support

  1. package main
  2. import (
  3. "github.com/gogf/gf/v2/frame/g"
  4. "github.com/gogf/gf/v2/net/ghttp"
  5. )
  6. func main() {
  7. s := g.Server()
  8. s.BindHandler("/", func(r *ghttp.Request){
  9. r.Response.Writeln("Hello!")
  10. })
  11. s.SetGraceful(true)
  12. s.EnableHTTPS("/home/john/temp/server.crt", "/home/john/temp/server.key")
  13. s.EnableAdmin()
  14. s.SetPort(8200)
  15. s.Run()
  16. }

The graceful restart feature of the GoFrame framework is also very user-friendly and simple for HTTPS support. The operation steps are as follows:

  1. Visit https://127.0.0.1:8200/debug/admin/restart to smoothly restart the HTTPS service;
  2. Visit https://127.0.0.1:8200/debug/admin/shutdown to smoothly shut down the WebServer service;

The following output information can be seen in the command line terminal:

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

Example 3: Multi-Service and Multi-Port

The graceful restart feature of the GoFrame framework is quite powerful and stable, supporting not only single service and single port listening management but also complex scenarios involving multi-service and multi-port listening management.

  1. package main
  2. import (
  3. "github.com/gogf/gf/v2/frame/g"
  4. )
  5. func main() {
  6. s1 := g.Server("s1")
  7. s1.SetGraceful(true)
  8. s1.EnableAdmin()
  9. s1.SetPort(8100, 8200)
  10. s1.Start()
  11. s2 := g.Server("s2")
  12. s2.SetGraceful(true)
  13. s2.EnableAdmin()
  14. s2.SetPort(8300, 8400)
  15. s2.Start()
  16. g.Wait()
  17. }

The example above demonstrates two WebServers, s1 and s2, respectively listening on 8100, 8200, and 8300, 8400. We then visit http://127.0.0.1:8100/debug/admin/reload to smoothly restart the service, and then `http://127.0.0.1:8100/debug/admin/shutdown](http://127.0.0.1:8100/debug/admin/shutdown)\) to smoothly shut down the service. The final information printed in the terminal is as follows:

  1. 2018-05-18 11:26:54.729 18111: http server started listening on [:8400]
  2. 2018-05-18 11:26:54.729 18111: http server started listening on [:8100]
  3. 2018-05-18 11:26:54.729 18111: http server started listening on [:8300]
  4. 2018-05-18 11:26:54.729 18111: http server started listening on [:8200]
  5. 2018-05-18 11:27:08.203 18111: server reloading
  6. 2018-05-18 11:27:08.203 18111: all servers shutdown
  7. 2018-05-18 11:27:08.207 18124: http server reloaded listening on [:8300]
  8. 2018-05-18 11:27:08.207 18124: http server reloaded listening on [:8400]
  9. 2018-05-18 11:27:08.207 18124: http server reloaded listening on [:8200]
  10. 2018-05-18 11:27:08.207 18124: http server reloaded listening on [:8100]
  11. 2018-05-18 11:27:19.379 18124: server shutting down
  12. 2018-05-18 11:27:19.380 18102: all servers shutdown

Command Line Management

Apart from providing Web management capabilities, the GoFrame framework also supports management via command line, as the command line uses signals for management.

Restart Service

Use the SIGUSR1 signal, usage:

  1. kill -SIGUSR1 process ID

Shut Down Service

Use any one of the SIGINT/SIGQUIT/SIGKILL/SIGHUP/SIGTERM signals, usage:

  1. kill -SIGTERM process ID

Other Management Methods

Since the WebServer of the GoFrame framework adopts a singleton design, the corresponding Server singleton object can be obtained anywhere through g.Server(name), and then managed using the Restart and Shutdown methods.