# 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文件夹: ![](./img/1.png) 访问index.css ![](./img/2.png) 访问images文件夹: ![](./img/3.png) 访问dog.png: ![](./img/4.png) 访问js文件夹: ![](./img/5.png) 访问index.js: ![](./img/6.png) ### 支持简单的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); }); }); ``` 运行结果: ![](./img/7.png) ![](./img/19.png) ### 提交表单,并输出一个表格(必须使用模板) 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界面 ![](./img/8.png) ![](./img/9.png) signin界面 ![](./img/10.png) ## 使用curl测试 首先要安装curl: `sudo install curl` 然后再另开一个cmd,输入以下命令进行测试: `curl -v http://localhost:4396` ![](./img/11.png) ![](./img/12.png) `curl -v http://localhost:4396/api/test` ![](./img/13.png) `curl -v -d "username=lzb&password=123&num1=99&num2=51" "localhost:4396/signin" ![](./img/14.png) ![](./img/15.png) ## 使用ab测试 下载ab工具 `sudo install apache2-utils` 输入以下命令进行测试: `ab -n 10000 localhost:4096/` ![](./img/16.png) ![](./img/17.png) ![](./img/18.png) ### 重要参数 命令参数: |参数 |解析 | | -------- | ----------- | | -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)