阅读 Sniper 源码实现,学习 Golang 中重载机制的实现

Sniper 是 Bilibili 开源的一款轻量级业务框架,通过阅读其代码,可以学习到很多优秀的设计理念,这里学习的主要是其中 cmd/server/main.go 中关于停止、重载的设计,首先利用 viper.OnConfigChange 函数监听配置文件,发生更改后,则向 reload channel 发送消息,通过 signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP) 监听 syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP 三个信号,并将其发送给 stop channel。其后在 for loop 循环中,通过 select case 获取两个channel 中的消息,进行相应的重制、停止等操作。

func main() {
	reload := make(chan int, 1)
	stop := make(chan os.Signal, 1)

	conf.OnConfigChange(func() { reload <- 1 })
	conf.WatchConfig()
	signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP)

	startServer()

	for {
		select {
		case <-reload:
			util.Reset()
		case sg := <-stop:
			stopServer()
			// 仿 nginx 使用 HUP 信号重载配置
			if sg == syscall.SIGHUP {
				startServer()
			} else {
				util.Stop()
				return
			}
		}
	}
}

代码片段链接

comments powered by Disqus

Tags

abcs accept acid activemq affinity algorithm allocation android array async aws b+tree b-tree backoff benchmark best-practices bfs big-o bigquery bind bitcount blog break broker bubble buffer cache cap cert cgroups channel citus class classmethod closure closures cluster concurrency config consistency consumer container context cookie cors crawler cronjob csrf ctr data-science data-structure database datadog dataflow datascience decorator deepcopy defer dfs distributed django dns docker double-shipping drf ecosia elastic-search enumerate epoll equal errgroup escaping event extra fabric2 facebook-pixel financial-report flask flutter forward-proxy freelance frontend frp garbage-collector gc gcp generator gesture get gil git golang goroutine graphql ha handbook haproxy hash hash-slot hashring hashtable hpa http http-auth http-proxy http_proxy https index init innodb instagram intention-lock intergration interview ios is javascript jinja2 jobboard json jwt k8s kafka kibana kqueue label lambda layer4 layer7 lean levels.io linked-list linux list listen loadbalancer lock logs long-tail lru marketing master matplotlib memory merge metaclass metaprogramming metrics metrics-server microservices mitm mobile model mongo mongoose mq myisam mysql namespace nat netflix network network-extension nginx nodejs nomad nosql notification npm oodesign openssl optimization orm osi pandas parallelism paramiko parkinglot patroni permission pg pipeline pixelme post postgresql postresql prefetch_related prerender private-key process proxy proxycommand put pvm python queue rabbitmq rbac react-native reactive reactjs rebase redis redis-cluster replication resource rest restfulapi retargeting retry revenue reverse-proxy rocketmq rsa rxswift saas scaffold scaleable search-engine security select seo serverless service session set shadosocks shadowsocks shard sharding shell shopify sigint signal sigterm singleton slack slave slow-query sniper sns socket socks5 source-code spa sql sqlalchemy sqs ssh ssl ssl-pinning stack startup state stateful stateless staticmethod string struct swift swiftui switch syscall system-design systemctl tcp tcp-proxy thread tmpreaper token traefik trustkit tunning type typeform udp userdefaults variable vc voidcallback vpn vuejs weak web web-development where widget with yarn zset 削峰 单例模式 宽索引 异步 看源码学-golang 窄索引 解耦 跨域 跳板机



Archives

2020 (6)
2019 (157)
0001 (5)