go语言学习-开发 web 服务程序

开发 web 服务程序 - Calculator

前言

主要工作:

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

完整代码:Github

前期工作

框架选择

虽然我这个web程序只是一个很简单的应用,但为了了解框架的使用,我选择了Martini进行web开发。

Martini具有以下功能:

  • 使用极其简单.
  • 无侵入式的设计.
  • 很好的与其他的Go语言包协同使用.
  • 超赞的路径匹配和路由.
  • 模块化的设计 - 容易插入功能件,也容易将其拔出来.
  • 已有很多的中间件可以直接使用.
  • 框架内已拥有很好的开箱即用的功能支持.
  • 完全兼容http.HandlerFunc接口.
框架使用方法阅读

在进行实验之前,当然需要了解Martini如何使用。阅读Martini

给出的例子如下,这样运行之后就会在localhost:3000上运行一个web程序。

package main

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

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

看上面代码,可以知道m.Run()是默认运行在3000端口,如果想要自定义端口则使用m.RunOnAddr(":8080")则可以该为8080,使用例子m.RunOnAddr(":" + port),记得port前一定要加:,否则会出错。

除了m.Get之外还有其他路由:

m.Get("/", func() {
  // 显示
})

m.Patch("/", func() {
  // 更新
})

m.Post("/", func() {
  // 创建
})

m.Put("/", func() {
  // 替换
})

m.Delete("/", func() {
  // 删除
})

m.Options("/", func() {
  // http 选项
})

m.NotFound(func() {
  // 处理 404
})

暂时可以用到的不多,所以就先开始实操吧!

程序架构以及关键代码

程序架构说明在这里插入图片描述
  • main.go为主程序入口
  • service/server.go使用框架建立一个服务器
  • static为加载文件使用到的静态资源
  • templates内含render渲染的HTML文件
关键代码分析

main.go
这个是参照课堂上的代码编写的,主要是设置了端口(或者获取命令行参数输入的端口)并调用server.go的函数启动服务器。

package main

import (
	"os"

	"github.com/github-user/cloudgo/service"
	flag "github.com/spf13/pflag"
)

const (
	PORT string = "8080"
)

func main() {
	//获取自定义的环境变量PORT作为端口值
	port := os.Getenv("PORT")

	//设置默认端口值
	if len(port) == 0 {
		port = PORT
	}

	//获取命令行参数-p作为端口值
	pPort := flag.StringP("port", "p", PORT, "PORT for httpd listening")
	flag.Parse()
	if len(*pPort) != 0 {
		port = *pPort
	}

	//运行服务器
	service.Run(port)
}

server.go
代码很短很简单,就是使用了Martini框架启动了一个web服务器。同时这里我渲染了一个HTML文件,这个文件是之前Web2.0课程上写过的一个计算器,这次作业就直接返回一个HTML即可。以前也写过一些注册登陆的功能的web,这次就不搞那么麻烦了,所以没有post路由,就一个get路由即完成。

package service

import (
	"net/http"

	"github.com/go-martini/martini"
	"github.com/unrolled/render"
)

//Run 运行服务器
func Run(port string) {
	m := martini.Classic()
	
	//加载j静态资源
	m.Use(martini.Static("static"))
	
	m.Get("/", func(res http.ResponseWriter, req *http.Request) {
		r := render.New()
		//渲染HTML文件
		r.HTML(res, http.StatusOK, "index", "World")
	})
	m.RunOnAddr(":" + port)
}

