trpc.group/trpc-go/trpc-go@v1.0.3/plugin/README.md (about)

     1  English | [中文](README.zh_CN.md)
     2  
     3  # Plugin
     4  
     5  tRPC-Go is designed with a plugin architecture concept, which allows the framework to connect with various ecosystems through plugins, providing openness and extensibility.
     6  The plugin package is used to manage plugins that need to be loaded based on configurations.
     7  Plugins that do not rely on configuration are relatively simple, such as [codec plugins](/codec/README.md), which will not be discussed here.
     8  Therefore, we will first introduce the design of the plugin package and then explain how to develop a plugin that needs to be loaded based on configuration.
     9  
    10  ## Design of the `plugin` package
    11  
    12  The plugin package manages all plugins through a "plugin factory".
    13  Each plugin needs to be registered with the plugin factory.
    14  The plugin factory adopts a two-level management mode:
    15  The first level is the plugin type, such as log type, conf type, selector type, etc.
    16  The second level is the plugin name, such as local file configuration, remote file configuration, local database configuration, etc. for conf plugins.
    17  
    18  ```ascii
    19                         +-----------------+
    20                     +---+  Plugin Factory +----+
    21                     |   +--------+--------+    |
    22                     |            |             |
    23                 +---v--+      +--v--+     +----v-----+
    24       +---------+ conf |      | log |     | selector |
    25       |         +---+--+      +-----+     +----+-----+
    26       |             |                          |
    27  +----v-----+ +-----v-------+             +----v----+
    28  |local-file| | remote-file |    ......   | polaris |
    29  +----------+ +-------------+             +---------+
    30  ```
    31  
    32  For the plugin type, the `plugin` package does not impose any restrictions, and you can add your own plugin types.
    33  
    34  ### Common plugin types
    35  
    36  According to their functions, the framework provides the following five types of common plugins:
    37  
    38  - Configuration: Provides a standard interface for obtaining configurations, getting configuration data from various data sources such as local files, configuration centers, etc., providing configuration parsing in multiple formats such as json, yaml, etc., and the framework also provides a watch mechanism to achieve dynamic updates of configurations.
    39  - Logging: Provides a unified logging print and log reporting standard interface. Log plugins can complete the docking with remote log systems by implementing the log reporting interface.
    40  - Protocol: Provides standard interfaces related to protocol encoding and decoding, allowing the expansion of business protocols, serialization types, data compression methods, and other protocol processing through plugins.
    41  - Name Service: Provides standard interfaces including service registration, service discovery, policy routing, load balancing, and fusing, used to implement service routing addressing.
    42  - Filter: Provides a generic filter interface, allowing users to set up buried points in the context of service calls to implement functions such as module monitoring, cross-cutting logging, link tracking, and overload protection.
    43  
    44  ## How to develop a plugin that needs to be loaded based on configuration
    45  
    46  Developing a plugin that needs to be loaded based on configuration usually involves implementing the plugin and configuring the plugin. [A runnable specific example](/examples/features/plugin)
    47  
    48  ### Implementing the plugin
    49  
    50  1. The plugin implements the `plugin.Factory` interface.
    51  
    52  ```go
    53  // Factory is a unified abstract for the plugin factory. External plugins need to implement this interface to generate specific plugins and register them in specific plugin types.
    54  type Factory interface {
    55      // Type is the type of the plugin, such as selector, log, config, tracing.
    56      Type() string
    57      // Setup loads the plugin based on the configuration node. Users need to define the specific plugin configuration data structure first.
    58      Setup(name string, configDec Decoder) error
    59  }
    60  ```
    61  
    62  2. The plugin calls `plugin.Register` to register itself with the `plugin` package.
    63  
    64  ```go
    65  // Register registers the plugin factory. You can specify the plugin name yourself, and different factory instances can be registered for the same implementation with different configurations.
    66  func Register(name string, p Factory)
    67  ```
    68  
    69  ### Configuring the plugin
    70  
    71  1. Import the plugin's package in the `main` package.
    72  2. Configure the plugin under the `plugins` field in the configuration file. The configuration file format is:
    73  ```yaml
    74  # Plugin configuration
    75  plugins:
    76    # Plugin type
    77    log:
    78      # Plugin name
    79      logger1:
    80        # Plugin detailed configuration, please refer to the instructions of each plugin for details
    81        ....
    82      logger2:
    83        # Plugin detailed configuration, please refer to the instructions of each plugin for details
    84        ....
    85    # Plugin type
    86    config:
    87      # Plugin name
    88      rainbow:
    89        # Plugin detailed configuration, please refer to the instructions of each plugin for details
    90        ....
    91      tconf:
    92        # Plugin detailed configuration, please refer to the instructions of each plugin for details
    93        ....
    94  ```
    95  The above configuration defines two plugin types and four plugins.
    96  There are logger1 and logger2 plugins under the log type.
    97  There are local-file and remote-file plugins under the config type.
    98  
    99  ### Plugin initialization order
   100  
   101  After the tRPC-GO server calls the `trpc.NewServer()` function, it reads all plugin configurations under the "plugins" field in the framework configuration file and then calls the "Setup()" function of each plugin to complete the initialization of the plugin configuration.
   102  In general, plugins are independent of each other, and the framework initializes the plugins in a random order (e.g., plugin A depends on plugin B).
   103  If a plugin depends on other plugins, it can implement the following methods to declare the dependency relationship.
   104  
   105  ```go
   106  // Depender is the interface for "Strong Dependence".
   107  // If plugin a "Strongly" depends on plugin b, b must exist and
   108  // a will be initialized after b's initialization.
   109  type Depender interface {
   110      // DependsOn returns a list of plugins that are relied upon.
   111      // The list elements are in the format of "type-name" like [ "selector-polaris" ].
   112      DependsOn() []string
   113  }
   114  
   115  // FlexDepender is the interface for "Weak Dependence".
   116  // If plugin a "Weakly" depends on plugin b and b does exist,
   117  // a will be initialized after b's initialization.
   118  type FlexDepender interface {
   119      FlexDependsOn() []string
   120  }
   121  ```
   122  
   123  The dependency relationship is divided into strong dependency and weak dependency.
   124  Strong dependency requires the depended plugin to exist, otherwise, the framework will panic.
   125  Weak dependency will not panic.
   126  The framework will first ensure that all strong dependencies are satisfied, and then check the weak dependencies.
   127  
   128  For example, in the following example, the plugin initialization strongly depends on the selector type plugin a and weakly depends on the config type plugin b.
   129  
   130  ```go
   131  func (p *Plugin) DependsOn() []string {
   132      return []string{"selector-a"}
   133  }
   134  func (p *Plugin) FlexDependsOn() []string {
   135      return []string{"config-b"}
   136  }
   137  ```