0

0

如何在 Golang 中优雅地关闭 HTTP 服务器

PHPz

PHPz

发布时间:2023-03-22 14:23:50

|

2856人浏览过

|

来源于php中文网

原创

golang (又称为 go) 是一门相对比较年轻的编程语言,它被广泛应用于后端服务和 api 的开发中。而 http 是一个常用的协议,很多 golang 开发人员会选择使用 golang 中自带的 http 包来进行 http 服务器的开发。然而,当我们需要关闭 http 服务器时会遇到一些问题。在本文中,我们将介绍如何在 golang 中优雅地关闭 http 服务器。

  1. HTTP 服务器的关闭方式

在 Golang 中,我们通常使用 http.ListenAndServe() 函数来启动 HTTP 服务器。该函数会一直运行直到程序被杀死或服务器关闭。如果我们直接关闭程序,HTTP 服务器就会立即停止运行。但是,这种方式并不是一个优雅的关闭方式,因为正在处理的客户端会被强制断开连接,这可能会导致数据丢失或异常。

另外一种关闭方式是使用服务端上下文(context)的 Done() 方法。当我们调用 Done() 方法时,HTTP 服务器会正确关闭并停止接受新的客户端连接,但仍会处理一些已经接受了的连接。这样虽然不会强制断开正在处理的客户端的连接,但仍可能会导致某些请求无响应的问题。

最后,我们还有一种优雅的关闭方式,即使用 http.Server 结构体中的 Shutdown() 方法。该方法会优雅地关闭 HTTP 服务器,即等待正在处理的请求处理完成后再关闭服务器。

  1. 实现 HTTP 服务器的优雅关闭

假设我们已经编写了以下代码用于启动 HTTP 服务器:

立即学习go语言免费学习笔记(深入)”;

package main

import (
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello World!"))
    })

    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

现在我们需要在程序退出时正确关闭 HTTP 服务器。我们可以采用以下步骤:

1) 创建一个 http.Server 实例,并将该实例的 Handler 属性设置为我们现有的 Handler 函数。

腾讯AI 开放平台
腾讯AI 开放平台

腾讯AI开放平台

下载
server := http.Server{
    Addr:    ":8080",
    Handler: http.DefaultServeMux,
}

2) 使用一个 goroutine 来启动 http.Server 的 ListenAndServe() 方法,以处理客户端连接请求。

go func() {
    if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        log.Fatal(err)
    }
}()

3) 在我们的程序退出时,使用 http.Server 的 Shutdown() 方法来安全地关闭服务器。

// 用于停止 HTTP 服务器的通道
stopChan := make(chan os.Signal)

// 监听 Interrupt 和 Terminate 信号
signal.Notify(stopChan, os.Interrupt, syscall.SIGTERM)

// 等待接收到信号,执行 Shutdown()
<-stopChan
log.Println("Shutting down server...")

// 等待处理完成的请求处理完成
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

if err := server.Shutdown(ctx); err != nil {
    log.Fatal(err)
}

log.Println("Server gracefully stopped.")

这段代码中我们首先创建了一个通道,用于监听操作系统发送的中断或终止信号(比如 Ctrl + C)。然后我们等待接收到信号,执行 Shutdown() 方法。在调用 Shutdown() 方法之前,我们使用 context.WithTimeout() 创建了一个上下文(Context),用于在规定的超时时间内等待正在处理的请求处理完成。待所有请求处理完成后,Shutdown() 方法能够安全地关闭 HTTP 服务器。

  1. 总结

本文介绍了在 Golang 中优雅地关闭 HTTP 服务器的方法。使用 http.Server 的 Shutdown() 方法能够优雅地关闭 HTTP 服务器,避免强制断开连接导致数据丢失或异常。

需要注意的是,若已经存在客户端和服务器正在处理的连接的情况下,服务器的关闭将需要等待这些连接被处理完毕,然后才能正常关闭。因此,为了更加确保完整的关闭,我们可以在调用 Shutdown() 方法之前使用 context.WithTimeout() 设置一个超时时间,以等待正在处理的请求处理完成。

希望本文对 Golang 开发人员在开发 HTTP 服务器时能够提供帮助。

相关专题

更多
Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

11

2026.01.12

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

106

2026.01.09

c++框架学习教程汇总
c++框架学习教程汇总

本专题整合了c++框架学习教程汇总,阅读专题下面的文章了解更多详细内容。

64

2026.01.09

学python好用的网站推荐
学python好用的网站推荐

本专题整合了python学习教程汇总,阅读专题下面的文章了解更多详细内容。

139

2026.01.09

学python网站汇总
学python网站汇总

本专题整合了学python网站汇总,阅读专题下面的文章了解更多详细内容。

13

2026.01.09

python学习网站
python学习网站

本专题整合了python学习相关推荐汇总,阅读专题下面的文章了解更多详细内容。

19

2026.01.09

俄罗斯手机浏览器地址汇总
俄罗斯手机浏览器地址汇总

汇总俄罗斯Yandex手机浏览器官方网址入口,涵盖国际版与俄语版,适配移动端访问,一键直达搜索、地图、新闻等核心服务。

93

2026.01.09

漫蛙稳定版地址大全
漫蛙稳定版地址大全

漫蛙稳定版地址大全汇总最新可用入口,包含漫蛙manwa漫画防走失官网链接,确保用户随时畅读海量正版漫画资源,建议收藏备用,避免因域名变动无法访问。

480

2026.01.09

php学习网站大全
php学习网站大全

精选多个优质PHP入门学习网站,涵盖教程、实战与文档,适合零基础到进阶开发者,助你高效掌握PHP编程。

52

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
golang socket 编程
golang socket 编程

共2课时 | 0.1万人学习

nginx浅谈
nginx浅谈

共15课时 | 0.8万人学习

golang和swoole核心底层分析
golang和swoole核心底层分析

共3课时 | 0.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号