Welcome to my GitHub


Content: all the original article classification summary and supporting source code, involving Java, Docker, Kubernetes, DevOps and so on;

This paper gives an overview of

  • This article is the “Java version of GRPC in action” series of the second, the previous “with Proto generation code” will be the parent project, dependent library version, HelloWorld. Proto corresponding Java code are ready, today’s task is the actual GRPC service development and call, the effect of the implementation is as follows:

  • The specific operation of this article is as follows:
  • local-server SpringBoot application provides GRPC service defined in helloworld.proto;
  • local-server GRPP service; local-server GRPP service;
  • Verify that GRPC service can be normally invoked;

Download the source code

  • This may be downloaded in making to combat the full source code, address and link information shown in the following table (https://github.com/zq2599/blo… :
The name of the link note
Project home page https://github.com/zq2599/blo… The project’s home page on GitHub
Git repository address (HTTPS) https://github.com/zq2599/blo… The project source warehouse address, HTTPS protocol
Git repository address (SSH) [email protected]:zq2599/blog_demos.git The project source warehouse address, SSH protocol
  • “grpc-tutorials”

  • GRPC-Tutorials local-server and local-client

Develop GRPC server

  • The first thing we need to develop is the GRPC server. Recall the services and interfaces defined in HelloWorld. proto in the previous article. As shown below, a service named Simple provides an interface called SayHello. This should provide the SayHello interface to other applications in GRPC mode for remote invocation:
Service Simple {// RPC SayHello (HelloRequest) Returns (HelloReply) {}}
  • To develop a common GRPC server application based on Spring Boot framework, a total of five steps are required, as shown in the figure below. Next, we will develop it in the order of the number in the figure below:

  • First is in the parent project < font color = “blue” > GRPC – turtorials < / font > below new called < font color = “” > local – server < / font > module, its build. Gradle content is as follows:
SpringBoot {id 'org.springframework.boot'} dependencies {implementation 'org.projectLoombok: loombok'} Implementation 'org. Springframework. The boot: spring - the boot - starter' / / as a gRPC service provider, Devh: GRPC-server-spring-boot-starter '// implementation project(': GRPC-lib ')} implementation 'net.devh: GRPC-server-spring-boot-starter'
  • This is a SpringBoot application with the following configuration file:
Spring: Application: Name: Local-Server # GRPC: Server: Port: 9898 (GRPC: Server: Port: 9898
  • loggrpcinterceptor.java This class will be intercepted when a GRPC request comes in.
package com.bolingcavalry.grpctutorials; import io.grpc.Metadata; import io.grpc.ServerCall; import io.grpc.ServerCallHandler; import io.grpc.ServerInterceptor; import lombok.extern.slf4j.Slf4j; @Slf4j public class LogGrpcInterceptor implements ServerInterceptor { @Override public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) { log.info(serverCall.getMethodDescriptor().getFullMethodName()); return serverCallHandler.startCall(serverCall, metadata); }}
  • In order for the LogGRPCInterceptor to be executed when a GRPC request arrives, you need to configure it as follows. Add an annotation to the configuration of a normal bean:
package com.bolingcavalry.grpctutorials; import io.grpc.ServerInterceptor; import net.devh.boot.grpc.server.interceptor.GrpcGlobalServerInterceptor; import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) public class GlobalInterceptorConfiguration { @GrpcGlobalServerInterceptor ServerInterceptor logServerInterceptor() { return new LogGrpcInterceptor(); }}
  • The application launch class is simple:
package com.bolingcavalry.grpctutorials; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class LocalServerApplication { public static void main(String[] args) { SpringApplication.run(LocalServerApplication.class, args); }}
  • Next comes the most important Service class, where the GRPC service is exposed to the outside world. The full code is as follows, with a few caveat points mentioned later:
package com.bolingcavalry.grpctutorials; import com.bolingcavalry.grpctutorials.lib.HelloReply; import com.bolingcavalry.grpctutorials.lib.SimpleGrpc; import net.devh.boot.grpc.server.service.GrpcService; import java.util.Date; @GrpcService public class GrpcServerService extends SimpleGrpc.SimpleImplBase { @Override public void sayHello(com.bolingcavalry.grpctutorials.lib.HelloRequest request, io.grpc.stub.StreamObserver<com.bolingcavalry.grpctutorials.lib.HelloReply> responseObserver) { HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + request.getName() + ", " + new Date()).build(); responseObserver.onNext(reply); responseObserver.onCompleted(); }}
  • There are a few things to note in the above GRPCServerService.java:
  • Is the use of < font color = “blue” > @ GrpcService < / font > annotations, inherit SimpleImplBase again, so you can use GRPC – server – spring – the boot – starter library will serve for GRPC sayHello exposure;
  • SimpleImplBase is the Java code automatically generated from the proto above, in the GRPC-lib module;
  • After processing the business logic in the sayHello method, call the HelloReply. OnNext method to fill in the returned content;
  • Call the HelloReply.onCompleted method to indicate that the GRPC service is complete;
  • At this point, GRPC server coding is complete, let’s start the client development;

