热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

优雅地关闭大猩猩服务器

如何解决《优雅地关闭大猩猩服务器》经验,为你挑选了1个好方法。

我正在使用https://github.com/gorilla/mux中的 gorilla多路复用器库构建服务器.问题是,当我使用Ctrl + C或者有特定的API调用时,我希望它能够正常关闭,例如"/ shutdown".

我已经知道在Go 1.8中,已经实现了正常关闭.但是如何将它与大猩猩多路复用器结合起来呢?另外,如何将它与SIGINT信号结合起来?

谁能告诉我怎么做?



1> putu..:

通道可用于通过API调用(/shutdown)或中断信号(Ctrl+C)捕获关闭请求.

    嵌入http.Server到自定义结构中,以便稍后调用http Server.Shutdown

    添加channel field(shutdownReq)以从API调用传递关闭请求/shutdown

    注册http处理程序,包括/shutdowngorilla/mux路由器中,然后分配路由器http.Server.Handler

    注册os.Interrupt/syscall.SIGINT, syscall.SIGTERM处理程序

    用于select通过API调用或interrupt信号捕获关闭请求

    通过调用执行干净关闭 Server.Shutdown

以下是示例代码:

package main

import (
    "context"
    "log"
    "net/http"
    "sync/atomic"
    "syscall"
    "time"

    "os"
    "os/signal"

    "github.com/gorilla/mux"
)

type myServer struct {
    http.Server
    shutdownReq chan bool
    reqCount    uint32
}

func NewServer() *myServer {
    //create server
    s := &myServer{
        Server: http.Server{
            Addr:         ":8080",
            ReadTimeout:  10 * time.Second,
            WriteTimeout: 10 * time.Second,
        },
        shutdownReq: make(chan bool),
    }

    router := mux.NewRouter()

    //register handlers
    router.HandleFunc("/", s.RootHandler)
    router.HandleFunc("/shutdown", s.ShutdownHandler)

    //set http server handler
    s.Handler = router

    return s
}

func (s *myServer) WaitShutdown() {
    irqSig := make(chan os.Signal, 1)
    signal.Notify(irqSig, syscall.SIGINT, syscall.SIGTERM)

    //Wait interrupt or shutdown request through /shutdown
    select {
    case sig := <-irqSig:
        log.Printf("Shutdown request (signal: %v)", sig)
    case sig := <-s.shutdownReq:
        log.Printf("Shutdown request (/shutdown %v)", sig)
    }

    log.Printf("Stoping http server ...")

    //Create shutdown context with 10 second timeout
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    //shutdown the server
    err := s.Shutdown(ctx)
    if err != nil {
        log.Printf("Shutdown request error: %v", err)
    }
}

func (s *myServer) RootHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello Gorilla MUX!\n"))
}

func (s *myServer) ShutdownHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Shutdown server"))

    //Do nothing if shutdown request already issued
    //if s.reqCount == 0 then set to 1, return true otherwise false
    if !atomic.CompareAndSwapUint32(&s.reqCount, 0, 1) {
        log.Printf("Shutdown through API call in progress...")
        return
    }

    go func() {
        s.shutdownReq <- true
    }()
}

func main() {
    //Start the server
    server := NewServer()

    done := make(chan bool)
    go func() {
        err := server.ListenAndServe()
        if err != nil {
            log.Printf("Listen and serve: %v", err)
        }
        done <- true
    }()

    //wait shutdown
    server.WaitShutdown()

    <-done
    log.Printf("DONE!")
}

注意:请注意与gracefull shutdown相关的此问题.


