zzh@ZZHPC:/zdata/Github/greenlight$ go run ./cmd/api time=2024-11-18T19:49:43.864+08:00 level=INFO msg="database connection pool established" time=2024-11-18T19:49:43.864+08:00 level=INFO msg="starting server" addr=:4000 env=development
Doing this should start a process with the name api on your machine. You can use the pgrep command to verify that this process exists, like so:
zzh@ZZHPC:~$ pgrep -l api 25711 api
Once that’s confirmed, go ahead and try sending a SIGKILL signal to the api process using the pkill command like so:
zzh@ZZHPC:~$ ps -ef | grep 25711 zzh 25711 25576 0 19:49 pts/0 00:00:00 /tmp/go-build3971774478/b001/exe/api zzh 25976 9327 0 19:53 pts/1 00:00:00 grep --color=auto 25711 zzh@ZZHPC:~$ pkill -SIGKILL api
zzh@ZZHPC:/zdata/Github/greenlight$ go run ./cmd/api time=2024-11-18T19:49:43.864+08:00 level=INFO msg="database connection pool established" time=2024-11-18T19:49:43.864+08:00 level=INFO msg="starting server" addr=:4000 env=development signal: killed
Feel free to repeat the same process, but sending a SIGTERM signal instead:
zzh@ZZHPC:~$ pgrep -l api 26248 api zzh@ZZHPC:~$ pkill -SIGTERM api
zzh@ZZHPC:/zdata/Github/greenlight$ go run ./cmd/api time=2024-11-18T19:56:08.698+08:00 level=INFO msg="database connection pool established" time=2024-11-18T19:56:08.698+08:00 level=INFO msg="starting server" addr=:4000 env=development signal: terminated
zzh@ZZHPC:~$ pgrep -l api 26488 api zzh@ZZHPC:~$ pkill -SIGQUIT api
zzh@ZZHPC:/zdata/Github/greenlight$ go run ./cmd/api time=2024-11-18T19:58:36.775+08:00 level=INFO msg="database connection pool established" time=2024-11-18T19:58:36.775+08:00 level=INFO msg="starting server" addr=:4000 env=development SIGQUIT: quit PC=0x476461 m=0 sigcode=0 goroutine 0 gp=0xa18580 m=0 mp=0xa191e0 [idle]: runtime.futex(0xa19320, 0x80, 0x0, 0x0, 0x0, 0x0) /home/zzh/.goenv/versions/1.23.0/src/runtime/sys_linux_amd64.s:557 +0x21 fp=0x7ffee822bb60 sp=0x7ffee822bb58 pc=0x476461 runtime.futexsleep(0x7ffee822bbd8?, 0x40da90?, 0x1e822bc08?) /home/zzh/.goenv/versions/1.23.0/src/runtime/os_linux.go:69 +0x30 fp=0x7ffee822bbb0 sp=0x7ffee822bb60 pc=0x432c10 runtime.notesleep(0xa19320) /home/zzh/.goenv/versions/1.23.0/src/runtime/lock_futex.go:170 +0x87 fp=0x7ffee822bbe8 sp=0x7ffee822bbb0 pc=0x40dc27 runtime.mPark(...) /home/zzh/.goenv/versions/1.23.0/src/runtime/proc.go:1866 runtime.stopm() /home/zzh/.goenv/versions/1.23.0/src/runtime/proc.go:2885 +0x8c fp=0x7ffee822bc18 sp=0x7ffee822bbe8 pc=0x43e16c runtime.findRunnable() /home/zzh/.goenv/versions/1.23.0/src/runtime/proc.go:3622 +0xd5c fp=0x7ffee822bd90 sp=0x7ffee822bc18 pc=0x43fbdc runtime.schedule() /home/zzh/.goenv/versions/1.23.0/src/runtime/proc.go:3995 +0xb1 fp=0x7ffee822bdc8 sp=0x7ffee822bd90 pc=0x440cb1 runtime.park_m(0xc0000061c0) /home/zzh/.goenv/versions/1.23.0/src/runtime/proc.go:4102 +0x1eb fp=0x7ffee822be20 sp=0x7ffee822bdc8 pc=0x4410cb runtime.mcall() /home/zzh/.goenv/versions/1.23.0/src/runtime/asm_amd64.s:459 +0x4e fp=0x7ffee822be38 sp=0x7ffee822be20 pc=0x47266e goroutine 1 gp=0xc0000061c0 m=nil [IO wait]: runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?) /home/zzh/.goenv/versions/1.23.0/src/runtime/proc.go:424 +0xce fp=0xc00014f9c8 sp=0xc00014f9a8 pc=0x46cbce runtime.netpollblock(0x10?, 0x405be6?, 0x0?) /home/zzh/.goenv/versions/1.23.0/src/runtime/netpoll.go:575 +0xf7 fp=0xc00014fa00 sp=0xc00014f9c8 pc=0x431eb7 internal/poll.runtime_pollWait(0x78b3a509d6a0, 0x72) /home/zzh/.goenv/versions/1.23.0/src/runtime/netpoll.go:351 +0x85 fp=0xc00014fa20 sp=0xc00014fa00 pc=0x46bec5 internal/poll.(*pollDesc).wait(0xc000130400?, 0x10?, 0x0) /home/zzh/.goenv/versions/1.23.0/src/internal/poll/fd_poll_runtime.go:84 +0x27 fp=0xc00014fa48 sp=0xc00014fa20 pc=0x4c3c07 internal/poll.(*pollDesc).waitRead(...) /home/zzh/.goenv/versions/1.23.0/src/internal/poll/fd_poll_runtime.go:89 internal/poll.(*FD).Accept(0xc000130400) ...
exit status 2
package main import ( "fmt" "log/slog" "net/http" "time" ) func (app *application) serve() error { srv := &http.Server{ Addr: fmt.Sprintf(":%d", app.config.port), Handler: app.routes(), IdleTimeout: time.Minute, ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, ErrorLog: slog.NewLogLogger(app.logger.Handler(), slog.LevelError), } app.logger.Info("starting server", "addr", srv.Addr, "env", app.config.env) return srv.ListenAndServe() }
With that in place, we can simplify our main() function to use this new app.serve() method like so:
... // Call app.serve() to start the server. err = app.serve() if err != nil { logger.Error(err.Error()) os.Exit(1) } ...
func (app *application) serve() error { srv := &http.Server{ Addr: fmt.Sprintf(":%d", app.config.port), Handler: app.routes(), IdleTimeout: time.Minute, ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, ErrorLog: slog.NewLogLogger(app.logger.Handler(), slog.LevelError), } // Start a background goroutine to catch signals. go func() { quit := make(chan os.Signal, 1) // Use signal.Notify() to listen for incoming SIGINT and SIGTERM signals and // relay them to the quit channel. signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // Read the signal from the quit channel. This code will block until a signal is received. s := <- quit app.logger.Info("caught signal", "signal", s.String()) os.Exit(0) }() app.logger.Info("starting server", "addr", srv.Addr, "env", app.config.env) return srv.ListenAndServe() }
zzh@ZZHPC:/zdata/Github/greenlight$ go run ./cmd/api time=2024-11-18T20:35:36.803+08:00 level=INFO msg="database connection pool established" time=2024-11-18T20:35:36.803+08:00 level=INFO msg="starting server" addr=:4000 env=development ^Ctime=2024-11-18T20:35:38.712+08:00 level=INFO msg="caught signal" signal=interrupt
zzh@ZZHPC:~$ pkill -SIGTERM api
zzh@ZZHPC:/zdata/Github/greenlight$ go run ./cmd/api time=2024-11-18T20:36:52.920+08:00 level=INFO msg="database connection pool established" time=2024-11-18T20:36:52.920+08:00 level=INFO msg="starting server" addr=:4000 env=development time=2024-11-18T20:37:16.602+08:00 level=INFO msg="caught signal" signal=terminated
func (app *application) serve() error { srv := &http.Server{ Addr: fmt.Sprintf(":%d", app.config.port), Handler: app.routes(), IdleTimeout: time.Minute, ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, ErrorLog: slog.NewLogLogger(app.logger.Handler(), slog.LevelError), } // The shutdownError channel is used to receive any errors returned by the // graceful Shutdown() function. shutdownError := make(chan error) // Start a background goroutine to catch signals. go func() { quit := make(chan os.Signal, 1) // Use signal.Notify() to listen for incoming SIGINT and SIGTERM signals and // relay them to the quit channel. signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // Read the signal from the quit channel. This code will block until a signal is received. s := <- quit app.logger.Info("shutting down server", "signal", s.String()) ctx, cancel := context.WithTimeout(context.Background(), 30 * time.Second) defer cancel() shutdownError <- srv.Shutdown(ctx) }() app.logger.Info("starting server", "addr", srv.Addr, "env", app.config.env) err := srv.ListenAndServe() if !errors.Is(err, http.ErrServerClosed) { return err } err = <-shutdownError if err != nil { return err } app.logger.Info("stopped server", "addr", srv.Addr) return nil }
func (app *application) healthcheckHandler(w http.ResponseWriter, r *http.Request) { data := envelope{ "status": "available", "system_info": map[string]string{ "environment": app.config.env, "version": version, }, } // Add a 4 second delay. time.Sleep(4 * time.Second) err := app.writeJSON(w, http.StatusOK, data, nil) if err != nil { app.serverErrorResponse(w, r, err) } }
zzh@ZZHPC:~$ curl localhost:4000/v1/healthcheck & pkill -SIGTERM api [1] 33833 (此行命令执行后立即出现) zzh@ZZHPC:~$ { "status": "available", "system_info": { "environment": "development", "version": "1.0.0" } } (以上输出在命令执行后4秒出现。光标停在此,好几分钟后按回车键才出现下面一行) [1]+ Done curl localhost:4000/v1/healthcheck zzh@ZZHPC:~$
zzh@ZZHPC:/zdata/Github/greenlight$ go run ./cmd/api time=2024-11-18T21:27:01.271+08:00 level=INFO msg="database connection pool established" time=2024-11-18T21:27:01.271+08:00 level=INFO msg="starting server" addr=:4000 env=development time=2024-11-18T21:27:02.114+08:00 level=INFO msg="shutting down server" signal=terminated(此行在 curl & pkill 命令执行后立即出现,因为该日志是在srv.Shutdown(ctx)之前) time=2024-11-18T21:27:06.295+08:00 level=INFO msg="stopped server" addr=:4000 (此行在 curl & pkill 命令执行后4秒出现)
标签:Chapter,11,00,app,zzh,Let,time,go,runtime From: https://www.cnblogs.com/zhangzhihui/p/18553720