我的2016年小结
2016, 瞎忙、穷。
(本来想完整发出来,但是想了想,其他篇幅有点多余,上面两个词,够了)
							
			
								
			
			
	2016, 瞎忙、穷。
(本来想完整发出来,但是想了想,其他篇幅有点多余,上面两个词,够了)
前段时间,线上服务器因为部分微服务提供的 HTTP API 响应慢,而我们没有用正确的姿势来处理 HTTP 超时(当然,还有少量 RPC 超时), 同时我们也没有服务降级策略和容灾机制,导致服务相继挂掉?。服务降级和容灾需要一段时间的架构改造,但是以正确的姿势使用 HTTP 超时确是马上可以习得的。
所有的 Timeout 都构建于 Golang 提供的 Set[Read|Write]Deadline 原语之上。

此外,http.ListenAndServe, http.ListenAndServeTLS and http.Serve 等方法都没有设置超时,且无法设置超时。因此不适合直接用来提供公网服务。正确的姿势是:
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21  | 
						package main import (     "net/http"     "time" ) func main() {     server := &http.Server{         Addr:         ":8081",         ReadTimeout:  3 * time.Second,         WriteTimeout: 5 * time.Second,     }     http.HandleFunc("/hi", func(w http.ResponseWriter, r *http.Request) {         w.Write([]byte("hi"))     })     server.ListenAndServe() }  | 
					

取消一个 http request 有两种方式:
后一种因为可以传递 parent context, 因此可以做级联 cancel, 效果更佳。代码示例:
| 
					 1 2 3 4 5 6 7 8 9 10 11  | 
						ctx, cancel := context.WithCancel(context.TODO())  // or parant context timer := time.AfterFunc(5*time.Second, func() {       cancel() }) req, err := http.NewRequest("GET", "http://httpbin.org/range/2048?duration=8&chunk_size=256", nil)   if err != nil {       log.Fatal(err) } req = req.WithContext(ctx)    |