1、概述
开发简单 web 服务程序 cloudgo,了解 web 服务器工作原理。
2、任务目标
· 熟悉 go 服务器工作原理
· 基于现有 web 库,编写一个简单 web 应用类似 cloudgo。
· 使用 curl 工具访问 web 程序
· 对 web 执行压力测试
3、任务要求
(1) 编程 web 服务程序 类似 cloudgo 应用。
· 要求有详细的注释
·是否使用框架、选哪个框架自己决定。请说明你决策的依据
(2) 使用 curl 测试,展示测试结果
(3) 使用 ab 测试,将测试结果写入 README.md。并解释重要参数。
4、具体实现
实验中,我决定选择使用martini框架。Martini框架是使用Go语言作为开发语言的一个强力的快速构建模块化web应用与服务的开发框架,专门用来处理Web相关内容的框架。它的核心是injector,代码非常简洁,功能仅仅是通过反射包, 对函数进行参数类型自动匹配进行调用,非常适合用于开发web服务程序。
首先,我们需要从github上下载martini(github.com/go-martini/martini)。下载好zip后,解压到go语言的workspace的src目录下:
接下来,编写一个service包,使用martini框架新建一个服务器:
package service
import (
"github.com/martini-master" //使用martini
)
//新建服务器
func NewServer(port string) {
m := martini.Classic()
//添加参数[name]martini的参数中
m.Get("/hello/:name", func(params martini.Params) string {
return "Hello " + params["name"] + "!"
})
//对应mian函数中的端口
m.RunOnAddr(":"+port)
}
service包的作用是将web服务返回给用户。代码实现了提取用户输入的参数,并将之打印的功能,具体见后文的实验结果。
完成service.go的编写后,在其目录下go install,应该可以在pkg目录下找到service.a文件。
接下来是main.go,主要实现监听网络请求,以及端口的设置。这里将默认端口设为8080:
package main
import (
"os"
"service"
flag "github.com/spf13/pflag"
)
const (
PORT string = "8080" //默认的端口为8080
)
func main() {
port := os.Getenv("PORT") //如果没有监听到端口,那么端口为8080
if len(port) == 0 {
port = PORT
}
//设置端口
pPort := flag.StringP("port", "p", PORT, "PORT for httpd listening")
flag.Parse()
if len(*pPort) != 0 {
port = *pPort
}
service.NewServer(port)//启动服务器
}
注意service的目录,应该对应到main.go中正确的import路径。
这时候,尝试运行main.go,发现报错缺少codegangsta包,我们仍然从github上下载zip,并解压到workspace的github.com目录下就ok了。
【测试】
在main.go目录下,输入指令:
go run main.go -p8080
开始监听网络请求:
在浏览器的地址栏,输入
https://localhost:8080/hello/xxx,则我们可以看到一个输出了"Hello xxx!"的网页:
下面用curl进行测试。curl命令是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯称curl为下载工具。作为一款强力工具,curl支持包括HTTP、HTTPS、ftp等众多协议。
在另一个命令行中输入如下指令:
curl -v http://localhost:8080/hello/world
可以看到,成功连接到服务器,显示了端口、协议、时间、内容(Hello jun!)等信息,说明通过curl测试。
接下来使用ab指令进行压力测试。ab是apachebench命令的缩写。
ab是apache自带的压力测试工具。ab非常实用,它不仅可以对apache服务器进行网站访问压力测试,也可以对或其它类型的服务器进行压力测试。
ab的安装:
yum -y install httpd-tools
输入如下指令进行测试:
ab -c 10 -n 100 http://localhost:8080/hello/jun
说明:-c10表示并发用户数为10,-n100表示请求总数为100
可以看到,在并发数为10的情况下,发送100个请求,总共用时0.048s,共传输12700字节。
对关键字段进行解释:
Server Software: #测试服务器的名字
Server Hostname: #请求的URL主机名
Server Port: #web服务器监听的端口
Document Path: #请求的URL中的根绝对路径,通过该文件的后缀名,我们一般可以了解该请求的类型
Document Length: #HTTP响应数据的正文长度
Concurrency Level: #并发用户数
Time taken for tests: #所有这些请求被处理完成所花费的总时间 单位秒
Complete requests: #总请求数量
Failed requests: # 表示失败的请求数量,指请求在连接服务器、发送数据等环节发生异常,以及无响应后超时的情况
Total transferred: #所有请求的响应数据长度总和。包括每个HTTP响应数据的头信息和正文数据的长度
HTML transferred: # 所有请求的响应数据中正文数据的总和,也就是减去了Total transferred中HTTP响应数据中的头信息的长度
Requests per second: #吞吐率,计算公式:总请求数/处理完成这些请求数所花费的时间
Time per request: #用户平均请求等待时间,计算公式:处理完成所有请求数所花费的时间/(总请求数/并发用户数)
Time per request: #服务器平均请求等待时间,计算公式:吞吐率的倒数。
Transfer rate: #表示这些请求在单位时间内从服务器获取的数据长度,说明服务器的处理能力达到极限时,其出口宽带的需求量。
最后,放上github项目地址。感谢您的阅读!