快速搭建 Web 服务器


在Golang仅需要几行代码,便可以建立一个简单的 Web 服务:

http://localhost:9999/helloHello, world!

当时刚接触到Go的时候,我是很震惊的!!!以前写 PHP,要配 web 服务,还得搭个 Nginx或Apache 服务器呢,配置下监听的接口转发到fastcgi进行处理。Go这么流氓吗,直接几行代码就完事了?是的,Go 就真的很流氓,它直接监听了 TCP 端口。


Web 服务器运转机制

以使用TCP协议通讯的socket为例,socket通信交互流程大概是这样子的

我们来看一段代码 net 包开头的一段示例代码

Listen Socket8080


实际上 Go 的 web server 也就是这么个处理逻辑,只是在这多了一些处理逻辑:请求的协议解析,读取客户端提交的数据,路由分配(根据请求分配对应的 handler 处理请求),封装响应数据。

http 包源码分析

http.ListenAndServe(":9999", nil)

1. 端口监听

让我们追进去看看,实际上,初始化一个server对象,调用了 server 的 ListenAndServe 方法。

ln, err := net.Listen("tcp", addr)

2. 接受请求

srv.Serve(ln)


for{}
listener.AcceptConngoroutine

知识点:每个请求都会创建一个对应的goroutine去处理,所以各个请求之间是相互不影响的,同时提高并发性能。

3. 读取请求并解析

go c.serve(ctx)
readRequest

最后将请求的数据赋值到Request,并初始化Response对象,供业务层调用。

4. 路由分配handler

serverHandler{c.server}.ServeHTTP(w, w.req)
http.ListenAndServe(":9999", nil)
handler = DefaultServeMuxListenAndServe


我们来看看httprouter的例子,你就会明白了:

看到了吧,上面router便是自定义的路由器,在走到上面ServerHTTP的时候,便是使用指定的路由器进行路由。

5. 路由分配handler

DefaultServeMux

我想你看到这已经累了,请不要轻易离开,学海无涯苦作舟啊~~

路由的过程里面我们只要弄懂下面的三个问题,就知道 Go 自带的路由是怎么运行的了:

  1. 什么时候注册的路由?
  2. 如何根据注册的路由找对应的handler?
  3. 如果没注册路由访问会返回什么?


DefaultServeMux
mes


mmes/a/b//a//a/b/c/a/b//a/

1. 什么时候注册的路由?

ListenAndServehttp.HandleFunc("/hello", helloHandler)
ServeMux.mServeMux.es

2. 如何根据注册的路由找对应的handler?

mes
handler.ServeHTTP(rw, req)


3. 如果没注册路由访问会返回什么?

NotFoundHandler()"404 page not found"


好了,我想你看完这个,应该对 Go 如何用几行代码搭建 Web 服务器有了基本了解了吧。

结尾

个人建议,看完这个文章后,自己点进去 Go 的源码包里,我想你会有新收获的。


如果有任何疑问或错误可直接留言,我看到会回复的~~


公众号『知否专栏』,欢迎关注。