知識
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!
您當前位置>首頁 » 新聞資訊 » 網(wǎng)站建設 >
Go語言Web基礎(chǔ)--Go如何使得Web工作
發(fā)表時間:2018-7-22
發(fā)布人:葵宇科技
瀏覽次數(shù):92
Go搭建一個Web服務器
前面小節(jié)已經(jīng)介紹了Web是基于http協(xié)議的一個服務,Go語言里面提供了一個完善的net/http包,通過http包可以很方便的就搭建起來一個可以運行的Web服務。同時使用這個包能很簡單地對Web的路由,靜態(tài)文件,模版,cookie等數(shù)據(jù)進行設置和操作。
http包建立Web服務器
package main
import (
"fmt"
"net/http"
"strings"
"log"
)
func sayhelloName(w http.ResponseWriter, r *http.Request) {
r.ParseForm() //解析參數(shù),默認是不會解析的
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 astaxie!") //這個寫入到w的是輸出到客戶端的
}
func main() {
http.HandleFunc("/", sayhelloName) //設置訪問的路由
err := http.ListenAndServe(":9090", nil) //設置監(jiān)聽的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
上面這個代碼,我們build之后,然后執(zhí)行web.exe,這個時候其實已經(jīng)在9090端口監(jiān)聽http鏈接請求了。
在瀏覽器輸入http://localhost:9090
可以看到瀏覽器頁面輸出了Hello astaxie!
可以換一個地址試試:http://localhost:9090/?url_long=111&url_long=222
看看瀏覽器輸出的是什么,服務器輸出的是什么?
在服務器端輸出的信息如下:
我們看到上面的代碼,要編寫一個Web服務器很簡單,只要調(diào)用http包的兩個函數(shù)就可以了。
如果你以前是PHP程序員,那你也許就會問,我們的nginx、apache服務器不需要嗎?Go就是不需要這些,因為他直接就監(jiān)聽tcp端口了,做了nginx做的事情,然后sayhelloName這個其實就是我們寫的邏輯函數(shù)了,跟php里面的控制層(controller)函數(shù)類似。
如果你以前是Python程序員,那么你一定聽說過tornado,這個代碼和他是不是很像,對,沒錯,Go就是擁有類似Python這樣動態(tài)語言的特性,寫Web應用很方便。
如果你以前是Ruby程序員,會發(fā)現(xiàn)和ROR的/script/server啟動有點類似。
我們看到Go通過簡單的幾行代碼就已經(jīng)運行起來一個Web服務了,而且這個Web服務內(nèi)部有支持高并發(fā)的特性,我將會在接下來的兩個小節(jié)里面詳細的講解一下Go是如何實現(xiàn)Web高并發(fā)的。
Go如何使得Web工作
前面介紹了如何通過Go搭建一個Web服務,我們可以看到簡單應用一個net/http包就方便的搭建起來了。那么Go在底層到底是怎么做的呢?萬變不離其宗,Go的Web服務工作也離不開我們前面介紹的Web工作方式。
web工作方式的幾個概念
以下均是服務器端的幾個概念
- Request:用戶請求的信息,用來解析用戶的請求信息,包括post、get、cookie、url等信息
- Response:服務器需要反饋給客戶端的信息
- Conn:用戶的每次請求鏈接
- Handler:處理請求和生成返回信息的處理邏輯
分析http包運行機制
如下圖所示,是Go實現(xiàn)Web服務的工作模式的流程圖
http包執(zhí)行流程:
-
創(chuàng)建Listen Socket, 監(jiān)聽指定的端口, 等待客戶端請求到來。
-
Listen Socket接受客戶端的請求, 得到Client Socket, 接下來通過Client Socket與客戶端通信。
-
處理客戶端的請求, 首先從Client Socket讀取HTTP請求的協(xié)議頭, 如果是POST方法, 還可能要讀取客戶端提交的數(shù)據(jù), 然后交給相應的handler處理請求, handler處理完畢準備好客戶端需要的數(shù)據(jù), 通過Client Socket寫給客戶端。
這整個的過程里面我們只要了解清楚下面三個問題,也就知道Go是如何讓Web運行起來了
- 如何監(jiān)聽端口?
- 如何接收客戶端請求?
- 如何分配handler?
Go是通過一個函數(shù)ListenAndServe
來處理這些事情的,這個底層其實這樣處理的:初始化一個server對象,然后調(diào)用了net.Listen("tcp", addr)
,也就是底層用TCP協(xié)議搭建了一個服務,然后監(jiān)控我們設置的端口。
下面代碼來自Go的http包的源碼,通過下面的代碼我們可以看到整個的http處理過程:
func (srv *Server) Serve(l net.Listener) error {
defer l.Close()
var tempDelay time.Duration // how long to sleep>監(jiān)控之后如何接收客戶端的請求呢?上面代碼執(zhí)行監(jiān)控端口之后,調(diào)用了srv.Serve(net.Listener)
函數(shù),這個函數(shù)就是處理接收客戶端的請求信息。這個函數(shù)里面起了一個for{}
,首先通過Listener接收請求,其次創(chuàng)建一個Conn,最后單獨開了一個goroutine,把這個請求的數(shù)據(jù)當做參數(shù)扔給這個conn去服務:go c.serve()
。這個就是高并發(fā)體現(xiàn)了,用戶的每一次請求都是在一個新的goroutine去服務,相互不影響。
那么如何具體分配到相應的函數(shù)來處理請求呢?conn首先會解析request:c.readRequest()
,然后獲取相應的handler:handler := c.server.Handler
,也就是我們剛才在調(diào)用函數(shù)ListenAndServe
時候的第二個參數(shù),我們前面例子傳遞的是nil,也就是為空,那么默認獲取handler = DefaultServeMux
,那么這個變量用來做什么的呢?對,這個變量就是一個路由器,它用來匹配url跳轉(zhuǎn)到其相應的handle函數(shù),那么這個我們有設置過嗎?有,我們調(diào)用的代碼里面第一句不是調(diào)用了http.HandleFunc("/", sayhelloName)
嘛。這個作用就是注冊了請求/
的路由規(guī)則,當請求uri為"/",路由就會轉(zhuǎn)到函數(shù)sayhelloName,DefaultServeMux會調(diào)用ServeHTTP方法,這個方法內(nèi)部其實就是調(diào)用sayhelloName本身,最后通過寫入response的信息反饋到客戶端。
詳細的整個流程如下圖所示:

至此我們的三個問題已經(jīng)全部得到了解答,你現(xiàn)在對于Go如何讓Web跑起來的是否已經(jīng)基本了解呢?
End
相關(guān)案例查看更多
相關(guān)閱讀
- 小程序開發(fā)費用
- 服務器
- 怎么做網(wǎng)站
- 網(wǎng)站收錄
- 云南網(wǎng)站建設 網(wǎng)絡服務
- 報廢車管理系統(tǒng)
- 百度小程序開發(fā)
- 云南做百度小程序的公司
- 網(wǎng)站建設公司哪家好
- 云南網(wǎng)站建設服務
- 云南網(wǎng)站建設方案 doc
- 云南小程序定制
- vue開發(fā)小程序
- 報廢車拆解系統(tǒng)
- 大理小程序開發(fā)
- 汽車報廢回收軟件
- 云南旅游網(wǎng)站建設
- painter
- 云南小程序開發(fā)首選品牌
- 云南小程序開發(fā)公司推薦
- 海報插件
- APP
- 小程序被騙退款成功
- 云南網(wǎng)站建設哪家公司好
- typescript
- 云南網(wǎng)站優(yōu)化公司
- 微信分銷
- 網(wǎng)站排名
- web
- 智慧農(nóng)貿(mào)市場