Go Web 学习笔记(二)自定义服务器


Go Web 服务器自定义

上一讲中介绍了一个简单的 Go Web 应用程序,在该程序中使用的都是默认的服务器设置。而 Go Web 其实也可以允许自定义一些服务器的相关配置信息。

本文介绍如何在一个 Web 服务器当中自定义请求处理器、自定义 Web 服务器的相关配置信息以及自定义 Web 服务器的多路复用器。

自定义请求处理器

Web 服务器当中的请求处理器 Handler 是非常重要的一个部分,其配合配置好的请求路径便可以针对这类请求进行相应的处理。

而默认的请求处理器是一类指定输入以格式的函数,然后利用 http 包下的 HandleFunc 方法将其转变为对应的请求处理器函数(开发中常用这种方式):

http.HandleFunc("/", handler)

// 创建处理器函数
func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "hello world", r.URL.Path)
}

对于一些具有特殊需求的处理器来说该方法并不支持相应的修改,因此 http 包中也支持自定义一个 Handler 类型的结构体,然后实现对应的 ServeHTTP 方法,从而自定义出一个请求处理器函数:

// 自定义处理器结构体
type MyHandler struct{}

// 创建自定义处理器handler方法
func (m *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "serve with myHandler", r.URL.Path)
}

// 将自定义处理器与请求路径进行绑定
http.Handle("/myhandler", &myHandler) // 注意传入的是自定义处理器的地址

自定义服务器配置

之前的 demo 中,启动一个 Web App 的方法是:

http.ListenAndServe(":8080", nil)

这样只是针对服务器的启动地址进行了设置,并没有针对其他信息进行设置。

想要自定义服务器的相关配置的话就需要自定义一个 http.Server 对象,然后利用该对象的 ListenAndServe() 来启动一个服务器。

Server 对象所对应的属性:

type Server struct {
    Addr           string        // 监听的TCP地址,如果为空字符串会使用":http"
    Handler        Handler       // 调用的处理器,如为nil会调用http.DefaultServeMux
    ReadTimeout    time.Duration // 请求的读取操作在超时前的最大持续时间
    WriteTimeout   time.Duration // 回复的写入操作在超时前的最大持续时间
    MaxHeaderBytes int           // 请求的头域最大长度,如为0则用DefaultMaxHeaderBytes
    TLSConfig      *tls.Config   // 可选的TLS配置,用于ListenAndServeTLS方法
    // TLSNextProto(可选地)指定一个函数来在一个NPN型协议升级出现时接管TLS连接的所有权。
    // 映射的键为商谈的协议名;映射的值为函数,该函数的Handler参数应处理HTTP请求,
    // 并且初始化Handler.ServeHTTP的*Request参数的TLS和RemoteAddr字段(如果未设置)。
    // 连接在函数返回时会自动关闭。
    TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
    // ConnState字段指定一个可选的回调函数,该函数会在一个与客户端的连接改变状态时被调用。
    // 参见ConnState类型和相关常数获取细节。
    ConnState func(net.Conn, ConnState)
    // ErrorLog指定一个可选的日志记录器,用于记录接收连接时的错误和处理器不正常的行为。
    // 如果本字段为nil,日志会通过log包的标准日志记录器写入os.Stderr。
    ErrorLog *log.Logger
    // 内含隐藏或非导出字段
}

例如创建一个自定义设置的 Web App 并启动:

// 详细配置服务器的具体信息
server := http.Server{
	Addr:        ":8080",
	ReadTimeout: 2 * time.Second,
}
// 使用该服务器进行监听服务
server.ListenAndServe()

自定义多路复用器

之前的 demo 中在创建服务的时候使用的是默认的多路复用器 DefaultServeMux,我们也可以自定义一个多路复用器。

多路复用器类型结构体:

type ServeMux struct {
    // 内含隐藏或非导出字段
}

自定义一个多路复用器需要使用 http.NewServerMux方法。

mux := http.NewServeMux()
mux.HandleFunc("/", handler)
http.ListenAndServe(":8080", mux)

总结

使用 Go 中的 http 模块实现一个 web 应用程序是非常简单的,并且还支持自定义处理器、服务器配置、多路复用器等。但一般情况下建议使用默认的多路服务器以及使用 HandleFunc 方法来将一个函数转换为处理器Handler