gRPCã使ã£ã¦ã¿ã
gRPC for Javaãããã£ã¦ã¿ãã®ã§ãä½¿ãæ¹ã®ã¾ã¨ã
gRPCã¨ã¯
GoogleãéçºãããRPC(Remote Procedure Call)ãå®è£ ããããã®ãã¬ã¼ã ã¯ã¼ã¯ã§ãã
Protocol Bufferãå©ç¨ããé«ééä¿¡ã.protoã«ããã¤ã³ã¿ã¼ãã§ã¼ã¹å®ç¾©ãJavaãNode.jsãªã©ãå«ãã夿°ã®ããã°ã©ãã³ã°è¨èªã«å¯¾å¿ãã¦ãããã¨ãªã©ãç¹å¾´ã
ä»çµã¿
大éæãªæµãã¯ã以ä¸ã®éãã§ãã
- .protoå½¢å¼ã§ã¤ã³ã¿ã¼ãã§ã¼ã¹å®ç¾©ãè¨è¿°
- .protoãããå©ç¨ãããããã°ã©ãã³ã°è¨èªç¨ã®ããµã¼ãã¼ã®ã¹ã±ã«ãã³å®è£ ã¨ã¯ã©ã¤ã¢ã³ãã¹ã¿ããçæ
- ã§çæããããã®ããã¼ã¹ã«ãµã¼ãã¼ãã¯ã©ã¤ã¢ã³ããå®è£
ã¯ã©ã¤ã¢ã³ãã§ã¹ã¿ãã®ã¡ã½ãããå¼ã³åºãã¨ãéä¿¡ã¯ãã¬ã¼ã ã¯ã¼ã¯ããããªã«ãã£ã¦ããã¾ãã

