婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > golang高并發的深入理解

golang高并發的深入理解

熱門標簽:浙江高速公路地圖標注 中國地圖標注省會高清 地圖標注的汽車標 廣州呼叫中心外呼系統 西部云谷一期地圖標注 高德地圖標注口訣 江西轉化率高的羿智云外呼系統 南通如皋申請開通400電話 學海導航地圖標注

前言

GO語言在WEB開發領域中的使用越來越廣泛,Hired 發布的《2019 軟件工程師狀態》報告中指出,具有 Go 經驗的候選人是迄今為止最具吸引力的。平均每位求職者會收到9 份面試邀請。


想學習go,最基礎的就要理解go是怎么做到高并發的。

那么什么是高并發?

高并發(High Concurrency)是互聯網分布式系統架構設計中必須考慮的因素之一,它通常是指,通過設計保證系統能夠同時并行處理很多請求。

嚴格意義上說,單核的CPU是沒法做到并行的,只有多核的CPU才能做到嚴格意義上的并行,因為一個CPU同時只能做一件事。那為什么是單核的CPU也能做到高并發。這就是操作系統進程線程調度切換執行,感覺上是并行處理了。所以只要進程線程足夠多,就能處理C1K C10K的請求,但是進程線程的數量又受到操作系統內存等資源的限制。每個線程必須分配8M大小的棧內存,不管是否使用。每個php-fpm需要占用大約20M的內存。所以目前有線程的Java就比只有進程的PHP的并發處理能力高。當然了,軟件的處理能力不僅僅跟內存有關,還有是否阻塞,是否異步處理,CPU等等。Nginx作為單線程的模型卻可以承擔幾萬甚至幾十萬的并發請求,Nginx的話題說起來也就更多了。
我們繼續聊我們的Go,那么是不是可以有一種語言使用更小的處理單元,占用內存比線程更小,那么它的并發處理能力就可以更高。所以Google就做了這件事,就有了golang語言,golang從語言層面就支持了高并發。

go為什么能做到高并發

goroutine是Go并行設計的核心。goroutine說到底其實就是協程,但是它比線程更小,幾十個goroutine可能體現在底層就是五六個線程,Go語言內部幫你實現了這些goroutine之間的內存共享。執行goroutine只需極少的棧內存(大概是4~5KB),當然會根據相應的數據伸縮。也正因為如此,可同時運行成千上萬個并發任務。goroutine比thread更易用、更高效、更輕便。

一些高并發的處理方案基本都是使用協程,openresty也是利用lua語言的協程做到了高并發的處理能力,PHP的高性能框架Swoole目前也在使用PHP的協程。

協程更輕量,占用內存更小,這是它能做到高并發的前提。

go web開發中怎么做到高并發的能力

學習go的HTTP代碼。先創建一個簡單的web服務。

package main

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

func response(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintf(w, "Hello world!") //這個寫入到w的是輸出到客戶端的
}

func main() {
 http.HandleFunc("/", response)
 err := http.ListenAndServe(":9000", nil)
 if err != nil {
  log.Fatal("ListenAndServe: ", err)
 }
}

然后編譯

go build -o test_web.gobin
./test_web.gobin

然后訪問

curl 127.0.0.1:9000
Hello world!

這樣簡單的一個WEB服務就搭建起來。接下來我們一步一步理解這個Web服務是怎么運行的,怎么做到高并發的。
我們順著http.HandleFunc("/", response)方法順著代碼一直往上看。

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
 DefaultServeMux.HandleFunc(pattern, handler)
}
var DefaultServeMux = defaultServeMux
var defaultServeMux ServeMux

type ServeMux struct {
 mu sync.RWMutex//讀寫鎖。并發處理需要的鎖
 m  map[string]muxEntry//路由規則map。一個規則一個muxEntry
 hosts bool //規則中是否帶有host信息
}
一個路由規則字符串,對應一個handler處理方法。
type muxEntry struct {
 h  Handler
 pattern string
}

上面是DefaultServeMux的定義和說明。我們看到ServeMux結構體,里面有個讀寫鎖,處理并發使用。muxEntry結構體,里面有handler處理方法和路由字符串。

