golang之web编程执行流程
为什么golang做web编程比其他语言并发高: Go是通过一个函数ListenAndServe来处理这些事情的,这个底层其实这样处 理的:初始化一个server对象,然后调用了net.Listen("tcp",addr),也就是底层用TCP协议搭建了一个服 务,然后监控我们设置的端口。 func (srv *Server) Serve(l net.Listener) error { defer l.Close() var tempDelay time.Duration // how long to sleep on 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") } 监控之后如何接收客户端的请求呢?上面代码执行监控端口之后,调用了srv.Serve(net.Listener)函数,这个 函数就是处理接收客户端的请求信息。这个函数里面起了一个for{},首先通过Listener接收请求,其次创建一个 Conn,最后单独开了一个goroutine,把这个请求的数据当做参数扔给这个conn去服务:go c.serve()。这个就是 高并发体现了,用户的每一次请求都是在一个新的goroutine去服务,相互不影响。 那么如何具体分配到相应的函数来处理请求呢?conn首先会解析request:c.readRequest(),然后获取相应的 handler:handler := c.server.Handler,也就是我们刚才在调用函数ListenAndServe时候的第二个参数,我们前面例子传递的是nil,也就是为空,那么默认获取handler = DefaultServeMux,那么这个变量用来做什么 的呢?对,这个变量就是一个路由器,它用来匹配url跳转到其相应的handle函数,那么这个我们有设置过吗?有,我 们调用的代码里面第一句不是调用了http.HandleFunc("/",sayhelloName)嘛。这个作用就是注册了请求/的 路由规则,当请求uri为"/",路由就会转到函数sayhelloName,DefaultServeMux会调用ServeHTTP方法,这个方法内 部其实就是调用sayhelloName本身,最后通过写入response的信息反馈到客户端。 Go代码的执行流程 通过对http包的分析之后,现在让我们来梳理一下整个的代码执行过程。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |