You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优雅停止go-diameter服务器?偏好使用其mux逻辑

优雅停止go-diameter服务器的实现方案

由于diam.ListenAndServe是阻塞式便捷调用,无法直接获取服务器实例进行优雅关闭操作,你可以通过手动创建Server实例的方式,既保留库内置的mux路由逻辑,又实现优雅停止:

  1. 创建并配置mux路由
mux := diam.NewServeMux()
// 注册你的Diameter消息处理函数,比如CER消息
mux.Handle("CER", func(c diam.Conn, m *diam.Message) {
    // 你的业务处理逻辑
})
// 注册其他消息处理函数...
  1. 手动初始化Server实例
server := &diam.Server{
    Addr:    addr, // 你的服务器监听地址,例如":3868"
    Handler: mux,  // 将mux作为请求处理器,保留原有路由逻辑
    Dict:    nil,  // 可传入自定义字典,和ListenAndServe的第三个参数一致
}
  1. 实现优雅停止逻辑
    结合上下文和系统信号监听,触发服务器的优雅关闭:
package main

import (
    "context"
    "errors"
    "log"
    "os"
    "os/signal"
    "syscall"

    "github.com/fiorix/go-diameter/v4/diam"
)

func main() {
    addr := ":3868"
    mux := diam.NewServeMux()
    // 注册处理函数...

    server := &diam.Server{
        Addr:    addr,
        Handler: mux,
    }

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    // 监听系统中断(Ctrl+C)和终止信号
    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

    // 启动信号监听协程
    go func() {
        <-sigCh
        log.Println("收到停止信号,开始优雅关闭服务器...")
        cancel()
        // 调用Shutdown等待现有连接处理完成后关闭
        if err := server.Shutdown(ctx); err != nil {
            log.Printf("关闭失败: %v", err)
        }
    }()

    // 启动服务器,阻塞直到Shutdown触发或出错
    if err := server.ListenAndServe(); err != nil && !errors.Is(err, context.Canceled) {
        log.Fatalf("服务器异常退出: %v", err)
    }
    log.Println("服务器已优雅停止")
}

关键说明

  • 手动创建Server实例后,调用其Shutdown方法可实现优雅关闭:该方法会停止接受新连接,等待现有请求处理完成后再退出。
  • 保留mux路由逻辑的核心是将diam.NewServeMux()创建的处理器赋值给Server.Handler,和diam.ListenAndServe的使用逻辑完全一致,仅更换了启动方式。

内容的提问来源于stack exchange,提问作者vk-code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:07:38