gRPC
gRPC
도구
멀리 있는 서비스의 함수를 제 코드 안의 함수처럼 부르게 해 주는 통신 규격으로, 회사 안 서비스끼리 자주 주고받는 자리에 씁니다.
등장 배경
서비스를 기능별로 잘게 쪼개는 마이크로서비스가 퍼지면서 서버끼리 부르는 횟수가 늘었습니다. 한 덩어리 안에서 함수를 부르던 일이 네트워크를 건너는 요청이 되었고, 화면 하나를 그리는 동안 서비스 대여섯 곳이 서로를 불렀습니다.
문제는 이 호출에 쓰던 도구가 원래 브라우저와 서버 사이를 위해 만들어졌다는 데 있었습니다. 주소를 불러 JSON을 주고받는 방식은 사람이 읽을 수 있어 편한데, 사람이 읽을 일 없는 서버끼리의 대화에서는 그 편의가 값을 못 합니다.
약속이 문서에만 적혀 있다는 점도 걸렸습니다. 페이지덱의 태오가 권한 서비스를 부르는 코드를 짜다가 응답 항목 이름을 확인하려고 사내 위키를 열었더니 석 달 전에 멈춘 문서였습니다. 서버에 요청을 직접 보내 눈으로 확인했는데, 그다음 주에 권한 서비스가 항목 이름을 바꿨고 문서 서비스는 배포가 끝난 뒤 사용자 화면에서야 그걸 알았습니다.
gRPC 는 이 두 자리를 겨냥해 만들어졌습니다. 약속을 사람이 읽는 문서가 아니라 기계가 읽는 파일로 못 박고, 데이터는 사람이 읽지 못하는 대신 훨씬 작은 형식으로 바꿉니다.
해결하는 문제
이 규격이 푸는 문제는 둘입니다. 어긋나는 약속과 쌓이는 왕복, 방법은 네 가지입니다.
- 약속을 파일 하나에 못 박습니다. 어떤 함수가 있고 무엇을 받아 무엇을 돌려주는지를 규격 파일에 적고 양쪽 코드를 그 파일에서 자동으로 뽑습니다. 항목 이름을 위키에서 찾을 일이 없어지고, 권한 서비스가 이름을 바꾸면 문서 서비스는 빌드 단계에서 막힙니다.
- 데이터를 작게 만듭니다. 항목 이름을 매번 글자로 싣는 대신 파일에 정해 둔 번호만 보냅니다. 사용자 번호 하나짜리 요청이 텍스트로는 스무 바이트 남짓인데 여기서는 대여섯 바이트입니다.
- 연결을 돌려 씁니다. 요청 100번에 연결 100개를 새로 여는 대신 한 연결에 여러 요청을 겹쳐 보냅니다. 연결을 새로 트는 시간이 요청 자체보다 긴 경우가 많아 이것만으로도 왕복이 줄어듭니다.
- 흐름으로 주고받습니다. 한 번 부르고 한 번 받는 모양 말고 결과가 계속 흘러오는 모양도 규격 안에 있어, 파일을 조각내 올리거나 진행 상황을 계속 받는 자리에 씁니다.
이득의 크기는 부르는 횟수에 달려 있습니다. 페이지덱의 문서 서비스는 목록 화면 하나에 권한 서비스를 40번 부릅니다. 왕복 하나가 12밀리초에서 4밀리초로 줄면 480밀리초가 160밀리초가 되고, 이건 사용자가 느끼는 차이입니다. 하루 100번 부르는 창구에서는 같은 8밀리초가 아무 의미도 없습니다.
대안
같은 자리에 놓고 견줄 수 있는 방식은 넷이고, 고르는 기준은 누가 부르느냐입니다.
- REST — 데이터마다 주소를 붙여 두고 그 주소를 불러 읽고 씁니다. 브라우저에서 바로 부를 수 있고 도구가 흔해 외부 공개 창구는 대개 이쪽입니다.
- GraphQL — 부르는 쪽이 필요한 항목만 골라 적어 보내고 딱 그만큼만 받습니다. 화면 하나에 창구를 다섯 번 부르던 일이 한 번으로 줄고, 대신 창구를 여는 쪽이 준비할 것이 늘어납니다.
- 웹소켓 — 연결을 열어 둔 채 양쪽이 아무 때나 말을 겁니다. 같은 문서를 둘이 동시에 고칠 때처럼 한쪽의 변화가 즉시 반대쪽에 보여야 하는 자리입니다.
- 웹훅 — 방향이 반대입니다. 부르는 쪽이 계속 물어보는 대신 사건이 생긴 쪽이 상대 주소로 먼저 알려 줍니다.
부르는 쪽이 브라우저면 gRPC 는 후보에서 빠집니다. 브라우저가 이 규격을 그대로 부르지 못해 변환 층을 한 겹 더 놓아야 하기 때문입니다. 외부 공개 창구도 마찬가지로, 연동하려는 쪽이 익숙한 도구로 바로 시험해 봐야 하는데 오가는 내용을 사람이 못 읽으면 문턱이 높아집니다.
치르는 값도 있습니다. 흔한 명령줄 도구로 요청을 찍어 볼 수 없어 전용 도구를 깔아야 하고, 규격 파일을 누가 고치는지에 대한 팀 규칙도 필요합니다. 페이지덱이 외부 창구는 REST 로 두고 내부만 gRPC 로 바꾼 것은 이 값을 한쪽에서만 치르기로 한 선택입니다.
실무 용례
"이건 내부 호출이니까 gRPC 로 가죠. 화면 한 번에 왕복이 너무 쌓여요."
부르는 쪽이 브라우저가 아니고 호출이 잦아 왕복 시간을 줄일 값이 있다는 판단입니다.
"규격 파일 먼저 올려 주시면 저희 쪽 코드는 거기서 뽑을게요."
문서로 항목 이름을 주고받는 대신 파일 하나를 기준으로 삼자는 요청입니다.
"gRPC 라 주소창으로는 못 찍어 봐요. 전용 도구 깔아야 합니다."
문제가 생겼을 때 확인하는 방법이 달라진다는 말입니다.
페이지덱이 이 규격으로 옮긴 건 문서 목록 화면이 느리다는 문의가 쌓인 뒤였습니다. 태오가 재 보니 화면을 그리는 800밀리초 가운데 480밀리초가 권한 서비스를 40번 오가는 시간이었습니다. 호출 횟수를 줄이는 쪽도 봤지만 문서마다 권한이 달라 묶기 어려웠습니다.
옮기는 데 든 시간 대부분은 규격 파일을 쓰는 일이었는데, 두 서비스가 주고받던 항목을 처음으로 한자리에 적어 보니 아무도 쓰지 않는 항목이 여섯 개 있었습니다.
흔한 오해
gRPC 가 REST 보다 언제나 빠르다고 읽는 경우가 가장 많습니다. 두 방식을 나란히 재 놓은 숫자가 몇 배씩 차이 나 보이니 믿기 쉽습니다. 그 차이는 왕복 한 번에 붙는 값이라 왕복이 잦은 자리에서만 느껴집니다. 하루 100번 부르는 창구에서 8밀리초를 아껴 봐야 1초가 안 됩니다. 이 오해를 두면 외부 공개 창구까지 gRPC 로 만들고, 연동하려던 상대는 시험조차 못 해 보고 돌아섭니다.
규격 파일이 있으니 약속이 깨질 일이 없다고 읽는 것도 흔합니다. 빌드가 몇 번 막아 주면 파일이 모든 걸 지켜 준다고 느끼기 쉽습니다. 실제로는 항목에 붙인 번호를 다시 쓰거나 항목의 형을 바꾸면 그대로 브레이킹 체인지, 곧 쓰던 쪽의 코드를 깨뜨리는 변경이 됩니다. 새 코드는 잘 도는데 아직 옮기지 않은 서비스가 엉뚱한 값을 읽어 알아차리기도 늦습니다. 항목을 지울 때 번호를 함께 예약해 두고 다시 쓰지 않는 것이 하위 호환성을 지키는 방법입니다.
같이 보면 좋은 페이지
마지막 업데이트 2026-09-16