trpc.group/trpc-go/trpc-go@v1.0.3/docs/developer_guide/develop_plugins/naming.md (about) 1 English | [中文](naming.zh_CN.md) 2 3 ## Background 4 5 Like most other modules in tRPC-Go, the name service module also supports plugin. This article assumes that you have read the [README](/naming/README.zh_CN.md) of the naming package. 6 7 ## Pluggable Design 8 9 tRPC-Go provides the [`Selector`](/naming/selector) interface as the entrance to the name service, and provides a default implementation [`TrpcSelector`](/naming/selector/trpc_selector.go). `TrpcSelector` combines [`Discovery`](/naming/discovery), [`ServiceRouter`](/naming/servicerouter), [`Loadbalance`](/naming/loadbalance) and [`CircuitBreaker`](/naming/circuitbreaker ) combined. The framework provides a default implementation for each module. 10 11 By [plugin](/plugin), users can individually customize `Selector` or its various modules. Let's look at how this is done. 12 13 ## `Selector` Plugin 14 15 The `Selector` interface is defined as follows: 16 ```go 17 type Selector interface { 18 Select(serviceName string, opts ...Option) (*registry.Node, error) 19 Report(node *registry.Node, cost time.Duration, err error) error 20 } 21 ``` 22 23 The `Select` method returns the corresponding node information by service name, and some options can be passed in by `opts`. `Report` reports the call status, which may affect the results of `Selector` later, for example, circuit break nodes with too high error rates. 24 25 Here is a simple fixed-node `Selector` implementation: 26 ```go 27 func init() { 28 plugin.Register("my_selector", &Plugin{Nodes: make(map[string]string)}) 29 } 30 31 type Plugin struct { 32 Nodes map[string]string `yaml:"nodes"` 33 } 34 35 func (p *Plugin) Type() string { return "selector" } 36 func (p *Plugin) Setup(name string, dec plugin.Decoder) error { 37 if err := dec.Decode(p); err != nil { 38 return err 39 } 40 selector.Register(name, p) 41 return nil 42 } 43 44 func (p *Plugin) Select(serviceName string, opts ...selector.Option) (*registry.Node, error) { 45 if node, ok := p.Nodes[serviceName]; ok { 46 return ®istry.Node{Address: node, ServiceName: serviceName}, nil 47 } 48 return nil, fmt.Errorf("unknown service %s", serviceName) 49 } 50 51 func (p *Plugin) Report(*registry.Node, time.Duration, error) error { 52 return nil 53 } 54 ``` 55 When using it, you need to anonymously import the above plugin package to ensure that the `init` function successfully registers `Plugin`, and add the following configuration to `trpc_go.yaml`: 56 ```yaml 57 client: 58 service: 59 - name: xxx 60 target: "my_selector://service1" 61 # ... omit other configures 62 - name: yyy 63 target: "my_selector://service2" 64 # ... omit other configures 65 66 plugins: 67 selector: 68 my_selector: 69 nodes: 70 service1: 127.0.0.1:8000 71 service2: 127.0.0.1:8001 72 ``` 73 In this way, client `xxx` will access `127.0.0.1:8000`, and client `yyy` will access `127.0.0.1:8001`. 74 75 ## `Discovery` Plugin 76 77 The interface definition of `Discovery` is as follows: 78 ```go 79 type Discovery interface { 80 List(serviceName string, opt ...Option) (nodes []*registry.Node, err error) 81 } 82 ``` 83 `List` lists a group of nodes based on service name for subsequent ServiceRouter and LoadBalance. 84 85 The code implementation of the `Discovery` plugin is similar to that of `Selector` and will not be described again here. 86 87 In order for Discovery to take effect, you also need to choose one of the following two options: 88 - If you use the default `TrpcSelector`, you need to add the following configuration to yaml: 89 ```yaml 90 client: 91 service: 92 - # Note that the name here is directly filled with service1 instead of xxx. 93 # We will directly use this field to select. 94 name: service1 95 # Note that target cannot be used here, but the name field above must be used to select. 96 # target: ... 97 discovery: my_discovery 98 ``` 99 - If the default `TrpcSelector` does not meet your needs, you can customize the Selector as in the previous section. However, you must correctly handle the `Option` of the `Select` method, that is, `selector.WithDiscovery`. 100 101 ## `ServiceRouter` `LoadBalance` and `CircuitBreaker` Plugins 102 103 These plugins are implemented similarly to `Discovery`. Either use `TrpcSelector` and set the corresponding fields in `yaml.client.service[i]`; Or handle `selector.WithXxx` in your own implementation of `Selector`. 104 105 ## Polaris Mesh Plugin 106 107 tRPC-Go supports Polaris Mesh plugin. You can read more [here](https://github.com/trpc-ecosystem/go-naming-polarismesh).