proxyServer.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package proxy
  2. import (
  3. . "bp.jydev.jianyu360.cn/BaseService/gateway/common/gatecode"
  4. "bp.jydev.jianyu360.cn/BaseService/gateway/core/node"
  5. "bp.jydev.jianyu360.cn/BaseService/gateway/core/proxy/broker"
  6. "bp.jydev.jianyu360.cn/BaseService/gateway/core/proxy/broker/outServer"
  7. "bp.jydev.jianyu360.cn/BaseService/gateway/core/proxy/middleware"
  8. "bp.jydev.jianyu360.cn/BaseService/gateway/core/proxy/proxyClient"
  9. "bp.jydev.jianyu360.cn/BaseService/gateway/core/router"
  10. "fmt"
  11. "github.com/gogf/gf/v2/frame/g"
  12. "github.com/gogf/gf/v2/net/ghttp"
  13. "github.com/gogf/gf/v2/os/gcfg"
  14. "github.com/gogf/gf/v2/os/gctx"
  15. "log"
  16. "net/http"
  17. "net/url"
  18. )
  19. var bManager = broker.InitBroker()
  20. var routerManager *router.Manager
  21. const errTryTime = 10 //错误尝试
  22. // InitGateWayServer 初始化网关服务
  23. func InitGateWayServer() *ghttp.Server {
  24. initCtx := gctx.New()
  25. //创建节点,并持续观察节点变化
  26. watchNode := node.NewNode(gcfg.Instance().MustGet(initCtx, "system.etcdListen", nil).Strings()...)
  27. go watchNode.NewWatcher(initCtx, bManager)
  28. //初始化可访问路由
  29. var err error
  30. routerManager, err = router.InitRouterManager()
  31. if err != nil {
  32. g.Log().Error(initCtx, err)
  33. }
  34. //初始化外部服务
  35. sussBiServer := outServer.InitSussBi(gcfg.Instance().MustGet(initCtx, "outServer.sussbi.addr", nil).String(),
  36. gcfg.Instance().MustGet(initCtx, "outServer.sussbi.user", nil).String(),
  37. gcfg.Instance().MustGet(initCtx, "outServer.sussbi.password", nil).String())
  38. bManager.RegisterOutServer(sussBiServer.Url, sussBiServer)
  39. gateWayServer := g.Server()
  40. //关闭系统自带请求日志
  41. gateWayServer.SetLogger(g.Log())
  42. gateWayServer.SetErrorLogEnabled(false)
  43. //注册中间件
  44. gateWayServer.Use(middleware.ErrorHandler) //错误拦截
  45. gateWayServer.Use(func(r *ghttp.Request) {
  46. r.SetError(routerManager.InfusionContext(r)) //context注入全局信息
  47. r.Middleware.Next()
  48. })
  49. gateWayServer.Use(middleware.FilterPolyHandler) //反爬虫策略
  50. gateWayServer.Use(middleware.FilterHandler) //权限过滤
  51. //加载代理客户端
  52. proxyClient.ReLoadClient()
  53. //注册代理
  54. gateWayServer.BindHandler("POST:/*", proxyHandler)
  55. gateWayServer.BindHandler("GET:/*", proxyHandler)
  56. return gateWayServer
  57. }
  58. // proxyHandler 网关代理Handler处理
  59. // 完成所有前置校验后,请求代理服务逻辑
  60. var proxyHandler = func(r *ghttp.Request) {
  61. if r.GetError() != nil {
  62. return
  63. }
  64. // 获取请求上下文内容
  65. gCtx := router.GetGContext(r.GetCtx())
  66. // 请求重试,防止某个服务中断不可用,导致接口不可用。
  67. for i := 0; i < errTryTime; i++ {
  68. var proxyAddr *url.URL
  69. var err error
  70. if gCtx.RouterRule.IsOutServer {
  71. //外部服务直接获取
  72. proxyAddr, err = bManager.GetOutSeverAutoLogin(gCtx.RouterRule.MiddleCode, r)
  73. } else {
  74. // 从etcd注册的地址,根据负载规则获取服务地址
  75. proxyAddr, err = bManager.GetServerAddr(gCtx.RouterRule.MiddleCode, r.GetClientIp())
  76. }
  77. if err != nil {
  78. r.SetError(err)
  79. return
  80. }
  81. // 代理地址存入上下文ctx中
  82. gCtx.ServerAddr = proxyAddr.String()
  83. router.UpdateGContext(r, gCtx)
  84. // 捕获异常,若代理出错,则进行重试
  85. var hasErr bool
  86. errHandel := func(hw http.ResponseWriter, hr *http.Request, err error) {
  87. hasErr = true
  88. if err.Error() == "context canceled" {
  89. return
  90. }
  91. if i == (errTryTime - 1) {
  92. r.SetError(NewErrorWithCode(GATEWAY_PROXY_ERR, fmt.Sprintf("代理异常:%s err:%v \n", gCtx.ServerAddr, err.Error())))
  93. }
  94. g.Log().Error(r.Context(), "ErrorHandler ", err)
  95. }
  96. log.Println("xxxx", r.Request.Header.Get("Cookie"))
  97. // 代理请求
  98. proxyClient.CreateCustomProxyClient(proxyAddr, errHandel).ServeHTTP(r.Response.ResponseWriter, r.Request)
  99. //if gCtx.RouterRule.IsOutServer {
  100. // if r.Response.Status == 401 {
  101. // hasErr = true
  102. // log.Println("do login Again")
  103. // r.Request.Header.Set("Cookie", "JSESSIONID=A4745CB36FA67EE15BA162033B0343F5")
  104. // r.Response.Flush()
  105. // }
  106. //}
  107. //log.Println("qqqqq", r.Request.RequestURI, r.Response.Status)
  108. // 未捕获到请求,标识请求成功
  109. if !hasErr {
  110. return
  111. }
  112. }
  113. }