使用Go寫后端架構(gòu)(一)
首先片酝, go語言的編譯器包含了所有素需要的包欧瘪,因此十分方便寫后臺(tái)眷射,甚至不需要使用框架,就可以輕松搭建。在學(xué)習(xí)Go語言有一個(gè)很好的起點(diǎn)妖碉,Go語言官方文檔很詳細(xì)涌庭,今天我們學(xué)習(xí)的Go Web服務(wù)器的搭建就需要用到Go語言官方提供的標(biāo)準(zhǔn)庫(kù)?net/http,通過http包提供了HTTP客戶端和服務(wù)端的實(shí)現(xiàn)欧宜。同時(shí)使用這個(gè)包能很簡(jiǎn)單地對(duì)web的路由坐榆,靜態(tài)文件,模版冗茸,cookie等數(shù)據(jù)進(jìn)行設(shè)置和操作席镀。如果對(duì)http概念不是太清楚的朋友可以自行google。
第一步:導(dǎo)入相關(guān)庫(kù)文件:
import (
"net/http"
"html/template"
? //"encoding/json"
? "fmt"
)
第二步:創(chuàng)建服務(wù)器結(jié)構(gòu)體:與C++類似:
type Serverstruct {
? ? ServerName string
? ? ServerIP? string
}
第三步:綁定端口夏漱,設(shè)置post豪诲,get方法:
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":9002", nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
if r.Method =="GET" {
t, err := template.ParseFiles("test.html")
if err != nil {
fmt.Fprintf(w,"parse template error: %s", err.Error())
return
? ? ? }
t.Execute(w, nil)
}else if r.Method =="POST" {
r.ParseForm()
username := r.Form["username"]
password := r.Form["password"]
fmt.Printf("username = %s, password = %s", username, password)
}
}
使用go寫后端最關(guān)鍵的兩個(gè)問題:
如何接收客戶端請(qǐng)求挂绰?
上面代碼執(zhí)行監(jiān)控端口之后,調(diào)用了srv.Serve(net.Listener)函數(shù)扮授,這個(gè)函數(shù)就是處理接收客戶端的請(qǐng)求信 息。這個(gè)函數(shù)里面起了一個(gè)for{}刹勃,首先通過Listener接收請(qǐng)求堪侯,其次創(chuàng)建一個(gè) Conn,最后單獨(dú)開了一個(gè) goroutine荔仁,把這個(gè)請(qǐng)求的數(shù)據(jù)當(dāng)做參數(shù)扔給這個(gè)conn去服務(wù):go c.serve()。這 個(gè)就是高并發(fā)體現(xiàn)了乏梁, 用戶的每一次請(qǐng)求都是在一個(gè)新的goroutine去服務(wù),相互不影響遇骑。
如何分配handler卖毁?
conn首先會(huì)解析request:c.readRequest(),然后獲取相應(yīng)的handler:handler := c.server.Handler,也就是我們剛才在調(diào)用函數(shù)ListenAndServe時(shí)候的第二個(gè)參數(shù)落萎,我們前面例子傳遞的是nil亥啦,也就是為空练链,那么默認(rèn)獲取handler = DefaultServeMux,那么這個(gè)變量用來做什么的呢翔脱?對(duì)媒鼓,這個(gè)變量就是一個(gè)路由器错妖,它用來匹配url跳轉(zhuǎn)到其相應(yīng)的handle函數(shù),那么這個(gè)我們有設(shè)置過嗎?有站玄,我們調(diào)用的代碼里面第一句不是調(diào)用了http.HandleFunc("/", sayhelloName)嘛濒旦。這個(gè)作用就是注冊(cè)了請(qǐng)求/的路由規(guī)則,當(dāng)請(qǐng)求uri為"/"再登,路由就會(huì)轉(zhuǎn)到函數(shù)sayhelloName,DefaultServeMux會(huì)調(diào)用ServeHTTP方法梯嗽,這個(gè)方法內(nèi)部其實(shí)就是調(diào)用sayhelloName本身,最后通過寫入response的信息反饋到客戶端灯节。
代碼如下:
package main
import (
"net/http"
"html/template"
? //"encoding/json"
? "fmt"
)
type Serverstruct {
ServerName string
ServerIP? string
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":9002", nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
if r.Method =="GET" {
t, err := template.ParseFiles("test.html")
if err != nil {
fmt.Fprintf(w,"parse template error: %s", err.Error())
return
? ? ? }
t.Execute(w, nil)
}else if r.Method =="POST" {
r.ParseForm()
username := r.Form["username"]
password := r.Form["password"]
fmt.Printf("username = %s, password = %s", username, password)
}
}