go-zero系列三:服务的加载过程及路由的注册

542 阅读2分钟

服务加载的主方法

签名方法
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)