Javaã§å®éã«ãã£ã¦ã¿ã
Javaã§å®éã«ãã£ã¦ã¿ã¾ããã ï¼ã³ã¼ãã¯ãã¡ãï¼
.protoã®ä½æ
以ä¸ã®æ§ãªæãã§ã.protoã使ãã¾ãã
syntax = "proto3"; option java_multiple_files = true; option java_package = "com.oracle.jdt2016.hackathon.hr"; option java_outer_classname = "HrProto"; option objc_class_prefix = "HR"; import "google/protobuf/empty.proto"; package hr; service Hr { rpc Employees(google.protobuf.Empty) returns (EmployeesReply) {} } message EmployeesReply { repeated Employee employee = 1; } message Employee { float commissionPct = 1; int64 departmentId = 2; string email = 3; int64 employeeId = 4; string firstName = 5; int64 hireDate = 6; string jobId = 7; string lastName = 8; int64 managerId = 9; string phoneNumber = 10; float salary = 11; }
ä»åã¯ããµã¼ãã¼ã«ããããã¼ã®å¾æ¥å¡ãã¼ã¿ãåå¾ããã¤ã³ã¿ã¼ãã§ã¼ã¹ãä½ãã¾ããã弿°ã¯ç¡ããè¿ãå¤ã¯å¾æ¥å¡ãã¼ã¿ã®é åã§ãã
"service"ã§å§ã¾ãé¨åãã¡ã½ããã®å®ç¾©ã§ãã弿°ãªããå®ç¾©ããã¨ãã¯ã"google/protobuf/empty.proto"ãã¤ã³ãã¼ããã¦âgoogle.protobuf.Emptyâã弿°ã«æå®ãã¾ãã
è¿ãå¤ã®åã¯âmessageâã§å§ã¾ãé¨åã§å®ç¾©ãã¦ãã¾ããè¦ç´ ã«é
åãå«ã¿ããå ´åãârepeated"ã¨è¨è¿°ããã¨ãå¾ç¶ããåã®é
åã ã¨ãã宣è¨ã«ãªãã¾ãã
ä»åã¯ãã¯ã©ã¤ã¢ã³ãããµã¼ãã¼ã¨ãåæçã«å¦çãè¡ãªãã¤ã³ã¿ã¼ãã§ã¼ã¹ãã¨ãã¦å®ç¾©ãã¦ãã¾ãããéåæã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã使ãã¾ãã
詳細ã¯å
¬å¼ã®ããã¥ã¡ã³ããåç
§ãã¦ä¸ããã
ãµã¼ãã¼ã¹ã±ã«ãã³ãã¯ã©ã¤ã¢ã³ãã¹ã¿ãã®çæ
ä»åã¯Gradleã使ãã¾ãï¼Mavenã§ããããããã§ãï¼ã
ã¾ããIDEã使ããªããã¦é©å½ãªGradleããã¸ã§ã¯ãã使ãã¦ããã¾ãã
次ã«ãsrc/main/protoãã©ã«ãã使ãã.protoãã¡ã¤ã«ãé
ç½®ãã¾ãã
ç¶ãã¦ãbuild.gradleãç·¨éãã¾ãã ä»å使ã£ãbuild.gradleï¼é¢é£ããé¨åãæç²ï¼ã¯ã以ä¸ã®éãã§ãã
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'com.google.protobuf'
â¦
def grpcVersion = '1.0.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
â¦
compile "io.grpc:grpc-netty:${grpcVersion}"
compile "io.grpc:grpc-protobuf:${grpcVersion}"
compile "io.grpc:grpc-stub:${grpcVersion}"
}
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.0.0'
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
}
}
generateProtoTasks {
all()*.plugins {
grpc {
// To generate deprecated interfaces and static bindService method,
// turn the enable_deprecated option to true below:
option 'enable_deprecated=false'
}
}
}
}
以ä¸ã®ã³ãã³ããå®è¡ããã¨ãbuild/generatedé
ä¸ã«ç®çã®ã³ã¼ããçæããã¾ãã
> gradle generateProto
çæãããã³ã¼ãã®ããã±ã¼ã¸åã«ã¯ã.protoã®"option java_package"ã§å®£è¨ãããã®ã«ãªãã¾ãã
ãµã¼ãã¼ã®å®è£
ãµã¼ãã¼ã®å®è£ ã¯ä»¥ä¸ã®éãã§ã(ã»ã¨ãã©å ¬å¼ã®HelloWorldãµã³ãã«ããæã£ã¦ãã¦ãã¾ãï¼ã
//importã¯çç¥ public class HrServer { /* The port on which the server should run */ private int port = 50051; private Server server; private void start() throws IOException { server = ServerBuilder.forPort(port).addService(new HrImpl()) .build().start(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { System.err.println("*** shutting down gRPC server since JVM is shutting down"); HrServer.this.stop(); System.err.println("*** server shut down"); } }); } private void stop() { if (server != null) { server.shutdown(); } } /** * Await termination on the main thread since the grpc library uses daemon threads. */ private void blockUntilShutdown() throws InterruptedException { if (server != null) { server.awaitTermination(); } } /** * Main launches the server from the command line. */ public static void main(String[] args) throws IOException, InterruptedException { final HrServer server = new HrServer(); server.start(); server.blockUntilShutdown(); } private class HrImpl extends HrGrpc.HrImplBase { @Override public void employees( Empty request, StreamObserver<EmployeesReply> responseObserver) { // DBãã徿¥å¡ãã¼ã¿ãåå¾ãã EntityManager em = EntityManagerUtils.getEntityManager(); @SuppressWarnings("unchecked") List<Employee> entities = em.createNamedQuery("Employee.findAll").getResultList(); em.close(); // è¿ãå¤ã使 EmployeesReply.Builder replyBuilder = EmployeesReply.newBuilder(); for (Employee entity : entities) { com.oracle.jdt2016.hackathon.hr.Employee employee = com.oracle.jdt2016.hackathon.hr.Employee.newBuilder() .setCommissionPct(entity.getCommissionPct()) .setDepartmentId(entity.getDepartmentId()) .setEmail(entity.getEmail()) .setEmployeeId(entity.getEmployeeId()) .setFirstName(entity.getFirstName()) .setHireDate(entity.getHireDate().getTime()) .setJobId(entity.getJobId()) .setLastName(entity.getLastName()) .setManagerId(entity.getManagerId()) .setPhoneNumber(entity.getPhoneNumber()) .setSalary(entity.getSalary()) .build(); replyBuilder.addEmployee(employee); } responseObserver.onNext(replyBuilder.build()); responseObserver.onCompleted(); } } }
ãµã¼ãã¼ã®èµ·åã¯ServerBuilderããServerã使âstartã¨ããæµãã
ãã¸ãã¯ã¯ã"HrGrpc.HrImplBase"ãextendsãã¦ãEmployeesã¡ã½ããããªã¼ãã¼ã©ã¤ããã¦è¨è¿°ãã¾ãã
ã¯ã©ã¤ã¢ã³ãã«è¿å´ãããã¼ã¿ã.protoãã¡ã¤ã«ãå ã«çæãããã¯ã©ã¹ã使ãã¾ããä»åã¯EmployeesReplyãEmployeeã¨ããã¯ã©ã¹ãä½ããã¦ãã¾ãã ãªã¼ãã¼ã©ã¤ãããã¡ã½ããã®ä¸ã§ãããã®ãªãã¸ã§ã¯ããä½ã£ã¦ãresponseObsererã«æ¸¡ãã¦ä¸ããã°ããããã§ãã
ã¯ã©ã¤ã¢ã³ãã®å®è£
ã¯ã©ã¤ã¢ã³ãã®å®è£ ã¯ä»¥ä¸ã®éãã§ã(ãã¡ããå ¬å¼ã®HelloWorldãµã³ãã«ããã¼ã¹ã«ãã¦ãã¾ãï¼ã
//importã¯çç¥ public class HrClient { private final ManagedChannel channel; private final HrGrpc.HrBlockingStub blockingStub; public HrClient(String host, int port) { channel = ManagedChannelBuilder.forAddress(host, port) .usePlaintext(true).build(); blockingStub = HrGrpc.newBlockingStub(channel); } public void shutdown() throws InterruptedException { channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); } public void getEmployees() { EmployeesReply response; long begin = System.currentTimeMillis(); try { response = blockingStub.employees(Empty.newBuilder().build()); } catch (StatusRuntimeException e) { System.out.println("RPC failed"); return; } System.out.println("Employees: " + response.getEmployeeCount()); } public static void main(String[] args) throws Exception { HrClient client = new HrClient("localhost", 50051); try { client.getEmployees(); } finally { client.shutdown(); } } }
ã¹ã¿ããªãã¸ã§ã¯ãããããã¼ã«ã«ã®ã¡ã½ãããå¼ã³åºãæè¦ã§employeeãå®è¡ã§ãã¾ãã
gRPCã¯ãProtocol Bufferã使ã£ã¦é«éãªéä¿¡ãå®ç¾ãã¦ããããã§ãããã¢ããªã±ã¼ã·ã§ã³ãå®è£ ããåã«ã¯ããããã³ã«ä¾åã®é¨åãæèããå¿ è¦ã¯ã»ã¨ãã©ããã¾ããã