gRPC를 실제로 Java 기반에서 구현해보기 위한 순서를 포스팅해봅니다.
다른 분들은 Spring Framework를 사용했는데, 저는 그냥 일반 Maven Project를 사용해서 구현해보았습니다.
결과적으로 Maven을 Build해서 IDL에 해당하는 proto파일을 컴파일 해주는 것은 같습니다.
다음에 기회가 되면 Spring과 일반 Maven Project와의 차이점에 대해서도 공부를 해서 포스팅 하도록 하겠습니다.
gRPC를 사용하기 위해 가장 중요한 것은 서버와 클라이언트의 IDL로서 사용하기 위한 proto파일을 컴파일 하는 것입니다.(사실 이부분에 가장 애를 먹었습니다.)
gRPC를 검색하면 나오는 자료는 다 github에 올라와 있는데 정작 .proto 파일을 컴파일 하는 부분에 대해서는 설명이 되어있지 않았거든요.
1. 프로젝트 생성
먼저 Maven Project를 생성해줍니다.
적당히 Next 누르면서 Group ID와 Artifact ID를 작성해주시면 됩니다.
저는 gRPCServer로 작성했어요.
2. protobuf-df 설치
Maven 프로젝트가 생성되었으면 pom.xml 파일이 생성되었을 겁니다.
파일이 생성되었으면 그다음으로 Eclipse Marketplace에 들어가서 protobuf-dt를 설치해줍니다.
proto로 검색하면 쉽게 찾으실 수 있어요.
앞으로 Json 대신에 사용할 proto 파일을 컴파일 하기 위한 플러그인입니다!
3. .proto 파일 작성
// The greeting service definition.
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.grpc";
option java_outer_classname = "HelloWorldProto";
package helloworld;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
src/main/resources 폴더에 hello.proto라는 이름으로 파일을 생성해줍니다.
2번에서 protobuf를 설치하지 않았다면 아마 파일 생성도 잘 안될 거에요.
정상적으로 파일이 생성되고 protobuf가 설치가 되었다면 파일에 Pb라고 되어있을 겁니다.
4. pom.xml
마지막으로 gRPC를 사용하기 위해 라이브러리를 pom.xml에 dependency에 기록하고 Maven Update를 하는 작업을 진행합니다.
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.31.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.31.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.31.1</version>
</dependency>
<dependency> <!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
</dependencies>
사용된 dependency
<build>
<!-- github 예제 코드 -->
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.31.1:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 추가적인 컴파일용 코드 -->
<plugin>
<groupId>com.github.os72</groupId>
<artifactId>protoc-jar-maven-plugin</artifactId>
<version>3.1.0.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<protocVersion>3.1.0</protocVersion>
<includeMavenTypes>direct</includeMavenTypes>
<inputDirectories>
<include>src/main/resources</include>
</inputDirectories>
<outputTargets>
<outputTarget>
<type>java</type>
<outputDirectory>src/main/java</outputDirectory>
</outputTarget>
</outputTargets>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
사용한 build 옵션
github와 웹에서 굴러다니는 소스를 보면 build 옵션에 대해 자세하게 적혀있지가 않더군요.
depedency는 라이브러리를 추가하는 과정이라 그냥 붙여넣어도 되지만,
밑의 build 코드에서는 조금 유의깊게 보시는 것을 추천드립니다.
build 밑 plugins이라는 태그가 보일 텐데, 이는 빌드에서 사용할 플러그인의 모음이라는 이야기입니다.
plugin에서 github에서 제공되는 기본적인 plugin의 org.xolstice.maven.plugins가 있는데, 사실 이것만으로는 proto파일이 컴파일 되지 않습니다.
밑의 com.github.os72의 protoc-jar-maven-plugin을 추가해서 빌드 과정에서 컴파일을 하도록 해야 합니다.
groupid와 artifactid 밑의 executions 태그는 실행 관련 옵션을 지정하는 태그인데,
configuration을 보면 input과 output이 지정되어 있는 것을 볼 수 있습니다.
저희가 3번에서 proto파일을 저장한 소스 경로가 src/main/resources로 되어있었죠?
거기에 있는 .proto파일을 읽어서 output으로 출력해주는 코드입니다.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>gRPCServer</groupId>
<artifactId>gRPCServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<jersey.version>2.16</jersey.version>
</properties>
<build>
<defaultGoal>clean generate-sources compile install</defaultGoal>
<finalName>shop</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>com.github.os72</groupId>
<artifactId>protoc-jar-maven-plugin</artifactId>
<version>3.11.4</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<includeMavenTypes>direct</includeMavenTypes>
<inputDirectories>
<include>src/main/resources</include>
</inputDirectories>
<outputTargets>
<outputTarget>
<type>java</type>
<outputDirectory>src/main/java</outputDirectory>
</outputTarget>
<outputTarget>
<type>grpc-java</type>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.15.0</pluginArtifact>
<outputDirectory>src/main/java</outputDirectory>
</outputTarget>
</outputTargets>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<!-- uncomment this to get JSON support <dependency> <groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId> </dependency> -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.15.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.15.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.15.1</version>
</dependency>
</dependencies>
</project>
* 만약에 위의 옵션이 안되면 아래의 pom.xml 코드를 참조하시면 될것 같습니다.
com.github.os72 라이브러리의 버전이 낮으면 오류가 나는 것 같더군요!
실제로 pom.xml 파일을 작성하고 Maven Update를 해주면
위처럼 .proto 파일에 기반한 IDL이 생성되는 것을 확인할 수 있습니다.
gRPC에서 proto로 생성된 클래스들은 빌더 패턴으로 구성되기 때문에 빌더 패턴에 대한 개념은 알아두는 것이 좋습니다.
다음에는 실제로 Server와 Client를 구현해서 proto 파일 기반으로 통신해보도록 하겠습니다.
참고 사이트
https://github.com/grpc/grpc-java
https://dzone.com/articles/compile-protocol-buffers-using-maven
https://medium.com/@deepakchandh/implementing-grpc-with-sample-java-project-53a0b28243ac
'프로토콜 > gRPC' 카테고리의 다른 글
[gRPC] Protocol Buffer란? (0) | 2022.05.31 |
---|---|
[C#] gRPC Server(Sevice) (0) | 2020.09.04 |
[C#] gRPC Client (0) | 2020.09.03 |
gRPC란? (0) | 2020.09.02 |