grpc框架_grpcexample 基于gRPC实现的简单rpc框架

grpc-example 基于gRPC实现的简单rpc框架

基于gRPC实现的简单rpc框架

aec0d36a42d860fa3e0c79a7cb787e83.png

配置

属性配置

pom.xml中配置依赖的gRPC版本号

	1.32.1${project.basedir}/src/main/java-proto${project.basedir}/src/main/java-grpc

Maven依赖

	io.grpcgrpc-netty${grpc.version}io.grpcgrpc-protobuf${grpc.version}io.grpcgrpc-stub${grpc.version}com.alibabafastjson1.2.74ch.qos.logbacklogback-classic1.2.3

Maven插件

	kr.motd.mavenos-maven-plugin1.6.2org.xolstice.maven.pluginsprotobuf-maven-plugin0.6.1
com.google.protobuf:protoc:3.13.0:exe:${os.detected.classifier}grpc-java
io.grpc:protoc-gen-grpc-java:1.32.1:exe:${os.detected.classifier}compilecompile-custom

框架开发

Protobuf文件

创建文件 src/main/proto/crpc_protocol.proto

syntax = "proto3";

option java_package = "com.github.leeyazhou.grpc";
option java_multiple_files = true;
option java_outer_classname = "CrpcProtocol";

message RequestGrpcMessage {
bytes invocation = 1;
}

message ResponseGrpcMessage {
bytes response = 1;
}

service MessageService {
rpc request (RequestGrpcMessage) returns (ResponseGrpcMessage);
}

执行如下命令会生成Protobuf文件对应的Java类

mvn protobuf:compile 
mvn protobuf:compile-custom

公用基础模型类

Invocation.java

package com.github.leeyazhou.grpc.core;

public class Invocation {

private String serviceName;
private String methodName;
private Object[] args;

public String getServiceName() {
return serviceName;
}

public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}

public String getMethodName() {
return methodName;
}

public void setMethodName(String methodName) {
this.methodName = methodName;
}

public Object[] getArgs() {
return args;
}

public void setArgs(Object[] args) {
this.args = args;
}


}

Response.java

package com.github.leeyazhou.grpc.core;

public class Response {

private boolean error;
private Object response;
private Throwable exception;

public boolean isError() {
return error;
}

public void setError(boolean error) {
this.error = error;
}

public Object getResponse() {
return response;
}

public void setResponse(Object response) {
this.response = response;
}

public Throwable getException() {
return exception;
}

public void setException(Throwable exception) {
this.exception = exception;
}

}

Server代码

GrpcServer.java

package com.github.leeyazhou.grpc.core.server;

import java.io.IOException;

import io.grpc.Server;
import io.grpc.ServerBuilder;

public class GrpcServer {
private Server server;
private ServiceHandler serviceHandler;

public GrpcServer(int port) {
this.serviceHandler = new ServiceHandler();
this.server = ServerBuilder.forPort(port)
// 将具体实现的服务添加到gRPC服务中
.addService(new GrpcServerHandler(serviceHandler))

.build();
}

public GrpcServer addService(String name, Object service) {
serviceHandler.addService(name, service);
return this;
}

public void start() throws IOException {
server.start();
}

public void shutdown() {
server.shutdown();
}
}

GrpcServerHandler.java负责处理接收到的请求,并转发给ServiceHandler.java处理,处理完成后响应给请求端。

package com.github.leeyazhou.grpc.core.server;

import com.github.leeyazhou.grpc.MessageServiceGrpc.MessageServiceImplBase;
import com.github.leeyazhou.grpc.core.Invocation;
import com.github.leeyazhou.grpc.core.Response;
import com.github.leeyazhou.grpc.core.serializer.JSONSerializer;
import com.github.leeyazhou.grpc.core.serializer.Serializer;
import com.github.leeyazhou.grpc.RequestGrpcMessage;
import com.github.leeyazhou.grpc.ResponseGrpcMessage;
import com.google.protobuf.ByteString;

import io.grpc.stub.StreamObserver;

