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.