Web/gRPC 2020. 7. 15. 20:27

 

이번 시간에 다루어볼 내용은 proto message로 생성한 Java를 Json String으로 변환하는 방법이다. proto로 생성한 java 인스턴스를 아래와 같이 json string으로 바꾸려면 예외가 발생한다.

 

#protoJava - proto로 생성한 java instance
ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(protoJava);

 

그렇기 때문에 protobuf의 JsonFormat으로 jsonString을 변환해주면 된다.

 

#protoJava - proto file로 생성한 java instance
final String jsonString = JsonFormat.printer().print(protoJava);

'Web > gRPC' 카테고리의 다른 글

gRPC - Protobuf란? 구글 프로토콜 버퍼(protocol buffers)  (0) 2020.05.03
gRPC - java gRPC 간단한 사용법  (0) 2020.05.03
gRPC - gRPC란 무엇인가?  (0) 2020.05.02
posted by 여성게
:
Web/gRPC 2020. 5. 3. 14:41

이전 포스팅에서는 grpc를 이용하여 간단하게 client-server 애플리케이션을 작성하였다. 간단하게 감을 익혀봤으니, 세세한 부분을 스터디 해본다. 오늘은 Protobuf(proto3)에 대해 다루어본다.

 

메시지 유형 정의

간단한 예를 보자. 검색 요청 메시지이며, 쿼리 문자열과 페이징을 위한 필드를 가지고 있다.

 

syntax = "proto3";

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

 

첫 줄은 proto3 syntax를 사용하고 있음을 지정한다. default는 proto2이다. 그리고 message SearchRequest를 정의한다. message는 자바로 비교하면 하나의 dto(model) 클래스라고 생각하면 좋다. 그리고 해당 message안에 필요한 필드를 선언한다. 위의 모든 필드는 scala type으로 지정되어 있지만, enum 및 다른 message 유형을 참조하여 복합 유형을 지정할 수도 있다. 

 

그리고 하나의 proto 파일에 여러 message 유형을 정의할 수 있다.

 

필드 번호

message의 각 필드에는 번호가 할당되어 있다. 이 필드 번호는 message가 이진형식으로 직렬화될때 필드를 식별하는데 사용되는 번호이다.

 

주석

proto 파일은 아래와 같이 주석 작성이 가능하다.

 

syntax = "proto3";

/*
검색 요청을 위한 요청 객체를 표현하는 message 정의
 */
message SearchRequest {
  string query = 1; //쿼리 문자열
  int32 page_number = 2;
  int32 result_per_page = 3;
}

 

Scala value types

스칼라 타입 유형은 아래와 같이 지원하고 있다.

 

TYPE

Notes

Java

Python

double

 

double

float

float

 

float

float

int32

Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.

int

int

int64

Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.

long

int/long[3]

uint32

Uses variable-length encoding.

int[1]

int/long[3]

uint64

Uses variable-length encoding.

long[1]

int/long[3]

sint32

Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.

int

int

sint64

Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.

long

int/long[3]

fixed32

Always four bytes. More efficient than uint32 if values are often greater than 228.

int[1]

int/long[3]

fixed64

Always eight bytes. More efficient than uint64 if values are often greater than 256.

long[1]

int/long[3]

sfixed32

Always four bytes.

int

int

sfixed64

Always eight bytes.

long

int/long[3]

bool

 

boolean

bool

string

A string must always contain UTF-8 encoded or 7-bit ASCII text, and cannot be longer than 232.

String

str/unicode[4]

bytes

May contain any arbitrary sequence of bytes no longer than 232.

ByteString

str

 

Default Value

messagefmf deserialize할때, 값이 없다면 각 타입에 대해 아래와 같은 기본 값을 가진다.

 

Type Default Value
string ""
bytes empty bytes
boolean false
numeric 0
enums 첫번째 정의된 enum value(must be 0)

 

Enum Type

protobuf에서도 자바와 같은 Enum 타입을 생성할 수 있다.

 

syntax = "proto3";

/*
검색 요청을 위한 요청 객체를 표현하는 message 정의
 */
message SearchRequest {
  string query = 1; //쿼리 문자열
  int32 page_number = 2;
  int32 result_per_page = 3;
  Corpus corpus = 4;
}

enum Corpus {
  UNIVERSAL = 0;
  WEB = 1;
  IMAGES = 2;
  LOCAL = 3;
  NEWS = 4;
  PRODUCTS = 5;
  VIDEO = 6;
}

 

