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.gopackage mainimport ("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$ ./main2019/12/28 16:39:51 CONF INIT,path:../conf/conf.ini2019/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.gopackage mainimport ("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 versionver := 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)//服务启动前的Hookss.AddServerBeforeFunc(bs.InitLoggerWithConf(), bs.InitTraceLogger("XueYan", "0.1"), bs.InitPerfutil(), bs.InitPprof(), s.InitConfig())//服务结束后的Hookss.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()))}}}
