基于Golang的简单web服务程序开发——CloudGo
基于Golang的簡單web服務程序開發——CloudGo【閱讀時間:約10分鐘】
- 一、概述
- 二、系統環境&項目介紹
- 1.系統環境
- 2.項目的任務要求
- (1)基本要求
- (2)擴展要求
- 三、具體程序設計及Golang代碼實現
- 1.預先準備
- 2.CloudGoClient.go的main函數
- 3.CloudServer.go的NewServer函數
- 4.CloudServer.go的initRoutes函數
- 5.CloudServer.go的apiTestHandler函數
- 6.CloudServer.go的homeHandler函數
- 7.CloudServer.go的userHandler函數
- 四、程序使用與測試
- 1.封裝并使用程序包
- 2.功能測試
- 3.curl連接測試
- 4.ab壓力測試,并解釋重要參數
- 五、完整代碼
- 六、擴展博客
- 七、References
一、概述
開發簡單 web 服務程序 cloudgo,了解 web 服務器工作原理。
任務目標
- 熟悉 go 服務器工作原理
- 基于現有 web 庫,編寫一個簡單 web 應用類似 cloudgo。
- 使用 curl 工具訪問 web 程序
- 對 web 執行壓力測試
二、系統環境&項目介紹
1.系統環境
操作系統:CentOS7
硬件信息:使用virtual box配置虛擬機(內存3G、磁盤30G)
編程語言:GO 1.15.2
2.項目的任務要求
(1)基本要求
- 編程 web 服務程序 類似 cloudgo 應用。
- 支持靜態文件服務
- 支持簡單 js 訪問
- 提交表單,并輸出一個表格(必須使用模板)
- 使用 curl 測試,將測試結果寫入 README.md
- 使用 ab 測試,將測試結果寫入 README.md。并解釋重要參數。
(2)擴展要求
選擇以下一個或多個任務,以博客的形式提交。
- 通過源碼分析、解釋一些關鍵功能實現
- 選擇簡單的庫,如 mux 等,通過源碼分析、解釋它是如何實現擴展的原理,包括一些 golang 程序設計技巧。
三、具體程序設計及Golang代碼實現
1.預先準備
首先需要安裝以下三個程序包:
[henryhzy@localhost ~]$ go get github.com/codegangsta/negroni
[henryhzy@localhost ~]$ go get github.com/gorilla/mux
[henryhzy@localhost ~]$ go get github.com/unrolled/render
下面我按照以下順序來介紹簡單web服務程序——CloudGo的程序設計:
①CloudGoClient.go的main函數
②CloudServer.go的NewServer函數
③CloudServer.go的initRoutes函數
④CloudServer.go的apiTestHandler函數
⑤CloudServer.go的homeHandler函數
⑥CloudServer.go的userHandler函數
2.CloudGoClient.go的main函數
借鑒課程博客1,編寫CloudGoClient.go的main函數如下:
package mainimport ("os"flag "github.com/spf13/pflag""github.com/user/CloudGo/service"
)const (PORT string = "2026"
)func main() {port := os.Getenv("PORT")if len(port) == 0 {port = PORT}pPort := flag.StringP("port", "p", PORT, "PORT for httpd listening")flag.Parse()if len(*pPort) != 0 {port = *pPort}server := service.NewServer()server.Run(":" + port)
}
3.CloudServer.go的NewServer函數
借鑒課程博客2,編寫CloudServer.go的NewServer函數如下:
// NewServer configures and returns a Server.
func NewServer() *negroni.Negroni {formatter := render.New(render.Options{Directory: "templates",Extensions: []string{".html"},IndentJSON: true,})n := negroni.Classic()mx := mux.NewRouter()initRoutes(mx, formatter)n.UseHandler(mx)return n
}
4.CloudServer.go的initRoutes函數
借鑒課程博客2,編寫CloudServer.go的initRoutes函數如下:
func initRoutes(mx *mux.Router, formatter *render.Render) {webRoot := os.Getenv("WEBROOT")if len(webRoot) == 0 {if root, err := os.Getwd(); err != nil {panic("Could not retrive working directory")} else {webRoot = root//fmt.Println(root)}}mx.HandleFunc("/api/test", apiTestHandler(formatter)).Methods("GET")mx.HandleFunc("/", homeHandler(formatter)).Methods("GET")mx.HandleFunc("/user", userHandler).Methods("POST")mx.PathPrefix("/").Handler(http.FileServer(http.Dir(webRoot + "/assets/")))
}
5.CloudServer.go的apiTestHandler函數
借鑒課程博客2,編寫CloudServer.go的apiTestHandler函數如下:
//mx.HandleFunc("/api/test", apiTestHandler(formatter)).Methods("GET")func apiTestHandler(formatter *render.Render) http.HandlerFunc {return func(w http.ResponseWriter, req *http.Request) {formatter.JSON(w, http.StatusOK, struct {ID string `json:"id"`Content string `json:"content"`}{ID: "18342026", Content: "Hello from Go!"})}
}
其對應的js文件為apitest.js,內容如下:
$(document).ready(function() {$.ajax({url: "/api/test"}).then(function(data) {$('.ID').append(data.ID);$('.Content').append(data.Content);});
});
6.CloudServer.go的homeHandler函數
借鑒課程博客2,編寫CloudServer.go的homeHandler函數如下:
//main
//mx.HandleFunc("/", homeHandler(formatter)).Methods("GET")func homeHandler(formatter *render.Render) http.HandlerFunc {return func(w http.ResponseWriter, req *http.Request) {template := template.Must(template.New("home.html").ParseFiles("./templates/home.html"))_ = template.Execute(w, struct {ID stringContent string}{ID: "18342026", Content: "Welcome to CloudGo!!"})}
}
home對應的是網頁的初始頁面,需要再編寫相對應的home.html和home.css,這里為了符合課程博客的“提交表單”要求,我將其設置為登錄頁面:
<html><head><link rel="stylesheet" href="css/home.css" />
</head><body><form class="box" action="./user" method="POST"><h1 class="Content">{{.Content}}</h1><input type="text" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" value="Sign In"><h4 class="Content">{{"Designed By HenryHZY, 18342026."}}</h4><img src="files/nice picture.png" height="400" width="400"/></form>
</body></html>
7.CloudServer.go的userHandler函數
借鑒課程博客2,編寫CloudServer.go的userHandler函數如下:
func userHandler(w http.ResponseWriter, r *http.Request) {r.ParseForm()username := template.HTMLEscapeString(r.Form.Get("username"))password := template.HTMLEscapeString(r.Form.Get("password"))t := template.Must(template.New("user.html").ParseFiles("./templates/user.html"))err := t.Execute(w, struct {Username stringPassword stringID stringMotto string}{Username: username, Password: password, ID: "18342026", Motto: "Stay hungry, stay foolish."})if err != nil {panic(err)}
}
user對應的是登錄后跳轉的頁面,需要再編寫相對應的user.html和user.css,這里為了符合課程博客的“輸出一個表格”要求,我將其設置為對應的登錄用戶的個人信息:
<html><head><link rel="stylesheet" href="css/user.css" />
</head><body><table class="box" border="4"><tr><td>Username</td><td>{{.Username}}</td></tr><tr><td>Password</td><td>{{.Password}}</td></tr><tr><td>ID</td><td>{{.ID}}</td></tr><tr><td>Motto</td><td>{{.Motto}}</td></tr></table>
</body></html>
四、程序使用與測試
1.封裝并使用程序包
在項目CloudGo的目錄下,執行如下指令:
go install
在其他路徑下建立main.go,并調用CloudGo庫即可。
2.功能測試
功能測試主要從用戶角度測試程序包的功能,在【三、具體程序設計及Golang代碼實現】已設計了main函數,直接通過以下指令運行即可:
[henryhzy@localhost CloudGo]$ go run CloudGoClient.go
然后在瀏覽器中進入http://localhost:2026瀏覽即可,下面以項目的要求來演示功能測試結果。
編程 web 服務程序 類似 cloudgo 應用。
①支持靜態文件服務
②支持簡單 js 訪問
③提交表單,并輸出一個表格(必須使用模板)
①支持靜態文件服務
進入http://localhost:2026/files:
訪問圖片文件:
訪問文本文件:
②支持簡單 js (JavaScript )訪問
上文我借鑒課程博客2,設計了apiTestHandler函數。
這段代碼非常簡單,輸出了一個 匿名結構,并 JSON (JavaScript Object Notation) 序列化輸出。
進入http://localhost:2026/api/test:
可以使用其來進行篩選和查看原始數據等操作:
③提交表單,并輸出一個表格(必須使用模板)
為了符合課程博客的要求,我將網頁的初始頁面設置為登錄頁面,需要輸入username和password,再點擊sign in按鈕來實現“提交表單”;將登錄后跳轉的頁面設置為顯示對應的登錄用戶的個人信息表格,來實現“輸出一個表格”。
此外根據博客要求,使用模板即使用html+css,此處已在【三、具體程序設計及Golang代碼實現】中給出。
訪問http://localhost:2026/:
3.curl連接測試
①curl -v http://localhost:2026/files
[henryhzy@localhost ~]$ curl -v http://localhost:2026/files
* About to connect() to localhost port 2026 (#0)
* Trying ::1...
* Connected to localhost (::1) port 2026 (#0)
> GET /files HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:2026
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Location: files/
< Date: Sun, 22 Nov 2020 12:37:50 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
②curl -v http://localhost:2026/files/nice_text.txt
[henryhzy@localhost ~]$ curl -v http://localhost:2026/files/nice_text.txt
* About to connect() to localhost port 2026 (#0)
* Trying ::1...
* Connected to localhost (::1) port 2026 (#0)
> GET /files/nice_text.txt HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:2026
> Accept: */*
>
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Content-Length: 21
< Content-Type: text/plain; charset=utf-8
< Last-Modified: Sun, 22 Nov 2020 12:36:41 GMT
< Date: Sun, 22 Nov 2020 12:38:37 GMT
<
* Connection #0 to host localhost left intact
③curl -v http://localhost:2026/api/test
[henryhzy@localhost ~]$ curl -v http://localhost:2026/api/test
* About to connect() to localhost port 2026 (#0)
* Trying ::1...
* Connected to localhost (::1) port 2026 (#0)
> GET /api/test HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:2026
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=UTF-8
< Date: Sun, 22 Nov 2020 12:39:01 GMT
< Content-Length: 54
<
{"id": "18342026","content": "Hello from Go!"
}
* Connection #0 to host localhost left intact
④curl -v http://localhost:2026
[henryhzy@localhost ~]$ curl -v http://localhost:2026
* About to connect() to localhost port 2026 (#0)
* Trying ::1...
* Connected to localhost (::1) port 2026 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:2026
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sun, 22 Nov 2020 12:39:26 GMT
< Content-Length: 504
< Content-Type: text/html; charset=utf-8
<
<html><head><link rel="stylesheet" href="css/home.css" />
</head><body><form class="box" action="./user" method="POST"><h1 class="Content">Welcome to CloudGo!!</h1><input type="text" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" value="Sign In"><h4 class="Content">Designed By HenryHZY, 18342026.</h4><img src="files/nice picture.png" height="400" width="400"/></form>
</body>* Connection #0 to host localhost left intact
⑤curl -v http://localhost:2026/errorTest
此處是進行錯誤測試,當對應的網頁不存在,便會返回404 NOT FOUND的錯誤信息。
[henryhzy@localhost ~]$ curl -v http://localhost:2026/errorTest
* About to connect() to localhost port 2026 (#0)
* Trying ::1...
* Connected to localhost (::1) port 2026 (#0)
> GET /errorTest HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:2026
> Accept: */*
>
< HTTP/1.1 404 Not Found
< Content-Type: text/plain; charset=utf-8
< X-Content-Type-Options: nosniff
< Date: Sun, 22 Nov 2020 12:40:20 GMT
< Content-Length: 19
<
404 page not found
* Connection #0 to host localhost left intact
4.ab壓力測試,并解釋重要參數
①首先安裝壓力測試需要的軟件:
[henryhzy@localhost ~]$ sudo yum -y install httpd-tools
②參數解釋
輸入ab -help:
[henryhzy@localhost ~]$ ab -help
Usage: ab [options] [http[s]://]hostname[:port]/path
Options are:-n requests Number of requests to perform-c concurrency Number of multiple requests to make at a time-t timelimit Seconds to max. to spend on benchmarkingThis implies -n 50000-s timeout Seconds to max. wait for each responseDefault is 30 seconds-b windowsize Size of TCP send/receive buffer, in bytes-B address Address to bind to when making outgoing connections-p postfile File containing data to POST. Remember also to set -T-u putfile File containing data to PUT. Remember also to set -T-T content-type Content-type header to use for POST/PUT data, eg.'application/x-www-form-urlencoded'Default is 'text/plain'-v verbosity How much troubleshooting info to print-w Print out results in HTML tables-i Use HEAD instead of GET-x attributes String to insert as table attributes-y attributes String to insert as tr attributes-z attributes String to insert as td or th attributes-C attribute Add cookie, eg. 'Apache=1234'. (repeatable)-H attribute Add Arbitrary header line, eg. 'Accept-Encoding: gzip'Inserted after all normal header lines. (repeatable)-A attribute Add Basic WWW Authentication, the attributesare a colon separated username and password.-P attribute Add Basic Proxy Authentication, the attributesare a colon separated username and password.-X proxy:port Proxyserver and port number to use-V Print version number and exit-k Use HTTP KeepAlive feature-d Do not show percentiles served table.-S Do not show confidence estimators and warnings.-q Do not show progress when doing more than 150 requests-g filename Output collected data to gnuplot format file.-e filename Output CSV file with percentages served-r Don't exit on socket receive errors.-h Display usage information (this message)-Z ciphersuite Specify SSL/TLS cipher suite (See openssl ciphers)-f protocol Specify SSL/TLS protocol(SSL3, TLS1, TLS1.1, TLS1.2 or ALL)
由上可知,ab壓力測試指令的格式為:ab [options] url
其中url為要進行壓力測試的連接,option為輸入參數,具體如下:
-n 即requests,用于指定壓力測試總共的執行次數。
-c 即concurrency,用于指定的并發數。
-t 即timelimit,等待響應的最大時間(單位:秒)。
-b 即windowsize,TCP發送/接收的緩沖大小(單位:字節)。
-p 即postfile,發送POST請求時需要上傳的文件,此外還必須設置-T參數。
-u 即putfile,發送PUT請求時需要上傳的文件,此外還必須設置-T參數。
-T 即content-type,用于設置Content-Type請求頭信息,例如:application/x-www-form-urlencoded,默認值為text/plain。
-v 即verbosity,指定打印幫助信息的冗余級別。
-w 以HTML表格形式打印結果。
-i 使用HEAD請求代替GET請求。
-x 插入字符串作為table標簽的屬性。
-y 插入字符串作為tr標簽的屬性。
-z 插入字符串作為td標簽的屬性。
-C 添加cookie信息,例如:"Apache=1234"(可以重復該參數選項以添加多個)。
-H 添加任意的請求頭,例如:"Accept-Encoding: gzip",請求頭將會添加在現有的多個請求頭之后(可以重復該參數選項以添加多個)。
-A 添加一個基本的網絡認證信息,用戶名和密碼之間用英文冒號隔開。
-P 添加一個基本的代理認證信息,用戶名和密碼之間用英文冒號隔開。
-X 指定使用的和端口號,例如:"126.10.10.3:88"。
-V 打印版本號并退出。
-k 使用HTTP的KeepAlive特性。
-d 不顯示百分比。
-S 不顯示預估和警告信息。
-g 輸出結果信息到gnuplot格式的文件中。
-e 輸出結果信息到CSV格式的文件中。
-r 指定接收到錯誤信息時不退出程序。
-h 顯示用法信息,其實就是ab -help。
此外,輸出參數如下:
Server Software: nginx/1.10.2 (服務器軟件名稱及版本信息)
Server Hostname: 192.168.1.106(服務器主機名)
Server Port: 80 (服務器端口)
Document Path: /index1.html. (供測試的URL路徑)
Document Length: 3721 bytes (供測試的URL返回的文檔大小)
Concurrency Level: 1000 (并發數)
Time taken for tests: 2.327 seconds (壓力測試消耗的總時間)
Complete requests: 5000 (的總次數)
Failed requests: 688 (失敗的請求數)
Write errors: 0 (網絡連接寫入錯誤數)
Total transferred: 17402975 bytes (傳輸的總數據量)
HTML transferred: 16275725 bytes (HTML文檔的總數據量)
Requests per second: 2148.98 [#/sec] (mean) (平均每秒的請求數) 這個是非常重要的參數數值,服務器的吞吐量
Time per request: 465.338 [ms] (mean) (所有并發用戶(這里是1000)都請求一次的平均時間)
Time request: 0.247 [ms] (mean, across all concurrent requests) (單個用戶請求一次的平均時間)
Transfer rate: 7304.41 [Kbytes/sec] received 每秒獲取的數據長度 (傳輸速率,單位:KB/s)
...
Percentage of the requests served within a certain time (ms)50% 347 ## 50%的請求在347ms內返回 66% 401 ## 60%的請求在401ms內返回 75% 43180% 51690% 60095% 84698% 157199% 1593100% 1619 (longest request)
③簡單的壓力測試
此處我主要使用-n和-c參數,即”用于指定壓力測試總共的執行次數“和”用于指定的并發數“。另外,我們需要注意-c的數值需要小于或等于-n的數值。
(1)ab -n 2026 -c 10 http://localhost:2026/files
[henryhzy@localhost ~]$ ab -n 2026 -c 10 http://localhost:2026/files
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 202 requests
Completed 404 requests
Completed 606 requests
Completed 808 requests
Completed 1010 requests
Completed 1212 requests
Completed 1414 requests
Completed 1616 requests
Completed 1818 requests
Completed 2020 requests
Finished 2026 requestsServer Software:
Server Hostname: localhost
Server Port: 2026Document Path: /files
Document Length: 0 bytesConcurrency Level: 10
Time taken for tests: 0.729 seconds
Complete requests: 2026
Failed requests: 0
Write errors: 0
Non-2xx responses: 2026
Total transferred: 218808 bytes
HTML transferred: 0 bytes
Requests per second: 2780.91 [#/sec] (mean)
Time per request: 3.596 [ms] (mean)
Time per request: 0.360 [ms] (mean, across all concurrent requests)
Transfer rate: 293.30 [Kbytes/sec] receivedConnection Times (ms)min mean[+/-sd] median max
Connect: 0 0 0.1 0 2
Processing: 1 3 4.0 1 24
Waiting: 0 3 4.0 1 23
Total: 1 4 4.0 2 24Percentage of the requests served within a certain time (ms)50% 266% 275% 380% 590% 795% 1498% 1899% 19100% 24 (longest request)
(2)ab -n 2026 -c 10 http://localhost:2026/files/nice_text.txt
[henryhzy@localhost ~]$ ab -n 2026 -c 10 http://localhost:2026/files/nice_text.txt
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 202 requests
Completed 404 requests
Completed 606 requests
Completed 808 requests
Completed 1010 requests
Completed 1212 requests
Completed 1414 requests
Completed 1616 requests
Completed 1818 requests
Completed 2020 requests
Finished 2026 requestsServer Software:
Server Hostname: localhost
Server Port: 2026Document Path: /files/nice_text.txt
Document Length: 21 bytesConcurrency Level: 10
Time taken for tests: 0.725 seconds
Complete requests: 2026
Failed requests: 0
Write errors: 0
Total transferred: 417356 bytes
HTML transferred: 42546 bytes
Requests per second: 2793.84 [#/sec] (mean)
Time per request: 3.579 [ms] (mean)
Time per request: 0.358 [ms] (mean, across all concurrent requests)
Transfer rate: 562.04 [Kbytes/sec] receivedConnection Times (ms)min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 1 3 4.1 2 23
Waiting: 0 3 4.1 1 23
Total: 1 4 4.2 2 23Percentage of the requests served within a certain time (ms)50% 266% 275% 380% 490% 895% 1698% 1899% 19100% 23 (longest request)
(3)ab -n 2026 -c 10 http://localhost:2026/api/test
[henryhzy@localhost ~]$ ab -n 2026 -c 10 http://localhost:2026/api/test
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 202 requests
Completed 404 requests
Completed 606 requests
Completed 808 requests
Completed 1010 requests
Completed 1212 requests
Completed 1414 requests
Completed 1616 requests
Completed 1818 requests
Completed 2020 requests
Finished 2026 requestsServer Software:
Server Hostname: localhost
Server Port: 2026Document Path: /api/test
Document Length: 54 bytesConcurrency Level: 10
Time taken for tests: 0.642 seconds
Complete requests: 2026
Failed requests: 0
Write errors: 0
Total transferred: 358602 bytes
HTML transferred: 109404 bytes
Requests per second: 3157.84 [#/sec] (mean)
Time per request: 3.167 [ms] (mean)
Time per request: 0.317 [ms] (mean, across all concurrent requests)
Transfer rate: 545.84 [Kbytes/sec] receivedConnection Times (ms)min mean[+/-sd] median max
Connect: 0 0 0.4 0 9
Processing: 1 3 3.4 1 18
Waiting: 0 3 3.4 1 18
Total: 1 3 3.5 2 22Percentage of the requests served within a certain time (ms)50% 266% 275% 380% 490% 795% 1398% 1799% 18100% 22 (longest request)
(4)ab -n 2026 -c 10 http://localhost:2026/
[henryhzy@localhost ~]$ ab -n 2026 -c 10 http://localhost:2026/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 202 requests
Completed 404 requests
Completed 606 requests
Completed 808 requests
Completed 1010 requests
Completed 1212 requests
Completed 1414 requests
Completed 1616 requests
Completed 1818 requests
Completed 2020 requests
Finished 2026 requestsServer Software:
Server Hostname: localhost
Server Port: 2026Document Path: /
Document Length: 504 bytesConcurrency Level: 10
Time taken for tests: 1.064 seconds
Complete requests: 2026
Failed requests: 0
Write errors: 0
Total transferred: 1258146 bytes
HTML transferred: 1021104 bytes
Requests per second: 1903.61 [#/sec] (mean)
Time per request: 5.253 [ms] (mean)
Time per request: 0.525 [ms] (mean, across all concurrent requests)
Transfer rate: 1154.44 [Kbytes/sec] receivedConnection Times (ms)min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 1 5 5.1 3 25
Waiting: 0 5 5.1 2 25
Total: 1 5 5.1 3 26Percentage of the requests served within a certain time (ms)50% 366% 475% 580% 890% 1195% 1898% 2399% 24100% 26 (longest request)
(5)ab -n 2026 -c 10 http://localhost:2026/errorTest
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking localhost (be patient)
Completed 202 requests
Completed 404 requests
Completed 606 requests
Completed 808 requests
Completed 1010 requests
Completed 1212 requests
Completed 1414 requests
Completed 1616 requests
Completed 1818 requests
Completed 2020 requests
Finished 2026 requestsServer Software:
Server Hostname: localhost
Server Port: 2026Document Path: /errorTest
Document Length: 19 bytesConcurrency Level: 10
Time taken for tests: 0.669 seconds
Complete requests: 2026
Failed requests: 0
Write errors: 0
Non-2xx responses: 2026
Total transferred: 356576 bytes
HTML transferred: 38494 bytes
Requests per second: 3028.19 [#/sec] (mean)
Time per request: 3.302 [ms] (mean)
Time per request: 0.330 [ms] (mean, across all concurrent requests)
Transfer rate: 520.47 [Kbytes/sec] receivedConnection Times (ms)min mean[+/-sd] median max
Connect: 0 0 0.1 0 1
Processing: 1 3 3.6 1 19
Waiting: 0 3 3.5 1 18
Total: 1 3 3.6 2 19Percentage of the requests served within a certain time (ms)50% 266% 275% 380% 490% 795% 1398% 1799% 18100% 19 (longest request)
五、完整代碼
具體代碼可見gitee倉庫:gitee
六、擴展博客
(2)擴展要求選擇以下一個或多個任務,以博客的形式提交。1. 通過源碼分析、解釋一些關鍵功能實現
2. 選擇簡單的庫,如 mux 等,通過源碼分析、解釋它是如何實現擴展的原理,包括一些 golang 程序設計技巧。
擴展博客:【Golang源碼分析】Go Web常用程序包gorilla/mux的源碼剖析
七、References
- 課程博客1
- 課程博客2
- ab壓力測試安裝與解釋
總結
以上是生活随笔為你收集整理的基于Golang的简单web服务程序开发——CloudGo的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中级实训总结报告
- 下一篇: 【Golang源码分析】Go Web常用