package main import ( "net/http" "fmt" "strings" "log" ) func sayHelloName(w http.ResponseWriter, r *http.Request) { r.ParseForm() fmt.Println(r.Form) fmt.Println("url", r.URL.Path) fmt.Println("scheme", r.URL.Scheme) fmt.Println(r.Form["url_long"]) for k, v:=range r.Form { fmt.Println("key:", k) fmt.Println("value:", strings.Join(v, "")) } fmt.Fprintln(w, "hello web") } func main() { http.HandleFunc("/", sayHelloName) err := http.ListenAndServe(":9876", nil) if err!= nil { log.Fatal("ListenAndServe ", err) } }
先看一个最基本的golang的web服务器代码。main中在HandleFunc中设置了路由,然后调用ListenAndServe选择监听的接口和路由方法(这里路由方法制空,即调用了默认的路由,即HandleFunc设置的路由)。
LestenAndServe调用了http库中的serve方法,代码如下:
func (srv *Server) Serve(l net.Listener) error { defer l.Close() if fn := testHookServerServe; fn != nil { fn(srv, l) } var tempDelay time.Duration // how long to sleep on accept failure if err := srv.setupHTTP2_Serve(); err != nil { return err } srv.trackListener(l, true) defer srv.trackListener(l, false) baseCtx := context.Background() // base is always background, per Issue 16220 ctx := context.WithValue(baseCtx, ServerContextKey, srv) for { rw, e := l.Accept() if e != nil { select { case <-srv.getDoneChan(): return ErrServerClosed default: } if ne, ok := e.(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", e, tempDelay) time.Sleep(tempDelay) continue } return e } tempDelay = 0 c := srv.newConn(rw) c.setState(c.rwc, StateNew) // before Serve can return go c.serve(ctx) } }
可以看到,serve建立了一个循环来监听请求。在接收到连接请求后,先接受请求,然后新建了连接,并利用go新建了线程来处理新的连接。这就是golang在处理web请求上支持高并发的根本。同时也保证了每个连接的独立性。
原文地址:https://www.cnblogs.com/wangzhao765/p/9037614.html
时间: 2024-07-31 17:10:33