Golang Singleflight 防缓存击穿验证示例
2024年8月30日 21:00

Singleflight 示例一:基础用法
多次请求共享一次请求的结果
package main
import (
"fmt"
"time"
"golang.org/x/sync/singleflight"
)
func main() {
var group singleflight.Group
// A function that simulates an expensive operation
expensiveOperation := func(key string) (interface{}, error) {
time.Sleep(2 * time.Second) // Simulate delay
return fmt.Sprintf("Result for %s", key), nil
}
key := "unique-key"
// Start multiple goroutines that call the expensive operation through singleflight
for i := 0; i < 3; i++ {
go func(id int) {
result, err, shared := group.Do(key, func() (interface{}, error) {
return expensiveOperation(key)
})
if err != nil {
fmt.Printf("Goroutine %d received error: %v\n", id, err)
} else {
fmt.Printf("Goroutine %d received result: %v (shared: %v)\n", id, result, shared)
}
}(i)
}
// Wait for goroutines to finish
time.Sleep(3 * time.Second)
}
输出
Goroutine 0 received result: Result for unique-key (shared: true)
Goroutine 2 received result: Result for unique-key (shared: true)
Goroutine 1 received result: Result for unique-key (shared: true)
Singleflight 示例二:解决缓存击穿
这个示例集成了数据库、缓存和 HTTP API,有以下几个关键点:
- 提供了
[GET] /gold/prcie和[POST] /gold两个接口模拟黄金价格的更新与查询 - 缓存由更新接口在更新数据后设置失效,由查询接口负责构建
- 高并发查询场景,缓存失效的一瞬间,面临多个请求会同时访问数据库,即缓存击穿
- 高并发查询场景,使用 Singleflight 避免缓存击穿
- 查看访问数据库的次数,看到 Singleflight 在这个场景中的重要作用
创建表作为数据源
-- 创建表
CREATE TABLE gold_realtime_prices (
id SERIAL PRIMARY KEY,
price NUMERIC NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入一条模拟数据
INSERT INTO gold_realtime_prices (price) VALUES (575.25);
代码示例
通关环境变量设置...
剩余内容已隐藏
查看完整文章以阅读更多