服务加载的主方法
签名方法
MustNewServer(c RestConf, opts ...RunOption) *Server
使用
server := rest.MustNewServer(c.RestConf)
First 先看一下对应的rest配置及opt选项吧
大概看一下 心里有数即可
RestConf struct {
service.ServiceConf
Host string `json:",default=0.0.0.0"`
Port int
CertFile string `json:",optional"`
KeyFile string `json:",optional"`
Verbose bool `json:",optional"`
MaxConns int `json:",default=10000"`
MaxBytes int64 `json:",default=1048576"`
// milliseconds
Timeout int64 `json:",default=3000"`
CpuThreshold int64 `json:",default=900,range=[0:1000]"`
Signature SignatureConf `json:",optional"`
// There are default values for all the items in Middlewares.
Middlewares MiddlewaresConf
// TraceIgnorePaths is paths blacklist for trace middleware.
TraceIgnorePaths []string `json:",optional"`
}
type (
// RunOption defines the method to customize a Server.
RunOption func(*Server)
// StartOption defines the method to customize http server.
StartOption = internal.StartOption
// A Server is a http server.
Server struct {
ngin *engine
router httpx.Router
}
)
// 这个比较重要
type engine struct {
conf RestConf
routes []featuredRoutes
// timeout is the max timeout of all routes
timeout time.Duration
unauthorizedCallback handler.UnauthorizedCallback
unsignedCallback handler.UnsignedCallback
chain chain.Chain
middlewares []Middleware
shedder load.Shedder
priorityShedder load.Shedder
tlsConfig *tls.Config
}
type Router interface {
http.Handler
Handle(method, path string, handler http.Handler) error
SetNotFoundHandler(handler http.Handler)
SetNotAllowedHandler(handler http.Handler)
}
// RouteOption defines the method to customize a featured route.
RouteOption func(r *featuredRoutes)
jwtSetting struct {
enabled bool //是否开启jwt验证
secret string
prevSecret string
}
signatureSetting struct {
SignatureConf
enabled bool
}
featuredRoutes struct {
timeout time.Duration
priority bool
jwt jwtSetting
signature signatureSetting
routes []Route
maxBytes int64
}
// A Route is a http route.
// 这个就是我们根据api文件中生成的handle中的路由结构了
Route struct {
Method string
Path string
Handler http.HandlerFunc
}
开始探索服务的加载流程
(1)、初始服务的开启
c.SetUp()
这个里面主要是将基础服务比如
- 日志服务、
- prometheus服务,如果配置了host的话
- 链路追踪
- 服务shutdown监听
- 日志远程上报服务
- 内嵌开启一个http服务(以下都是默认开启的)
- 健康检查
- prometheus监听
- metrics上报
- pprof
(2)、初始化server
server := &Server{
// 会设置一个cpu阈值,默认900,范围1-1000
ngin: newEngine(c),
// 我理解的是搜索树,k是请求路由 v是对应的方法
// &patRouter{trees: make(map[string]*search.Tree),}
router: router.NewRouter(),
}
// 默认添加一个处理404的handler
opts = append([]RunOption{WithNotFoundHandler(nil)}, opts...)
opt选项常用的有
WithTimeout(超时设置)
WithPrefix(设置路由前缀)
WithJwt(jwt设置)
WithMiddlewares()
路由注册
handler.RegisterHandlers(server, ctx)
func (s *Server) AddRoutes(rs []Route, opts ...RouteOption) {
r := featuredRoutes{
routes: rs,
}
// 将我们定义的,jwt 前缀等加载进去
for _, opt := range opts {
opt(&r)
}
将我们定义的路由添加进engin的路由中,
engin 路由对应的类型为[]featuredRoutes
s.ngin.addRoutes(r)
}
中间件opt选项的处理和jwt等有一点不同
// 套了一层
rest.WithMiddlewares(
[]rest.Middleware{serverCtx.RefreshToken},
[]rest.Route{
{
Method: http.MethodPost,
Path: "/user/detail",
Handler: user.GetuserdetailHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/user/update",
Handler: user.UpdateuserinfoHandler(serverCtx),
},
}...,
),
中间件的处理方式
func WithMiddlewares(ms []Middleware, rs ...Route) []Route {
for i := len(ms) - 1; i >= 0; i-- {
rs = WithMiddleware(ms[i], rs...)
}
return rs
}
// WithMiddleware adds given middleware to given route.
func WithMiddleware(middleware Middleware, rs ...Route) []Route {
routes := make([]Route, len(rs))
for i := range rs {
route := rs[i]
routes[i] = Route{
Method: route.Method,
Path: route.Path,
//主要看这里 重点
Handler: middleware(route.Handler)
RefreshToken: middleware.NewRefreshTokenMiddleware(c).Handle
Handler: middleware(route.Handler),
}
}
return routes
}
// go_zero中 中间件方法定义是 func(next http.HandlerFunc) http.HandlerFunc
// 中间件的本质是func(http.Handler) http.Handler
//形象点说明就是在处理路由本身的handlefunc之前插队插了一个中间件的handlefunc,没问题了就通过next(w, r)调路由中的handlefunc
middleware(route.Handler)