Golang學習-第二篇 搭建一個簡單的Go Web伺服器

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

序言

由於本人一直從事Web伺服器端的程式開發,所以在學習Golang也想從Web這裡開始學起,如果對Golang還不太清楚怎麼搭建環境的朋友們可以參考我的上一篇文章 Golang的簡單介紹及Windows環境下安裝、部署,這一篇我們來瞭解一下Golang的Web開發入門:搭建一個簡單的Go Web伺服器。

註:此文借鑒了Astaxie《Go Web編程》一書中的內容

本文

Go語言標準庫 - net/http

在學習Go語言有一個很好的起點,Go語言官方文檔很詳細,今天我們學習的Go Web伺服器的搭建就需要用到Go語言官方提供的標準庫 net/http,通過http包提供了HTTP用戶端和服務端的實現。同時使用這個包能很簡單地對web的路由,靜態檔案,模版,cookie等資料進行設定和操作。如果對http概念不是太清楚的朋友可以自行google。

http包建立Web伺服器

package mainimport (    "fmt"    "net/http"    "strings"    "log")func sayhelloName(w http.ResponseWriter, r *http.Request) {    r.ParseForm() //解析參數,預設是不會解析的    fmt.Println(r.Form) //這些資訊是輸出到伺服器端的列印資訊    fmt.Println("path", r.URL.Path)    fmt.Println("scheme", r.URL.Scheme)    fmt.Println(r.Form["url_long"])    for k, v := range r.Form {        fmt.Println("key:", k)        fmt.Println("val:", strings.Join(v, ""))    }    fmt.Fprintf(w, "Hello Wrold!") //這個寫入到w的是輸出到用戶端的}func main() {    http.HandleFunc("/", sayhelloName) //設定訪問的路由    err := http.ListenAndServe(":9090", nil) //設定監聽的連接埠    if err != nil {        log.Fatal("ListenAndServe: ", err)    }}

上面的代碼我們在IDE中編譯後並運行成功後,這個時侯我們就可以在9090連接埠監聽http連結請求了。



中,我們在瀏覽器中輸入了 http://localhost:9090 ,可以看到瀏覽器頁面中輸入出 Hello World!
這個時侯如果我們在瀏覽器地址後面加一些參數試試:http://localhost:9090?url_long=111&url_long=222,看看瀏覽器中輸出什嗎?伺服器端輸出的又是什嗎?


瀏覽器中輸出圖片
伺服器端輸出圖片

我們看到了上面的代碼,要編寫一個Web伺服器是不是很簡單,只要調用http包的兩個函數就可以了。
如果以前你是.NET程式員,那你也許就會問,我們的IIS伺服器不需要嗎?Go就是不需要這些,因為他直接就監聽了TCP連接埠了。
我們看到Go通過簡單的幾行代碼就已經運行起來一個Web服務了,而且這個Web服務內部有支援高並發的特性。現在Web服務已經搭建完成了,那我們現在來瞭解一個這個服務是怎麼運行起來的呢?

Web工作方式的幾個概念

以下幾個為伺服器段的概念

  • Request:使用者請求的資訊,用來解析使用者的請求資訊,包括post、get、cookie、url等資訊
  • Response:伺服器需要反饋給用戶端的資訊
  • Conn:使用者的每次請求連結
  • Handler:處理請求和產生返回資訊的處理邏輯

分析http包運行機制


Go實現Web服務的工作模式流程圖


這個過程我們需要清楚以下三個問題,則就清楚Go是如何讓Web運行起來了

  • 如何監聽連接埠?
    通過上面的代碼我們看到Go是通過一個函數ListenAndServe來處理這些事情的,這個底層其實這樣處
    理的:初始化一個server對象,然後調用了net.Listen("tcp", addr),也就是底層用TCP協議搭建了一個服
    務,然後監控我們設定的連接埠。

Go http包的源碼,這裡我們可以看到整個http處理過程

func (srv *Server) Serve(l net.Listener) error {    defer l.Close()    var tempDelay time.Duration // how long to sleep on accept failure    for {        rw, e := l.Accept()        if e != nil {            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                }                log.Printf("http: Accept error: %v; retrying in %v", e, tempDelay)                time.Sleep(tempDelay)                continue            }            return e        }        tempDelay = 0        if srv.ReadTimeout != 0 {            rw.SetReadDeadline(time.Now().Add(srv.ReadTimeout))        }        if srv.WriteTimeout != 0 {            rw.SetWriteDeadline(time.Now().Add(srv.WriteTimeout))        }        c, err := srv.newConn(rw)        if err != nil {            continue        }        go c.serve()    }    panic("not reached")}
  • 如何接收用戶端請求?
    上面代碼執行監控連接埠之後,調用了srv.Serve(net.Listener)函數,這個函數就是處理接收用戶端的請求信 息。這個函數裡面起了一個for{},首先通過Listener接收請求,其次建立一個 Conn,最後單獨開了一個 goroutine,把這個請求的資料當做參數扔給這個conn去服務:go c.serve()。這 個就是高並發體現了, 使用者的每一次請求都是在一個新的goroutine去服務,相互不影響。
  • 如何分配handler?
    conn首先會解析request:c.readRequest(),然後擷取相應的handler:handler := c.server.Handler,也就是我們剛才在調用函數ListenAndServe時候的第二個參數,我們前面例子傳遞的是nil,也就是為空白,那麼預設擷取handler = DefaultServeMux,那麼這個變數用來做什麼的呢?對,這個變數就是一個路由器,它用來匹配url跳轉到其相應的handle函數,那麼這個我們有設定過嗎?有,我們調用的代碼裡面第一句不是調用了http.HandleFunc("/", sayhelloName)嘛。這個作用就是註冊了請求/的路由規則,當請求uri為"/",路由就會轉到函數sayhelloName,DefaultServeMux會調用ServeHTTP方法,這個方法內部其實就是調用sayhelloName本身,最後通過寫入response的資訊反饋到用戶端。

一個http串連處理流程

至此我們的三個問題已經全部得到瞭解答,你現在對於Go如何讓Web跑起來的是否已經基本瞭解。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.