go http模块源码分析-server端

前言

近期使用go开发api后台服务,对http模块源码有初步了解,所以整理总结一下。

server端核心模型包括

  • Server 类型结构,代表了一个指定端口下的服务。

同时也保存了tls,超时等配置。最重要的是一个handler处理器。

type Server struct {
    Addr    string  // TCP address to listen on, ":http" if empty
    Handler Handler // handler to invoke, http.DefaultServeMux if nil
    TLSConfig *tls.Config
    ReadTimeout time.Duration
        //...
}

ListenAndServe方法开启监听,等待连接。
server 监听客户端请求,启动goroutine处理。

func (srv *Server) Serve(l net.Listener) error {
    //...
    for {
        rw, e := l.Accept()
        // ...
        c := srv.newConn(rw)
        go c.serve(ctx)
    }
}
  • Handler 接口,响应一个http请求
type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}
  • ServeMux : http请求多路复用器,实现了 Handler接口,它的实现为: 转发请求到匹配的handler处理。
type ServeMux struct {
    mu    sync.RWMutex
    m     map[string]muxEntry
    es    []muxEntry // slice of entries sorted from longest to shortest.
    hosts bool       // whether any patterns contain hostnames
}

// ServeHTTP dispatches the request to the handler whose
// pattern most closely matches the request URL.
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
    if r.RequestURI == "*" {
        if r.ProtoAtLeast(1, 1) {
            w.Header().Set("Connection", "close")
        }
        w.WriteHeader(StatusBadRequest)
        return
    }
    h, _ := mux.Handler(r)
    h.ServeHTTP(w, r)
}
  • DefaultServeMux: 是ServeMux类型一个实力, 作为一个全局对象导出。当新建的server对象,handler为空时,使用DefaultServeMux。
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = &defaultServeMux

var defaultServeMux ServeMux

可以通过HandleFunc方法,向全局多路复用器中加入路由模式及其handler。
处理请求时根据所有加入的路由模式中匹配。

// HandleFunc registers the handler function for the given pattern
// in the DefaultServeMux.
// The documentation for ServeMux explains how patterns are matched.
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    DefaultServeMux.HandleFunc(pattern, handler)
}

注册pattern, 如果以/结尾,会加入到排序的切片中,在map中匹配不到路由时,使用它,做最长匹配。

if pattern[len(pattern)-1] == '/' {
        mux.es = appendSorted(mux.es, e)
    }

路由匹配规则,先在map中精确匹配。
匹配失败则 用到排序的slice 进行最长匹配。

func (mux *ServeMux) match(path string) (h Handler, pattern string) {
    // Check for exact match first.
    v, ok := mux.m[path]
    if ok {
        return v.h, v.pattern
    }

    // Check for longest valid match.  mux.es contains all patterns
    // that end in / sorted from longest to shortest.
    for _, e := range mux.es {
        if strings.HasPrefix(path, e.pattern) {
            return e.h, e.pattern
        }
    }
    return nil, ""
}

总结:

    1. go的http server模块同时也包含了处理socker 连接的代码,所以不需要像java需要额外的应用服务器,例如tomcat。 go更易于部署,开发迭代。
      我认为一部分原因 是得益于go对并发的原生支持,go的并发模型。go开发时,可以使用goroute简单 并且低代价的方式,即可获得高并发的支持。
    1. go server中路由匹配 力度太大,一个url匹配一个handler,不区分http方法,也无法在url中加入参数匹配。
      所以 路由部分 还是建议使用开源模块
      https://github.com/gorilla/mux
      https://github.com/julienschmidt/httprouter
      mux源码分析参考 : 这里

参考:
https://www.godoc.org/net/http

原文链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容

  • 前面有介绍beego web框架, 其实很多框架都是在 最简单的http服务上做扩展的的,基本上都是遵循http协...
    若与阅读 35,469评论 4 31
  • 译注: 这篇文章的内容非常基础,也非常容易理解。原文地址,感觉是最能清晰的讲述了net/http包的用法的一篇,故...
    li3p阅读 1,966评论 0 3
  • 《Go语言四十二章经》第三十六章 net/http包 作者:李骁 在Go中,搭建一个http server简单到令...
    ffhelicopter阅读 2,240评论 0 8
  • Go语言中HTTP Server: HTTP server,顾名思义,支持http协议的服务器,HTTP是一个简单...
    WuXiao_阅读 9,341评论 2 24
  • 小忆在许多人眼里是一个乖巧懂事,性格内向话很少的小姑娘,可是这样的性格让她在生活和工作中不够自信,存在感太低,常常...
    万妮妮阅读 203评论 0 1