tRPC-Go Documentation

repository·main·Indexed 22 days ago

https://github.com/trpc-group/trpc-go

A high-performance, pluggable RPC framework for Go featuring a modular architecture for protocols, filters, and database integrations. Includes documentation on the Admin management service, client configuration via YAML and client.Option, the codec package's processing pipeline (Framer, Codec, Compressor, Serializer), and a comprehensive error handling system using the errs package to categorize framework, callee, and business errors.

Tokens
163.9K
Snippets
442
Records
604
Agent score
71%

What's inside tRPC-Go

  1. Overview of the tRPC-Go Framework

    main

    tRPC-Go is a pluggable, high-performance RPC framework implemented in Go. It is designed to be highly extensible, allowing developers to swap out or add third-party components for various functionalities.

    Key capabilities include:

    • Multi-service support: Start multiple services within a single process, each listening on different addresses.
    • Pluggable architecture: All components are pluggable. While default implementations are provided for basic functions, you can replace them or implement third-party components.
    • Protocol flexibility: Supports any third-party protocol by implementing the codec interfaces. It supports trpc and http protocols by default.
    • Testability: All interfaces can be mocked using gomock and mockgen to facilitate unit testing.
    • Code Generation: Provides the trpc command-line tool for generating code templates.
  2. What is RPCZ and how to use it for debugging

    main

    RPCZ is a monitoring tool for tRPC-Go that records the running state of RPC calls. It tracks events such as serialization/deserialization, compression/decompression, and filter execution. This makes it useful for debugging and performance optimization by providing detailed visibility into the lifecycle of an RPC request.

    Configuration for RPCZ can be applied in three ways:

    1. Basic configuration: Configures sampling for all spans.
    2. Advanced configuration: Allows sampling specific spans of interest (e.g., errors).
    3. Code configuration: Enables dynamic sampling of spans via code.
  3. What is RPCZ?

    main

    RPCZ is a monitoring tool for RPC (Remote Procedure Call) systems. It records various events occurring during an RPC lifecycle, such as serialization/deserialization, compression/decompression, and interceptor execution.

    Key benefits include:

    • Debugging: Allows users to configure which events to record and view them via an admin tool to quickly locate issues.
    • Performance Optimization: Records the duration of events and the size of sent/received data packets, helping to analyze timeouts and optimize service performance.
  4. tRPC-Go HTTP Service Types Overview

    main

    tRPC-Go supports three types of HTTP-related services:

    1. Generic HTTP Standard Service: Does not require IDL or stub code. Uses http_no_protocol or http2_no_protocol. Best for standard web APIs.
    2. Generic HTTP RPC Service: Shares the same IDL and stub code used by standard tRPC protocols. Allows HTTP to act as a transport for RPC calls.
    3. Generic HTTP RESTful Service: Provides RESTful APIs based on your IDL and generated stubs. (See /restful documentation for details).
  5. Advanced Features: Timeout, Metadata, and Custom Codecs

    main

    tRPC-Go provides several advanced capabilities:

    • Timeout Control: Mechanisms for managing call timeouts. See Timeout Control Guide.
    • Metadata Transmission: Allows passing fields between clients and servers across the entire call chain. Supported protocols include tRPC, Generic HTTP RPC, and TAF. See Metadata Transmission Guide.
    • Custom Compression: Users can define their own compression and decompression logic. See implementation examples in /codec/compress_gzip.go.
    • Custom Serialization: Users can define custom serialization and deserialization types. See implementation examples in /codec/serialization_json.go.
  6. Explore tRPC-Go service types and features

    main

    tRPC-Go provides a comprehensive set of capabilities for building high-performance microservices. Depending on your requirements, you can implement different communication patterns and management features:

    Service Patterns

    • HTTP RESTful Services: Standard web-based communication.
    • Streaming Services: For long-lived connections and data streams.
    • FlatBuffers Services: For high-performance, low-latency serialization.

    Core Capabilities

    • Reliability: Timeout control, retry hedging, and health checks.
    • Observability: Metrics monitoring, logging management, and RPC tracing (RPCZ).
    • Infrastructure: Metadata transmission (context propagation), reverse proxy support, and graceful restarts.
    • Advanced Features: Attachment (large binary data) transmission and high-performance networking via tnet.
  7. Understand the tRPC-Go Server, Service, and Proto service abstractions

    main

    tRPC-Go uses three primary abstractions to manage network services within a single process:

    • Server: Represents the entire tRPC server instance (typically one per process). A single Server can host multiple Services.
    • Service: Represents a logical service listening on a specific port. It maps one-to-one with entries in your configuration file. Each Service is identified by a unique name used by clients for routing.
    • Proto service: Represents the actual protocol definition (e.g., a service block in a .proto file).

    While a Service usually corresponds to one Proto service, you can map multiple Services to the same Proto service or combine them arbitrarily using the Register method.

    // Server is a tRPC server. One process, one server.
    type Server struct {
        MaxCloseWaitTime time.Duration
    }
    
    // Service is the interface that provides services.
    type Service interface {
        // Register registers a proto service.
        Register(serviceDesc interface{}, serviceImpl interface{}) error
        // Serve starts serving.
        Serve() error
        // Close stops serving.
        Close(chan struct{}) error
    }
  8. Manage interfaces with PB files

    main

    For built-in tRPC services, tRPC streaming services, and generic HTTP RPC services, interfaces are defined using Protocol Buffers (PB) files.

    Best Practice: To ensure transparency for both upstream and downstream consumers, it is recommended to:

    1. Separate PB files from the service code.
    2. Make PB files language-independent.
    3. Manage PB files in an independent central repository for unified version management.
  9. Understand Stream RPC in trpc-go

    main

    trpc-go supports Stream RPC, which allows the client and server to establish a continuous connection. This enables both parties to send and receive data continuously, allowing the server to provide a stream of responses rather than a single response. The framework supports three primary streaming patterns:

    1. ClientStream: The client sends a stream of messages to the server, and the server responds once.
    2. ServerStream: The client sends a single request, and the server responds with a stream of messages.
    3. BidirectionalStream: Both the client and the server can send and receive streams of messages simultaneously over the same connection.
  10. Manage plugin initialization dependencies

    main

    Plugins are generally initialized in a random order. If your plugin depends on another plugin being initialized first, you can implement dependency interfaces.

    There are two types of dependencies:

    1. Strong Dependence (Depender): The required plugin must exist. If it is missing, the framework will panic. Use this for critical dependencies.
    2. Weak Dependence (FlexDepender): The required plugin is preferred. If it exists, it will be initialized before your plugin; if it does not exist, your plugin will still initialize without panicking.

    Dependency strings must follow the format "type-name" (e.g., "selector-polaris").

    Example implementation:

    // Strong dependency on 'selector-a'
    func (p *Plugin) DependsOn() []string {
        return []string{"selector-a"}
    }
    
    // Weak dependency on 'config-b'
    func (p *Plugin) FlexDependsOn() []string {
        return []string{"config-b"}
    }
    // Depender is the interface for "Strong Dependence".
    // If plugin a "Strongly" depends on plugin b, b must exist and
    // a will be initialized after b's initialization.
    type Depender interface {
        // DependsOn returns a list of plugins that are relied upon.
        // The list elements are in the format of "type-name" like [ "selector-polaris" ].
        DependsOn() []string
    }
    
    // FlexDepender is the interface for "Weak Dependence".
    // If plugin a "Weakly" depends on plugin b and b does exist, 
    // a will be initialized after b's initialization.
    type FlexDepender interface {
        FlexDependsOn() []string
    }
  11. How interceptors (filters) work in tRPC-Go

    main

    Interceptors (also called Filters) allow you to inject logic into the request execution flow, similar to an onion model. You can implement both Client and Server interceptors.

    Client Interceptors

    Client interceptors use a next function to allow the request to proceed. Code before next is the 'pre-process' phase, and code after is the 'post-process' phase.

    type ClientFilter func(ctx context.Context, req, rsp interface{}, next ClientHandleFunc) error
    type ClientHandleFunc func(ctx context.Context, req, rsp interface{}) error

    Server Interceptors

    Server interceptors differ slightly as the response (rsp) is returned by the handler rather than passed as an argument.

    type ServerFilter func(ctx context.Context, req interface{}, next ServerHandleFunc) (rsp interface{}, err error)
    type ServerHandleFunc func(ctx context.Context, req interface{}) (rsp interface{}, err error)

    Loading Interceptors

    Interceptors can be added via code using client.WithFilters or server.WithFilters, or globally/specifically via trpc_go.yaml configuration. If both are used, code-defined interceptors execute before configuration-defined ones.

    // Example Client Interceptor implementation
    func MyFilter(ctx context.Context, req, rsp interface{}, next ClientHandleFunc) error {
        // Pre-process
        err := next(ctx, req, rsp)
        // Post-process
        return err
    }
  12. Implement and use Server Filters

    main

    Server filters allow you to intercept incoming RPC requests. Unlike client filters, the response (rsp) is returned as a value from the handler.

    Filter Signature:

    type ServerFilter func(ctx context.Context, req interface{}, next ServerHandleFunc) (rsp interface{}, err error)
    type ServerHandleFunc func(ctx context.Context, req interface{}) (rsp interface{}, err error)

    Usage:

    • Code: Inject filters using server.WithFilters(...).
    • Config: Add filter names to server.filter (global) or server.service[].filter (per-service) in trpc_go.yaml. Filters must be registered via filter.Register beforehand.

    Note: If both code-based and configuration-based filters are present, code-based interceptors execute first.

    type ServerFilter func(ctx context.Context, req interface{}, next ServerHandleFunc) (rsp interface{}, err error)
    type ServerHandleFunc func(ctx context.Context, req interface{}) (rsp interface{}, err error)