0

0

解析golang中如何优雅地关闭http服务

PHPz

PHPz

发布时间:2023-04-11 10:43:28

|

1559人浏览过

|

来源于php中文网

原创

golang是一种非常流行的编程语言,它具有高效的并发处理能力和优秀的性能表现。相信许多golang的开发人员都会遇到一个这样的问题,在golang中如何优雅地关闭http服务?

首先,我们需要知道,创建一个http服务是比较容易的,只需要几行代码就可以搞定。例如下面这个简单的示例:

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello")
    })
    http.ListenAndServe(":8080", nil)
}

这里我们新建了一个http服务,监听本地的8080端口,每次访问会返回一个"Hello"。但如何优雅的关闭此服务呢?

常用的方法是使用os.Signal管理服务的生命周期。os.Signal是操作系统给进程发送的中断信号,比如Ctrl+C等,目的是要求程序终止执行。在golang中,我们可以监听这些信号,然后在接收到信号后执行一些钩子函数,以实现优雅地关闭http服务。

具体实现如下:

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

package main

import (
    "context"
    "fmt"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello")
    })
    srv := &http.Server{Addr: ":8080"}

    signalChan := make(chan os.Signal, 1)
    signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)

    go func() {
        sig := <-signalChan
        fmt.Printf("Signal Received: %s,  Gracefully shutting down...\n", sig)
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()
        srv.Shutdown(ctx)
    }()

    fmt.Println("Server starting...")
    if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        fmt.Printf("server start failed, err: %v\n", err)
        return
    }

    fmt.Println("Server closed.")
}

我们通过signal.Notify方法,注册了两种信号,分别是Ctrl+C和kill。然后,在main函数里通过一个死循环等待信号的到来。当信号到来时,我们会先打印一行日志,表示我们成功地接收到了一个信号,然后我们会调用http.Server的Shutdown()方法,将http服务正常地关闭,这些操作都会在上下文中进行。

Noya
Noya

让线框图变成高保真设计。

下载

当我们向http.Server的Shutdown()方法传递一个context.Context对象时,http服务就会进入到优雅关闭的过程,Shutdown()方法的具体流程如下所示:

  1. Immediately return ErrServerClosed for all active connections.
  2. Call Shutdown on all active connections.
  3. Call Shutdown on the server's listener.
  4. Wait for all goroutines associated with the server to complete.

也就是说,在Shutdown()方法被调用后,所有的活跃连接会被立即关闭,同时新的连接请求也会被禁止。然后,Shutdown()方法会调用所有活跃连接的Shutdown()方法来关闭连接,这样我们就可以保证所有的连接都被正常关闭了。最后,Shutdown()方法会关闭我们的http server,关闭完成后,程序再退出。

通过这样的优雅关闭方式,我们可以保证http服务在关闭时不会影响正在处理的请求,即使你正在完成HTTP请求时调用了Ctrl+C也不会影响HTTP连接的性能。这样做可以让我们的程序更健壮、更可靠,非常适合用于生产环境中。

当然,这只是一个golang优雅关闭http服务的示例,你可以根据你的实际环境来进行修改,希望这篇文章能为你带来帮助。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

174

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

224

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

335

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

206

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

193

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

188

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

191

2025.06.17

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

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

精品课程

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

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