国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

一文講懂服務(wù)的優(yōu)雅重啟和更新

開發(fā) 架構(gòu)
在重啟過程中,會有一段時間不能給用戶提供正常服務(wù);同時粗魯關(guān)閉服務(wù),也可能會對業(yè)務(wù)依賴的數(shù)據(jù)庫等狀態(tài)服務(wù)造成污染。所以我們服務(wù)重啟或者是重新發(fā)布過程中,要做到新舊服務(wù)無縫切換,同時可以保障變更服務(wù) 零宕機(jī)時間!

[[404467]]

本文轉(zhuǎn)載自微信公眾號「微服務(wù)實(shí)踐」,作者h(yuǎn)xl。轉(zhuǎn)載本文請聯(lián)系微服務(wù)實(shí)踐公眾號。   

在服務(wù)端程序更新或重啟時,如果我們直接 kill -9 殺掉舊進(jìn)程并啟動新進(jìn)程,會有以下幾個問題:

  1. 舊的請求未處理完,如果服務(wù)端進(jìn)程直接退出,會造成客戶端鏈接中斷(收到 RST)
  2. 新請求打過來,服務(wù)還沒重啟完畢,造成 connection refused
  3. 即使是要退出程序,直接 kill -9 仍然會讓正在處理的請求中斷

很直接的感受就是:在重啟過程中,會有一段時間不能給用戶提供正常服務(wù);同時粗魯關(guān)閉服務(wù),也可能會對業(yè)務(wù)依賴的數(shù)據(jù)庫等狀態(tài)服務(wù)造成污染。

所以我們服務(wù)重啟或者是重新發(fā)布過程中,要做到新舊服務(wù)無縫切換,同時可以保障變更服務(wù) 零宕機(jī)時間!

作為一個微服務(wù)框架,那 go-zero 是怎么幫開發(fā)者做到優(yōu)雅退出的呢?下面我們一起看看。

優(yōu)雅退出

在實(shí)現(xiàn)優(yōu)雅重啟之前首先需要解決的一個問題是 如何優(yōu)雅退出:

對 http 服務(wù)來說,一般的思路就是關(guān)閉對 fd 的 listen , 確保不會有新的請求進(jìn)來的情況下處理完已經(jīng)進(jìn)入的請求, 然后退出。

go 原生中 http 中提供了 server.ShutDown(),先來看看它是怎么實(shí)現(xiàn)的:

  1. 設(shè)置 inShutdown 標(biāo)志
  2. 關(guān)閉 listeners 保證不會有新請求進(jìn)來
  3. 等待所有活躍鏈接變成空閑狀態(tài)
  4. 退出函數(shù),結(jié)束

分別來解釋一下這幾個步驟的含義:

