123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- package router
- import (
- "app.yhyue.com/moapp/jybase/redis"
- "errors"
- "fmt"
- "log"
- "regexp"
- "github.com/gogf/gf/v2/net/ghttp"
- "github.com/gogf/gf/v2/net/gtrace"
- "github.com/gogf/gf/v2/util/gconv"
- "jygit.jydev.jianyu360.cn/dataservice/tripartite_gateway/common/db"
- . "jygit.jydev.jianyu360.cn/dataservice/tripartite_gateway/common/gatecode"
- "jygit.jydev.jianyu360.cn/dataservice/tripartite_gateway/core/util"
- )
- type Manager struct {
- eqRouters map[string]*Router
- regexRouter map[*regexp.Regexp]*Router
- }
- // InitRouterManager 初始化系统代理路由
- // 支持完全匹配和正则匹配
- func InitRouterManager() (*Manager, error) {
- redis.DelByCodePattern("other", "reqLimit_tripartite_*")
- //加载规则
- res := db.GateWatMySql.SelectBySql(`SELECT * FROM front_proxy`)
- if res == nil {
- return nil, errors.New("未发现可用路由")
- }
- // 初始化 routerManager
- routerManager := &Manager{
- eqRouters: make(map[string]*Router),
- regexRouter: make(map[*regexp.Regexp]*Router),
- }
- for _, row := range *res {
- // 获取路由信息
- router := gconv.String(row["url"])
- routerRule := &Router{
- Id: gconv.Int(row["id"]),
- Status: gconv.Int(row["status"]),
- ReqUrl: router,
- TimeOut: gconv.Int64(row["timeout"]),
- Remark: gconv.String(row["remark"]),
- Server: gconv.String(row["server"]),
- Price: gconv.Int64(row["price"]),
- }
- routerRule.ReqLimit = &util.ReqLimit{
- Size: gconv.Int(row["pool_size"]),
- Key: fmt.Sprintf("reqLimit_tripartite_%d", routerRule.Id),
- }
- routerRule.ReqLimit.Init()
- routerRule.IsFree = routerRule.Price <= 0
- // 判断路由匹配方式是完全匹配还是正则匹配 (此处逻辑参考x-web框架)
- if regexp.QuoteMeta(router) == router {
- routerManager.eqRouters[router] = routerRule
- } else {
- reg, err := regexp.Compile(router)
- if err != nil {
- log.Println("路由", router, "装载异常", err)
- continue
- }
- routerManager.regexRouter[reg] = routerRule
- }
- }
- return routerManager, nil
- }
- // GetRouterRule 获取路由规则
- // 根据用户请求地址匹配路由规则,优先绝对匹配后用正则匹配。
- func (m *Manager) GetRouterRule(url string) (*Router, error) {
- routerRule, exists := m.eqRouters[url]
- if !exists {
- for reg, thisRouterRule := range m.regexRouter {
- if reg.MatchString(url) {
- routerRule = thisRouterRule
- break
- }
- }
- }
- if routerRule == nil || routerRule.Status != 1 {
- return nil, NewErrorWithCode(GLOBAL_ERR_NOTFIND)
- }
- return routerRule, nil
- }
- // InfusionContext 注入通用结构体gContext
- func (m *Manager) InfusionContext(r *ghttp.Request) (err error) {
- _, span := gtrace.NewSpan(r.Context(), "InfusionContext")
- defer span.End()
- //r.SetCtx(ctx)
- var router *Router
- var GCtx = &GContext{
- RouterRule: &Router{},
- }
- router, err = m.GetRouterRule(r.URL.Path)
- if err != nil {
- return err
- }
- appid := r.GetQuery("appid").String()
- res := db.GateWatMySql.SelectBySql(`SELECT b.* FROM USER a INNER JOIN user_api b ON (a.appid=? AND b.front_proxy_id=? AND a.id=b.user_id)`, appid, router.Id)
- if res == nil || len(*res) == 0 {
- return NewErrorWithCode(GLOBAL_ERR_NOPERMISSION)
- }
- router = &Router{
- Id: router.Id,
- Status: router.Status,
- ReqUrl: router.ReqUrl,
- TimeOut: router.TimeOut,
- Price: router.Price,
- Remark: router.Remark,
- Server: router.Server,
- ReqLimit: router.ReqLimit,
- IsFree: router.IsFree,
- }
- if price := gconv.Int64((*res)[0]["price"]); price >= 0 {
- router.Price = price
- }
- rl := &util.ReqLimit{
- Size: gconv.Int((*res)[0]["pool_size"]),
- Key: fmt.Sprintf("reqLimit_tripartite_%d_%d", router.Id, gconv.Int((*res)[0]["user_id"])),
- }
- sizeKey := router.ReqLimit.Key + "_size"
- if rl.Size > 0 {
- router.ReqLimit = rl
- //数据库中调整了某个用户的某个接口并发数,重新初始化
- if redis.GetInt("other", sizeKey) != router.ReqLimit.Size {
- redis.PutCKV("other", sizeKey, router.ReqLimit.Size)
- router.ReqLimit.Clear()
- router.ReqLimit.Init()
- }
- } else {
- redis.Del("other", sizeKey)
- rl.Clear()
- }
- GCtx.RouterRule = router
- //获取session
- /*jySess, _ := InitJySessionContext(r)
- GCtx.Sess = jySess*/
- r.SetCtxVar(GContextKey, GCtx)
- return
- }
|