接下來我們看下,http.HandleFunc函數,也就是DefaultServeMux.HandleFunc做了什么事。我們先看mux.Handle第二個參數HandlerFunc(handler)

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
 mux.Handle(pattern, HandlerFunc(handler))
}
type Handler interface {
 ServeHTTP(ResponseWriter, *Request) // 路由實現器
}
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
 f(w, r)
}

我們看到,我們傳遞的自定義的response方法被強制轉化成了HandlerFunc類型,所以我們傳遞的response方法就默認實現了ServeHTTP方法的。

我們接著看mux.Handle第一個參數。

func (mux *ServeMux) Handle(pattern string, handler Handler) {
 mux.mu.Lock()
 defer mux.mu.Unlock()

 if pattern == "" {
  panic("http: invalid pattern")
 }
 if handler == nil {
  panic("http: nil handler")
 }
 if _, exist := mux.m[pattern]; exist {
  panic("http: multiple registrations for " + pattern)
 }

 if mux.m == nil {
  mux.m = make(map[string]muxEntry)
 }
 mux.m[pattern] = muxEntry{h: handler, pattern: pattern}

 if pattern[0] != '/' {
  mux.hosts = true
 }
}

將路由字符串和處理的handler函數存儲到ServeMux.m 的map表里面,map里面的muxEntry結構體,上面介紹了,一個路由對應一個handler處理方法。

接下來我們看看,http.ListenAndServe(":9000", nil)做了什么

func ListenAndServe(addr string, handler Handler) error {
 server := Server{Addr: addr, Handler: handler}
 return server.ListenAndServe()
}

func (srv *Server) ListenAndServe() error {
 addr := srv.Addr
 if addr == "" {
  addr = ":http"
 }
 ln, err := net.Listen("tcp", addr)
 if err != nil {
  return err
 }
 return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
}

net.Listen("tcp", addr) ,就是使用端口addr用TCP協議搭建了一個服務。tcpKeepAliveListener就是監控addr這個端口。

接下來就是關鍵代碼,HTTP的處理過程

func (srv *Server) Serve(l net.Listener) error {
 defer l.Close()
 if fn := testHookServerServe; fn != nil {
  fn(srv, l)
 }
 var tempDelay time.Duration // how long to sleep on accept failure

 if err := srv.setupHTTP2_Serve(); err != nil {
  return err
 }

 srv.trackListener(l, true)
 defer srv.trackListener(l, false)

 baseCtx := context.Background() // base is always background, per Issue 16220
 ctx := context.WithValue(baseCtx, ServerContextKey, srv)
 for {
  rw, e := l.Accept()
  if e != nil {
   select {
   case -srv.getDoneChan():
    return ErrServerClosed
   default:
   }
   if ne, ok := e.(net.Error); ok  ne.Temporary() {
    if tempDelay == 0 {
     tempDelay = 5 * time.Millisecond
    } else {
     tempDelay *= 2
    }
    if max := 1 * time.Second; tempDelay > max {
     tempDelay = max
    }
    srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay)
    time.Sleep(tempDelay)
    continue
   }
   return e
  }
  tempDelay = 0
  c := srv.newConn(rw)
  c.setState(c.rwc, StateNew) // before Serve can return
  go c.serve(ctx)
 }
}

for里面l.Accept()接受TCP的連接請求,c := srv.newConn(rw)創建一個Conn,Conn里面保存了該次請求的信息(srv,rw)。啟動goroutine,把請求的參數傳遞給c.serve,讓goroutine去執行。

這個就是GO高并發最關鍵的點。每一個請求都是一個單獨的goroutine去執行。

那么前面設置的路由是在哪里匹配的?是在c.serverde的c.readRequest(ctx)里面分析出URI METHOD等,執行serverHandler{c.server}.ServeHTTP(w, w.req)做的。看下代碼

func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
 handler := sh.srv.Handler
 if handler == nil {
  handler = DefaultServeMux
 }
 if req.RequestURI == "*"  req.Method == "OPTIONS" {
  handler = globalOptionsHandler{}
 }
 handler.ServeHTTP(rw, req)
}

