Golang中HTTP服务的分析与设计详解
来源:脚本之家
时间:2023-05-12 10:45:34 495浏览 收藏
小伙伴们有没有觉得学习Golang很有意思?有意思就对了!今天就给大家带来《Golang中HTTP服务的分析与设计详解》,以下内容将会涉及到HTTP、设计、分析,若是在学习中对其中部分知识点有疑问,或许看了本文就能帮到你!
http.ListenAndServe
type Server struct {
// 请求监听地址
Addr string
// 请求核心处理函数
Handler Handler
}http.ListenAndServe(httpAddr, nil)
// ListenAndServe always returns a non-nil error.
// 创造了一个server对象并调用ListenAndServe
func ListenAndServe(addr string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}
func (srv *Server) ListenAndServe() error {
// 如果关闭了http监听则直接返回ErrServerClosed
if srv.shuttingDown() {
return ErrServerClosed
}
addr := srv.Addr
if addr == "" {
addr = ":http"
}
// 开启net包的Listen监听方法,根据传入的类型返回监听的对象
ln, err := net.Listen("tcp", addr)
if err != nil {
return err
}
return srv.Serve(ln)
}Serve方法. 接收一个监听者
func (srv *Server) Serve(l net.Listener) error {
if fn := testHookServerServe; fn != nil {
fn(srv, l) // call hook with unwrapped listener
}
origListener := l
l = &onceCloseListener{Listener: l}
defer l.Close()
if err := srv.setupHTTP2_Serve(); err != nil {
return err
}
if !srv.trackListener(&l, true) {
return ErrServerClosed
}
defer srv.trackListener(&l, false)
baseCtx := context.Background()
if srv.BaseContext != nil {
baseCtx = srv.BaseContext(origListener)
if baseCtx == nil {
panic("BaseContext returned a nil context")
}
}
var tempDelay time.Duration // how long to sleep on accept failure
// 将整个Server对象设置进ctx中,在多个goroutinue中共享
ctx := context.WithValue(baseCtx, ServerContextKey, srv)
for {
rw, err := l.Accept() // 阻塞等待连接
if err != nil {
select {
case max {
tempDelay = max
}
srv.logf("http: Accept error: %v; retrying in %v", err, tempDelay)
time.Sleep(tempDelay)
continue
}
return err
}
connCtx := ctx
if cc := srv.ConnContext; cc != nil {
connCtx = cc(connCtx, rw)
if connCtx == nil {
panic("ConnContext returned nil")
}
}
tempDelay = 0
c := srv.newConn(rw)
c.setState(c.rwc, StateNew, runHooks) // before Serve can return
go c.serve(connCtx) //Serve a new connection 建立新的连接
}
}c.serve 这个函数主要是判断本次http请求是否升级为https,接着创建文本的reader,和写文本的buffer,再进一步读取本次的请求数据!
最后是调用关键的方法serverHandler{c.server}.ServeHttp(w,w.req)来处理本次请求!
serverHandler
// serverHandler 代表请求对应的处理逻辑
type serverHandler struct {
srv *Server
}
// 具体的处理函数
func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
handler := sh.srv.Handler
//如果入口设置传入了`Handler`,那么调用的就是传入的,否则就是DefaultServeMux
if handler == nil {
handler = DefaultServeMux
}
if req.RequestURI == "*" && req.Method == "OPTIONS" {
handler = globalOptionsHandler{}
}
if req.URL != nil && strings.Contains(req.URL.RawQuery, ";") {
var allowQuerySemicolonsInUse int32
req = req.WithContext(context.WithValue(req.Context(), silenceSemWarnContextKey, func() {
atomic.StoreInt32(&allowQuerySemicolonsInUse, 1)
}))
defer func() {
if atomic.LoadInt32(&allowQuerySemicolonsInUse) == 0 {
sh.srv.logf("http: URL query contains semicolon, which is no longer a supported separator; parts of the query may be stripped when parsed; see golang.org/issue/25192")
}
}()
}
handler.ServeHTTP(rw, req)
}流程梳理
上述大致调用的流程梳理完毕总结一下
创建服务->创建连接->监听请求(net.Listen)->处理请求(ServeHTTP)
- 标准库创建HTTP服务是通过Server对象完成的
- Server对象在for循环中不断监听每一个连接
- 每个连接都默认开启了一个goroutine
- serverHandler结构代表请求对应的逻辑,并用其ServeHTTP进行处理执行
- 具有默认处理Handler,DefaultServeMux
- DefaultServeMux是通过map来寻找路由的
自己动手写一个serverHandler

core.go
package framework
import "net/http"
type Core struct {
}
func (c Core) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
panic("implement me")
}
func NewCore() *Core {
return &Core{}
}main.go
package main
import (
"log"
"net/http"
"testdemo1/coredemo/framework"
)
func main() {
server:=&http.Server{Addr: ":8080",Handler: framework.NewCore()}
err := server.ListenAndServe()
if err!=nil{
log.Fatal(err)
}
}后续再往自己的serverHttp方法里自定义补充处理请求逻辑!
本文到此结束,欢迎收看下一篇
今天关于《Golang中HTTP服务的分析与设计详解》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于golang的内容请关注golang学习网公众号!
声明:本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
-
387 收藏
-
447 收藏
-
101 收藏
-
343 收藏
-
419 收藏
最新阅读
更多>
-
169 收藏
-
492 收藏
-
474 收藏
-
199 收藏
-
342 收藏
-
434 收藏
-
478 收藏
-
388 收藏
-
424 收藏
-
258 收藏
-
262 收藏
-
484 收藏
课程推荐
更多>
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习