github
任务目标
- 熟悉 go 服务器工作原理
- 基于现有 web 库,编写一个简单 web 应用类似 cloudgo
- 使用 curl 工具访问 web 程序
- 对 web 执行压力测试
- 根据代码提示,按照
cloud_go
应用,编写相应的Web
程序。
-
main.go
- 按照
flag
包的应用,从命令行获取特定的端口号,默认为8080
,并获取web
服务,调用Run
对特定端口开启特定服务,相应代码如下:
const (
PORT string = "8080"
)
func main() {
port := os.Getenv("PORT")//get custom environment variables
if len(port) == 0 {
port = PORT
}
flag.StringVar(&port, "p", PORT, "PORT for httpd listening")
flag.Parse()
server := service.NewServer() // get server
server.Run(":" + port) // run the server at specific port
}
-
server.go
- 该
go
文件函数NewServer
提供main.go
创建相应的web
服务。
- 调用
render.New()
函数为相应的web
服务渲染格式,此处只简单的设置IndentJSON
格式,后分别调用negroni.Classic
和mux.NewRouter
,以默认参数创建web
服务对象和Router
路由对象。
func NewServer() *negroni.Negroni {
// New constructs a new Render instance with the supplied options.
formatter := render.New(render.Options{
IndentJSON: true,
}) // rendering a web format
n := negroni.Classic()
mx := mux.NewRouter()
initRoutes(mx, formatter)
// set the router
n.UseHandler(mx)
return n
}
- 其上的
initRoutes
函数负责设置路由配置,主要是按照不同的路由提供不同的服务,其中包含通过变量名获取参数信息如通过对http.Request
调用URL
处理获取特定信息,也如通过Methods
方法获取形如{id}
对应的变量值。其中,对路由调用HandleFunc
设置不同路由特定的函数操作,需要传入func(w http.ResponseWriter, req *http.Request)
形式的函数处理。
func initRoutes(mx *mux.Router, formatter *render.Render) {
// Methods adds a matcher for HTTP methods.
// It accepts a sequence of one or more methods to be matched, e.g.:
// "GET", "POST", "PUT".
mx.HandleFunc("/{status}/{id}", testHandler(formatter)).Methods("GET")
mx.HandleFunc("/{status}", testHandler(formatter)).Methods("GET")
//provide a hanlder func to deal with specific router
//corresponding to func(w http.ResponseWriter, req *http.Request)
}
- 根据传入的路由形式,我们可以获取处理的
localhost:9090/xxx
以及localhost:9090/xxx/yyy
形式的路由并获取对应的参数值。通过形如map[string] string
的方式输入对应的xxx
或yyy
即可获取对应的参数。此处再调用render.JSON
函数对http.ResponseWriter
处理,再其上输出文本信息,即如下即可。
func testHandler(formatter *render.Render) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
id := vars["id"]
status := vars["status"]
formatter.JSON(w, http.StatusOK, struct{ Test string }{"Hello " + status + id})
}
}
-
测试
- 在
linux
系统上调用curl -v http://www.sysu.edu.cn/
访问网址,根据输出内容可以看出
- 以
*
为首的信息为curl
程序的操作内容
- 以
>
为首的信息为发送到指定网址的内容
- 以
<
为首的信息为指定网址返回的内容
- 以上述代码运行后输入
http://localhost:9090/hello
时,对应路由信息为/{status}
,即status
对应hello,id
为空,输出内容如下:
- 输入
http://localhost:9090/hello/world
时,status
对应hello,id
为对应world,输出内容如下:
- 修改代码,去掉对路由
/{status}
的处理后再次输入http://localhost:9090/hello
,输出内容如下,可以发现报错404
,此时可以认为设置路由时需要处理不同层次的内容,上级路由与下级路由之间不能互通。
- 此时,通过
Apache
软件对服务进行压力测试,输入指令ab -n 1000 -c 100 http://localhost:9090/hello/world
,输出如下结果,其中左侧为链接网络消耗的时间等信息,右侧为测试后的结果,通过对信息的分析可以了解到连接的速度以及网址访问的相关信息。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)