在demo1中,我们简单使用了net/http搭建了一个server,其实在日常开发中,比较少去使用标准库去直接写api,更多的是使用前人搭建好的轮子(我呢,是个不太喜欢重复造轮子的开发者,有开源的靠谱的,直接用就好,自己调整成自己需要的即可),那么说的go的框架,不得不说gin了。
对于gin的介绍,是github上star最多的go框架了,其他不多说,我们上手写起来吧!
目标:
- 自定义配置
- 整合mysql和Redis
- 独立路由管理
- 日志
- 平滑重启
- 脚本打包
使用到的库:
- github.com/fsnotify/fsnotify
- github.com/gin-gonic/gin
- github.com/go-Redis/Redis
- github.com/jinzhu/gorm
- http://github.com/lestrrat-go/file-rotatelogs
- http://go.uber.org/zap
- github.com/spf13/pflag
- github.com/spf13/viper
初始化
modules的引入之后,我们就可以不必使用gopath去管理项目目录了,对于modules的基本使用,建议看文章:
我们开始:
go mod init sai0556/demo2-gin-frame |
因为我们暂时本地开发:
PS:当时理解有误,其实无需做local.com替换,import直接使用sai0556/demo2-gin-frame即可,这里有点多余
// 使用本地module |
可以看到go.mod已生成:
module sai0556/demo2-gin-frame |
/Users/@/Work/golang/go-example/demo2-gin-frame 此目录就是项目目录,视具体情况不一
自定义配置与读取:
在我们使用Redis和mysql之前,我们先来读取一下配置,配置呢我们使用常见的yaml,当然你也可以使用其他,比如env等。
新建config目录,用来读取与监听配置文件(config.yaml):
package config |
main:
package main |
这里有用到大牛spf13的两个包,pflag和viper,命令行参数解析包pflag可以看作flag的进阶版本,在我们这里可以用来指定配置文件,viper是读取配置文件的包,配合fsnotify可以实现配置的热更新。(spf13大神还有其他有用的包,相信在你的go编码生涯会用到的)
写完我们可以运行一下:
go run main.go -c ./config.yaml
可以看到有打印出我们配置的name。
整合mysql与Redis
mysql包我们就选用gorm,Redis的使用比较多的是redigo和go-Redis,redigo曾在我使用中出现过问题,因而我们选择后者,后者也支持连接池。
mysql:
package db |
后面获取连接池就可以直接使用 db.GetInstance()
Redis:
package db |
RedisClient就是我们后面可以用的Redis连接池。
在main中加入初始化连接池的代码即可:
// 连接mysql数据库 |
路由与控制器
为了方便路由,我们把路由管理单独到router。
package router |
controller:
package controller |
到这呢,基本也就差不多了。
我们来看下完整的main:
package main |
整合日志
这里我们先定义下log:
log: |
整合logger:
package logger |
这里注意init函数,我们直接调用logger其中函数即可,程序加载包的过程中会自动执行init函数。关于init有以下说明:
- init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等
- 每个包可以拥有多个init函数
- 包的每个源文件也可以拥有多个init函数
- 同一个包中多个init函数的执行顺序go语言没有明确的定义(说明)
- 不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序
- init函数不能被其他函数调用,而是在main函数执行之前,自动被调用
我们直接使用:
logger.Info("i'm log123-----Info") |
平滑重启
当程序在线上稳定运行后,我们可能会去更新一些功能,但发布代码的同时,假如有用户正在使用,盲目发布代码可能会造成用户短暂失真,这时候平滑重启就来了。
对于平滑重启,其实有很多方案,这里我们只从自身代码级别来完成,而即便是代码级别,目前也有多种实现方案,比如第三方库endless这种,我这里主要参考了
https://github.com/kuangchanglang/gracefulgithub.com/kuangchanglang/graceful
简单说明下处理步骤:
- 监听信号(USR2,可自定义其他信号)
- 收到信号时fork子进程(使用相同的启动命令),将服务监听的socket文件描述符传递给子进程
- 子进程监听父进程的socket,这个时候父进程和子进程都可以接收请求
- 子进程启动成功之后,父进程停止接收新的连接,等待旧连接处理完成(或超时)
- 父进程退出,重启完成
详细分析可看底部参考-Golang服务器热重启、热升级、热更新。
启动检查
结合上面的优雅重启,我们在启动时配置上启动健康检查:
package main |
这里就比较简单,另外启动一个协程,去ping健康检测的url即可。
打包脚本
shell
|
bat
echo "build..." |
对于程序的重启和保活,建议配合supervisor使用。
好,到这里我们的round 2就结束了。下一轮我们来玩玩钉钉智能机器人。
参考: