php小编西瓜在这篇文章中为大家介绍Worker和HTTP服务器的正常关闭。在开发过程中,正确关闭Worker和HTTP服务器是非常重要的,可以确保资源的释放和程序的正常退出。本文将详细讲解如何正确关闭Worker和HTTP服务器,以及一些常见的问题和解决方法。让我们一起来学习如何保证服务器的正常关闭,提高应用程序的稳定性和可靠性。
问题内容
我正在尝试创建一个独立启动的工作进程和一个 http 服务器,并侦听终止并在完成后正常退出。
由于某种原因,工作线程启动,但 http 服务器没有启动,直到发送 sigterm 事件。只有在发送 sigterm 事件后,http 服务器才会启动。下面的问题出在哪里?
输出
https://gosamples.dev is the best
https://gosamples.dev is the best
https://gosamples.dev is the best
^c2023/05/27 15:07:52 listening on http server port:
process finished with the exit code 0
登录后复制
代码
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
go func() {
signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Interrupt, syscall.SIGTERM)
登录后复制
解决方法
如果我正确地阅读了您的代码,您将在定义路由处理程序之前启动服务器。这意味着当服务器启动时,它不知道您的 /readiness
和 /liveness
端点,因为您尚未添加它们。结果,服务器启动,但它不执行任何操作,因为它没有要处理的路由。
然后,您不会在 http.server
实例中定义 addr
字段。 listenandserve()
使用调用它的 http.server
实例的 addr
字段中定义的地址。如果为空,则默认为 ":http"
,但这在您的代码中没有明确说明,可能会导致混乱。
我将 srv.listenandserve
移至 startserver 的最末尾。我错过了什么?
问题不在于 srv.listenandserve
在函数中的位置,而在于如何配置 http.server
以及何时设置 http 处理程序。
在原始代码中,您在服务器启动后设置 http 处理程序。需要在启动服务器之前设置处理程序,因为一旦服务器运行,它将不会拾取稍后定义的任何新处理程序。
并且日志语句log.printf("listening on http server port: %s", srv.addr)
位于srv.listenandserve()
之后,这是一个阻塞调用。这意味着日志语句只会在服务器停止后运行,这就是为什么您只能在发送 sigterm 信号后才能看到它。
尝试重新组织您的 startserver
函数,如下所示:
func startServer(ctx context.Context) error {
srv := &http.Server{
Addr: ":8080", // Define the address where you want the server to listen
}
http.HandleFunc("/readiness", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
})
http.HandleFunc("/liveness", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
})
go func() {
登录后复制
在 startserver
函数的修改版本中,服务器现在知道您的 /readiness
和 /liveness
端点,因为它们是在服务器启动之前定义的。
http 处理程序在服务器启动之前设置,并且日志语句在服务器启动之前打印。这应该可以解决您的问题并允许服务器按预期启动和处理请求。另外,现在服务器知道在哪里监听,因为 addr
已明确定义。
以上就是Worker 和 HTTP 服务器正常关闭的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!