public class GrpcServerHandler extends MessageServiceImplBase {
private ServiceHandler serviceHandler;
private Serializer serializer = new JSONSerializer();

public GrpcServerHandler(ServiceHandler serviceHandler) {
this.serviceHandler = serviceHandler;
}

@Override
public void request(RequestGrpcMessage request, StreamObserver responseObserver) {
try {
final Invocation invocation = serializer.deserialize(request.getInvocation().toByteArray(),
Invocation.class);
final Response response = handleRequest(invocation);
byte[] jsonByte = serializer.serialize(response);
ResponseGrpcMessage resp = ResponseGrpcMessage.newBuilder().setResponse(ByteString.copyFrom(jsonByte))
.build();
responseObserver.onNext(resp);
responseObserver.onCompleted();
} catch (Exception e) {
responseObserver.onError(e);
}
}
private Response handleRequest(Invocation invocation) {
Response response = new Response();
response.setError(false);
try {
Object ret = serviceHandler.handle(invocation);
response.setResponse(ret);
} catch (Exception e) {
response.setError(true);
response.setException(e);
}
return response;
}
}

ServiceHandler.java

package com.github.leeyazhou.grpc.core.server;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.github.leeyazhou.grpc.core.Invocation;

public class ServiceHandler {
private Map services = new ConcurrentHashMap<>();
private Map serviceMethods = new ConcurrentHashMap<>();
public Object handle(Invocation invocation) {
Object service = services.get(invocation.getServiceName());
Method serviceMethod = serviceMethods.get(invocation.getServiceName() + "$" + invocation.getMethodName());
try {
return serviceMethod.invoke(service, invocation.getArgs());
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public void addService(String name, Object service) {
this.services.put(name, service);
Method[] methods = service.getClass().getDeclaredMethods();
if (methods != null) {
for (Method method : methods) {
String key = name + "$" + method.getName();
serviceMethods.put(key, method);
}
}
}
}

Client代码

GrpcClient.java

package com.github.leeyazhou.grpc.core.client;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.github.leeyazhou.grpc.MessageServiceGrpc;
import com.github.leeyazhou.grpc.RequestGrpcMessage;
import com.github.leeyazhou.grpc.ResponseGrpcMessage;
import com.github.leeyazhou.grpc.core.Invocation;
import com.github.leeyazhou.grpc.core.Response;
import com.github.leeyazhou.grpc.core.serializer.JSONSerializer;
import com.github.leeyazhou.grpc.core.serializer.Serializer;
import com.google.protobuf.ByteString;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

public class GrpcClient {
private final Serializer serializer = new JSONSerializer();
private final MessageServiceGrpc.MessageServiceBlockingStub blockingStub;
private static final Map clientCache = new ConcurrentHashMap<>();
public static GrpcClient get(String host, int port) {
final String key = host + ":" + port;
return clientCache.compute(key, (k1, v1) -> {
return v1 != null ? v1 : new GrpcClient(host, port);
});
}
public GrpcClient(String host, int port) {
ManagedChannel managedChannel = ManagedChannelBuilder.forAddress(host, port)
// 使用非安全机制传输
.usePlaintext().build();
this.blockingStub = MessageServiceGrpc.newBlockingStub(managedChannel);
}
public Response request(Invocation invocation) {
byte[] jsonBytes = serializer.serialize(invocation);
ByteString byteString = ByteString.copyFrom(jsonBytes);
RequestGrpcMessage greeting = RequestGrpcMessage.newBuilder().setInvocation(byteString).build();
ResponseGrpcMessage resp = blockingStub.request(greeting);
byte[] responseByte = resp.getResponse().toByteArray();
return serializer.deserialize(responseByte, Response.class);
}
}

示例

服务类开发

EchoService.java定义服务接口

public interface EchoService {
String echo(String echo);
}

EchoServiceImpl.java实现服务功能:

public class EchoServiceImpl implements EchoService {
@Override
public String echo(String echo) {
System.err.println("回声: " + echo);
return echo;
}
}

启动服务端

GrpcProvider.java 启动Server服务,并监听端口8000

public class GrpcProvider {

public static void main(String[] args) throws Exception {
new GrpcProvider().start();
Thread.sleep(Integer.MAX_VALUE);
}

public void start() throws Exception {
int port = 8000;
GrpcServer server = new GrpcServer(port);
server.addService(EchoService.class.getSimpleName(), new EchoServiceImpl());
server.start();
}
}

客户端调用服务

public class GrpcConsumer {

public static void main(String[] args) {
new GrpcConsumer().start();
}

public void start() {
String host = "127.0.0.1";
int port = 8000;
GrpcClient client = GrpcClient.get(host, port);

Invocation invocation = new Invocation();
invocation.setServiceName("EchoService");
invocation.setMethodName("echo");
invocation.setArgs(new String[] { "测试GRPC" });
Response response = client.request(invocation);
System.out.println(response.getResponse());
}
}

其他

源码地址github.com/leeyazhou/grpc-example

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值