Web服务孵化
web框架在Gin框架的基础上又封装了一层,包括服务进程管理、路由中间件、启动项自定义加载等
其中,服务进程的管理式型支持三种
- Golang原生http Server启动模式
- oversee Master/Slave启动模式,Master是监控Slave进程启停的管理单元,Slave提供对外服务
- gracehttp 带有信号处理的独立进程启动模式,当接收到SIGUSR2 信号量时,关闭自身服务并在退出前启动新的服务进程
配置服务进程管理模式
在这里特别说明一下,我们所有组件、框架的配置文件存放位置、格式以及用法都是一致的,可参考Gaea 的配置文件
[Server]
//...
;进程管理模式
grace=true
grace控制是否开启平滑重启,取值为:true
开启;false
关闭
- 开启
- 默认为oversee 模式,配合supervisor的信号指令可以实现服务无间断运行
- gracehttp模式,也支持平滑重启,但是无法和supervisor结合使用,所以设置成了可选项
- 关闭
- Golang原生的启动模式,只能做到安全退出,即收到服务终止信号时,可以保证正在处理的任务正常结束
使用hera孵化web服务
在任一地方创建一个main.go
文件,然后执行命令go mod tidy
.注:*在没有特殊说明的情况下,我们的依赖管理统一使用go mod
创建一个极简的web服务
//main.go
package main
import (
"github.com/tal-tech/xesGoKit/xesgin"
bs "github.com/tal-tech/xesServer/bootstrap"
"github.com/tal-tech/xesServer/ginhttp"
_ "github.com/tal-tech/xesTools/expvarutil"
"github.com/gin-gonic/gin"
"log"
"net/http"
)
func main() {
s := ginhttp.NewServer()
engine := s.GetGinEngine()
engine.GET("/index", demoFun)
s.AddServerBeforeFunc(bs.InitTraceLogger("XueYan", "0.1"))
er := s.Serve()
if er != nil {
log.Printf("Server stop err:%v", er)
} else {
log.Printf("Server exit")
}
}
func demoFun(ctx *gin.Context){
ctx.JSON(http.StatusOK, xesgin.Success("hello world!"))
}
编译&运行
$ go build main.go
$ ./main
2019/12/28 16:39:51 CONF INIT,path:../conf/conf.ini
2019/12/28 16:39:51 [expvarutil] Expvar not enabled
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /index --> main.demoFun (1 handlers)
[16:39:51 CST 2019/12/28] [INFO] (server.go:57:561420000000001 localhost.localdomain) GIN-Server http server start and serve:
访问API
ginhttp Server
的默认配置如下:
func DefaultOptions() ServerOptions {
return ServerOptions{
Addr: ":10088", //web监听端口
ReadTimeout: 5 * time.Second, //读超时时间
WriteTimeout: 5 * time.Second, //响应超时时间
IdleTimeout: 5 * time.Second, //链接空闲时间
}
}
curl 测试
$ curl http://127.0.0.1:10088/index
{"code":0,"data":"hello world!","msg":"ok","stat":1}
至此,您已经成功创建了一个web服务!
当然我们还提供了其它丰富的功能,下面我们看一个实战项目
实战应用案例
我们的web框架Gaea的核心代码就是利用Hera孵化器
生成的
服务主入口文件:
//文件位置:https://github.com/tal-tech/gaea/blob/master/main/main.go
package main
import (
"log"
"runtime/debug"
"gaea/app/router"
"gaea/version"
"github.com/tal-tech/xesGoKit/middleware"
bs "github.com/tal-tech/hera/bootstrap"
"github.com/tal-tech/hera/ginhttp"
"github.com/tal-tech/xesTools/confutil"
_ "github.com/tal-tech/xesTools/expvarutil"
"github.com/tal-tech/xesTools/flagutil"
"github.com/spf13/cast"
)
func main() {
//show version
ver := flagutil.GetVersion()
if *ver {
version.Version()
return
}
//配置文件加载和解析模块
confutil.InitConfig()
//panic恢复
defer recovery()
//通过Hera 生成一个Gin服务
s := ginhttp.NewServer()
//获取Gin引擎
engine := s.GetGinEngine()
//装载默认中间件
engine.Use(middleware.Logger(), middleware.Recovery(), middleware.XesLoggerMiddleware(), middleware.PerfMiddleware(), middleware.TraceMiddleware(), middleware.RequestHeader())
//中间件绑定到路由上
router.RegisterRouter(engine)
//服务启动前的Hooks
s.AddServerBeforeFunc(bs.InitLoggerWithConf(), bs.InitTraceLogger("XueYan", "0.1"), bs.InitPerfutil(), bs.InitPprof(), s.InitConfig())
//服务结束后的Hooks
s.AddServerAfterFunc(bs.CloseLogger())
//启动服务,没有发生错误的情况下会阻塞在这里
er := s.Serve()
if er != nil {
log.Printf("Server stop err:%v", er)
} else {
log.Printf("Server exit")
}
}
func recovery() {
if rec := recover(); rec != nil {
log.Printf("Panic Panic occur")
if err, ok := rec.(error); ok {
log.Printf("PanicRecover Unhandled error: %v\n stack:%v", err.Error(), cast.ToString(debug.Stack()))
} else {
log.Printf("PanicRecover Panic: %v\n stack:%v", rec, cast.ToString(debug.Stack()))
}
}
}