Golang中gin框架API请求处于pending状态如何解决
Golang中gin框架API请求处于pending状态如何解决 我在使用 Golang Gin 框架时,如果使用了第三方库 sirupsen/logrus,我的 API 会显示为“挂起”状态。
如果我在服务器应用程序上按下回车键,它就会开始工作。
为什么不使用Go内置的结构化日志记录器(slog)?
更多关于Golang中gin框架API请求处于pending状态如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
好的,谢谢。我会按你的建议进行更新。
packs:
sirupsen/logrus
你好!我们需要更多上下文才能提供帮助,如果可以的话,也许分享一些代码;
你尝试过其他的日志库吗?另外,请注意 sirupsen/logrus 目前处于维护模式,其最后一次提交是在一年多以前,我建议使用一些维护更活跃的库,比如 Zerolog 或 phuslu/log。
在 Gin 框架中使用 logrus 时 API 请求处于 pending 状态,通常是由于 logrus 的默认输出配置与 Gin 的并发处理冲突导致的。logrus 默认使用带锁的 os.Stdout,在高并发场景下可能阻塞请求处理。
以下是解决方案和示例代码:
1. 使用带缓冲的日志输出
package main
import (
"bufio"
"os"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
func main() {
// 创建带缓冲的 writer
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
// 配置 logrus 使用缓冲输出
logrus.SetOutput(writer)
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
logrus.Info("处理请求")
c.JSON(200, gin.H{"message": "pong"})
})
r.Run(":8080")
}
2. 使用异步日志处理器
package main
import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
// 配置日志轮转(异步写入文件)
logger := &lumberjack.Logger{
Filename: "app.log",
MaxSize: 100, // MB
MaxBackups: 3,
MaxAge: 28, // days
}
logrus.SetOutput(logger)
logrus.SetFormatter(&logrus.JSONFormatter{})
r := gin.Default()
r.GET("/api", func(c *gin.Context) {
// 异步记录日志
go func() {
logrus.WithFields(logrus.Fields{
"path": c.Request.URL.Path,
"method": c.Request.Method,
}).Info("请求记录")
}()
c.JSON(200, gin.H{"status": "success"})
})
r.Run(":8080")
}
3. 禁用 logrus 的锁机制
package main
import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"io"
)
func main() {
// 创建无锁的 logger 实例
logger := logrus.New()
logger.SetOutput(io.Discard) // 或指定其他输出
logger.SetLevel(logrus.InfoLevel)
logger.SetFormatter(&logrus.TextFormatter{
DisableColors: true,
FullTimestamp: true,
})
// 替换标准 logger
logrus.StandardLogger().ReplaceHooks(make(logrus.LevelHooks))
r := gin.Default()
// 使用自定义的 logger 中间件
r.Use(func(c *gin.Context) {
c.Next()
logger.WithFields(logrus.Fields{
"status": c.Writer.Status(),
"path": c.Request.URL.Path,
}).Info("请求完成")
})
r.GET("/test", func(c *gin.Context) {
c.JSON(200, gin.H{"data": "test"})
})
r.Run(":8080")
}
4. 检查是否存在死锁情况
package main
import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"sync"
)
var (
logMutex sync.Mutex
logger = logrus.New()
)
func safeLog(fields logrus.Fields, message string) {
go func() {
logMutex.Lock()
defer logMutex.Unlock()
logger.WithFields(fields).Info(message)
}()
}
func main() {
r := gin.Default()
r.GET("/endpoint", func(c *gin.Context) {
// 使用线程安全的日志记录
safeLog(logrus.Fields{
"endpoint": "/endpoint",
"ip": c.ClientIP(),
}, "请求到达")
c.JSON(200, gin.H{"result": "ok"})
})
r.Run(":8080")
}
这些解决方案通过调整 logrus 的输出方式、使用异步处理或禁用锁机制,可以解决 Gin 框架中因 logrus 导致的 API 请求 pending 问题。选择哪种方案取决于具体的应用场景和性能要求。

