github.com/annwntech/go-micro/v2@v2.9.5/client/selector/dns/dns.go (about) 1 // Package dns provides a dns SRV selector 2 package dns 3 4 import ( 5 "fmt" 6 "net" 7 "strconv" 8 9 "github.com/annwntech/go-micro/v2/client/selector" 10 "github.com/annwntech/go-micro/v2/registry" 11 ) 12 13 type dnsSelector struct { 14 options selector.Options 15 domain string 16 } 17 18 var ( 19 DefaultDomain = "local" 20 ) 21 22 func (d *dnsSelector) Init(opts ...selector.Option) error { 23 for _, o := range opts { 24 o(&d.options) 25 } 26 return nil 27 } 28 29 func (d *dnsSelector) Options() selector.Options { 30 return d.options 31 } 32 33 func (d *dnsSelector) Select(service string, opts ...selector.SelectOption) (selector.Next, error) { 34 var srv []*net.SRV 35 36 // check if its host:port 37 host, port, err := net.SplitHostPort(service) 38 // not host:port 39 if err != nil { 40 // lookup the SRV record 41 _, srvs, err := net.LookupSRV(service, "tcp", d.domain) 42 if err != nil { 43 return nil, err 44 } 45 // set SRV records 46 srv = srvs 47 // got host:port 48 } else { 49 p, _ := strconv.Atoi(port) 50 51 // lookup the A record 52 ips, err := net.LookupHost(host) 53 if err != nil { 54 return nil, err 55 } 56 57 // create SRV records 58 for _, ip := range ips { 59 srv = append(srv, &net.SRV{ 60 Target: ip, 61 Port: uint16(p), 62 }) 63 } 64 } 65 66 nodes := make([]*registry.Node, 0, len(srv)) 67 for _, node := range srv { 68 nodes = append(nodes, ®istry.Node{ 69 Id: node.Target, 70 Address: fmt.Sprintf("%s:%d", node.Target, node.Port), 71 }) 72 } 73 74 services := []*registry.Service{ 75 { 76 Name: service, 77 Nodes: nodes, 78 }, 79 } 80 81 sopts := selector.SelectOptions{ 82 Strategy: d.options.Strategy, 83 } 84 85 for _, opt := range opts { 86 opt(&sopts) 87 } 88 89 // apply the filters 90 for _, filter := range sopts.Filters { 91 services = filter(services) 92 } 93 94 // if there's nothing left, return 95 if len(services) == 0 { 96 return nil, selector.ErrNoneAvailable 97 } 98 99 return sopts.Strategy(services), nil 100 } 101 102 func (d *dnsSelector) Mark(service string, node *registry.Node, err error) {} 103 104 func (d *dnsSelector) Reset(service string) {} 105 106 func (d *dnsSelector) Close() error { 107 return nil 108 } 109 110 func (d *dnsSelector) String() string { 111 return "dns" 112 } 113 114 func NewSelector(opts ...selector.Option) selector.Selector { 115 options := selector.Options{ 116 Strategy: selector.Random, 117 } 118 119 for _, o := range opts { 120 o(&options) 121 } 122 123 return &dnsSelector{options: options, domain: DefaultDomain} 124 }