github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/registry/registry.go (about) 1 package registry 2 3 import ( 4 "errors" 5 "fmt" 6 "sync" 7 8 "github.com/volts-dev/volts/logger" 9 ) 10 11 var ( 12 log = logger.New("Registry") 13 defaultRegistry IRegistry 14 ErrNotFound = errors.New("service not found") // Not found error when GetService is called 15 ErrWatcherStopped = errors.New("watcher stopped") // Watcher stopped error when watcher is stopped 16 registryMap = make(map[string]func(opts ...Option) IRegistry) 17 registryHost sync.Map 18 ) 19 20 type ( 21 // 注册中心接口 22 IRegistry interface { 23 Init(...Option) error 24 Config() *Config 25 Register(*Service, ...Option) error // 注册 26 Deregister(*Service, ...Option) error // 注销 27 GetService(string) ([]*Service, error) 28 ListServices() ([]*Service, error) 29 Watcher(...WatchOptions) (Watcher, error) 30 LocalServices() []*Service 31 String() string 32 } 33 34 // 微服务 35 Service struct { 36 Name string `json:"name"` 37 Version string `json:"version"` 38 Metadata map[string]string `json:"metadata"` 39 Endpoints []*Endpoint `json:"endpoints"` 40 Nodes []*Node `json:"nodes"` 41 } 42 43 // 微服务节点 相当于每个程序/Port一个节点 44 Node struct { 45 Id string `json:"id"` 46 Address string `json:"address"` 47 Metadata map[string]string `json:"metadata"` 48 } 49 50 Endpoint struct { 51 // RPC Method e.g. Greeter.Hello 52 Name string `json:"name"` 53 // HTTP Host e.g example.com 54 Host []string `json:"host"` 55 // HTTP Methods e.g GET, POST 56 Method []string `json:"method"` 57 // HTTP Path e.g /greeter. Expect POSIX regex 58 Path string `json:"path"` 59 // Description e.g what's this endpoint for 60 Description string `json:"description"` 61 // Stream flag 62 Stream bool `json:"stream"` 63 64 // 以下待确认 65 Request *Value `json:"request"` 66 Response *Value `json:"response"` 67 Metadata map[string]string `json:"metadata"` 68 69 // API Handler e.g rpc, proxy 70 Handler string 71 // Body destination 72 // "*" or "" - top level message value 73 // "string" - inner message value 74 Body string 75 } 76 77 Value struct { 78 Name string `json:"name"` 79 Type string `json:"type"` 80 Values []*Value `json:"values"` 81 } 82 ) 83 84 func Register(name string, creator func(opts ...Option) IRegistry) { 85 registryMap[name] = creator 86 } 87 88 func Use(name string, opts ...Option) IRegistry { 89 cfg := &Config{Name: name} 90 cfg.Init(opts...) 91 92 // 加载存在的服务 93 for _, addr := range cfg.Addrs { 94 if addr == "" { 95 continue 96 } 97 98 regName := fmt.Sprintf("%s-%s", cfg.Name, addr) 99 if reg, has := registryHost.Load(regName); has { 100 return reg.(IRegistry) 101 } 102 } 103 104 if fn, has := registryMap[name]; has { 105 reg := fn(opts...) 106 for _, addr := range reg.Config().Addrs { 107 if addr == "" { 108 continue 109 } 110 111 regName := fmt.Sprintf("%s-%s", cfg.Name, addr) 112 registryHost.Store(regName, reg) 113 } 114 return reg 115 } 116 117 return newNopRegistry() 118 } 119 120 // NopRegistry as default registry 121 func Default(new ...IRegistry) IRegistry { 122 if new != nil { 123 defaultRegistry = new[0] 124 } else if defaultRegistry == nil { 125 defaultRegistry = newNopRegistry() 126 } 127 128 return defaultRegistry 129 } 130 131 // 比对服务节点UID是否一致, 132 func (self *Service) Equal(to *Service) bool { 133 // noop 会返回nil 这里需要判断 134 if self != nil && len(self.Nodes) == len(to.Nodes) { 135 var macth bool 136 for _, node := range self.Nodes { 137 macth = false 138 for _, n := range to.Nodes { 139 if node.Id == n.Id { 140 macth = true 141 break 142 } 143 } 144 145 if !macth { 146 return false 147 } 148 } 149 } 150 151 return true 152 }