使用gin框架構建一個簡單的微服務


一個功能齊全的微服務可能需要下面幾個功能:

  • 讀取命令行參數

  • 讀取配置文件

  • 路由

  • 優雅退出

  • 操作數據庫

這里實現一個微服務的雛形,實現上面除了操作數據庫以外的四個功能,方便以后參考。

想要運行該源碼,只需要准備一個配置文件/tmp/config.yaml:

log_path: /tmp/logstash.log.%Y%m%d%H%M # 定義日志文件名稱格式

然后執行命令:

go run main.go --config=/tmp/config.yaml

其中使用到的工具庫包括:

"github.com/gin-gonic/gin" 路由功能
"github.com/fvbock/endless" 優雅退出
"github.com/spf13/viper" 讀取配置文件
rotatelogs "github.com/lestrrat-go/file-rotatelogs" 日志定時清除
"flag" 讀取命令行參數

源碼:

package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"time"

	"github.com/fvbock/endless"
	"github.com/gin-gonic/gin"
	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"github.com/spf13/viper"
)

func main() {
	StartServer()
}

func StartServer() {
	// 程序啟動命令:go run main.go --config=/tmp/config.yaml (文件內容:log_path: /tmp/logstash.log.%Y%m%d%H%M)

	// 從啟動命令讀取配置文件路徑:config(string類型)
	var configFile = flag.String("config", "", "set config file path by: -config=/path/to/log_file")
	flag.Parse()
	if *configFile == "" {
		panic("please set config file path by: -config=/path/to/log_file")
	}
	fmt.Printf("log file path: %s\n", *configFile)

	// 使用viper讀取配置文件
	config := viper.New()
	config.SetConfigFile(*configFile)
	err := config.ReadInConfig()
	if err != nil {
		panic(fmt.Sprintf("failed to read configuration file: %s", *configFile))
	}

	// 日志文件:logstash.log.202105251600;每1小時產生一個日志文件;日志文件24小時以后自動清理
	log_path := config.GetString("log_path")
	logFile, err := rotatelogs.New(log_path,
		rotatelogs.WithRotationTime(time.Duration(1)*time.Hour),
		rotatelogs.WithMaxAge(time.Duration(24)*time.Hour))
	if err != nil {
		log.Fatalln("fail to create log file!")
	}
	log := log.New(logFile, "", log.Ldate|log.Ltime|log.Lshortfile)

	// gin.SetMode(gin.ReleaseMode)
	// gin 的日志輸出到日志文件以及控制台
	gin.DefaultWriter = io.MultiWriter(logFile, os.Stdout)
	router := gin.Default()

	v1 := router.Group("/api/v1", func(c *gin.Context) {
		log.Println("group v1...")
	})
	{
		v1.GET("/configs/list", func(c *gin.Context) {
			log.Println("v1 configs/list, wait 10 seconds...")
			time.Sleep(10 * time.Second)
			c.JSON(http.StatusOK, "action: list")
			log.Println("v1 configs/list finished")
		})
		v1.GET("/configs/add", func(c *gin.Context) {
			log.Println("v1 configs/add wait 5 seconds")
			time.Sleep(5 * time.Second)
			c.JSON(http.StatusOK, "action: add")
			log.Println("v1 configs/add finished")
		})
	}
	// SIGHUP will trigger a fork/restart
	// syscall.SIGINT and syscall.SIGTERM will trigger a shutdown of the server (it will finish running requests)
	endless.ListenAndServe(":8080", router)
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM