manager.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package router
  2. import (
  3. "errors"
  4. "fmt"
  5. "log"
  6. "regexp"
  7. "github.com/gogf/gf/v2/net/ghttp"
  8. "github.com/gogf/gf/v2/net/gtrace"
  9. "github.com/gogf/gf/v2/util/gconv"
  10. "jygit.jydev.jianyu360.cn/dataservice/tripartite_gateway/common/db"
  11. . "jygit.jydev.jianyu360.cn/dataservice/tripartite_gateway/common/gatecode"
  12. "jygit.jydev.jianyu360.cn/dataservice/tripartite_gateway/core/util"
  13. )
  14. type Manager struct {
  15. eqRouters map[string]*Router
  16. regexRouter map[*regexp.Regexp]*Router
  17. }
  18. // InitRouterManager 初始化系统代理路由
  19. // 支持完全匹配和正则匹配
  20. func InitRouterManager() (*Manager, error) {
  21. //加载规则
  22. res := db.GateWatMySql.Query(`SELECT * FROM front_proxy`)
  23. if res == nil {
  24. return nil, errors.New("未发现可用路由")
  25. }
  26. // 初始化 routerManager
  27. routerManager := &Manager{
  28. eqRouters: make(map[string]*Router),
  29. regexRouter: make(map[*regexp.Regexp]*Router),
  30. }
  31. for _, row := range *res {
  32. // 获取路由信息
  33. router := gconv.String(row["url"])
  34. routerRule := &Router{
  35. Status: gconv.Int(row["status"]),
  36. ReqUrl: router,
  37. TimeOut: gconv.Int64(row["timeout"]),
  38. Remark: gconv.String(row["remark"]),
  39. Server: gconv.String(row["server"]),
  40. Price: gconv.Int64(row["price"]),
  41. ReqLimit: &util.ReqLimit{
  42. Size: gconv.Int(row["pool_size"]),
  43. Key: fmt.Sprintf("reqLimit_tripartite_%d", gconv.Int(row["id"])),
  44. },
  45. }
  46. routerRule.ReqLimit.Init()
  47. // 判断路由匹配方式是完全匹配还是正则匹配 (此处逻辑参考x-web框架)
  48. if regexp.QuoteMeta(router) == router {
  49. routerManager.eqRouters[router] = routerRule
  50. } else {
  51. reg, err := regexp.Compile(router)
  52. if err != nil {
  53. log.Println("路由", router, "装载异常", err)
  54. continue
  55. }
  56. routerManager.regexRouter[reg] = routerRule
  57. }
  58. }
  59. return routerManager, nil
  60. }
  61. // GetRouterRule 获取路由规则
  62. // 根据用户请求地址匹配路由规则,优先绝对匹配后用正则匹配。
  63. func (m *Manager) GetRouterRule(url string) (*Router, error) {
  64. routerRule, exists := m.eqRouters[url]
  65. if !exists {
  66. for reg, thisRouterRule := range m.regexRouter {
  67. if reg.MatchString(url) {
  68. routerRule = thisRouterRule
  69. break
  70. }
  71. }
  72. }
  73. if routerRule == nil || routerRule.Status != 1 {
  74. return nil, NewErrorWithCode(GLOBAL_ERR_NOTFIND)
  75. }
  76. return routerRule, nil
  77. }
  78. // InfusionContext 注入通用结构体gContext
  79. func (m *Manager) InfusionContext(r *ghttp.Request) (err error) {
  80. _, span := gtrace.NewSpan(r.Context(), "InfusionContext")
  81. defer span.End()
  82. //r.SetCtx(ctx)
  83. var router *Router
  84. var GCtx = &GContext{
  85. RouterRule: &Router{},
  86. }
  87. router, err = m.GetRouterRule(r.URL.Path)
  88. if err != nil {
  89. r.SetCtxVar(GContextKey, GCtx)
  90. return
  91. }
  92. GCtx.RouterRule = router
  93. //获取session
  94. /*jySess, _ := InitJySessionContext(r)
  95. GCtx.Sess = jySess*/
  96. r.SetCtxVar(GContextKey, GCtx)
  97. return
  98. }