golang中的優雅中止

2021-10-17 05:13:47 字數 2804 閱讀 5096

不過,業務中 ① 總會存在對中止比較敏感的介面(比如支付相關),並且 ② 總會存在一些帶狀態的服務,此時優雅中止就顯得比較重要了。

本文通過乙個go 定時任務示例來簡單介紹 go 技術棧中優雅中止的處理思路。

作為高可靠的服務平台,k8s 定義了終止 pod (業務程序在 pod 中執行)的基本步驟:當主動刪除 pod 時,系統會在強制終止 pod 之前將 term 訊號傳送到每個容器中的主程序,過一段時間後(預設為 30 秒),再把 kill 訊號傳送到這些程序。除此之外, k8s 還通過鉤子方法提供了對 容器生命週期 的管理能力,允許使用者通過自定義的方式配置容器啟動後或終止前執行的操作。

當打包進映象的應用執行在 k8s 中的時候,如果應用實現了優雅中止的機制,就可以充分利用上面提到的 k8s 的能力,在公升級應用(發新版本)和管理 pod (宿主機維護時把 pod 漂移到另乙個宿主機,或者在閒時動態地收縮 pod 數量從而把資源省出來另作他用)的過程中實現服務的零中斷。

下面的**定義了兩個定時任務:mysecondjobs 每秒鐘會觸發一次,每次持續約 1 秒鐘;myminutejobs 每分鐘會觸發一次,每次持續約 2 秒鐘。具體地可以閱讀下面的**(可以直接複製下面的**到自己的環境中執行):

package main

import (

"fmt"

"os"

"os/signal"

"syscall"

"time"

)func main()

} fmt.println("graceful ending")

// 做一些操作讓非同步任務正常結束,這裡偷懶地採取簡單等待的方式 ?

time.sleep(time.second * 10)

fmt.println("graceful ended.")

}func mysecondjobs()

func myminutejobs()

**中採用了 go mysecondjobs() 和 go myminutejobs() 非同步任務的方式;如果採用同步的方式將無法捕獲訊號,因為此時主線程在處理業務邏輯,沒有空閒處理訊號捕獲邏輯。

原始碼中偷懶地採取簡單等待的方式來保證非同步任務正常結束,非普適方法,實際開發中需要根據情況做定製。

time.ticker 的使用是有注意事項的,當 select 語句中同一時刻有多個分支滿足條件時會隨機取乙個執行,從而導致資訊丟失,不過本文的**不會觸發這個問題,大家可以思考一下原因。

如何優雅的關閉http服務在go web開發中一直被提及和討論的話題,今天go 1.8的發布終於為我們帶來了這個特性。

文件中是這樣介紹的:

func (srv *server) shutdown(ctx context.context) error
shutdown將無中斷的關閉正在活躍的連線,然後平滑的停止服務。處理流程如下:

需要注意的是,shutdown並不嘗試關閉或者等待hijacked連線,如websockets。如果需要的話呼叫者需要分別處理諸如長連線型別的等待和關閉。

其實,你只要呼叫shutdown方法就好了。

}執行程式:

go run main.go
然後ctrl + c終止該程式,會列印出如下資訊:

2017/02/17 11:36:28 server shutdown可以看到,服務被正確關閉了。

在沒有shutdown方法之前,ctrl + c就硬生生的終止了,然後就沒有然後了

預設情況下,go 應用在接收到 term 訊號後直接退出主程序,如果此時有過程沒處理完(比如 接收到外部請求後尚未返回響應,或者內部的非同步任務尚未結束),則會導致過程的異常中斷,影響服務質量。通過在**中顯式地捕獲 term 訊號及其他訊號,感知作業系統對程序的處理,可以主動採取措施優雅地結束應用程序。

隨著 k8s 的普及,考慮到其對程序生命週期的規範化管理,應用支援**級的優雅中止(尤其是容器化的應用)有必要成為一種開發規範,值得引起每一位開發者的注意

優雅的執行緒中止

stop 中止執行緒,並清除監控器鎖的資訊,但是可能導致執行緒安全問題,jdk不建議使用 執行緒安全問題 當子執行緒未執行完時在主線程使用stop終止了子執行緒會導致執行緒安全問題 示例 package com.hzw public class demo2 thread.print package ...

Golang的優雅重啟

更新 2015年4月 florian von bock 已將本文中描述的內容轉換為乙個名為 endless 的優秀go包 如果您有golang http服務,可能需要重新啟動它以公升級二進位制檔案或更改某些配置。如果你 像我一樣 因為網路伺服器處理它而優雅地重新啟動是理所當然的,你可能會發現這個配方...

如何優雅的入門golang

golang標準庫文件 高效能分布式系統開發 海量並行處理 遊戲服務端開發再好不過了 package main import fmt func main 複製 go run main.go hello world 複製 識別符號用來命名變數 型別等程式體。乙個或者多個字母 a za z 數字 0 9...