열거형은 반드시 시작을 0으로 시작해야한다. 그래야 역직렬화할때, 값이 존재하지 않을경우 0에 할당된 값을 기본값으로 쓰기 때문이다. 

 

다른 message 유형 사용

다른 message 타입을 필드 타입으로 사용할 수 있다.

 

message SearchResponse {
  SearchResult results = 1;
}

message SearchResult {
  string url = 1;
  string title = 2;
}

 

그렇다면 다른 .proto 파일에 있는 message 타입을 사용하려면 어떻게 해야할까?

 

#SearchResult.proto
syntax = "proto3";

option java_multiple_files = true;
option java_outer_classname = "SearchResultProto";
option java_package = "com.levi.yoon.proto";

package grpc.sample;

message SearchResult {
  string url = 1;
  string title = 2;
}

#SearchProto.proto
syntax = "proto3";
import "SearchResult.proto";

option java_multiple_files = true;
option java_outer_classname = "SearchProto";
option java_package = "com.levi.yoon.proto";

package grpc.sample;

/*
검색 요청을 위한 요청 객체를 표현하는 message 정의
 */
message SearchRequest {
  string query = 1; //쿼리 문자열
  int32 page_number = 2;
  int32 result_per_page = 3;
  Corpus corpus = 4;
}

enum Corpus {
  UNIVERSAL = 0;
  WEB = 1;
  IMAGES = 2;
  LOCAL = 3;
  NEWS = 4;
  PRODUCTS = 5;
  VIDEO = 6;
}

message SearchResponse {
  SearchResult results = 1;
}

 

import 문을 통해서 다른 .proto 파일을 가져와서 사용할 수 있다.

 

중첩 타입

message 타입을 중첩해서 사용가능하다. 마치 자바에서 클래스 안에 클래스를 가지듯 !

 

syntax = "proto3";

message SearchResponse {
  message Result {
    string url = 1;
    string title = 2;
  }
  repeated Result results = 1;
}

 

Map type

필드 타입으로 Map을 사용할 수 있다.

 

syntax = "proto3";

option java_multiple_files = true;
option java_outer_classname = "ExampleRequestProto";
option java_package = "com.levi.yoon.proto";

package grpc.sample;

message ExampleRequest {
  map<string, string> requests = 1;
}

 

해당 필드를 set/get 할때는 아래와 같은 메서드를 지원한다.

 

ExampleRequest exampleRequest = ExampleRequest.newBuilder()
        .putRequests("a", "a")
        .putRequests("b", "b")
        .build();
exampleRequest.getRequestsMap();
exampleRequest.getRequestsOrDefault("a", "defaultValue");
exampleRequest.getRequestsOrThrow("a");

 

주의해야할 점은 Map 타입은 repeated를 사용할 수 없다.

 

Package

protobuf message 타입간 이름 충돌을 피하기 위해 파일에 선택적으로 package 지정자를 추가할 수 있다.

 

#ExampleRequestProto1.proto
syntax = "proto3";

package grpc.sample1;

message ExampleRequest {
  map<string, string> requests = 1;
}

#ExampleRequestProto2.proto
syntax = "proto3";

package grpc.sample2;

message ExampleRequest {
  map<string, string> requests = 1;
}

 

서비스 정의

client에서 stub 객체로 호출할 원격 프로시져(서비스)를 정의할 수 있다.

 

service SearchService {
  rpc Search (SearchRequest) returns (SearchResponse);
}

 

우리가 정의한 SearchRequest message를 매개변수로 받고, 응답으로 SearchResponse를 반환하는 서비스를 정의하였다. 해당 interface를 gRPC server에서 override하여 구현하고, client는 Stub 객체 안에 해당 서비스이름의 메서드를 콜하여 원격 gRPC service를 호출하게 된다.

 

기타 옵션

option java_multiple_files = true; -> proto 파일안의 message와 enum, service 등이 각 java 파일로 생성된다.

option java_outer_classname = "SearchProto"-> 생성될 자바코드의 클래스명이 된다.

option java_package = "com.levi.yoon.proto"-> 생성된 자바코드의 package 경로가 된다.

 

여기까지 간단하게 Protobuf에 대한 기능들 몇가지를 다루어보았다. 미쳐 다루지 못한 것은 실제 grpc 실습에서 다루어본다.

'Web > gRPC' 카테고리의 다른 글

gRPC - convert proto generate java to jsonString  (0) 2020.07.15
gRPC - java gRPC 간단한 사용법  (0) 2020.05.03
gRPC - gRPC란 무엇인가?  (0) 2020.05.02
posted by 여성게
:
Web/gRPC 2020. 5. 2. 22:14

