1、我的實驗代碼
package main
import (
"errors"
"fmt"
"io"
"log"
"net/http"
"os"
"runtime"
"time"
"github.com/gin-gonic/gin"
)
type myStruct struct { 伊頓
Name string
Age string
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
// 引擎設置
router := gin.Default()
gin.SetMode(gin.DebugMode)
gin.DisableConsoleColor()
// 寫文件
f, _ := os.Create(time.Now().Format("2006_01_02") + ".log")
defer f.Close()
gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
// 中間件
router.Use(gin.LoggerWithWriter(f, ""))
router.Use(func(c *gin.Context) {
log.Println(">>>>>>>> 進入 >>>>>>>>") // 請求
c.Next() // next handler func
log.Println(">>>>>>>> 退出 >>>>>>>>") // 響應
})
// 調試
if gin.IsDebugging() {
fmt.Fprintln(gin.DefaultWriter, ">>>>>>>> the framework is running in debug mode")
}
// 路由分組
v1 := router.Group("/v1")
v1.Use(func(c *gin.Context) {
fmt.Printf(">>>>>>>> FullPath = %s\n", c.FullPath())
fmt.Println(">>>>>>>> v1 group middleware ") // 添加中間件到組
if c.FullPath() == "/v1/" {
c.Abort() // 阻斷調用鏈
}
})
{
v1.GET("/", XiaoKouTian, HelloWorld) // 調用鏈測試
v1.GET("/user/:name/*action", Pong)
v1.GET("/welcome", Welcome)
v1.POST("/json", JSON)
v1.POST("/formpost", Post)
v1.POST("/getpost", GetPost)
v1.POST("/map", Map)
v1.POST("/upload", Upload)
v1.POST("/multiupload", MultiUpload)
}
s := &http.Server{
Addr: ":8000",
Handler: router,
ReadTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
MaxHeaderBytes: 1 << 20,
}
if err := s.ListenAndServe(); err != nil {
log.Fatalln(err)
}
}
// Upload 上傳文件
// curl -X POST http://127.0.0.1:8000/v1/multiupload -F "upload[]=@./ping.txt" -F "upload[]=@./pong.txt" -H "Content-Type: multipart/form-data"
func Upload(c *gin.Context) {
file, _ := c.FormFile("file")
log.Println(file.Filename)
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
}
// MultiUpload 上傳多個文件
// curl -X POST http://127.0.0.1:8000/v1/upload -F "upload[]=@/Users/appleboy/ping.txt" -F "upload[]=@/Users/appleboy/pong.txt" -H "Content-Type: multipart/form-data"
func MultiUpload(c *gin.Context) {
form, _ := c.MultipartForm()
files := form.File["upload[]"]
for _, file := range files {
log.Println(file.Filename)
// Upload the file to specific dst.
// c.SaveUploadedFile(file, dst)
}
c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
}
// Map map作爲get和post參數
// curl -XPOST http://127.0.0.1:8000/v1/map?ids[a]=1234\&ids[b]=hello -d "names[first]=thinkerou\&names[second]=tianou"
func Map(c *gin.Context) {
ids := c.QueryMap("ids")
names := c.PostFormMap("names")
fmt.Printf("\nids: %v; names: %v\n\n", ids, names)
c.JSON(http.StatusOK, gin.H{
"a": ids["a"],
"b": ids["b"],
})
}
// XiaoKouTian 設置元數據
func XiaoKouTian(c *gin.Context) {
c.Set("user", "wuxian") // 元數據管理
c.Set("passwd", "123")
now := time.Now().Format("2006-01-02 15:04:05")
fmt.Fprintln(gin.DefaultWriter, ">>>>>>>> 我是小口天呀!"+now)
}
// HelloWorld 讀元數據 + 寫日誌
// curl -XGET http://127.0.0.1:8000/v1/
func HelloWorld(c *gin.Context) {
fmt.Println(" >>>>>>>> helloworld!>>>>>>>>>>")
value1, ok1 := c.Get("user") // 元數據管理
if ok1 {
fmt.Fprintf(gin.DefaultWriter, ">>>>>>>> 賬號 = %s\n", value1)
}
value2, ok2 := c.Get("passwd")
if ok2 {
fmt.Fprintf(gin.DefaultWriter, ">>>>>>>> 密碼 = %s\n", value2)
}
now := time.Now().Format("2006-01-02 15:04:05")
fmt.Fprintln(gin.DefaultWriter, ">>>>>>>> 我正在調試,勿擾! "+now)
fmt.Fprintln(gin.DefaultWriter, ">>>>>>>> "+c.ClientIP())
fmt.Fprintln(gin.DefaultWriter, ">>>>>>>> "+gin.Mode())
fmt.Fprintln(gin.DefaultWriter, ">>>>>>>> "+gin.EnvGinMode)
fmt.Fprintln(gin.DefaultWriter, ">>>>>>>> "+gin.Version)
c.String(http.StatusOK, "Hello World")
}
// Pong 路由參數
// curl -XGET http://127.0.0.1:8000/v1/user/wuxian/me
func Pong(c *gin.Context) {
name := c.Param("name")
action := c.Param("action")
message := name + " is " + action
c.String(http.StatusOK, "%s", message)
}
// Welcome 請求參數
// curl -XGET http://127.0.0.1:8000/v1/welcome?firstname=wu\&lastname=xian
func Welcome(c *gin.Context) {
fmt.Fprintf(gin.DefaultWriter, ">>>>>>>> %s\n", c.FullPath())
firstname := c.Query("firstname")
lastname := c.Query("lastname")
c.String(http.StatusOK, "%s %s", firstname, lastname)
}
// JSON 響應json
// curl -XPOST http://127.0.0.1:8000/v1/json -H "Content-Type:application/json" -d '{"name":"wuxian", "age":"111"}'
func JSON(c *gin.Context) {
var buf myStruct
if err := c.BindJSON(&buf); err != nil {
c.AbortWithError(300, errors.New("json格式不對"))
}
c.JSON(http.StatusOK, myStruct{
Name: "wuxian",
Age: "18",
})
}
// Post POST方法
// curl -XPOST http://127.0.0.1:8000/v1/formpost -d "name=wuxian&age=20"
func Post(c *gin.Context) {
name := c.PostForm("name")
age := c.PostForm("age")
c.JSON(http.StatusOK, gin.H{
"name": name,
"age": age,
})
}
// GetPost URL參數 + body
// curl -XPOST http://127.0.0.1:8000/v1/getpost?name=wuxian\&age=20 -d "sex=male"
func GetPost(c *gin.Context) {
name := c.Query("name")
age := c.Query("age")
sex := c.PostForm("sex")
c.JSON(http.StatusOK, gin.H{
"name": name,
"age": age,
"sex": sex,
})
}
2、wrt壓力測試
// GET
wrk -t12 -c100 -d30s --latency http://192.168.100.35:8000/v1/
// POST
wrk -t4 -c2000 -d60s --script=post.lua --latency http://192.168.100.35:8000/v1/formpost
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
wrk.body = "name=wuxian&age=20"
3、ab壓力測試 webbench
ab -c 10 -n 100 http://esc.engma.net/#/?_k=3dpswa
4、http_load壓力測試
./http_load -p 1021 -s 10 ./urls
3、webbench壓力測試
3、技術資料參考