正文

Golang中HTTP服务的分析与设计详解(朗格男表价格及图片)不看后悔

文章摘要

这篇文章描述了一个Go语言实现的服务器启动和管理逻辑,重点展示了服务器启动时的钩子函数调用、监听器替换与跟踪、资源管理及连接重传机制。代码通过创建内部的钩子函数调用`testHookServerServe`,并将其与原监听器进行替换,确保在监听器关闭时触发`defer`语句以释放资源。同时,服务器启动时会设置HTTP/2协议,并通过`trackListener`函数正确跟踪和取消监听器。在处理连接失败时,代码根据错误类型计算重试时间,并通过`go`语句启动新的连接处理,确保服务器能够持续处理请求。整体逻辑逻辑严谨,但对Go语言的网络模型和上下文管理有一定的要求。

func (srv *Server) Serve(l net.Listener) error { if fn :=testHookServerServe; fn !=nil { fn(srv, l) // call hook with unwrapped listener } origListener :=l l=&onceCloseListener{Listener: l} defer l.Close() if err :=srv.setupHTTP2_Serve(); err !=nil { return err } if !srv.trackListener(&l, true) { return ErrServerClosed } defer srv.trackListener(&l, false) baseCtx :=context.Background() if srv.BaseContext !=nil { baseCtx=srv.BaseContext(origListener) if baseCtx==nil { panic(“BaseContext returned a nil context”) } } var tempDelay time.Duration // how long to sleep on accept failure // 将整个Server对象设置进ctx中,在多个goroutinue中共享 ctx :=context.WithValue(baseCtx, ServerContextKey, srv) for { rw, err :=l.Accept() // 阻塞等待连接 if err !=nil { select { case <-srv.getDoneChan(): return ErrServerClosed default: } if ne, ok :=err.(net.Error); ok && ne.Temporary() { if tempDelay==0 { tempDelay=5 * time.Millisecond } else { tempDelay *=2 } if max :=1 * time.Second; tempDelay > max { tempDelay=max } srv.logf(“http: Accept error: %v; retrying in %v”, err, tempDelay) time.Sleep(tempDelay) continue } return err } connCtx :=ctx if cc :=srv.ConnContext; cc !=nil { connCtx=cc(connCtx, rw) if connCtx==nil { panic(“ConnContext returned nil”) } } tempDelay=0 c :=srv.newConn(rw) c.setState(c.rwc, StateNew, runHooks) // before Serve can return go c.serve(connCtx) //Serve a new connection 建立新的连接 } }