오늘은 gRPC가 무엇인지 알아본다. 그동안 스터디한다고 마음만 먹고 매일 미루기만 했는데, 황금연휴에 맘잡고 gRPC에 대해 다루어 볼 것이다.

 

개요

gRPC를 사용하면 클라이언트 애플리케이션에서 마치 자신의 메서드를 호출하는 것처럼 원격서버(gRPC서버)의 메서드를 직접 호출 할 수 있으므로 MSA환경의 서비스를 보다 쉽게 만들 수 있다. 여타 다른 RPC와 마찬가지로 gRPC는 IDL(Interface Definition Language)를 이용하여 서비스를 정의하고 페이로드를 정의하며 gRPC서버는 이 인터페이스를 구현하고 클라이언트 호출을 처리하기 위해 gRPC서버를 실행한다. 클라이언트 측에서 클라이언트는 서버와 동일한 인터페이스를 가지는 스텁 객체를 가지고 있다.

 

 

ProtoBuf

gRPC는 기본적으로 구조화된 데이터를 직렬화하기 위해 Google의 ProtoBuf를 사용한다. 

 

ProtoBuf로 작업할 때는 첫번째로 .proto 파일에 직렬화하려는 데이터의 구조를 정의한다. 메시지라는 오브젝트(?)로 구성되며, 각 메시지는 데이터 타입과 key&value쌍을 이루는 필드를 하나이상 가지고 있다.

 

message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}

 

그 이후 protoc를 사용하여 원하는 언어로 컴파일이 가능하다. 컴파일된 소스는 각 필드에 대한 간단한 setter/getter를 제공한다. 또한 .proto 파일을 이용하여 위 proto message가 매개변수, 리턴 값으로 사용된 service를 정의할 수 있다.

 

// The greeter service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (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;
}

 

 

일반 RPC와 다를게 없을 수도 있는데, gRPC가 왜 좋은가? 

 

성능

gRPC 메시지는 효율적인 이진 메시지 형식인 ProtoBuf를 사용하여 직렬화된다. protobuf는 서버와 클라이언트에서 엄청 빠르게 직렬화된다. 또한 적은 용량의 페이로드로 형성되어 있어, 제한된 대역폭에서 아주 중요한 역할을 한다.

 

코드 생성

모든 gRPC 프레임워크는 코드 생성에 대한 최고 수준의 지원을 제공한다. gRPC 개발에 대한 핵심 파일은 gRPC 서비스 및 메시지의 계약을 정의하는 .proto file이다. 이 파일에서 gRPC 프레임워크는 서비스 기본 클래스, 메시지 및 전체 클라이언트를 코드 생성한다.

서버와 클라이언트 간에 proto 파일을 공유하여 메시지와 클라이언트 코드를 종단 간에 생성할 수 있다. 클라이언트의 코드 생성은 클라이언트와 서버에서 메시지의 중복을 제거하고 강력한 형식의 클라이언트를 만든다. 클라이언트를 작성하지 않아도 되므로 많은 서비스를 갖춘 응용 프로그램의 개발 시간이 상당히 절감된다.

 

엄격한 사양

일반적으로 JSON을 주고 받는 HTTP는 엄격한 사양이 존재하지 않는다. 그래서 개발자끼리 URL, HTTP payload, 응답코드 등을 논의해야한다. 하지만 gRPC는 gRPC가 따라야하는 명확한 형식이 있기 때문에 HTTP와 같이 큰 논의가 필요없다. 단순히 생성된 코드를 사양에 맞게 사용하면 된다.

 

그렇다면 gRPC는 어떠한 상황에서 사용하는 것이 좋을까?

 

  • 마이크로 서비스 - gRPC는 대기 시간이 짧고 처리량이 높은 통신을 위해 설계되었습니다. gRPC는 효율성이 중요한 경량 마이크로 서비스에 적합합니다.
  • gRPC – 지점 간 실시간 통신은 양방향 스트리밍을 위한 뛰어난 지원 기능을 제공합니다. gRPC 서비스는 폴링을 사용하지 않고 실시간으로 메시지를 푸시할 수 있습니다.
  • Polyglot 환경 – gRPC 도구는 널리 사용되는 모든 개발 언어를 지원하며, 따라서 gRPC는 다중 언어 환경에 적합합니다.
  • 네트워크 제한 환경 – gRPC 메시지는 경량 메시지 형식인 Protobuf를 사용하여 직렬화됩니다. gRPC 메시지는 항상 해당하는 JSON 메시지보다 작습니다.

 

