使用互斥锁、通道或第三方库实现并发安全日志写入,推荐zap等高性能库以平衡安全性与性能。

在高并发场景下,多个Goroutine同时写入日志容易引发竞争问题,导致日志错乱或丢失。使用Golang实现安全的并发日志写入,关键在于同步控制和性能平衡。下面介绍几种实用方法。
最直接的方式是用sync.Mutex确保同一时间只有一个Goroutine能写入日志文件。
示例代码:
package main
<p>import (
"log"
"os"
"sync"
)</p><p>var (
logFile *os.File
mutex sync.Mutex
)</p><p>func init() {
var err error
logFile, err = os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatal(err)
}
log.SetOutput(logFile)
}</p><p>func writeLog(message string) {
mutex.Lock()
defer mutex.Unlock()
log.Println(message)
}</p><p>func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
writeLog("来自 Goroutine 的日志:" + string(rune(id+'0')))
}(i)
}
wg.Wait()
logFile.Close()
}
优点:简单可靠;缺点:高并发时可能成为性能瓶颈。
立即学习“go语言免费学习笔记(深入)”;
通过一个专用的Goroutine负责实际写入,其他协程通过通道发送日志消息,避免直接竞争。
示例:
package main
<p>import (
"bufio"
"os"
)</p><p>var logChan = make(chan string, 100)</p>
<div class="aritcle_card">
<a class="aritcle_card_img" href="/ai/970">
<img src="https://img.php.cn/upload/ai_manual/000/000/000/175680015863684.png" alt="火龙果写作">
</a>
<div class="aritcle_card_info">
<a href="/ai/970">火龙果写作</a>
<p>用火龙果,轻松写作,通过校对、改写、扩展等功能实现高质量内容生产。</p>
<div class="">
<img src="/static/images/card_xiazai.png" alt="火龙果写作">
<span>106</span>
</div>
</div>
<a href="/ai/970" class="aritcle_card_btn">
<span>查看详情</span>
<img src="/static/images/cardxiayige-3.png" alt="火龙果写作">
</a>
</div>
<p>func logger() {
file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
defer file.Close()</p><pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">writer := bufio.NewWriter(file)
defer writer.Flush()
for msg := range logChan {
writer.WriteString(msg + "\n")
}}
func init() { go logger() }
func writeLog(message string) { logChan <- message }
这种方式解耦了日志生产与消费,适合高并发环境,且可通过缓冲提升性能。
uber-go/zap 和 sirupsen/logrus 等库原生支持并发安全的日志写入,底层已做优化。
以 zap 为例:
import "go.uber.org/zap"
<p>func main() {
logger, _ := zap.NewProduction()
defer logger.Sync()</p><pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
logger.Info("并发日志", zap.Int("goroutine", id))
}(i)
}
wg.Wait()}
zap 性能优异,结构化输出清晰,推荐用于生产项目。
基本上就这些。选择哪种方式取决于性能要求和系统复杂度。小项目用 Mutex 足够,中大型服务建议用 channel 模式或 zap 这类成熟库。关键是保证线程安全,同时不拖慢主业务逻辑。
以上就是如何使用Golang实现并发日志写入的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号