Pure dry goods: GRPC of Microservice Development Manual

1 Introduction

In the GRPC framework, the client can directly call server methods located on different machines like local objects, so we can create some distributed application services very conveniently.

On the server side, we implement the defined services and methods that can be called remotely, and run a gRPC server to process client requests; on the client side, gRPC implements a stub (which can be simply understood as a client), which provides follow-up The same method on the server side.

Pure dry goods: GRPC of Microservice Development Manual

 

gRPC uses protocol buffers as the interface description language (IDL) and the underlying information exchange format. Generally, it is recommended to use proto3 because it can support more languages ​​and reduce some compatibility issues. Since gRPC involves several important technical points http2 and protobuf, it is these technical points that make gRPC widely used, and here are also some of these technical points.

1.1 http2

HTTP/2 is the latest HTTP protocol, which improves the efficiency of resource access. Through this science essay, you can understand the concept and advantages of the HTTP/2 protocol.

HTTP/2 is also known as HTTP 2.0. Compared with HTTP 1.1, it adds multiplexing, compression of HTTP headers, request priority, server push and other features, which solves the problems that have always existed in HTTP 1.1 and optimizes requests. Performance is compatible with the semantics of HTTP 1.1.

In 2015, HTTP/2 was released. HTTP/2 is a replacement for the current HTTP protocol (HTTP/1.1), but it is not a rewrite. The HTTP method, status code, and semantics are the same as HTTP/1.1. Compared with HTTP/1.1, HTTP/2 can be said to greatly improve the performance of web pages. Only by upgrading to this protocol can reduce a lot of performance optimization work that needs to be done before. HTTP/2 is based on SPDY and focuses on performance. One of the biggest goals is to use only one connection between the user and the website.

New features of HTTP/2

1.1.1 Binary transmission

There are two main reasons for the substantial reduction in the amount of data transmitted by HTTP/2: binary transmission and header compression. Let's first introduce binary transmission. HTTP/2 uses binary format to transmit data instead of the plain text message in HTTP/1.1. The binary protocol is more efficient to parse. HTTP/2 divides the request and response data into smaller frames, and they use binary encoding. The core of all performance enhancements of HTTP/2 lies in the new binary framing layer, which defines how to encapsulate HTTP messages and transmit them between the client and the server.

1.1.2 Header compression

The HTTP/1.1 header carries a lot of information, and it must be sent repeatedly every time. HTTP/2 does not use the traditional compression algorithm, but develops a special "HPACK" algorithm, and establishes a "dictionary" on both the client and the server. ", use the index number to represent the repeated string, and also use Huffman coding to compress integers and strings, which can reach a high compression rate of 50% to 90%.

1.1.3 Multiplexing

Multiplexing allows multiple request-response messages to be initiated through a single HTTP/2 connection at the same time, which solves the problem of browsers limiting the number of requests under the same domain name, and it is also easier to achieve full-speed transmission.

1.1.4 Server Push

HTTP2 has also changed the traditional "request-response" mode of work to a certain extent. The server no longer responds to requests completely passively, and can also create a new "stream" to actively send messages to the client. For example, when the browser just requests HTML, it sends the JS and CSS files that may be used to the client in advance to reduce the waiting delay. This is called "Server Push" (also called Cache push).

1.2 Protobuf

Protocol buffers is a language-neutral, platform-independent, and extensible serialized data format that can be used for communication protocols, data storage, etc.

Protocol buffers are flexible and efficient in terms of serializing data. Compared to XML, Protocol buffers are smaller, faster, and simpler. Once the data structure of the data to be processed is defined, the code generation tool of Protocol buffers can be used to generate the relevant code. You can even update the data structure without redeploying the program. You only need to use Protobuf to describe the data structure once, and you can easily read and write your structured data in a variety of different languages ​​or from a variety of different data streams.

Protocol buffers are very suitable for data storage or RPC data exchange format. It can be used for language-independent, platform-independent, and extensible serialized structured data formats in communication protocols, data storage and other fields.

