陈银波的知识小站

  • 首页
  • 数学
  • 算法
  • 图
  • 数据
复杂 = f (简单1, 简单2, ... , 简单n)
  1. 首页
  2. 工程
  3. 正文

Go:net/http 服务端底层设计简述

1 9 月, 2024 526点热度 2人点赞 0条评论

0 前言

我自己使用 Go 语言进行项目开发已经有一年多的时间,不过一直很少去了解 Go 语言相关的底层设计的一些东西。最近花时间去看了 net/http 的底层设计的一些东西,这篇文章就是把我觉得 net/http 最有价值、最需要了解的东西拿出来分享。

1 从使用 net/http 的使用方式出发

使用 net/http 启动一个服务非常简单:

package main

import (
	"io"
	"log"
	"net/http"
)

func main() {
	// Hello world, the web server

	helloHandler := func(w http.ResponseWriter, req *http.Request) {
		io.WriteString(w, "Hello, world!\n")
	}

	http.HandleFunc("/", helloHandler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

上面这段代码有三个核心。

定义处理器函数

	helloHandler := func(w http.ResponseWriter, req *http.Request) {
		io.WriteString(w, "Hello, world!\n")
	}

这里定义了一个匿名函数 helloHandler,它接受两个参数:

  • w http.ResponseWriter: 这是一个用于构造 HTTP 响应的接口对象。我们可以使用它来向客户端发送数据。
  • req *http.Request: 这是一个包含 HTTP 请求所有信息的结构体。

io.WriteString 方法用来向 http.ResponseWriter 写入字符串 "Hello, world!\n",客户端接收 http.ResponseWriter 中的内容。

注册处理器

http.HandleFunc("/", helloHandler)

http.HandleFunc 用来注册处理器函数。第一个参数是路径模式,这里我们指定为根路径 /,这意味着对于所有发往服务器根路径的请求都将由 helloHandler 处理。

启动服务器

log.Fatal(http.ListenAndServe(":8080", nil))

http.ListenAndServe 方法用来启动 HTTP 服务器,监听并服务于指定的网络地址。这里我们让服务器监听本地机器上的 8080 端口。函数的第二个参数是处理器,当该参数为 nil 时,默认使用 http.DefaultServeMux。

2 http.ListenAndServe

我们当然选择从最关键的启动服务 http.ListenAndServe 入手,看看启动服务这个过程具体是做了什么。

  • 监听地址:当 http.ListenAndServe 启动后,它会在指定的地址上创建一个监听套接字(socket),等待客户端的连接请求。
  • 接受连接:每当有一个新的连接请求到达时,ListenAndServe 会接受这个连接,并为每个连接创建一个新的 goroutine。(一个连接一个 goroutine)
  • 读取请求:在每个新创建的 goroutine 中,服务器会读取客户端发送过来的 HTTP 请求。请求中包含了客户端想要访问的 URL、请求方法(如 GET、POST 等)以及其他相关信息。(每个连接可能有多个 HTTP 请求)
  • 请求分发:一旦请求被完全读取,服务器会将请求传递给多路复用器进行分发。(多路复用器可以基于请求的 URL 路径来决定哪个处理器应该处理这个请求)
  • 请求处理:多路复用器查找与请求 URL 匹配的处理器,并调用这个处理器来处理请求。
  • 发送响应:处理函数完成请求处理后,向客户端发送响应。响应可以包括状态码、响应头和响应体等部分。

上面流程就是 http.ListenAndServe 具体在做的事情。我刻意回避了一些底层的关键模块名如多路复用器 http.ServeMux,原因是希望你们对基本流程有所了解,然后再深入细节。

3 http.ServeMux 多路复用器

前面我们了解了 http.ListenAndServe 的具体流程,这里面涉及到非常重要的一点就是,请求的分发和处理,不同的路由使用不同的处理器进行处理。

在我们实际使用 net/http 进行开发的时候,什么样的路由如何进行对应的处理,这是我们自己决定和编写的,这是我们在进行 web 开发中非常重要的一步。因此,下面我们来了解 net/http 是如何对我们的路由和处理进行管理的。

http.ServeMux 的内部维护了一个路由表,它存储了所有注册的处理器。路由表是由一组键值对组成的,其中键是 URL 路径模式,值是对应的处理器。当一个 HTTP 请求到达时,ServeMux 会使用其内部的路由表来查找与请求 URL 匹配的处理器。

注册处理器主要有两种方式:

  • 使用 http.HandleFunc:

    http.HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))
    
  • 这个函数会将给定的处理函数注册到默认的 http.ServeMux 上。pattern 是一个 URL 路径模式,handler 是一个处理函数。

  • 使用 http.ServeMux.Handle:

    func (mux *ServeMux) Handle(pattern string, handler Handler)
    

    这个方法允许你将任意实现了 http.Handler 接口的对象注册到一个具体的 ServeMux 实例上。而 http.Handler 接口对象需要实现的函数是 func(http.ResponseWriter, *http.Request)

可以看到,无论是 处理函数 还是 处理器,其核心都是函数 func(http.ResponseWriter, *http.Request)。

所以:

  • 如果你有一个处理函数 func(http.ResponseWriter, *http.Request),可以直接使用 http.HandleFunc 进行注册。
  • 同样,你也可以把处理函数 func(http.ResponseWriter, *http.Request) 包装进 http.Handler,然后使用 func (mux *ServeMux) Handle(pattern string, handler Handler) 进行注册。

4 总结

以上即为我关于 Go net/http 的简单分享,实际简单使用 net/http 时,就是简单两步:

  • 准备路由和处理函数 func(ResponseWriter, *Request),进行注册
  • 调用 http.ListenAndServe 完成服务的启动

谢谢大家。

标签: 暂无
最后更新:1 9 月, 2024

陈银波

邮箱:agwave@foxmail.com 知乎:https://www.zhihu.com/people/agwave github:https://github.com/agwave leetcode:https://leetcode.cn/u/agwave

点赞
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

文章目录
  • 0 前言
  • 1 从使用 net/http 的使用方式出发
  • 2 http.ListenAndServe
  • 3 http.ServeMux 多路复用器
  • 4 总结
分类
  • 图
  • 工程
  • 数学
  • 数据
  • 算法
最新 热点 随机
最新 热点 随机
Change Data Capture (CDC) 技术初探 IPv6在物联网中的应用 IPv6首部的改进:简化与优化网络通信 IPv6:下一代互联网协议 联邦图学习:连接联邦学习与图神经网络的新桥梁
二次型化标准型的应用:最值求解图注意力网络(GAT):一个例子解释从输入到输出维度变化的完整过程图卷积网络(GCN):一个例子解释从输入到输出维度变化的完整过程联邦图学习:连接联邦学习与图神经网络的新桥梁IPv6首部的改进:简化与优化网络通信
遗传算法解决旅行商问题 Change Data Capture (CDC) 技术初探 高阶导数题四大解法一文搞定 PDF简历信息提取——BiLSTM-CRF IPv6:下一代互联网协议
归档
  • 2024 年 10 月
  • 2024 年 9 月
  • 2024 年 8 月
  • 2024 年 7 月
  • 2024 年 6 月
  • 2024 年 5 月

COPYRIGHT © 2024 陈银波的知识小站. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

粤ICP备2024254302号-1

粤公网安备44030002003798号