loadbalance.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package loadbalance
  2. import (
  3. "sync"
  4. "time"
  5. "imuslab.com/zoraxy/mod/geodb"
  6. "imuslab.com/zoraxy/mod/info/logger"
  7. )
  8. /*
  9. Load Balancer
  10. Handleing load balance request for upstream destinations
  11. */
  12. type BalancePolicy int
  13. // Data structure to hold the upstream server information
  14. type Upstream struct {
  15. ProxyTargetIpOrDomain string //Target IP address or domain name with port
  16. RequireTLS bool //Require TLS connection
  17. PreferedCountryCode []string //Prefered country codes, default to empty string slice (not assigned)
  18. Priority int //Prirotiy of fallback, set all to 0 for round robin
  19. }
  20. // LoadBalanceRule stores the load balance option of this host. If there are no usable upstreams for lb, the primary one will be used
  21. type LoadBalanceRule struct {
  22. Upstreams []Upstream //Reverse proxy upstream servers
  23. UseStickySession bool //Enable stick session
  24. }
  25. // PrimaryRoutingRule stores the primary routing target of this host
  26. type PrimaryRoutingRule struct {
  27. MatchingDomainOrIp string //Primary proxy upstream origin server
  28. RequireTLS bool //Target require TLS
  29. }
  30. type Options struct {
  31. Geodb *geodb.Store //GeoIP resolver for checking incoming request origin country
  32. Logger *logger.Logger
  33. }
  34. type RouteManager struct {
  35. LoadBalanceMap sync.Map //Sync map to store the last load balance state of a given node
  36. OnlineStatusMap sync.Map //Sync map to store the online status of a given ip address or domain name
  37. onlineStatusTickerStop chan bool //Stopping channel for the online status pinger
  38. Options Options //Options for the load balancer
  39. }
  40. // Create a new load balancer
  41. func NewLoadBalancer(options *Options) *RouteManager {
  42. onlineStatusCheckerStopChan := make(chan bool)
  43. return &RouteManager{
  44. LoadBalanceMap: sync.Map{},
  45. OnlineStatusMap: sync.Map{},
  46. onlineStatusTickerStop: onlineStatusCheckerStopChan,
  47. Options: *options,
  48. }
  49. }
  50. func (m *RouteManager) UpdateKeepAliveTargets(pingTargets []*PrimaryRoutingRule) {
  51. ticker := time.NewTicker(1 * time.Minute)
  52. defer ticker.Stop()
  53. go func() {
  54. for {
  55. select {
  56. case <-m.onlineStatusTickerStop:
  57. ticker.Stop()
  58. return
  59. case <-ticker.C:
  60. for _, target := range pingTargets {
  61. isOnline := PingTarget(target)
  62. m.LoadBalanceMap.Store(target.MatchingDomainOrIp, isOnline)
  63. }
  64. }
  65. }
  66. }()
  67. }
  68. // GetProxyTargetIP Get the proxy target given the primary routing rule and load balance options
  69. func (m *RouteManager) GetProxyTargetIP(pr *PrimaryRoutingRule, lbr *LoadBalanceRule) {
  70. }
  71. func (m *RouteManager) Close() {
  72. m.onlineStatusTickerStop <- true
  73. }
  74. // Print debug message
  75. func (m *RouteManager) debugPrint(message string, err error) {
  76. m.Options.Logger.PrintAndLog("LoadBalancer", message, err)
  77. }