1.2.1 Advantages

1. Good performance/high efficiency

Time cost: The cost of XML formatting (serialization) is good; but the cost of XML parsing (deserialization) is not flattering. But protobuf is optimized in this respect. The time overhead of serialization and deserialization can be reduced.

Space overhead: also reduced a lot

2. There is a code generation mechanism

For example, if you write something similar to the structure


 message testA  
{  
    required int32 m_testA = 1;  
}  

Like writing a structure like this, protobuf can automatically generate its .h file and point .cpp file. protobuf encapsulates the operation of the structure testA into a class.

3. Support backward compatibility and forward compatibility

When the client and server use a protocol at the same time, when the client adds a byte to the protocol, it will not affect the use of the client

4. Support multiple programming languages

The source code officially released by Google contains three languages: c++, java and Python

1.2.2 Disadvantages

1. The binary format leads to poor readability

To improve performance, protobuf uses a binary format for encoding. This directly leads to poor readability. This directly affects the efficiency of development and testing. Of course, under normal circumstances, protobuf is very reliable and will not cause major problems.

2. Lack of self-description

Generally speaking, XML is self-describing, while the protobuf format is not. Give you a binary format of the protocol content, it won’t work if you don’t match the structure you wrote.

3, passability difference

Although protobuf supports serialization and deserialization of a large number of languages, it is still not a cross-platform and language transmission standard. In multi-platform messaging, the compatibility with other projects is not very good, and corresponding adaptation work needs to be done. Compared to json and XML, versatility is still not so good.

1.2.3 Comparison with other serialization methods

protobuf handles integer types very fast. If you need to understand the principle, you can check the efficient data compression encoding method Protobuf

As for the comparison with other serialization methods and usage scenarios, please refer to the following article Is Protobuf 5 times faster than JSON? Use code to break the myth of pb performance

Comprehensive evaluation: Is Protobuf performance 5 times faster than JSON?

2 grpc four modes

1. Simple mode: Simple mode just uses parameters and return values ​​as a way to transfer data between the server and the client, the simplest.

2. Client streaming mode: that is, the data sent from the client to the server uses the stream, that is, the server-side parameter is the stream type, but the data is returned to the client after the server responds, and the stream send method is also used. Generally, the code on the server side needs to recv first and then send, while the client side is the opposite. But in the following two-way mode, go's coroutine collaboration can be used.

3. Server-side streaming mode: The streaming mode is used when the server-side returns results, that is, the incoming data is passed in through parameters. But using the send method when sending data to the client is similar to the way the client returns data.

4. Two-way mode: If the client does not use the coroutine, the sending must be before the receiving. If you use a coroutine, there is no order of sending and receiving. In order to ensure the synchronization of the coroutine, you can use mutexes to constrain.

If you want to know the detailed demo, you can check the Chinese version of gRPC official document

3 Integrate springcloud

There are two solutions for integrating grpc here,

3.1 Implement public protobuf, remotely call through java grpc

This solution does not need to write protobuf, you can directly provide java api like dubbo to achieve rpc call. For details, please refer to the demo ttps://github.com/ChinaSilence/spring-boot-starter-grpc on github

Pure dry goods: GRPC of Microservice Development Manual

 

  • Facade : Independent Maven module, which depends on spring-boot-starter-grpc, and the methods that need to be called remotely are all defined in this module, which can be in the form of interface or abstract class
  • server : The service provider depends on the facade module and needs to implement the interface defined by the facade module or the abstract method of the abstract class
  • client : The service caller, which depends on the facade module, can be called directly when used

Analysis of advantages and disadvantages

advantage:

  • No need to write probuff files, define the interface in the form of java api
  • Not dependent on eureka, perfect for k8s

Disadvantages:

  • Only supports java, if you want to support heterogeneous languages, you need to use springcloudsidecar or manually register to eureka
  • eureka has limited support and does not support load balancing

