一个功能齐全的微服务可能需要下面几个功能:
读取命令行参数
读取配置文件
路由
优雅退出
操作数据库
这里实现一个微服务的雏形,实现上面除了操作数据库以外的四个功能,方便以后参考。
想要运行该源码,只需要准备一个配置文件/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)
}
原文:https://www.cnblogs.com/lizcww/p/14810060.html