# cloudgo
**Repository Path**: bmchris0200/cloudgo
## Basic Information
- **Project Name**: cloudgo
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-11-23
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 开发web服务程序
## 概述
开发简单 web 服务程序 cloudgo,了解 web 服务器工作原理。
### 任务目标
1. 熟悉 go 服务器工作原理
2. 基于现有 web 库,编写一个简单 web 应用类似 cloudgo。
3. 使用 curl 工具访问 web 程序
4. 对 web 执行压力测试
## 安装框架
根据潘老师的课件,我们需要安装mux、negroni和unrolled/render包,输入以下命令行:
`go get github.com/gorilla/mux`
`go get github.com/urfave/negroni`
`go get github.com/unrolled/render`
## 编程 web 服务程序 类似 cloudgo 应用
### 准备工作
在github.com文件夹中创建service文件夹,创建service.go和handlers.go文件,具体代码见项目文件。
在另一个文件目录下创建cloudgo文件夹,文件目录结构如下:
cloudgo
|-assets
|-css
|-index.css
|-images
|-dog.png
|-js
|-index.js
|-templates
|-index.html
|-signin.html
+main.go
具体代码见项目文件。
在该文件目录下运行命令行 go run main.go,然后进入浏览器,打开localhost:4396。
### 支持静态文件服务
service.go文件中的initRoutes函数包含以下语句:
```go
mx.PathPrefix("/static").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(webRoot+"/assets/"))))
```
将 path 以 “/” 前缀的 URL 都定位到 `webRoot + "/assets/"` 为虚拟根目录的文件系统。
然后可以静态访问静态文件夹中的文件夹和文件:
访问css文件夹:

访问index.css

访问images文件夹:

访问dog.png:

访问js文件夹:

访问index.js:

### 支持简单的js访问
我设计的js访问是返回我的学号和一个简单的字符串。
service.go中设置/api/test调用apiTestHandler。
```go
mx.HandleFunc("/api/test", apiTestHandler(formatter)).Methods("GET")
```
apiTestHandler的实现:
```go
func apiTestHandler(formatter *render.Render) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
formatter.JSON(w, http.StatusOK, struct {
ID int
Content string
}{ID: 18342063,Content:" hello!!!"})
}
}
```
js文件的格式:
```go
$(document).ready(function() {
$.ajax({
url: "/api/test"
}).then(function(data) {
$('.greeting-id').append(data.ID);
$('.greeting-content').append(data.Content);
});
});
```
运行结果:


### 提交表单,并输出一个表格(必须使用模板)
index.html设计好了提交表单的页面,并且最后要输入两个数字,点击Signin!按钮后,会显示表格,显示了输入的信息,以及两个数的和。其中设计了将输入的数据传到sign界面的操作,代码实现如下:
```go
func homeHandler(formatter *render.Render) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
template := template.Must(template.New("index.html").ParseFiles("./templates/index.html"))
_ = template.Execute(w, struct {
ID string
Content string
}{ID: "18342063", Content: "Bonjour!"})
}
}
func checkform(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
username := template.HTMLEscapeString(r.Form.Get("username"))
password := template.HTMLEscapeString(r.Form.Get("password"))
num1 := template.HTMLEscapeString(r.Form.Get("num1"))
num2 := template.HTMLEscapeString(r.Form.Get("num2"))
n1,_ := strconv.Atoi(num1)
n2,_ := strconv.Atoi(num2)
sum := strconv.Itoa(n1+n2)
t := template.Must(template.New("signin.html").ParseFiles("./templates/signin.html"))
err := t.Execute(w, struct {
Username string
Password string
Num1 string
Num2 string
Sum string
}{Username: username, Password: password, Num1: num1,Num2:num2, Sum:sum})
if err != nil {
panic(err)
}
}
```
index界面


signin界面

## 使用curl测试
首先要安装curl:
`sudo install curl`
然后再另开一个cmd,输入以下命令进行测试:
`curl -v http://localhost:4396`


`curl -v http://localhost:4396/api/test`

`curl -v -d "username=lzb&password=123&num1=99&num2=51" "localhost:4396/signin"


## 使用ab测试
下载ab工具
`sudo install apache2-utils`
输入以下命令进行测试:
`ab -n 10000 localhost:4096/`



### 重要参数
命令参数:
|参数 |解析 |
| -------- | ----------- |
| -n | 请求执行的数量 |
| -c | 并发请求的个数 |
| -t | 等待响应的最大时间(单位:秒)。|
| -s | TCP发送/接收的缓冲大小(单位:字节)|
| -p | 包含了需要 POST 的数据的文件 |
| -u | 包含了需要 PUT 的数据的文件|
| -T | content-type,POST/PUT 的数据的 Content-type 头信息 |
| -v | 指定打印帮助信息的冗余级别 |
| -w | 以HTML表格形式打印结果|
| -i | 使用HEAD请求代替GET请求。 |
| -x | 插入字符串作为table标签的属性。|
| -y | 插入字符串作为tr标签的属性。|
| -z | 插入字符串作为td标签的属性。|
| -C | 添加cookie信息 |
结果参数:
| 参数 | 解析 |
| -------------------- | -------------------------- |
| Server Software | 平台 |
| Server Hostname | 服务器域名 |
| Server Port | 服务器端 |
| Concurrency Level | 此次测试的一轮请求的并发数 |
| Time taken for tests | 测试的时长 |
| Complete request | 成功请求的次数 |
| Failed requests | 失败的请求数量 |
| Total transferred | 整个场景中的网络传输量 |
| HTML transferred | 整个场景中的HTML内容传输量 |
| Request per second | 每秒完成的请求数 |
| Time per request | 每次请求所用的时间 |
| Transfer rate | 平均每秒网络上的流量 |
## 拓展部分
见[对应的项目文件](https://gitee.com/bmchris0200/cloudgo/blob/master/%E4%BB%A3%E7%A0%81%E5%88%86%E6%9E%90.md)