inShutdown

  1. func (srv *Server) ListenAndServe() error { 
  2.     if srv.shuttingDown() { 
  3.         return ErrServerClosed 
  4.     } 
  5.     .... 
  6.     // 實(shí)際監(jiān)聽端口;生成一個 listener 
  7.     ln, err := net.Listen("tcp", addr) 
  8.     if err != nil { 
  9.         return err 
  10.     } 
  11.     // 進(jìn)行實(shí)際邏輯處理,并將該 listener 注入 
  12.     return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) 
  13.  
  14. func (s *Server) shuttingDown() bool { 
  15.   return atomic.LoadInt32(&s.inShutdown) != 0 

ListenAndServe 是http啟動服務(wù)器的必經(jīng)函數(shù),里面的第一句就是判斷 Server 是否被關(guān)閉了。

inShutdown 就是一個原子變量,非0表示被關(guān)閉。

listeners

  1. func (srv *Server) Serve(l net.Listener) error { 
  2.     ... 
  3.     // 將注入的 listener 加入內(nèi)部的 map 中 
  4.     // 方便后續(xù)控制從該 listener 鏈接到的請求 
  5.     if !srv.trackListener(&l, true) { 
  6.         return ErrServerClosed 
  7.     } 
  8.     defer srv.trackListener(&l, false
  9.    ... 

Serve 中注冊到內(nèi)部 listeners map 中 listener,在 ShutDown 中就可以直接從 listeners 中獲取到,然后執(zhí)行 listener.Close(),TCP四次揮手后,新的請求就不會進(jìn)入了。

closeIdleConns

簡單來說就是:將目前 Server 中記錄的活躍鏈接變成變成空閑狀態(tài),返回。

關(guān)閉

  1. func (srv *Server) Serve(l net.Listener) error { 
  2.   ... 
  3.   for { 
  4.     rw, err := l.Accept() 
  5.     // 此時 accept 會發(fā)生錯誤,因?yàn)榍懊嬉呀?jīng)將 listener close了 
  6.     if err != nil { 
  7.       select { 
  8.       // 又是一個標(biāo)志:doneChan 
  9.       case <-srv.getDoneChan(): 
  10.         return ErrServerClosed 
  11.       default
  12.       } 
  13.     } 
  14.   } 

其中 getDoneChan 中已經(jīng)在前面關(guān)閉 listener 時,對 doneChan 這個channel中push。

總結(jié)一下:Shutdown 可以優(yōu)雅的終止服務(wù),期間不會中斷已經(jīng)活躍的鏈接。

但服務(wù)啟動后的某一時刻,程序如何知道服務(wù)被中斷了呢?服務(wù)被中斷時如何通知程序,然后調(diào)用Shutdown作處理呢?接下來看一下系統(tǒng)信號通知函數(shù)的作用

服務(wù)中斷

這個時候就要依賴 OS 本身提供的 signal。對應(yīng) go 原生來說,signal 的 Notify 提供系統(tǒng)信號通知的能力。

https://github.com/tal-tech/go-zero/blob/master/core/proc/signals.go

  1. func init() { 
  2.   go func() { 
  3.     var profiler Stopper 
  4.      
  5.     signals := make(chan os.Signal, 1) 
  6.     signal.Notify(signals, syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGTERM) 
  7.  
  8.     for { 
  9.       v := <-signals 
  10.       switch v { 
  11.       case syscall.SIGUSR1: 
  12.         dumpGoroutines() 
  13.       case syscall.SIGUSR2: 
  14.         if profiler == nil { 
  15.           profiler = StartProfile() 
  16.         } else { 
  17.           profiler.Stop() 
  18.           profiler = nil 
  19.         } 
  20.       case syscall.SIGTERM: 
  21.         // 正在執(zhí)行優(yōu)雅關(guān)閉的地方 
  22.         gracefulStop(signals) 
  23.       default
  24.         logx.Error("Got unregistered signal:", v) 
  25.       } 
  26.     } 
  27.   }() 
  • SIGUSR1 -> 將 goroutine 狀況,dump下來,這個在做錯誤分析時還挺有用的
  • SIGUSR2 -> 開啟/關(guān)閉所有指標(biāo)監(jiān)控,自行控制 profiling 時長
  • SIGTERM -> 真正開啟 gracefulStop,優(yōu)雅關(guān)閉

而 gracefulStop 的流程如下:

  1. 取消監(jiān)聽信號,畢竟要退出了,不需要重復(fù)監(jiān)聽了
  2. wrap up,關(guān)閉目前服務(wù)請求,以及資源
  3. time.Sleep() ,等待資源處理完成,以后關(guān)閉完成
  4. shutdown ,通知退出
  5. 如果主goroutine還沒有退出,則主動發(fā)送 SIGKILL 退出進(jìn)程

這樣,服務(wù)不再接受新的請求,服務(wù)活躍的請求等待處理完成,同時也等待資源關(guān)閉(數(shù)據(jù)庫連接等),如有超時,強(qiáng)制退出。

整體流程

我們目前 go 程序都是在 docker 容器中運(yùn)行,所以在服務(wù)發(fā)布過程中,k8s 會向容器發(fā)送一個 SIGTERM 信號,然后容器中程序接收到信號,開始執(zhí)行 ShutDown:

到這里,整個優(yōu)雅關(guān)閉的流程就梳理完畢了。

但是還有平滑重啟,這個就依賴 k8s 了,基本流程如下:

  • old pod 未退出之前,先啟動 new pod
  • old pod 繼續(xù)處理完已經(jīng)接受的請求,并且不再接受新請求
  • new pod接受并處理新請求的方式
  • old pod 退出

這樣整個服務(wù)重啟就算是成功了,如果 new pod 沒有啟動成功,old pod 也可以提供服務(wù),不會對目前線上的服務(wù)造成影響。

項(xiàng)目地址

https://github.com/tal-tech/go-zero

歡迎使用 go-zero 并 star 支持我們!

 

責(zé)任編輯:武曉燕 來源: 微服務(wù)實(shí)踐
相關(guān)推薦

2021-09-03 05:03:58

模塊命令項(xiàng)目

2020-03-26 09:18:54

高薪本質(zhì)因素

2025-01-13 12:00:00

反射Java開發(fā)

2025-01-20 09:15:00

iOS 18.3蘋果iOS 18

2019-09-23 10:51:14

JavaJava虛擬機(jī)Linux

2019-10-12 08:59:36

軟件DevOps技術(shù)

2024-08-13 17:09:00

架構(gòu)分庫分表開發(fā)

2020-08-04 10:56:09

進(jìn)程線程協(xié)程

2020-07-16 09:02:45

aPaaS云計算aPaaS平臺

2025-12-04 09:14:06

2022-02-15 08:38:04

錯誤邏輯異常編程程序

2023-11-09 08:41:25

DevOpsAIOps軟件

2020-12-03 08:23:23

函數(shù)柯里化代碼

2025-01-02 11:55:08

HashMapJava哈希沖突

2020-05-20 09:55:42

Git底層數(shù)據(jù)

2021-01-18 13:05:52

Serverless Serverfull FaaS

2020-12-01 11:34:14

Elasticsear

2020-01-02 09:06:23

微服務(wù)數(shù)據(jù)框架

2018-05-10 10:53:47

分布式架構(gòu)負(fù)載均衡Web

2019-03-14 15:59:44

前端開發(fā)編程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

狠狠久久五月精品中文字幕| 成人18在线| 天天做夜夜做人人爱精品| 欧美一区二区视频在线观看 | 一区二区三区 在线观看视| 浮妇高潮喷白浆视频| 激情综合电影网| 91大神福利视频在线| 成人全视频免费观看在线看| 欧美日韩在线播放| 中文字幕乱码一区二区三区| 亚洲日本视频| 久久av免费一区| 亚洲免费一区二区| 国产精品国色综合久久| 一区二区三区视频播放| 在线播放国产一区二区三区| 国产成+人+综合+亚洲欧美| 宅男66日本亚洲欧美视频| 激情都市亚洲| 国产亚洲人成网站在线观看| 国产精品videossex国产高清| 你懂的在线免费观看| 在线看片欧美| 在线观看日产精品| 五月天综合婷婷| 日本欧美韩国国产| 成人黄页毛片网站| 中文字幕在线看视频国产欧美在线看完整 | 中文字幕久精品免费视频| av成人亚洲| 国产精品人成电影在线观看| 色爱综合区网| 欧美精品一区二区蜜臀亚洲| 日本免费久久| 中文字幕亚洲一区| 日韩欧美国产精品一区二区三区| 99视频在线视频| 蜜桃精品视频| 国产精品美女一区二区| 亚洲r级在线观看| 亚洲欧洲综合| 亚洲精品永久www嫩草| 久久精品国产精品青草| 在线免费观看成人网| 亚洲天堂中文字幕| 欧美尤物美女在线| 精品国产91亚洲一区二区三区婷婷 | 无遮挡亚洲一区| 国产精品第五页| 亚洲第一影院| 91免费在线视频网站| av成人免费在线| 国产免费av高清在线| 久久久久久国产精品久久| 久久人体视频| 一区二区成人网| 中文字幕亚洲一区二区三区五十路| 欧美午夜在线| 日韩精品另类天天更新| 国产精品黄色在线观看| 成人免费黄色| 日本黄网站色大片免费观看| 91精品午夜视频| 久久99国产成人小视频| 国产极品在线视频| 欧美中文字幕一二三区视频| 亚洲综合福利| 正义之心1992免费观看全集完整版| aaa国产精品视频| 日韩精品免费在线视频| 欧美一区二区三区爽大粗免费| 久久不射2019中文字幕| 久久久久久亚洲精品不卡| 欧美成人性生活视频| 国产999精品久久久| 99国产精品久久久久久久久久| 成人免费在线观看| 久久人人九九| 在线这里只有精品| 99精品国产在热久久| yw193.com尤物在线| 亚洲天天在线日亚洲洲精| 久久国产综合精品| 中文字幕在线视频免费观看| 日韩黄色av网站| 欧美激情综合| 嫩模私拍啪啪| 国产亚洲第一区| 日韩精品极品视频| 国产精品88888| 久久夜色电影| 男人天堂v视频| 欧美激情亚洲另类| 一区二区不卡在线视频 午夜欧美不卡在| 首页亚洲中字| 自拍视频在线| 欧美乱偷一区二区三区在线| 亚洲激情电影中文字幕| 国产成人在线视频网站| 精品九九在线| 松下纱荣子在线观看| 久久久天堂国产精品| 欧美三级资源在线| 91在线视频观看| 午夜精品偷拍| 原纱央莉成人av片| 黑粗硬长欧美在线视频免费的| 久久99热精品| 欧美精品免费视频| 久久精品国产在热久久| 亚洲最好看的视频| 一区二区三区短视频| 一区二区三区性视频| 国模无码视频一区二区三区| 95av在线视频| 久久久精品欧美| 欧美一区2区视频在线观看| 成人欧美一区二区三区白人| 奇米综合一区二区三区精品视频| 日韩精品欧美激情一区二区| 毛片在线网址播放| 99热这里只有精品免费| 成人在线看片| 国产精品久久激情| 欧美激情在线观看视频| 精品999在线播放| 91影院在线观看| 久久综合99| 三级精品视频| 国产伊人久久| 日韩护士脚交太爽了| 永久免费网站在线| 在线观看你懂得| 国产一伦一伦一伦| 午夜视频在线瓜伦| 中文字幕第100页| 日本人视频jizz页码69| 人妻熟女一二三区夜夜爱| 91久久精品国产91性色| 成人在线一区二区| 91视频-88av| 国产精品久久久久久久久久久久冷 | 日韩毛片在线观看| 日本成人一区二区| 男人草女人视频| 久久久久久久有限公司| 久久国产主播精品| 高清国语自产拍免费一区二区三区| 91久久中文字幕| 韩国成人一区| 久久亚洲国产精品日日av夜夜| 久久精品一二三区| 免费国产一区| 一本久久a久久精品vr综合| 久久久久久久久久久一区| 国产偷久久久精品专区| 日韩免费av一区二区| 97超碰色婷婷| 成人影片在线播放| 久久av免费一区| youjizz.com在线观看| 国外av网站| 欧美日韩经典丝袜| 98视频精品全部国产| 日韩有码av| 韩日欧美一区二区三区| 国产精品嫩草影院av蜜臀| 在线观看91视频| 欧美精品成人一区二区三区四区| 亚洲黄色成人网| 91精品免费看| 欧美亚洲爱爱另类综合| 亚洲一区二区少妇| 午夜精品亚洲一区二区三区嫩草 | 成人精品在线视频| 麻豆传媒一区二区| 不卡影院一区二区| 欧美三级理论片| 成人影院在线播放| 国产在线观看a视频| 日韩成人亚洲| 国产精品a久久久久| 久久99国产精品免费网站| 国产日韩欧美精品综合| 中文字幕在线观看不卡| 亚洲国产成人久久综合| 91久久国产综合久久蜜月精品| 日本中文字幕在线视频观看| 中文字幕在线播放| 亚洲激情77| 亚洲男人的天堂在线aⅴ视频| 亚洲男人天堂久| 久久精品在线播放| 91成品人片a无限观看| 在线观看欧美一区| av最新在线| 韩国三级在线一区| 亚洲国产欧美一区二区三区久久| 久久国产精品久久|