Call gRPC

  • grpc-turtorials local-client Note that you need to use the spingboot plugin and rely on the grpc-client-spring-boot-starter library:
plugins {
    id 'org.springframework.boot'

dependencies {
    implementation 'org.projectlombok:lombok'
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'net.devh:grpc-client-spring-boot-starter'
    implementation project(':grpc-lib')
  • The application configuration file GRPC – tutorials/local client/SRC/main/resources/application. Yml, pay attention to the value is the GRPC information from the server address, Here, local-server and local-client are running on the same computer, so please set it according to your own situation:
server: port: 8080 spring: application: name: local-grpc-client grpc: client: # GRPC server address: 'static://' enableKeepAlive: true keepAliveWithoutCalls: true negotiationType: plaintext

– Next create the classes shown in the following image, in ordinal order:

  • The first interceptor class is LogGRPCInterceptor, which is similar to the server interceptor class but implements a different interface:
package com.bolingcavalry.grpctutorials; import io.grpc.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LogGrpcInterceptor implements ClientInterceptor { private static final Logger log = LoggerFactory.getLogger(LogGrpcInterceptor.class); @Override public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) { log.info(method.getFullMethodName()); return next.newCall(method, callOptions); }}
  • In order for the interceptor class to work properly, that is, to be executed when a GRPC request is made, a new configuration class is required:
package com.bolingcavalry.grpctutorials; import io.grpc.ClientInterceptor; import net.devh.boot.grpc.client.interceptor.GrpcGlobalClientInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; @Order(Ordered.LOWEST_PRECEDENCE) @Configuration(proxyBeanMethods = false) public class GlobalClientInterceptorConfiguration { @GrpcGlobalClientInterceptor ClientInterceptor logClientInterceptor() { return new LogGrpcInterceptor(); }}
  • Start the class:
package com.bolingcavalry.grpctutorials; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class LocalGrpcClientApplication { public static void main(String[] args) { SpringApplication.run(LocalGrpcClientApplication.class, args); }}
  • Next comes the most important service class, GRPCClientService, with a few caveat points mentioned later:
package com.bolingcavalry.grpctutorials; import com.bolingcavalry.grpctutorials.lib.HelloReply; import com.bolingcavalry.grpctutorials.lib.HelloRequest; import com.bolingcavalry.grpctutorials.lib.SimpleGrpc; import io.grpc.StatusRuntimeException; import net.devh.boot.grpc.client.inject.GrpcClient; import org.springframework.stereotype.Service; @Service public class GrpcClientService { @GrpcClient("local-grpc-server") private SimpleGrpc.SimpleBlockingStub simpleStub; public String sendMessage(final String name) { try { final HelloReply response = this.simpleStub.sayHello(HelloRequest.newBuilder().setName(name).build()); return response.getMessage(); } catch (final StatusRuntimeException e) { return "FAILED with " + e.getStatus().getCode().name(); }}}
  • There are a few caveats to the above GRPCClientService class:
  • @service register grpcclientService as a normal Spring bean instance;
  • @grpcclient to make a GRPC call from the grpc-client-spring-boot-starter library. local-grpc-server >
  • SimpleBlockingStub comes from the Java code generated from HelloWorld.proto in the previous section;
  • SimpleBlockingStub. SayHello method can remote call local – server application gRPC service;
  • In order to verify the gRPC service call success, adding a web interface, the interface internal calls GrpcClientService. SendMessage, so let’s through the browser can verify whether gRPC service call succeeds the:
package com.bolingcavalry.grpctutorials; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class GrpcClientController { @Autowired private GrpcClientService grpcClientService; @RequestMapping("/") public String printMessage(@RequestParam(defaultValue = "will") String name) { return grpcClientService.sendMessage(name); }}
  • After the encoding is completed, both services will be started to verify whether the GRPC service is normal;

Verify the GRPC service

  1. local-serverlocal-client > and >local-client > are common springboot applications. Run ‘localServerApplication ‘ to start local-server:

  1. When local-server is started, the console will tell you that GRPC server has started and is listening on port 9898, as shown in the figure below:

  1. After local-client, type in the browser http://localhost:8080/? Name =Tom, you can see that the content of the response is from the local-server GRPCServerService.java:

  1. The key node information from the Web side to the GRPC server side is as follows:

  • You can see the local-server intercept log:

  • There is also local-client interception logs:

  • At this point, the simplest Java version of GRPC service release and call verification passed, the task of this article is completed, the next article, we will continue to in-depth study of Java version of GRPC related technologies;

You are not alone, Xin Chen original all the way

  1. Java series
  2. Spring series
  3. The Docker series
  4. Kubernetes series
  5. Database + middleware series
  6. The conversation series

Welcome to pay attention to the public number: programmer Xin Chen

WeChat search “programmer Xin Chen”, I am Xin Chen, looking forward to traveling with you in the JAVA world…