2025/9/28小于 1 分钟
Go 标准库中的 encoding/json 包是我们日常开发中最常用的包之一,已在 Go 生态中服务超过十年,应用极其广泛。然而,该包也因为一些长期存在的设计问题——如部分 API 的行为不一致、灵活性不足以及在性能敏感场景下的瓶颈——而受到社区的多次讨论和批评。
值得关注的是,Go 官方团队在 v1.25.0 版本对 encoding/json 进行重大升级,推出了下一代实现:encoding/json/v2,并可通过实验性环境变量 GOEXPERIMENT=jsonv2 进行体验。
2025/8/23大约 8 分钟
Go 1.25 是一个聚焦于工具链、运行时、编译器优化和标准库增强的版本,进行了大量的更新和优化,推荐升级。
一、语言层面
- 无语法变更: Go 1.25 未引入任何新的语言语法特性。
- 规范澄清: 语言规范中移除了
核心类型 (core type)的概念,其功能已被更精确、专用的语法结构所替代。
2025/8/19大约 11 分钟
2025/8/19大约 10 分钟
2025/8/18大约 4 分钟
2025/8/18大约 4 分钟
2025/8/18大约 3 分钟
2025/8/16大约 3 分钟
2025/8/16大约 2 分钟
相关信息
在 Golang 中,优雅关闭服务是确保程序退出时能够正确处理完当前请求、释放资源的重要机制。
实现方法
1. 信号处理机制
Golang 可以通过 os/signal 包监听系统信号(如 SIGINT、SIGTERM)来触发优雅关闭流程:
package main
import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
// 创建一个HTTP服务器
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
time.Sleep(5 * time.Second) // 模拟耗时操作
fmt.Fprintf(w, "Hello World")
})
server := &http.Server{
Addr: ":8080",
Handler: mux,
}
// 启动服务器(非阻塞方式)
go func() {
fmt.Println("Server is starting on :8080")
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
fmt.Printf("Listen: %s\n", err)
}
}()
// 等待中断信号优雅关闭服务器
quit := make(chan os.Signal, 1)
// 只接收 SIGINT 和 SIGTERM 信号
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit // 阻塞等待信号
fmt.Println("Shutting down server...")
// 创建一个5秒超时的上下文
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 优雅关闭服务器
if err := server.Shutdown(ctx); err != nil {
fmt.Printf("Server forced to shutdown: %s\n", err)
}
fmt.Println("Server exiting")
}
2. 优雅关闭的核心要素
(1)使用 Shutdown() 方法
http.Server 提供的 Shutdown() 方法会:
- 停止接收新的连接
- 等待已有的连接处理完毕(在超时时间内)
- 释放所有资源
(2)设置合理的超时时间
通过 context.WithTimeout 设置超时时间,防止服务无限期等待:
- 太短可能导致未完成的请求被强制终止
- 太长可能导致关闭过程耗时过长
(3)处理其他资源
除了 HTTP 服务器,还需要考虑关闭其他资源:
// 示例:关闭数据库连接
func closeDB(ctx context.Context, db *sql.DB) error {
return db.Close()
}
// 在主关闭流程中调用
if err := closeDB(ctx, db); err != nil {
fmt.Printf("Error closing database: %v\n", err)
}
3. 进阶技巧
(1)实现健康检查端点
添加健康检查端点,便于外部监控系统判断服务状态:
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
})
(2)使用 WaitGroup 管理 goroutine
如果有多个工作协程,使用 sync.WaitGroup 确保它们都能优雅退出:
var wg sync.WaitGroup
// 启动工作协程
wg.Add(1)
go func() {
defer wg.Done()
worker()
}()
// 关闭时等待所有工作协程完成
go func() {
<-quit
// 通知工作协程停止
stopWorker()
wg.Wait()
// 继续服务器关闭流程
}()
(3)优雅关闭的完整流程
- 收到终止信号
- 标记服务为"正在关闭"状态
- 停止接收新请求/任务
- 等待现有请求/任务处理完成
- 关闭外部资源连接(数据库、缓存等)
- 退出程序
通过以上机制,可以确保服务在关闭时不会丢失数据,也不会影响正在处理的请求,从而实现真正的优雅关闭。
2025/8/13大约 2 分钟