← 中文资源

简体中文版本

用 atomic.Value 热更新配置

把不可变配置快照存入 atomic.Value,读取无需加锁;更新前先校验并复制切片,避免调用方与旧快照共享可变数据。

阅读英文原文

功能说明

Store 用 atomic.Value 保存不可变的 Config 快照。读取方调用 Load 直接取当前快照,不加锁;更新方先复制切片、校验字段,再一次性 Store,因此读方要么看到完整旧版本,要么看到完整新版本。示例中读协程持续读取,主协程在此期间切换配置并尝试写入非法配置。

关键代码

func (s *Store) Update(next Config) error {
	next = next.clone()
	if err := next.Validate(); err != nil {
		return err
	}
	s.current.Store(next)
	return nil
}

atomic.Value 要求每次存储的具体类型一致,第一次存入 Config 后就不能再存其他类型。

使用注意

  • 结构体本身不可变,但切片字段仍可被修改,因此 clone 必须复制底层数组。
  • Load 也返回副本,调用方修改它不会影响已发布的配置。
  • 每次读取都会复制特性列表,读取非常频繁且列表很大时可考虑只读视图。
  • 更新不是事务性的,多个字段在同一个快照里同时生效,不会出现半新半旧。
  • 没有变更通知机制,读方只能在下一次读取时感知新版本。

验证方式

运行示例,读协程会先打印 staging,随后打印 production 和新的特性列表;非法配置被拒绝并打印错误。可以去掉 clone 后修改切片,验证旧快照被意外污染的风险。