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 &registry.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).