index.tepl
就是一个html文件,因为render渲染需要以这样的规则编写文件。同时还有用到的CSS与JS文件放置在静态资源文件目录下。

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Calculator</title>
        <meta http-equiv="Content-Type" content="text/html;
            charset=utf-8" />
        <link href="style.css" type="text/css" rel="stylesheet" />
        <script src="script.js" ></script>
        <link rel="icon" href="image/calculator.png">
    </head>
    <body>
        
        <div id = "whole">
            <h1>Calculator</h1>
            <div id = "window">
                <span id="result">0</span>
            </div>
            <div>
                <ul>
                    <li id = "left" class = "dark" onclick = "calculate('(');">(</li>
                    <li id = "right" class = "dark" onclick = "calculate(')');">)</li>  
                    <li id = "delete" class = "dark" onclick="calculate('d')">←</li>
                    <li id = "div" class = "dark" onclick="calculate('/');">/</li>
                    <li id = "sev" class = "num" onclick="calculate('7')">7</li>
                    <li id = "eig" class = "num" onclick="calculate('8')">8</li>
                    <li id = "nin" class = "num" onclick="calculate('9')">9</li>
                    <li id = "mul" class = "dark" onclick="calculate('*')">*</li>
                    <li id = "for" class = "num" onclick="calculate('4')">4</li>
                    <li id = "fiv" class = "num" onclick="calculate('5')">5</li>
                    <li id = "sex" class = "num" onclick="calculate('6')">6</li>
                    <li id= "sub" class = "dark" onclick="calculate('-')">-</li>
                    <li id = "one" class = "num" onclick="calculate('1')">1</li>
                    <li id = "two" class = "num" onclick="calculate('2')">2</li>
                    <li id = "thr" class = "num" onclick="calculate('3')">3</li>
                    <li id = "add" class = "dark" onclick="calculate('+')">+</li>
                    <li id = "clear" class = "dark" onclick = "calculate('c');">CE</li>
                    <li id = "zero" class = "num" onclick="calculate('0')">0</li>
                    <li id = "point" class = "dark" onclick="calculate('.')">.</li>
                    <li id = "equal" class = "dark" onclick="calculate('=')">=</li>
                </ul>
            </div>
        </div>
    </body>
</html>

结果展示

  1. 运行程序
    在这里插入图片描述
  2. 访问localhost:9000
    出现了我实现的一个计算器,功能完善哦!
    在这里插入图片描述
    服务器这样输出:
    在这里插入图片描述
  3. curl 工具访问 web 程序
    在这里插入图片描述
    完整输出:
* About to connect() to localhost port 9000 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 9000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:9000
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Date: Sun, 10 Nov 2019 05:09:14 GMT
< Transfer-Encoding: chunked
< 
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Calculator</title>
        <meta http-equiv="Content-Type" content="text/html;
            charset=utf-8" />
        <link href="style.css" type="text/css" rel="stylesheet" />
        <script src="script.js" ></script>
        <link rel="icon" href="image/calculator.png">
    </head>
    <body>
        
        <div id = "whole">
            <h1>Calculator</h1>
            <div id = "window">
                <span id="result">0</span>
            </div>
            <div>
                <ul>
                    <li id = "left" class = "dark" onclick = "calculate('(');">(</li>
                    <li id = "right" class = "dark" onclick = "calculate(')');">)</li>  
                    <li id = "delete" class = "dark" onclick="calculate('d')">←</li>
                    <li id = "div" class = "dark" onclick="calculate('/');">/</li>
                    <li id = "sev" class = "num" onclick="calculate('7')">7</li>
                    <li id = "eig" class = "num" onclick="calculate('8')">8</li>
                    <li id = "nin" class = "num" onclick="calculate('9')">9</li>
                    <li id = "mul" class = "dark" onclick="calculate('*')">*</li>
                    <li id = "for" class = "num" onclick="calculate('4')">4</li>
                    <li id = "fiv" class = "num" onclick="calculate('5')">5</li>
                    <li id = "sex" class = "num" onclick="calculate('6')">6</li>
                    <li id= "sub" class = "dark" onclick="calculate('-')">-</li>
                    <li id = "one" class = "num" onclick="calculate('1')">1</li>
                    <li id = "two" class = "num" onclick="calculate('2')">2</li>
  1. ab进行压力测试
    在这里插入图片描述
    完整输出:
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        
Server Hostname:        localhost
Server Port:            9000

Document Path:          /
Document Length:        2288 bytes

Concurrency Level:      100
Time taken for tests:   0.435 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      2384000 bytes
HTML transferred:       2288000 bytes
Requests per second:    2300.26 [#/sec] (mean)
Time per request:       43.473 [ms] (mean)
Time per request:       0.435 [ms] (mean, across all concurrent requests)
Transfer rate:          5355.29 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2   1.5      2       7
Processing:     6   39  15.8     39     100
Waiting:        1   30  15.6     28      98
Total:          6   42  15.6     41     100

Percentage of the requests served within a certain time (ms)
  50%     41
  66%     48
  75%     51
  80%     54
  90%     66
  95%     71
  98%     76
  99%     79
 100%    100 (longest request)

未来工作

这次只是大概的了解一下如何使用框架进行web开发,未来就可以实现一些逻辑更加复杂的web程序,如加上一些登陆注册等功能。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值