여기까지 gRPC가 무엇이고, 어떠한 특징을 가지며 장점이 무엇인지 다루어보았다. 다음 포스팅부턴 제대로된 실습을 해본다.

posted by 여성게
:

티스토리(tistory) 구글 애드센스(AdSense)등록 방법!



얼마전에 승인되었던 구글 애드센스 신청방법에 대해 알려드리려고 합니다. 저는 구글 애드센스라는 것을 나중에 알게되어 블로그에 글을 조금 많이 올려놓은 상태에서 신청하여 하루만에 승인나기는 했지만, 주위에서 들어보면 승인이 쉽지만은 않다고 하더라구요. 간단히 팁과 방법을 알려드리겠습니다.


▶︎▶︎▶︎구글 애드센스 신청 페이지




위 사이트를 접속해주세요.




애드센스 아이디가 있으시다면 로그인, 없으시다면 애드센스 첫화면의 초록색 지금 가입하기 버튼을 눌러주세요. 구글 계정이

없으시다면 하나만들어 놓으시는게 좋습니다.!





애드센스에서 요구하는 정보를 기입하시고 가입하시면 됩니다.

맞춤도움말과 실적 개선 제안을 제공하는 이메일 받기를 해두시면 애드센스 활용법을 메일로 받아보실 수 있습니다.

이메일 주소는 구글 이메일인 지메일(Gmail)을 이용하시는 것을 추천해드립니다.





가입 후 애드센스를 켜보시면 가입자 정보를 적는 화면이 보여집니다.

수익금을 받을 수취인 주소를 적는 항목이므로 정확하게 적어주시는게 좋습니다.





정보기입이 완료 되면 애드센스를 사이트에 연결하기 위한 코드를 발급해줍니다.

3번 아래 박스에 있는 코드를 전체 복사 하시고

본인의 티스토리 블로그의 블로그관리 - 꾸미기 - 스킨편집로 이동해줍니다.





  1.         <!-- Google AdSense -->
  2.         <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
  3.         <script>
  4.                 어쩌고저쩌고코드
  5.         </script>
  6.         <!-- Google AdSense -->
  7.         
  8. </head>



이동된 화면 오른쪽에 보시면 HTML 태그 소스들이 가득한 박스가 있습니다.

Ctrl+F를 이용하시거나 화면 스크롤을 이용하여 </head> 태그가 있는 곳으로 이동합니다.

태그 바로 위쪽에 복사한 코드를 붙여넣기 해줍니다.

그리고 페이지 우측 상단의 저장을 반드시 눌러준 뒤 빠져나옵니다.  

그리고 다시 애드센스 사이트 화면으로 돌아갑니다.





코드 아래쪽에 '코드를 사이트에 붙여넣었습니다.' 를 체크하시고 완료버튼을 눌러주시면 됩니다.





그럼 '사이트를 검토 중입니다.'라는 문구의 페이지가 보이면서 구글 애드센스 신청이 완료됩니다.

신청하시면 일주일 내로 답변이 옵니다.

신청이 몰리는 경우에는 좀 더 걸릴 수도 있을 것 같습니다만

저는 주말인데도 불구하고 하루만에 결과가 나왔습니다!








이렇게 1차 승인이 끝났습니다. 2차승인도 있다는데 저도 모르고 있다가 일단 광고를

올리게 되면 바로 광고가 뜨는 것이 아니라고 합니다.

스크립트 코드를 통해 광고가 삽입되기 전에 뭔가 2차 승인과정이 있다고합니다.

하지만 무엇보다도 꾸준히 글을 포스팅하는 것이 중요하고 나의 블로그의

테마를 딱 명확하게 정해놓는 것이 중요한 것 같습니다.


마지막으로 인터넷에 많이 돌고 있는 승인 팁입니다.



1. 포스팅 당 글자수는 기본 1000자를 넘어야 한다.

2. 비어있는 카테고리가 있으면 안된다.

3. 카테고리 당 포스팅이 10개 이상 되어야 한다.

4. 매일 포스팅 해야한다.

5. 첨부되는 사진 갯수는 최소화 해야한다.

6. 문장은 완성형 문장이어야 한다.

7. 띄어쓰기를 많이하면 안된다.

8. 링크는 되도록 없어야 한다.

9. 블로그 제목과 블로그 포스팅 내용이 연결성이 있어야 한다.

10. 블로그 제목이 애매모호하지 않아야 한다.








posted by 여성게
: