This is a creation in Article, where the information may have evolved or changed.
Why Golang do Web programming with higher concurrency than other languages:
Go is handled by a function listenandserve, which is actually handled by initializing a server object and then calling net. Listen ("tcp", addr), which is the bottom layer, builds a service with the TCP protocol and then monitors the ports we set up.
The following code from Go HTTP package source code, through the following code we can see the entire HTTP processing process:
Func (SRV *server) Serve (l net. Listener) Error {defer l.close () var tempdelay time. Duration//How long-to-sleep on the Accept failure for {RW, E: = L.accept () if E! = nil {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} log. Printf ("Http:accept error:%v; Retrying in%v ", E, Tempdelay) time. Sleep (Tempdelay) Continue} return e} tempdelay = 0 if srv. ReadTimeout! = 0 {rw. Setreaddeadline (time. Now (). ADD (SRV. readtimeout))} if srv. WriteTimeout! = 0 {rw. Setwritedeadline (time. Now (). ADD (SRV. writetimeout)})} C, err: = Srv.newconn (rw) if err! =Nil {Continue} Go C.serve ()} Panic ("Not reached")}
How to receive client requests after monitoring? SRV is called after the above code executes the monitoring port. Serve (NET. Listener) function, which is the processing of request information from the receiving client. This function inside a for{}, first through the listener receive the request, followed by creating a Conn, and finally opened a separate goroutine, the request data as parameters thrown to this Conn to service: Go C.serve (). This is the high concurrency reflects that the user's every request is in a new goroutine to service, not affect each other.
So how do you assign the appropriate function to handle the request? Conn first parses Request:c.readrequest () and then gets the corresponding Handler:handler: = C.server.handler, That is, we just called the function listenandserve when the second parameter, our previous example passed nil, that is, the null, then the default to get handler = Defaultservemux, then what is this variable used to do? This variable is a router, it is used to match the URL to jump to its corresponding handle function, then this we have set it? Yes, the first sentence in the code we call is not HTTP. Handlefunc ("/", Sayhelloname). This function is to register the request/routing rule, when the request URI is "/", the route will go to the function Sayhelloname,defaultservemux will call the Servehttp method, this method is actually called Sayhelloname itself, Finally, by writing the response feedback to the client.
After the execution of the Go Code through the analysis of the HTTP packet, let's now comb through the entire code execution process.
First Call Http.handlefunc
In order to do a few things:
1 called the Handlefunc of Defaultservermux.
2 called the handle of Defaultservermux.
3 Add the corresponding handler and routing rules to the map[string]muxentry in Defaultservemux next call HTTP. Listenandserve (": 9090", nil)
In order to do a few things:
1 instantiating the server
2 calling the server's Listenandserve ()
3 Call net. Listen ("tcp", addr) Listening port
4 Start A For loop, accept requests in the loop body
5 instantiate a conn for each request and open a Goroutine to service the request Go C.serve ()
6 read the contents of each request W, err: = C.readrequest ()
7 Determine if handler is empty, if not set handler (this example is not set handler), handler is set to Defaultservemux
8 Calling Handler's Servehttp
9 In this example, the following goes into the Defaultservermux.servehttp
10 Select handler according to request and enter into the Servehttp Mux.handler (R) of this handler. Servehttp (W, R)
11 Select handler:
A determine if there is a route to satisfy this request (looping through Servermux's muxentry)
B If there is a route to satisfy, call this route handler Servehttp
C If no route is met, call Notfoundhandler's servehttp