Welcome to my GitHub
https://github.com/zq2599/blog_demos
Content: Classification and summary of all original articles and supporting source code, involving Java, Docker, Kubernetes, DevOPS, etc.;
Overview of this article
- This article is the second in the "java version of gRPC combat" series. The previous article "Generate code with proto" the parent project, the dependent library version, and the java code corresponding to helloworld.proto. Today's task is the actual combat gRPC service The development and invocation of, the achieved effect is as shown in the figure below:
- The specific operations of this article are as follows:
- Develop a springboot application named <font color="blue">local-server</font> to provide the gRPC service defined in helloworld.proto;
- Develop a springboot application named <font color="blue">local-client</font> and call the gRPP service provided by <font color="blue">local-server</font>;
- Verify that the gRPC service can be called normally;
Source download
- The complete source code in this actual combat can be downloaded on GitHub. The address and link information are shown in the following table ( https://github.com/zq2599/blog_demos):
name | Link | Remarks |
---|---|---|
Project homepage | https://github.com/zq2599/blog_demos | The project's homepage on GitHub |
git warehouse address (https) | https://github.com/zq2599/blog_demos.git | The warehouse address of the source code of the project, https protocol |
git warehouse address (ssh) | git@github.com:zq2599/blog_demos.git | The warehouse address of the source code of the project, ssh protocol |
- There are multiple folders in this git project. The source code of the "java version of gRPC combat" series is under the <font color="blue">grpc-tutorials</font> folder, as shown in the red box below:
- There are multiple directories under the <font color="blue">grpc-tutorials</font> folder. The code for this article is in <font color="blue">local-server</font> and <font color= In "blue">local-client</font>, the red box as shown in the figure below:
Develop gRPC server
- The first thing to develop is the gRPC server. Review the services and interfaces defined in helloworld.proto in the previous article. As shown below, the service named Simple provides an interface named SayHello. This is our next task, to create a springboot application , The application provides the SayHello interface to other applications to remotely call in the form of gRPC:
service Simple {
// 接口定义
rpc SayHello (HelloRequest) returns (HelloReply) {
}
}
- To develop a common gRPC server application based on the springboot framework, a total of five steps are required, as shown in the figure below. Next, we will develop it in the order of the sequence numbers in the figure below:
- First, create a new module named <font color="">local-server</font> under the parent project <font color="blue">grpc-turtorials</font>, and its build.gradle content is as follows:
// 使用springboot插件
plugins {
id 'org.springframework.boot'
}
dependencies {
implementation 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter'
// 作为gRPC服务提供方,需要用到此库
implementation 'net.devh:grpc-server-spring-boot-starter'
// 依赖自动生成源码的工程
implementation project(':grpc-lib')
}
- This is a springboot application, the configuration file content is as follows:
spring:
application:
name: local-server
# gRPC有关的配置,这里只需要配置服务端口号
grpc:
server:
port: 9898
- Create a new interception class <font color="blue">LogGrpcInterceptor.java</font>, this class will be executed first whenever a gRPC request arrives, here is the method name is printed out in the log, you can make more details about the request response Processing:
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 LogGrpcInterceptor to be executed when a gRPC request arrives, you need to do the corresponding configuration, as shown below, just add an annotation to the configuration of the ordinary 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 startup class is very 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 is the most important service class. The gRPC service is exposed to the outside world. The complete code is as follows. Several points to note are 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 several points in the above GrpcServerService.java that need to be noted:
- Use the <font color="blue">@GrpcService</font> annotation, and then inherit SimpleImplBase, so that you can use grpc-server-spring-boot-starter library to expose sayHello as a gRPC service;
- SimpleImplBase is the java code automatically generated based on proto in the previous article, in the grpc-lib module;
- After the business logic is processed in the sayHello method, call the HelloReply.onNext method to fill in the returned content;
- Call the HelloReply.onCompleted method to indicate the completion of this gRPC service;
- At this point, gRPC server-side coding is complete, let's start client-side development;
Call gRPC
- Create a new module named <font color="">local-client</font> under the parent project <font color="blue">grpc-turtorials</font>, the content of build.gradle is as follows, pay attention to use spingboot Plug-in, dependency 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')
}
- Application configuration file grpc-tutorials/local-client/src/main/resources/application.yml, note that the value of address is the information of the gRPC server. Here, local-server and local-client run on the same computer. Please follow Set your own situation:
server:
port: 8080
spring:
application:
name: local-grpc-client
grpc:
client:
# gRPC配置的名字,GrpcClient注解会用到
local-grpc-server:
# gRPC服务端地址
address: 'static://127.0.0.1:9898'
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext
-Next, we will create the classes shown in the figure below, in order of serial number:
- The first is the interception class LogGrpcInterceptor, which is similar to the server-side interception class, but the implemented interface is different:
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 interception class to work normally, that is, to be executed when a gRPC request is initiated, a new configuration class needs to be added:
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();
}
}
- Startup 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 is the most important service class GrpcClientService. There are several points to note that will be 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 things to pay attention to in the above GrpcClientService class:
- Use <font color="blue">@Service</font> to register GrpcClientService as an ordinary bean instance of spring;
- Decorate SimpleBlockingStub with <font color="blue">@GrpcClient</font>, so that gRPC calls can be initiated through the grpc-client-spring-boot-starter library, and the called server information comes from the name <font color=" red">local-grpc-server</font> configuration;
- SimpleBlockingStub comes from the java code generated according to helloworld.proto in the previous article;
- The SimpleBlockingStub.sayHello method will remotely call the gRPC service of the local-server application;
- In order to verify the success of the gRPC service call, a new web interface is added. The interface will call GrpcClientService.sendMessage, so that we can verify whether the gRPC service call is successful through the browser:
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 complete, start both services to verify whether the gRPC service is normal;
Verify gRPC service
- <font color="blue">local-server</font> and <font color="blue">local-client</font> are ordinary springboot applications, which can be started in IDEA, click on the red box position in the figure below , Select <font color="red">Run'LocalServerApplication'</font> in the pop-up menu to start the local-server:
- After the local-server is started, the console will prompt that the gRPC server has been started and is listening on port 9898, as shown in the following figure:
- After local-client, enter <font color="blue"> http://localhost:8080/?name=Tom </font> in the browser, and you can see that the response is exactly the GrpcServerService from local-server .java:
- The key node information from the web to the gRPC server is as follows:
- You can see the interception log of local-server:
- And the interception log of local-client:
- At this point, the simplest java version of gRPC service release and call verification are passed, and the task of this article is completed. In the next article, we will continue to learn more about the related technologies of java version of gRPC;
You are not lonely, Xinchen is with you all the way
- Java series
- Spring series
- Docker series
- kubernetes series
- database + middleware series
- DevOps series
Welcome to pay attention to the public account: programmer Xin Chen
Search "Programmer Xin Chen" on WeChat, I am Xin Chen, and I look forward to traveling the Java world with you...
https://github.com/zq2599/blog_demos
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。