3.2 Use protobuf to define the interface every time (integrate net.devh.grpc)

There is still a lot of content here. For details, please refer to my blog springcloud integration grpc (1) This method of integration requires writing proto interface files and automatically generating code each time, and the client and server need to assemble additional parameters.

However, the advantage is that there are detailed interface specifications (protobuf) and can support heterogeneous language calls.

4 Service discovery and load balancing

The gRPC open source component officially does not directly provide the implementation of service registration and discovery functions, but its design documents have provided implementation ideas, and have provided naming resolution and load balancing interfaces for expansion in gRPC code APIs in different languages.

Its basic realization principle:

After the service is started, the gRPC client sends a name resolution request to the name server. The name will be resolved to one or more IP addresses. Each IP address indicates whether it is a server address or a load balancer address, and indicates which client load balancing strategy to use Or service configuration.

The client instantiates the load balancing strategy. If the address returned by the resolution is the load balancer address, the client will use the grpclb strategy, otherwise the client will use the load balancing strategy requested by the service configuration.

The load balancing strategy creates a sub-channel for each server address.

When there is an rpc request, the load balancing strategy determines which subchannel, that is, the grpc server, will receive the request. When the available server is empty, the client's request will be blocked.

According to the design ideas provided by the gRPC official, based on the in-process LB scheme (the second case, Ali’s open source service framework Dubbo also uses a similar mechanism), combined with distributed and consistent components (such as Zookeeper, Consul, Etcd), gRPC services can be found Find feasible solutions for load balancing. Next, take the GO language as an example to briefly introduce the key code implementation based on Etcd3:

4.1 dubbo

As described above, dubbo supports grpc, the solution is similar to the solution proposed in 3.1 of this article, but Ali provides a complete set of microservice system, including the registry nacas, dubbo, sentinel all support grpc

4.2 springcloud

This solution is also similar to chapter 3.2. The above is the integration of net.devh.grpc. The latest version of the plug-in also supports springcloud family bucket. For details, please refer to github: https://github.com/yidongnan/grpc-spring-boot- starter. If it is a heterogeneous language, you need to integrate the sidecar in springcloud to realize service discovery. This is only to support Java to call other heterogeneous languages. If you need other languages ​​to also support mutual calls, you need to correspond to the language according to the official open source component. To implement the corresponding components

4.3 istio

What is Istio: Istio is an open source project jointly developed by Google/IBM/Lyft. The first release 0.1.0 was released in May 2017. The official definition is:

Istio: An open platform to connect, manage and protect microservices.

According to the definition given in the isito documentation:

Istio provides a simple way to build a network of deployed services, with load balancing, service-to-service authentication, monitoring and other functions without the need to change any service code.

