trpc.group/trpc-go/trpc-go@v1.0.3/docs/user_guide/server/overview.md (about)

     1  English | [中文](overview.zh_CN.md)
     2  
     3  tRPC-Go Server Development Guide
     4  
     5  # Introduction
     6  
     7  This article outlines the considerations involved in developing a server-side program, such as:
     8  
     9  - What protocol should the service use?
    10  - How to define the service?
    11  - How to choose plugins?
    12  - How to test the service?
    13  
    14  # Service Selection
    15  
    16  ## Built-in protocol service
    17  
    18  The tRPC framework provides built-in support for **tRPC services**, **tRPC streaming services**, **generic HTTP RPC services** and **generic HTTP standard services**. “Generic HTTP”specifically refers to the underlying protocols of services using "http", "https", "http2", and "http3".
    19  
    20  - What is the difference between **generic HTTP standard services** and generic **HTTP RPC services** ? Generic HTTP RPC services are a set of RPC models based on the generic HTTP protocol, designed by the tRPC framework, with protocol details encapsulated internally and completely transparent to users. Generic HTTP RPC services define services through PB IDL protocol and generate RPC stub code through scaffolding. Generic HTTP standard services are used exactly the same as the golang http standard library, with users defining handle request functions, registering http routes, and filling in http headers themselves. Standard HTTP services do not require IDL protocol files.
    21  - What is the difference between **generic HTTP RPC services** and **tRPC services**? The only difference between generic HTTP RPC services and tRPC services is the difference in protocols. Generic HTTP RPC services use the generic HTTP protocol, while tRPC services use the tRPC private protocol. The difference is only visible within the framework and there is almost no difference in business development usage.
    22  - What is the difference between **tRPC services** and **tRPC streaming services**? For a single RPC call, tRPC services require the client to initiate a request, wait for the server to process it, and then return the result to the client. On the other hand, tRPC streaming services support continuous data transmission between the client and server after establishing a stream connection. The two services differ in protocol format and IDL syntax.
    23  
    24  ## Scheduled task service
    25  
    26  The scheduled task service adopts the ordinary service model and provides the ability to perform scheduled tasks, such as regularly loading cache or verifying transactions. A scheduled task service only supports one scheduled task. If there are multiple scheduled tasks, multiple scheduled task services need to be created. For a description of the functionality of the scheduled task service, please refer to the [tRPC-Go Build Scheduled Task Service](https://github.com/trpc-ecosystem/go-database/tree/main/timer).
    27  
    28  The scheduled task service is not an RPC service and does not provide service calls to clients. The scheduled task service and RPC service do not affect each other, and an application can have multiple RPC services and multiple scheduled task services at the same time.
    29  
    30  ## Consumer service
    31  
    32  The use case for the consumer service is for a program to consume messages from a message queue as a consumer. Like the scheduled task service, it adopts the ordinary service model and reuses the framework's service governance capabilities, such as automatic monitoring reporting, service tracing, and call chains. The service does not provide service calls to clients.
    33  
    34  Currently, tRPC-Go supports message queues such as [kafka](https://github.com/trpc-ecosystem/go-database/tree/main/kafka), etc. The development and configuration of each message queue may vary, please refer to their respective documentation.
    35  
    36  # Define Naming Service
    37  
    38  After selecting the protocol for the service, we need to define the **Naming Service**, which determines the address of the service provider and the routing identifier used in the naming system for addressing. 
    39  
    40  The Naming Service is responsible for network communication and protocol parsing. A Naming Service ultimately represents an `[ip, port, protocol]` combination for addressing. The Naming Service is defined through the "service" configuration in the "server" section of the framework configuration file.
    41  
    42  We usually use a string to represent a Naming Service. The naming format depends on how the service model is defined in the service management platform where the service is located. This article takes the common practice of using the four-segment format `trpc.{app}.{server}.{service}` as an example.
    43  
    44  ```yaml
    45  server:  # server configuration
    46    service:  # services which are provided by business server, there can be more than one
    47      - name: trpc.test.helloworld.Greeter1  # the route name of the service, this is an array, note the "-" sign in front of "name"
    48        ip: 127.0.0.1  # service listening IP address, choose either IP or NIC, IP has priority
    49        port: 8000  # service listening port
    50        network: tcp  # network listening type,tcp/udp
    51        protocol: trpc  # application layer protocol, trpc/http
    52        timeout: 1000  # maximum processing time for a request, in milliseconds
    53  ```
    54  
    55  In this example, the routing identifier for the service is "trpc.test.helloworld.Greeter1", the protocol type is "trpc", and the address is "127.0.0.1:8000". When the program starts, it will automatically read this configuration and generate a Naming Service. If the server chooses the "service registration" plugin, the application will automatically register the "name" and "ipport" information of the Naming Service to the naming service, so that the client can use this name for addressing.
    56  
    57  # Define Proto Service
    58  
    59  Proto Service is a logical combination of a set of interfaces. It needs to define the package, proto service, RPC name, and data types for interface requests and responses. At the same time, Proto Service needs to be combined with Naming Service to complete the service assembly. Although there are slight differences in the registration interface provided to developers between "IDL protocol type" and "non-IDL protocol type" for service assembly, the implementation of both is consistent within the framework.
    60  
    61  ## IDL protocol type
    62  
    63  IDL language can be described by interfaces in a neutral way, which use tools to convert IDL files into stub code in a specified language, allowing programmers to focus on business logic development. tRPC services, tRPC streaming services, and generic HTTP RPC services are all IDL protocol type services. For IDL protocol type services, the definition of Proto Service is usually divided into the following three steps:
    64  
    65  **The following examples are all based on tRPC services**
    66  
    67  Step 1: Use IDL language to describe the RPC interface specification and generate an IDL file. Taking tRPC service as an example, the definition of its IDL file is as follows:
    68  
    69  ```protobuf
    70  syntax = "proto3";
    71  
    72  package trpc.test.helloworld;
    73  option go_package="github.com/some-repo/examples/helloworld";
    74  
    75  service Greeter {
    76      rpc SayHello (HelloRequest) returns (HelloReply) {}
    77  }
    78  
    79  message HelloRequest {
    80      string msg = 1;
    81  }
    82  
    83  message HelloReply {
    84      string msg = 1;
    85  }
    86  ```
    87  
    88  Step 2: The corresponding stub code for the server and client can be generated by [trpc-cmdline](https://github.com/trpc-group/trpc-cmdline):
    89  
    90  ```shell
    91  trpc create -p helloworld.proto
    92  ```
    93  
    94  Step 3: Register the Proto Service to Naming Service to complete the service assembly:
    95  
    96  ```go
    97  type greeterServerImpl struct{}
    98  
    99  // SayHello is the interface processing function.
   100  func (s *greeterServerImpl) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) {
   101      return &pb.HelloReply{ Msg: "Hello, I am tRPC-Go server." }, nil
   102  }
   103  
   104  func main() {
   105      // Create Naming Service by reading the server.service configuration item in the framework configuration.
   106      s := trpc.NewServer()
   107      // Register the implementation instance of Proto Service to Naming Service.
   108      pb.RegisterGreeterService(s, &greeterServerImpl{})
   109      // ...
   110  }
   111  ```
   112  
   113  For programs with only one Proto Service and Naming Service, the server generated by `trpc.NewServer()` can be used directly to map with Proto Service.
   114  
   115  ## non-IDL protocol type
   116  
   117  For non-IDL protocol types, there still needs to be a definition and registration process for Proto Service. Usually, the framework and plugins have different levels of encapsulation for each protocol, and developers need to follow the usage documentation for each protocol when developing. Taking the generic HTTP standard service as an example, its code is as follows:
   118  
   119  ```go
   120  // interface processing function
   121  func handle(w http.ResponseWriter, r *http.Request) error {
   122      // construct Http Head
   123      w.WriteHeader(403)
   124      // construct Http Body
   125      w.Write([]byte("response body"))
   126  
   127      return nil
   128  }
   129  
   130  func main() {
   131      // create Naming Service by reading the server.service configuration item in the framework configuration
   132      s := trpc.NewServer()
   133  
   134      thttp.HandleFunc("/xxx/xxx", handle)
   135      // register the implementation instance of Proto Service to Naming Service
   136      thttp.RegisterNoProtocolService(s)
   137      s.Serve()
   138  }
   139  ```
   140  
   141  ## Multi-service registry
   142  
   143  For programs that are not in single-service mode (only one naming service and one proto service), users need to explicitly specify the mapping relationship between naming service and proto service. 
   144  
   145  For registration of multiple services, we define two Proto Services for tRPC services as an example: `trpc.test.helloworld.Greeter` and `trpc.test.helloworld.Hello`:
   146  
   147  ```protobuf
   148  syntax = "proto3";
   149  package trpc.test.helloworld;
   150  option go_package="github.com/some-repo/examples/helloworld";
   151  service Greeter {
   152      rpc SayHello (HelloRequest) returns (HelloReply) {}
   153  }
   154  
   155  service Hello {
   156      rpc SayHi (HelloRequest) returns (HelloReply) {}
   157  }
   158  
   159  message HelloRequest {
   160      string msg = 1;
   161  }
   162  
   163  message HelloReply {
   164      string msg = 1;
   165  }
   166  ```
   167  
   168  Correspondingly, two Naming Services also need to be defined: `trpc.test.helloworld.Greeter` and `trpc.test.helloworld.Hell`o`:
   169  
   170  ``` yaml
   171  server:  # server configuration
   172    service:  # services which are provided by business server, there can be more than one
   173      - name: trpc.test.helloworld.Greeter  # the route name of the service, this is an array, note the "-" sign in front of "name"
   174        ip: 127.0.0.1  # service listening IP address, choose either IP or NIC, IP has priority
   175        port: 8000  # service listening port
   176        network: tcp  # network listening type,tcp/udp
   177        protocol: trpc  # application layer protocol, trpc/http
   178        timeout: 1000  # maximum processing time for a request, in milliseconds
   179      - name: trpc.test.helloworld.Hello  # the route name of the service, this is an array, note the "-" sign in front of "name"
   180        ip: 127.0.0.1  # service listening IP address, choose either IP or NIC, IP has priority
   181        port: 8001  # service listening port
   182        network: tcp  # network listening type,tcp/udp
   183        protocol: trpc  # application layer protocol, trpc/http
   184        timeout: 1000  # maximum processing time for a request, in milliseconds
   185  ```
   186  
   187  Register the Proto Service to the Naming Service, and the name of the Naming Service needs to be specified in a multi-service scenario.
   188  
   189  ```go
   190  func main() {
   191      // create Naming Service by reading the server.service configuration item in the framework configuration
   192      s := trpc.NewServer()
   193      // construct Greeter service
   194      pb.RegisterGreeterService(s.Service("trpc.test.helloworld.Greeter"), &greeterServerImpl{})
   195      // construct Hello service
   196      pb.RegisterHelloService(s.Service("trpc.test.helloworld.Hello"), &helloServerImpl{})
   197      ...
   198  }
   199  ```
   200  
   201  ## Interface management
   202  
   203  For the built-in tRPC services, tRPC streaming services, and generic HTTP RPC services in the framework, it is recommended to follow some certain development specifications.
   204  
   205  These three types of services all use PB files to define interfaces. In order to facilitate upstream and downstream to obtain interface information more transparently, we recommend **separating PB files from services, making them language-independent, and managing them through an independent central repository for unified version management**. Use a shared platform to manage PB files.
   206  
   207  # Service Development
   208  
   209  For the setup of common service types, please refer to the following links:
   210  
   211  - [Setup tRPC streaming service](/stream/README.md)
   212  - [Setup HTTP RPC/standard service](/http/README.md)
   213  
   214  Some third-party codec plugins: [trpc-ecosystem/go-codec](https://github.com/trpc-ecosystem/go-codec).
   215  
   216  ## Common APIs
   217  
   218  For log, metrics, and config, the framework provides standard calling interfaces. Service development can only interface with the service governance system by using these standard interfaces. For example, for logs, if the standard log interface is not used and "fmt.Printf()" is used directly, log information cannot be reported to the remote log center.
   219  
   220  tRPC-Go server configuration supports two ways of configuring services: "**through framework configuration files**" and "**function call parameters**". The priority of "function call parameters" is greater than that of "through framework configuration files". It is recommended to use the framework configuration file to configure the server first, which has the advantage of decoupling configuration and code and facilitating management.
   221  
   222  ## Error codes
   223  
   224  tRPC-Go recommends using `errors.New()` encapsulated by tRPC-Go to return business error codes when writing server-side business logic, so that the framework can automatically report business error codes to the monitoring system. If the business customizes the error, it can only rely on the business to actively call the Metrics SDK to report the error code. For the API usage of error codes, please refer to [here](/errs).
   225  
   226  # Framework Configuration
   227  
   228  For the server, it is necessary to configure the "global" and "server" parts of the framework configuration. For the specific meanings, value ranges, and other information of configuration parameters, please refer to the [Framework Configuration document](/docs/user_guide/framework_conf.md). The configuration of the "plugins" part depends on the selected plugin, please refer to the "Plugin Selection" section below.
   229  
   230  # Plugin Selection
   231  
   232  The core of tRPC framework is to modularize framework functional plugins, and the framework core does not include specific implementations. For the use of plugins, we need to **import plugins in the main file** and **configure plugins in the framework configuration file** at the same time. It should be emphasized here that **the selection of plugins must be determined at the stage of development**. Please refer to the example in the [Polaris Naming Service](https://github.com/trpc-ecosystem/go-naming-polarismesh) for how to use plugins.
   233  
   234  The tRPC plugin ecosystem provides a rich set of plugins. How can programs choose the appropriate plugins? Here we provide some ideas for reference. We can roughly divide plugins into three categories: independent plugins, service governance plugins, and storage interface plugins.
   235  
   236  - Independent plugins: For example, protocol, compression, serialization, local memory cache, and other plugins, their operation does not depend on external system components. The idea of this type of plugin is relatively simple, mainly based on the needs of business functions and the maturity of the plugin to make choices.
   237  - Service governance plugins: Most service governance plugins, such as remote logs, naming services, configuration centers, etc., need to interface with external systems and have a great dependence on the microservice governance system. For the selection of these plugins, we need to clarify on what operating platform the service will ultimately run, what governance components the platform provides, which capabilities the service must interface with the platform, and which ones do not.
   238  - Storage interface plugins: Storage plugins mainly encapsulate the interface calls of mature databases, message queues, and other components in the industry and within the company. For this part of the plugin, we first need to consider the technical selection of the business, which database is more suitable for the needs of the business. Then, based on the technical selection, we can see if tRPC supports it. If not, we can choose to use the native SDK of the database or recommend that everyone contribute plugins to the tRPC community.
   239  
   240  ## Built-in Plugins
   241  
   242  The framework has built-in some necessary plugins for services, which ensures that the framework can still provide normal RPC call capabilities with default plugins without setting any plugins. Users can replace the default plugins themselves.
   243  
   244  The table below lists the default plugins provided by the framework as a server and the default behavior of the plugins.
   245  
   246  | Plugin Type | Plugin Name  | Default Plugin | Plugin Behavior  |
   247  | ---------- | --------- | --------  | ------------------------------------- |
   248  | log      | Console  | Yes     | Default debug level or above logs are printed to the console, and the level can be set through configuration or API   |
   249  | metric   | Noop     | Yes     | No metric information is reported     |
   250  | config   | File     | Yes     | Supports users to use the interface to obtain configuration items from a specified local file   |
   251  | registry | Noop     | Yes     | No registration or deregistration of services is performed   |
   252  
   253  # Filter
   254  
   255  tRPC-Go provides an interceptor (filter) mechanism, which sets up event tracking in the context of RPC requests and responses, allowing businesses to insert custom processing logic at these points. Functions such as call chain tracking and authentication and authorization are usually implemented using interceptors. Please refer to the [trpc-ecosystem/go-filter](https://github.com/trpc-ecosystem/go-filter) for commonly used interceptors.
   256  
   257  The business can customize filter. Filter are usually combined with plugins to implement functions. Plugins provide configuration, while interceptors are used to insert processing logic into the RPC call context. For the principle, triggering timing, execution order, and example code of custom interceptors, please refer to [trpc-go/filter](/filter).
   258  
   259  # Testing Related
   260  
   261  tRPC-Go has considered the testability of the framework from the beginning of the design. When generating stub code through pb, mock code is generated by default.
   262  
   263  # Advanced Features
   264  
   265  ## Timeout control
   266  
   267  tRPC-Go provides three timeout mechanisms for RPC calls: link timeout, message timeout, and call timeout. For an introduction to the principles and related configurations of these three timeout mechanisms, please refer to [tRPC-Go Timeout Control](/docs/user_guide/timeout_control.md).
   268  
   269  This feature requires protocol support (the protocol needs to carry timeout metadata downstream). The tRPC protocol, generic HTTP RPC protocol all support timeout control.
   270  
   271  ## Idle Timeout
   272  
   273  The server has a default idle timeout of 60 seconds to prevent excessive idle connections from consuming server-side resources. This value can be modified through the `idletimeout` setting in the framework configuration:
   274  
   275  ```yaml
   276  server:
   277    service:
   278      - name: trpc.server.service.Method
   279        network: tcp
   280        protocol: trpc
   281        idletime: 60000 # The unit is milliseconds. Setting it to -1 means there is no idle timeout (setting it to 0 will still default to the 60s by the framework)
   282  ```
   283  
   284  ## Link transmission
   285  
   286  The tRPC-Go framework provides a mechanism for passing fields between the client and server and passing them down the entire call chain. For the mechanism and usage of link transmission, please refer to [tRPC-Go Link Transmission](/docs/user_guide/metadata_transmission.md).
   287  
   288  This feature requires protocol support for metadata distribution. The tRPC protocol, generic HTTP RPC protocol all support link transmission. 
   289  
   290  ## Reverse proxy
   291  
   292  tRPC-Go provides a mechanism for programs that act as reverse proxies to complete the transparent transmission of binary body data without serialization and deserialization processing to improve forwarding efficiency. For the principles and example programs of reverse proxies, please refer to [tRPC-Go Reverse Proxy](/docs/user_guide/reverse_proxy.md).
   293  
   294  ## Custom compression method
   295  
   296  tRPC-Go allows businesses to define and register compression and decompression algorithms for custom RPC message body compression and decompression. For specific examples, please refer to [here](/codec/compress_gzip.go).
   297  
   298  ## Custom serialization method
   299  
   300  tRPC-Go allows businesses to define and register serialization and deserialization algorithms for custom RPC message body serialization and deserialization. For specific examples, please refer to [here](/codec/serialization_json.go).
   301  
   302  ## Setting the maximum number of service coroutines
   303  
   304  tRPC-Go supports service-level synchronous/asynchronous packet processing modes. For asynchronous mode, a coroutine pool is used to improve coroutine usage efficiency and performance. Users can set the maximum number of service coroutines through framework configuration and Option configuration. For details, please refer to the service configuration in the [tRPC-Go Framework Configuration](/docs/user_guide/framework_conf.md) section.