服務計算 第十一週
開發 web 服務程序 信息查詢小程序
1 主要內容
在老師原有的博客基礎上,添加了新的功能,做成了一個信息查詢系統,由於時間比較緊,所以比較粗糙,但是大致框架已經構建好了。
這裏是github鏈接。
2 程序介紹
2.1 功能介紹
2.1.1 註冊信息
介紹:當您需要在網上註冊自己的信息,只需要登陸網站輸入相關信息即可。
需要指令:regist
輸入格式:curl -v http://localhost:9090/regist:[name]:[email]:[phone]
例如:curl -v http://localhost:9090/regist:wyj:[email protected]:122
如果成功,會有如下顯示:
{
"RESULT": "Success! Have regist!"
}
否則即爲失敗,即您已經註冊過。
注:如哦您只想分享一部分信息,只要在不想分享的部分以empty替代即可,例如,若您不想分享你的電話,只需輸入:
curl -v http://localhost:9090/regist:wyj:[email protected]:empty
2.1.2 更新信息
介紹:當您需要在網上更新自己的信息,只需要登陸網站輸入相關信息即可。
需要指令:update
輸入格式:curl -v http://localhost:9090/update:[name]:[email]:[phone]
例如:curl -v http://localhost:9090/check:wyj:1:1curl -v http://localhost:9090/update:wyj:[email protected]:999
如果成功,會有如下顯示:
{
"RESULT": "Update Success!"
}
否則即爲失敗,即您尚未註冊。
注:如哦您只想更新一部分信息,只要在不想分享的部分以原有信息替代即可。
2.1.3 查詢信息
介紹:當您需要在網上查詢信息,只需要登陸網站輸入相關信息即可。
需要指令:check
輸入格式:curl -v http://localhost:9090/check:[name]:[0]:[0]
例如:curl -v http://localhost:9090/check:wyj:0:0
如果成功,會有如下顯示:
{
"RESULT": "Name: wyj Email: [email protected] Phone: 999"
}
否則即爲失敗,即該用戶尚未註冊,請您耐心等待!
2.2 實現原理
服務器的建立,客戶端的請求思路及代碼都非常清晰了,也沒有什麼好擴展的了。因此,我在此基礎上增加了一些參數,並在服務器端建立了本地服務器,實現了一個簡單的信息查詢系統。
C-S之間原理就不講了,老師博客已經講得很清楚了,講一下做了那些改動。
2.2.1 通過分割獲得更多的指令參數
在之前的輸入解析的部分,是這樣的:
mx.HandleFunc("/hello/{id}", testHandler(formatter)).Methods("GET")
而實際上,我們至少需要四個參數,因此,我們使用
:
分割,得到四個不同的段,如下:
mx.HandleFunc("/{command}:{name}:{email}:{phone}", testHandler(formatter)).Methods("GET")
並解析:
command := vars["command"]
name := vars["name"]
email := vars["email"]
phone := vars["phone"]
2.2.2 在本地處理所有的信息
當有了參數之後,很自然的事情就是如何根據這些參數得到信息,爲了達到
數據分離
,將數據庫處理部分(信息)與服務器端分離爲兩個文件。在服務器端,通過調用函數
Manager(command string, name string, email string, phone string) string
來傳遞參數,並獲得反饋信息。
而在數據處理模塊,共有3個功能。
實現功能的部分由於很小,因此集成在了Manager
中,(當然,後面功能多了肯定是要單獨拿出來的):
/*Manager 處理指令
regist 註冊,需要信息:名字 Email 電話
chcek 查詢,需要信息:查詢名字
update 更新數據,需要信息:名字 Email 電話
接收參數:指令 名字 email 電話
返回參數:
regist 註冊成功/失敗
check 查詢結果
update 更新成功/失敗
*/
func Manager(command string, name string, email string, phone string) string {
users := READUSERS()
switch command {
case "regist" : {
//遍歷查詢,沒有找到纔可以註冊
for _, user := range users {
if user.Name == name {
return "This name has been regist!"
}
}
newUser := User{Name: name, Email: email, Phone: phone}
users = append(users, newUser)
WRITEUSER(users)
return "Success! Have regist!"
}
case "check" : {
//遍歷查詢,找到名字就返回結果
for _, user := range users {
if user.Name == name {
return "Name: " + user.Name + " Email: " + user.Email + " Phone: " + user.Phone
}
}
return "Not regist!"
}
case "update" : {
//遍歷查詢,找到名字就更新信息
for i, user := range users {
if user.Name == name {
users[i].Email = email
users[i].Phone = phone
WRITEUSER(users)
return "Update Success!"
}
return "Wrong Name!"
}
return "Not regist!"
}
default : return " "
}
}
2.2.3 每次操作讀寫
每次處理時,先讀取所有的數據。每次操作完了,如果數據更改,則調用函數寫回文件。
實現實際上非常簡單,就是在調用Manager
時讀入,只在註冊成功
及更新信息成功
之後寫回。
文件讀寫使用的是io/ioutil
以及json
/*READUSERS 讀取用戶*/
func READUSERS() (user []User) {
_, err := os.Getwd()
checkerr(err)
b, err := ioutil.ReadFile("Database/Users.txt")
checkerr(err)
//json轉變爲對象
var users []User
json.Unmarshal(b, &users)
return users
}
/*WRITEUSER 寫回用戶*/
func WRITEUSER(users []User) {
_, err := os.Getwd()
checkerr(err)
data, err := json.Marshal(users)
checkerr(err)
b := []byte(data)
err = ioutil.WriteFile("Database/Users.txt", b, 0777)
checkerr(err)
}
3 測試
先登陸系統,在
cloudgo
文件夾下運行。
go run main.go -p9090
3.1 註冊
客戶端:
服務器端:
3.2 更新信息
客戶端:
服務器端:
3.3 查詢
此時查詢到新的信息
客戶端:
服務器端:
4 壓力測試
安裝工具並檢測。此處使用查詢指令來檢測。
yum -y install httpd-tools
ab -n 1000 -c 100 http://localhost:9090/check:wyj:0:0
結果顯示:
分析結果,完成一半的時候只用了52ms,而全部完成則用了131ms,說明中間有很長的處理時間。觀察發現,還是有很長的等待時間。