Simply put, with Istio, your services no longer need any microservice development frameworks (typically Spring Cloud, Dubbo), and you no longer need to implement various complex service governance functions yourself (many are Spring Cloud and Dubbo can't provide it, you need to do it yourself). As long as the service client and server can perform simple direct network access, they can obtain a series of complete functions by entrusting the network layer to Istio. Key features of Istio:

  • Automatic zone-aware load balancing and failover for HTTP/1.1, HTTP/2, gRPC and TCP traffic.
  • Through rich routing rules, fault tolerance and fault injection, fine-grained control of traffic behavior.
  • Pluggable policy layer and configuration API supporting access control, rate limiting and quota.
  • Automatic measurement, log and tracking of all traffic in the cluster, including cluster entry and exit.
  • Secure service-to-service authentication, with strong identity between services in the cluster.

It can be roughly understood as: Istio = microservice framework + service governance The following is the official topology of Istio:

Pure dry goods: GRPC of Microservice Development Manual

 

The premise here is that k8s is used, and istio can be seamlessly integrated in k8s. I will not describe the specific steps in detail here. For details, please refer to the link below to use Istio and Envoy to practice service mesh gRPC measurement

5 grpc interceptor

grpc comes with authentication, but sometimes you need to do some operations before or after the call, such as recording monitoring information, or transparently transmitting headers, etc. At this time, you need to use grpc interceptor, here only java language Let's talk about interceptor usage.

5.1 server interceptor

public class MyServerInsterceptor implements ServerInterceptor{


    @Override
    public <reqt, respt> ServerCall.Listener<reqt> interceptCall(ServerCall<reqt, respt> call,
                                                                 Metadata headers, ServerCallHandler<reqt, respt> next) {
      
        return next.startCall(call,headers);
    }
}

Here you can set the global interceptor

@Configuration
public class GrpcOpenConfig {

    //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow server-side interceptors to be registered with all
    //server stubs, we are just taking advantage of that to install the server-side gRPC tracer.
    @Bean
    ServerInterceptor grpcServerInterceptor() {
        return new MyServerInterceptor();
    }

    @Bean
    public GlobalServerInterceptorConfigurer globalInterceptorConfigurerAdapter(ServerInterceptor grpcServerInterceptor) {
        return registry -> registry.addServerInterceptors(grpcServerInterceptor);
    }
}

At the same time, if you integrate grpc-spring-boot-starter, you can also use @GrpcGlobalInterceptor to add a global interceptor, hi need to add this annotation to the class name

5.2 client interceptor

public class MyClientInterceptor implements ClientInterceptor {


    Metadata.Key<string> token = Metadata.Key.of("token", Metadata.ASCII_STRING_MARSHALLER);

    @Override
    public <reqt, respt> ClientCall<reqt, respt> interceptCall(MethodDescriptor<reqt, respt> method,
            CallOptions callOptions, Channel next) {
        return new SimpleForwardingClientCall<reqt, respt>(next.newCall(method, callOptions)) {

            @Override
            public void start(Listener<respt> responseListener, Metadata headers) {
                //此处为你登录后获得的token的值
                headers.put(token, "A2D05E5ED2414B1F8C6AEB19F40EF77C");
                super.start(new SimpleForwardingClientCallListener<respt>(responseListener) {
                    @Override
                    public void onHeaders(Metadata headers) {
                        super.onHeaders(headers);
                    }
                }, headers);
            }
        };
    }
}


Here you can set the global interceptor

@Order(Ordered.LOWEST_PRECEDENCE)
@Configuration
@Slf4j
public class GrpcOpenTracingConfig {
    //We also create a client-side interceptor and put that in the context, this interceptor can then be injected into gRPC clients and
    //then applied to the managed channel.
    @Bean
    ClientInterceptor grpcClientInterceptor() {
        return new MyclientInterceptor();
    }

    @Bean
    public GlobalClientInterceptorConfigurer globalInterceptorConfigurerAdapter(ClientInterceptor grpcClientInterceptor) {
        return registry -> registry.addClientInterceptors(grpcClientInterceptor);
    }

}

At the same time, if you integrate grpc-spring-boot-starter, you can also use @GrpcGlobalInterceptor to add a global interceptor, hi need to add this annotation to the class name

6 Full link of grpc monitoring

For full link monitoring, please refer to my full link series blog

Microservice full link tracking: grpc integrated zipkin

Microservice full link tracking: jaeger integrates grpc

Microservice full link tracking: jaeger integrates istio, and is compatible with uber-trace-id and b3

7 Prometheus for grpc monitoring

If you integrate grpc-spring-boot-starter, you only need to visit http://service domain name/actuator/prometheus, you can see grpc related monitoring indicators

Pure dry goods: GRPC of Microservice Development Manual

 

Pure dry goods: GRPC of Microservice Development Manual

 

Pure dry goods: GRPC of Microservice Development Manual

 

If grafana is integrated, you can see the following effects:

Pure dry goods: GRPC of Microservice Development Manual

 

Pure dry goods: GRPC of Microservice Development Manual

Guess you like

Origin blog.csdn.net/weixin_48612224/article/details/109212770