handler為空,就我們剛開始項目中的ListenAndServe第二個參數。我們是nil,所以就走DefaultServeMux,我們知道開始路由我們就設置的是DefaultServeMux,所以在DefaultServeMux里面我一定可以找到請求的路由對應的handler,然后執行ServeHTTP。前邊已經介紹過,我們的reponse方法為什么具有ServeHTTP的功能。流程大概就是這樣的。

我們看下流程圖


結語

我們基本已經學習忘了GO 的HTTP的整個工作原理,了解到了它為什么在WEB開發中可以做到高并發,這些也只是GO的冰山一角,還有Redis MySQL的連接池。要熟悉這門語言還是多寫多看,才能掌握好它。靈活熟練的使用。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。

您可能感興趣的文章:
  • 基于Golang 高并發問題的解決方案
  • golang高并發限流操作 ping / telnet
  • golang-gin-mgo高并發服務器搭建教程
  • 如何利用Golang寫出高并發代碼詳解
  • 關于golang高并發的實現與注意事項說明

標簽:許昌 吐魯番 曲靖 德宏 東營 常州 貴州 保定

巨人網絡通訊聲明:本文標題《golang高并發的深入理解》,本文關鍵詞  golang,高并發,高,并發,的,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《golang高并發的深入理解》相關的同類信息!
  • 本頁收集關于golang高并發的深入理解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    91精品国产aⅴ一区二区| 亚洲成人av在线电影| 亚洲国产精品成人久久综合一区| 一区二区三区资源| 91免费在线视频观看| 中文字幕日韩欧美一区二区三区| 国产91精品精华液一区二区三区| 国产偷国产偷亚洲高清人白洁| 久草热8精品视频在线观看| 欧美一区二区黄色| 激情综合色综合久久| 久久天堂av综合合色蜜桃网| 国产麻豆91精品| 日韩伦理免费电影| 欧美三级三级三级| 免费高清在线视频一区·| 91精品国产入口| 国产激情91久久精品导航| 国产精品视频yy9299一区| 99精品久久免费看蜜臀剧情介绍| 亚洲欧美日韩一区| 欧美亚洲一区三区| 日本不卡1234视频| 欧美美女一区二区| 另类成人小视频在线| 久久精品视频在线免费观看| 成人午夜碰碰视频| 日韩精品亚洲一区| 久久免费美女视频| 成人美女视频在线看| 亚洲自拍欧美精品| 久久伊人中文字幕| 欧美日韩综合在线免费观看| 国产成人在线色| 亚洲精品五月天| 欧美一区二区二区| 成人一级片在线观看| 一区二区国产视频| www国产精品av| 色综合天天综合网国产成人综合天| 美女www一区二区| 亚洲r级在线视频| ●精品国产综合乱码久久久久| 精品视频免费在线| 国产91精品精华液一区二区三区 | 欧美日韩精品一区二区三区| 亚洲高清视频中文字幕| 精品粉嫩aⅴ一区二区三区四区| 成人精品小蝌蚪| 奇米精品一区二区三区在线观看| 亚洲一二三四久久| 亚洲男女一区二区三区| 在线不卡a资源高清| 91丨国产丨九色丨pron| 麻豆成人综合网| 亚洲一区二区偷拍精品| 欧美精品一区二区在线播放| 欧美在线免费观看视频| 成人av网在线| 成人的网站免费观看| 蜜臀久久久99精品久久久久久| 亚洲一区二区三区三| 久久久久久久久久久久电影 | 欧美日韩精品欧美日韩精品一综合| 国产精品99久久久久久似苏梦涵| 首页欧美精品中文字幕| 亚洲一区二区三区三| 国产精品欧美精品| 1000部国产精品成人观看| 中国色在线观看另类| 国产日韩精品久久久| 91精品婷婷国产综合久久竹菊| 欧美日韩国产综合久久| 欧美三级在线看| 91精品国产综合久久香蕉的特点| 91精品一区二区三区在线观看| 欧美日韩国产美女| 欧美tickling挠脚心丨vk| 久久久久99精品一区| 国产精品久久午夜| 一区二区三区在线免费观看| 亚洲午夜精品17c| 久久草av在线| 成人91在线观看| 欧美精品视频www在线观看| 欧美蜜桃一区二区三区| 精品成人私密视频| 国产精品国产精品国产专区不片| 一区二区三区在线视频观看58 | 精品国产欧美一区二区| 欧美精品一区二区久久婷婷 | 天天操天天色综合| 亚洲一二三四区| 蜜桃视频一区二区三区| 经典三级视频一区| 91丨porny丨户外露出| 欧美日韩一区二区三区在线| 久久亚洲欧美国产精品乐播| 亚洲美女屁股眼交3| 麻豆精品一区二区综合av| 成人性生交大片免费看在线播放| 在线亚洲人成电影网站色www| 欧美一级片在线观看| 国产日韩精品视频一区| 亚洲一区免费在线观看| 高清beeg欧美| 欧美巨大另类极品videosbest | 亚洲婷婷国产精品电影人久久| 亚洲成年人网站在线观看| 精品中文字幕一区二区小辣椒| 99久久99久久久精品齐齐| 精品国产伦一区二区三区观看方式 | 国产自产视频一区二区三区| 成人精品鲁一区一区二区| 欧美精品18+| 日韩理论片在线| 成人中文字幕合集| 日韩精品一区二区三区中文精品| 欧美日韩五月天| 丁香另类激情小说| 日韩视频一区二区在线观看| www国产成人| 91久久国产最好的精华液| 97aⅴ精品视频一二三区| 国内精品视频一区二区三区八戒| 日本丰满少妇一区二区三区| 美女精品一区二区| 青椒成人免费视频| 久久精品二区亚洲w码| 高清不卡一区二区在线| 国产一区二区在线电影| 欧美挠脚心视频网站| 国产精品沙发午睡系列990531| 欧美日韩国产色站一区二区三区| 欧美人成免费网站| 国产欧美日韩精品在线| 久久精品国产成人一区二区三区| 欧美在线观看一区| 亚洲人成亚洲人成在线观看图片 | 久久午夜免费电影| 精品系列免费在线观看| 日韩一区二区免费电影| 日日夜夜精品视频天天综合网| 在线视频亚洲一区| 亚洲一区二区三区四区中文字幕| 91免费国产在线| 1024成人网| 91农村精品一区二区在线| 亚洲美女视频在线| 欧美片在线播放| 精品一区二区三区在线观看国产| 精品国精品自拍自在线| 国产a久久麻豆| 亚洲欧美一区二区在线观看| 99久久精品费精品国产一区二区| 国产精品丝袜久久久久久app| eeuss鲁一区二区三区| 一区二区三区四区蜜桃| 欧美美女一区二区三区| 韩国欧美国产1区| 国产精品久99| 欧美高清性hdvideosex| 精品制服美女丁香| 国产精品久久久久久户外露出 | 一区二区三区四区蜜桃| 欧美一区二区成人| 成人在线综合网| 天堂久久一区二区三区| www亚洲一区| 一本色道久久加勒比精品| 香蕉成人伊视频在线观看| 久久久久久97三级| 91农村精品一区二区在线| 捆绑调教一区二区三区| 中文字幕日韩欧美一区二区三区| 欧美丰满少妇xxxbbb| 成人午夜碰碰视频| 亚洲国产精品久久久男人的天堂| 精品国产伦理网| 欧美日韩亚洲另类| 波多野结衣中文字幕一区二区三区| 亚洲成精国产精品女| 国产精品视频yy9299一区| 欧美一区二区久久久| 色视频成人在线观看免| 国产91丝袜在线播放| 日韩精品成人一区二区三区 | 2欧美一区二区三区在线观看视频| 成人中文字幕在线| 韩日欧美一区二区三区| 一区二区成人在线视频| 国产精品免费视频一区| 精品国产伦一区二区三区观看体验 | 亚洲美女区一区| 国产三级一区二区| 日韩欧美一区二区视频| 色香蕉成人二区免费| 国产精品影视在线观看| 日本 国产 欧美色综合| 亚洲高清在线精品|