开发 web 服务程序

概述

开发简单 web 服务程序 cloudgo,了解 web 服务器工作原理。

任务目标

  • 熟悉 go 服务器工作原理
  • 基于现有 web 库,编写一个简单 web 应用类似 cloudgo。
  • 使用 curl 工具访问 web 程序
  • 对 web 执行压力测试

相关知识

可参考课件

任务要求

基本要求

  • 编程 web 服务程序 类似 Cloudgo 应用
    • 框架选择

      本次使用的web开发框架是Martini框架,Martini 是Go 语言的 Web 框架,使用 Go 的 net/http 接口开发,类似 Sinatra 或者 Flask 之类的框架,也可使用自己的 DB 层、会话管理和模板。具有如下特性:

      • 无侵入设计
      • 与其他 Go 的包配合工作
      • 模块化设计,可轻松添加工具
    • 框架搭建
      我们使用go get命令安装所需软件包:
      在这里插入图片描述

开发Cloudgo应用

在运行程序之前,可以参照官网github的使用方式,一个简单的例子如下所示:

package main

import "github.com/go-martini/martini"

func main() {
  m := martini.Classic()
  m.Get("/", func() string {
    return "Hello world!"
  })
  m.Run()
}

这样就可以在localhost:3000上运行。

程序框架

我们的代码结构如下所示:

├── main.go
├── server
│   └── server.go
├── static
│   ├── image
│   │   ├── background.jpg
│   │   ├── icon.png
│   │   └── panda.png
│   ├── jigsaw.css
│   ├── jigsaw.js
│   └── js
│       └── jquery-3.3.1.min.js
└── templates
    └── jigsaw.tmpl

其中:

  • main.go为是主程序入口
  • server/server.go使用框架建立一个服务器
  • static为加载文件使用到的静态资源,包括js和css以及用到的图片资源
  • templates内含render渲染的HTML文件

代码分析

  • main.go

main.go主要作用是创建端口,调用server.go的Run方法启动服务器
为了从用户输入获得指定的端口,我们使用了pflag包。其中,第一个参数是参数名,第二个参数简写,第三个参数参数的默认值,第四个参数此参数的解释

currentPort := pflag.StringP("port", "p", "1234", "Port for http listening")
pflag.Parse()

完整代码如下:

package main

import (
    "os"
    "./server"
    "github.com/spf13/pflag"
)

func main() {
    port := os.Getenv("PORT")
    // set default port
    if (len(port) == 0) {
        port = "1234"
    }
    // parse port 
    currentPort := pflag.StringP("port", "p", "1234", "Port for http listening")
    pflag.Parse()
    if (len(*currentPort) != 0) {
        port = *currentPort
    }
    // run server
    server.Run(port)
}
  • server.go

server.go的作用主要是调用Matrini框架启动了web服务器,这里我选择了一个之前web课程的作业代码,看能否渲染出效果:
这里还需要补充安装渲染HTML的工具:

go get github.com/unrolled/render

我们使用Get请求来渲染HTML:

m.Get("/", func(res http.ResponseWriter, req *http.Request) {
    r := render.New()
    r.HTML(res, http.StatusOK, "jigsaw", "World");
})

我们这里只用到了Get请求,没有用到Post请求,完整代码如下:

package server

import(
    "net/http"
	"github.com/go-martini/martini"
	"github.com/unrolled/render"
)

func Run(port string) {
    // default setting
    m := martini.Classic()
    // set path
    m.Use(martini.Static("static"));
    // Get request
    m.Get("/", func(res http.ResponseWriter, req *http.Request) {
        r := render.New()
        r.HTML(res, http.StatusOK, "jigsaw", "World");
    })
    // run
    m.RunOnAddr(":" + port)
}

效果展示

打开localhost:1234,我们可以看到HTML如下所示:
在这里插入图片描述
服务器的输出如下所示:
在这里插入图片描述

测试

使用 curl 工具访问 web 程序

使用curl -v命令来显示客户端与服务器交互的详细信息,其中Content显示的就是当前显示页面的HTML代码。
在这里插入图片描述

使用 ab测试

我们首选需要安装相关工具apache benchmark:

sudo yum -y install httpd-tools

ab测试的参数说明如下:

  • -n 执行的请求数量
  • -c 并发请求个数
  • -t 测试所进行的最大秒数
  • -p 包含了需要POST的数据的文件
  • -T POST数据所使用的Content-type头信息
  • -k 启用HTTP KeepAlive功能,即在一个HTTP会话中执行多个请求,默认时,不启用KeepAlive功能

  • 返回值包括:
  • Concurrency Level:并发数
  • Time taken for tests:完成所有请求总共花费的时间
  • Complete requests:成功请求的次数
  • Failed requests:失败请求的次数
  • Total transferred:总共传输的字节数
  • HTML transferred:实际页面传输的字节数
  • Requests per second:每秒请求数
  • Time per request: [ms] (mean): 平均每个用户等待的时间
  • Time per request: [ms] (mean, across all concurrent requests) :服务器处理的平均时间
  • Transfer rate:传输速率

我们使用如下命令进行测试:

ab -n 10000 -c 1000 http://localhost:1234/

其表示执行10000个请求,1000个并发,结果如下:
在这里插入图片描述
在这里插入图片描述
总共花费了9s左右的时间来进行处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值