golang HTTPサービスは、スムーズな再起動を達成します

パッケージメイン

インポート(
	"コンテキスト" 
	、 "符号化/ JSON" 
	"FMT" 
	"数学/ RAND" 
	"NET / HTTP" 
	"OS" 
	"OS /信号" 
	"時間" 

VAR logChan =メーク(チャンマップ[文字列]インターフェース{} )

VAR requestStatusMap =マップ[INT]} {BOOLの


VAR = makeがDONE(BOOLチャン,. 1)
VAR =メイク(チャンos.Signal ,. 1)終了


//なぜできGRを?
//通常の状況server.ListenAndServe()の下では、この場所は、プロセス全体の周りにハングアップする
//このプログラムは2つの部分として見ることができるのWebサーバが開いていない場合は、1は、Webサービス、契約の一部のリスニング部分でありますそれは新しい着信(リードとしての道を理解することができる)の要求処理できない
主なプロセスが壊れているので//本当にこの要求を行うと(メイン)キルされる
ので、原則の円滑な再起動は、ウェブサーバから最初のキル//です、ありません新しい要求が入って来て、以上のすべての既存の要求して行い、その後、現在のプロセスの終了
メイン(){FUNCを
	サーバー:
	signal.Notify(、os.Interruptを終了)
	monitorKill(サーバー、終了を)行く
	server.ListenAndServe()
	<-done 
} 


FUNC NEWSERVER()* http.Server { 
	ルータ:= http.NewServeMux()
	router.HandleFunc( "/ハロー」、のsayHello)
	リターン&http.Server { 
		ADDR: ":8262"、
		ハンドラー:ルータ、
	} 
} 

monitorKill(サーバーFUNC * http.Server、終了<ちゃんos.Signal){ 
	-quitは< 
	シャットダウン(サーバー)に行く
	ために{ 
		lenの場合(requestStatusMap)!= 0 { 
			fmt.Println( "目前还有进行中的请求、请稍等")
			time.Sleep(time.Second * 1)が
			継続
		}他{ 
			近い(行われる)
			ブレーク
		}
	} 
} 

FUNCシャットダウン(サーバ* http.Server){ 
	場合ERR:= server.Shutdown(context.Background())。ERR!=ゼロ{ 
		fmt.Println(ERR)
	} 
} 

のsayHello FUNC(W http.ResponseWriter、R * http.Request){ 
	行くWriteInfo()//请求写日志
	VARユニークID = GenerateRangeNum(1、1000)
	requestStatusMap [一意ID] =偽
	URL:= r.URL.Path 
	クエリ:= r.URL.RawQuery 
	方法:= r.Method 
	A:=マップ[ストリング]インターフェイス{} { 
		"URL":URL、
		"方法":方法、
		"クエリ" :クエリ、
		"応答": "!こんにちは世界"、
	} 
	logChan <-a 
	w.Write([]バイト( "Hello Worldの!"))
	time.Sleep(時間。
	、(requestStatusMap を削除

WriteInfo(){FUNC 
	= <-logChan:情報
	ファイル名:= "/tmp/weekhomework.log" 
	_、ERR:=はos.stat(fileNameに)
	!誤る場合= nilの|| os.IsNotExist(ERR){ 
		_、_ = os.Create(filename)で
	} 
	F、ERR = os.OpenFile(ファイル名、os.O_WRONLY、0644)
	f.Close延期() 場合ERR =ゼロ{ 
		fmt.Println (err.Error())
	}他{ 
		//追加写入为什么O_APPEND模式无法写入TODO?
		N、_:= f.Seek(0,2)
		infostr、_:= json.Marshal(情報)
		_、ERR = f.WriteAt([]バイト(文字列(infostr)+ "\ n")、N)
	} 
} 

GenerateRangeNum(分INT、最大INT)INT {FUNC 
	なら分== maxの{  
		戻り分
	} 
	rand.Seed(time.Now( ).Unix())
	randNum:= rand.Intn(最大-最小)+分
	リターンrandNum 
}

  

主なアイデア:すべての要求は、メモを取るためには、処理が完了した後、削除を行います。割り込み信号を監視するためのコルーチンでは、割り込み信号最初のHTTPサービスがオフになって。

この時には、要求が、その後回転で待機し、処理されていない、とすべてが終了シグナルをメインプロセスの実行の終了を与えられ、その後、処理がある場合

おすすめ

転載: www.cnblogs.com/tobemaster/p/11986814.html