如何在Golang包中启动不阻塞主程序的Web服务器
问题解决:Go包启动Web服务器同时主程序正常完成并保持服务器运行
问题根源分析
- 直接调用
RunServer阻塞主程序:原代码中log.Fatal(http.ListenAndServe(...))会先阻塞在ListenAndServe(该方法会一直运行直到服务器停止),一旦出现错误还会直接调用os.Exit终止程序,导致主程序无法执行完自身逻辑。 - goroutine中启动服务器无法访问:主程序执行完自身逻辑后会直接退出,Go运行时会终止所有未完成的goroutine,服务器进程还未稳定启动就被杀死,因此浏览器无法连接。
解决方案
步骤1:修改包内代码,移除log.Fatal并支持优雅关闭
调整包的RunServer函数,返回服务器实例和错误,同时保存http.Server对象用于后续优雅关闭:
package mypackage import ( "context" "log" "net/http" ) type HandleServer struct { mux *http.ServeMux server *http.Server } func NewMux() *HandleServer { return &HandleServer{ mux: http.NewServeMux(), } } // RunServer 启动Web服务器,返回服务器实例和启动错误 func RunServer() (*HandleServer, error) { h := NewMux() h.registerHandlers() h.server = &http.Server{ Addr: ":8001", Handler: h.mux, } // 启动服务器在goroutine中,避免阻塞调用方 go func() { if err := h.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Printf("服务器运行异常: %v", err) } }() return h, nil } func (h *HandleServer) registerHandlers() { h.mux.HandleFunc("/", h.rootHandler) } func (h *HandleServer) rootHandler(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("root handler")) } // Shutdown 优雅关闭服务器 func (h *HandleServer) Shutdown(ctx context.Context) error { return h.server.Shutdown(ctx) }
步骤2:主程序调用逻辑调整
主程序在完成自身业务逻辑后,需要等待信号来保持程序运行,确保服务器goroutine持续存活,同时支持优雅关闭:
package main import ( "context" "log" "mypackage" "os" "os/signal" "syscall" "time" ) func main() { // 执行主程序自身业务逻辑 log.Println("主程序业务逻辑执行完成") // 启动Web服务器 server, err := mypackage.RunServer() if err != nil { log.Fatalf("服务器启动失败: %v", err) } // 监听中断信号(Ctrl+C 或者系统终止信号) sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) <-sigChan // 优雅关闭服务器,等待5秒处理剩余请求 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := server.Shutdown(ctx); err != nil { log.Fatalf("服务器关闭失败: %v", err) } log.Println("服务器已优雅关闭") }
关键说明
- 包内不再使用
log.Fatal,而是将错误返回给主程序处理,避免直接终止整个进程。 - 主程序通过监听系统信号保持运行状态,确保服务器goroutine可以持续处理请求。
- 新增的
Shutdown方法支持优雅关闭服务器,允许处理完当前正在进行的请求后再停止。
内容的提问来源于stack exchange,提问作者Leahcim
相关产品推荐
相关产品推荐