推荐阅读
  • Go语言实现Redis客户端与服务器的交互机制深入解析
    在前文对Godis v1.0版本的基础功能进行了详细介绍后,本文将重点探讨如何实现客户端与服务器之间的交互机制。通过具体代码实现,使客户端与服务器能够顺利通信,赋予项目实际运行的能力。本文将详细解析Go语言在实现这一过程中的关键技术和实现细节,帮助读者深入了解Redis客户端与服务器的交互原理。 ... [详细]
  • 在Hive中合理配置Map和Reduce任务的数量对于优化不同场景下的性能至关重要。本文探讨了如何控制Hive任务中的Map数量,分析了当输入数据超过128MB时是否会自动拆分,以及Map数量是否越多越好的问题。通过实际案例和实验数据,本文提供了具体的配置建议,帮助用户在不同场景下实现最佳性能。 ... [详细]
  • Android目录遍历工具 | AppCrawler自动化测试进阶(第二部分):个性化配置详解
    终于迎来了“足不出户也能为社会贡献力量”的时刻,但有追求的测试工程师绝不会让自己的生活变得乏味。与其在家消磨时光,不如利用这段时间深入研究和提升自己的技术能力,特别是对AppCrawler自动化测试工具的个性化配置进行详细探索。这不仅能够提高测试效率,还能为项目带来更多的价值。 ... [详细]
  • 深入解析十大经典排序算法:动画演示、原理分析与代码实现
    本文深入探讨了十种经典的排序算法,不仅通过动画直观展示了每种算法的运行过程,还详细解析了其背后的原理与机制,并提供了相应的代码实现,帮助读者全面理解和掌握这些算法的核心要点。 ... [详细]
  • 结语 | 《探索二进制世界:软件安全与逆向分析》读书笔记:深入理解二进制代码的逆向工程方法
    结语 | 《探索二进制世界:软件安全与逆向分析》读书笔记:深入理解二进制代码的逆向工程方法 ... [详细]
  • 本文详细介绍了如何在Linux系统中搭建51单片机的开发与编程环境,重点讲解了使用Makefile进行项目管理的方法。首先,文章指导读者安装SDCC(Small Device C Compiler),这是一个专为小型设备设计的C语言编译器,适合用于51单片机的开发。随后,通过具体的实例演示了如何配置Makefile文件,以实现代码的自动化编译与链接过程,从而提高开发效率。此外,还提供了常见问题的解决方案及优化建议,帮助开发者快速上手并解决实际开发中可能遇到的技术难题。 ... [详细]
  • ESP32 IRAM 内存优化策略与实践总结
    本文总结了针对ESP32 IRAM内存溢出问题的优化策略与实践经验。通过详细分析ESP32的内存结构和IRAM分配机制,提出了一系列有效的解决方案,包括代码优化、内存管理技巧和编译器配置调整,旨在帮助开发者有效解决`.espressif/tools/xtensa-esp32-elf/esp-2`等类似错误,提升系统性能和稳定性。 ... [详细]
  • 深入解析Gradle中的Project核心组件
    在Gradle构建系统中,`Project` 是一个核心组件,扮演着至关重要的角色。通过使用 `./gradlew projects` 命令,可以清晰地列出当前项目结构中包含的所有子项目,这有助于开发者更好地理解和管理复杂的多模块项目。此外,`Project` 对象还提供了丰富的配置选项和生命周期管理功能,使得构建过程更加灵活高效。 ... [详细]
  • 在将 MySQL 查询转换为 LINQ 时遇到了挑战,特别是在使用 Any 方法时。尽管已成功建立了连接并执行了查询,但返回的结果集中 lambda 表达式部分为空,导致无法正确映射数据。本文探讨了这一问题的根源,并提供了几种可能的解决方案,包括调整查询逻辑和优化 LINQ 表达式的建议。 ... [详细]
  • voc生成xml 代码
    目录 lxmlwindows安装 读取示例 可视化 生成示例 上面是代码,下面有调用示例 api调用代码,其实只有几行:这个生成代码也很简 ... [详细]
  • 在探讨 AS3 中的数据深度复制技术时,本文详细介绍了实现数据深度克隆的有效方法。通过对比多种方案,最终确定了一种高效且可靠的实现方式,所有代码均来源于公开资源,确保了方法的实用性和可操作性。 ... [详细]
  • Go语言中Goroutine与通道机制及其异常处理深入解析
    在Go语言中,Goroutine可视为一种轻量级的并发执行单元,其资源消耗远低于传统线程,初始栈大小仅为2KB,而普通线程则通常需要几MB。此外,Goroutine的调度由Go运行时自动管理,能够高效地支持成千上万个并发任务。本文深入探讨了Goroutine的工作原理及其与通道(channel)的配合使用,特别是在异常处理方面的最佳实践,为开发者提供了一套完整的解决方案,以确保程序的稳定性和可靠性。 ... [详细]
  • 题目《UVa 11978 福岛核爆问题》涉及圆与多边形交集面积的计算及二分法的应用。该问题的核心在于通过精确的几何运算与高效的算法实现来解决复杂图形的面积计算。在实现过程中,特别需要注意的是对多边形顶点的平移处理,确保所有顶点包括最后一个顶点 \( p[n] \) 都经过正确的位移,以避免因细节疏忽导致的错误。此外,使用循环次数为50次的二分法能够有效提高算法的精度和稳定性。 ... [详细]
  • POJ 1696: 空间蚂蚁算法优化与分析
    针对 POJ 1696 的空间蚂蚁算法进行了深入的优化与分析。本研究通过改进算法的时间复杂度和空间复杂度,显著提升了算法的效率。实验结果表明,优化后的算法在处理大规模数据时表现优异,能够有效减少计算时间和内存消耗。此外,我们还对算法的收敛性和稳定性进行了详细探讨,为实际应用提供了可靠的理论支持。 ... [详细]
  • 在 Oracle 数据库中,`NULLS FIRST` 和 `NULLS LAST` 是 `ORDER BY` 子句中用于控制空值排序位置的关键字。当使用 `NULLS FIRST` 时,无论排序顺序是升序 (`ASC`) 还是降序 (`DESC`),包含空值的记录都会被排列在结果集的最前面。相反,`NULLS LAST` 则确保空值记录被放置在结果集的最后。这些关键字提供了灵活的排序选项,特别是在处理包含大量空值的数据集时,能够更好地满足不同的业务需求。 ... [详细]
author-avatar
tuitu
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有