๐ gRPC๋ ๋ฌด์์ด๊ณ , ์ด๋ป๊ฒ ์ค๋ฌด์์ ํ์ฉ๋๋๊ฐ?
1๏ธโฃ ์ค๋ฌด ํ์ฉ ์ฌ๋ก: ์ gRPC์ธ๊ฐ?
gRPC๋ ๋จ์ํ "๋น ๋ฅธ API" ๊ธฐ์ ์ ๋์ด, ํ๋์ ์ธ ์ํํธ์จ์ด ์์คํ ์์ ๋ค์ํ ์ค์๊ฐ ํต์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ํต์ฌ ๋๊ตฌ๋ก ๋ ์ค๋ฅด๊ณ ์์ต๋๋ค. ํนํ ์๋ฐฉํฅ ์คํธ๋ฆฌ๋ฐ ๊ธฐ๋ฅ์ ๊ธฐ์กด์ REST API๋ก๋ ๊ตฌํ์ด ์ด๋ ต๊ฑฐ๋ ๋นํจ์จ์ ์ธ ํต์ ์ ์์ฐ์ค๋ฝ๊ฒ ๊ตฌํํ ์ ์๊ฒ ํด์ค๋๋ค.
๐ฌ 1. ์ค์๊ฐ ์ฑํ ์์คํ
- Slack, Zoom, Discord์ ๊ฐ์ ๋ฉ์์ง ์๋น์ค๋ ์ฌ์ฉ์ ๊ฐ์ ๋ฉ์์ง๋ฅผ ์ง์ฐ ์์ด ์ฃผ๊ณ ๋ฐ์์ผ ํฉ๋๋ค.
- gRPC์ ์๋ฐฉํฅ ์คํธ๋ฆฌ๋ฐ์ ํด๋ผ์ด์ธํธ์ ์๋ฒ๊ฐ ํ๋์ ์ฐ๊ฒฐ์ ์ ์งํ๋ฉด์ ๋์์ ๋ฉ์์ง๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์๊ฒ ํด์ค๋๋ค.
๐ก 2. IoT ์ค์๊ฐ ๋ชจ๋ํฐ๋ง
- ์ผ์๊ฐ ์๋ฒ์ ์ง์์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๊ณ , ์๋ฒ๋ ์ค์๊ฐ ์ ์ด ์ ํธ๋ฅผ ๋ค์ ์ผ์๋ก ์ ์กํฉ๋๋ค.
- ์: ์ค๋งํธ ๊ณต์ฅ, ๋๋ก ์ ์ด ์์คํ , ํฌ์ค์ผ์ด ๋ชจ๋ํฐ๋ง ๋ฑ
๐ฎ 3. ๋ฉํฐํ๋ ์ด์ด ๊ฒ์ ์๋ฒ
- ํ๋ ์ด์ด ๊ฐ ์์น, ์ํ, ์ด๋ฒคํธ ๋๊ธฐํ๊ฐ ๋ฐ๋ฆฌ์ด ๋จ์๋ก ์ด๋ฃจ์ด์ ธ์ผ ํ๋ ํ๊ฒฝ์์๋, gRPC ์คํธ๋ฆฌ๋ฐ์ด REST๋ณด๋ค ํจ์ฌ ์ ํฉํฉ๋๋ค.
๐๏ธ 4. ์ค์๊ฐ ์์ฑ/ํ ์คํธ ์ฒ๋ฆฌ
- ์ฌ์ฉ์์ ๋ง์ดํฌ ์ ๋ ฅ์ ์ง์์ ์ผ๋ก ๋ณด๋ด๊ณ , ์๋ฒ๋ ์ค์๊ฐ์ผ๋ก ํ ์คํธ๋ก ๋ณํ(STT).
- Google Speech-to-Text, Amazon Transcribe ๋ฑ์ ์ค์ ์๋น์ค๋ค์ด gRPC ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํ๋์ด ์์
๐น 5. ๊ธ์ต ๋ฐ์ดํฐ ์ ์ก
- ์ค์๊ฐ์ผ๋ก ์ฃผ์ ์ฒด๊ฒฐ ์ ๋ณด, ์์ธ ๋ณ๋ ๋ฑ์ ๋ฐ์์ผ ํ๋ ๊ธ์ต ์๋น์ค๋ gRPC๋ฅผ ํตํด ๊ตฌ๋ ๊ธฐ๋ฐ ์คํธ๋ฆฌ๋ฐ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํจ
2๏ธโฃ gRPC๋ ๋ฌด์์ธ๊ฐ?
๐ฆ ์ ์
gRPC๋ Google์ด ๊ฐ๋ฐํ ๊ณ ์ฑ๋ฅ ์๊ฒฉ ํ๋ก์์ ํธ์ถ(Remote Procedure Call) ํ๋ ์์ํฌ์
๋๋ค.
๊ธฐ์กด์ REST API ๋ฐฉ์๊ณผ ๋ฌ๋ฆฌ, ํจ์ ํธ์ถ์ฒ๋ผ ์๋ฒ์ ๋ฉ์๋๋ฅผ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์์ฌ ์ ์๋๋ก ์ค๊ณ๋์์ต๋๋ค.
๐ ํน์ง ์์ฝ
ํญ๋ชฉ | ์ค๋ช |
---|---|
๋ฐ์ดํฐ ํฌ๋งท | JSON ๋์ Protobuf (Protocol Buffers) ์ฌ์ฉ |
์๋ | ํ ์คํธ ๊ธฐ๋ฐ๋ณด๋ค ์๊ณ ๋น ๋ฆ |
์ฐ๊ฒฐ ๋ฐฉ์ | HTTP/2 ๊ธฐ๋ฐ – ํ๋์ ์ฐ๊ฒฐ๋ก ์ฌ๋ฌ ์์ฒญ ์ฒ๋ฆฌ |
ํต์ ํจํด | ์์ฒญ-์๋ต, ์๋ฒ ์คํธ๋ฆฌ๋ฐ, ํด๋ผ์ด์ธํธ ์คํธ๋ฆฌ๋ฐ, ์๋ฐฉํฅ ์คํธ๋ฆฌ๋ฐ ์ง์ |
์๋ ์ฝ๋ ์์ฑ | .proto ํ์ผ๋ก๋ถํฐ ๋ค๊ตญ์ด ํด๋ผ์ด์ธํธ/์๋ฒ ์ฝ๋ ์๋ ์์ฑ |
๐ ํต์ฌ ๊ฐ๋
: .proto
ํ์ผ
syntax = "proto3";
service Translator {
rpc Translate (TextInput) returns (TextOutput);
}
message TextInput {
string text = 1;
string lang = 2;
}
message TextOutput {
string translated_text = 1;
}
์์ ๊ฐ์ด ์๋น์ค(Translator) ์ ๋ฉ์์ง ๊ตฌ์กฐ๋ฅผ ์ ์ํ๋ฉด, protoc
๋ช
๋ น์ด๋ฅผ ํตํด Python, Java, Go ๋ฑ ๋ค์ํ ์ธ์ด๋ก ์๋ ์ฝ๋๊ฐ ์์ฑ๋ฉ๋๋ค.
3๏ธโฃ Python์ผ๋ก gRPC ๊ตฌํํ๊ธฐ – ์ค์ ์์
์ด์ ์ค์ ๋ก gRPC ์๋ฒ์ ํด๋ผ์ด์ธํธ๋ฅผ Python์ผ๋ก ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค.
์ฐ๋ฆฌ๊ฐ ๊ตฌํํ ์์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
๐ฏ ๋ชฉํ: ํด๋ผ์ด์ธํธ๊ฐ ๋ฌธ์์ด์ ๋ณด๋ด๋ฉด, ์๋ฒ๊ฐ ํด๋น ๋ฌธ์์ด์ ๋๋ฌธ์๋ก ๋ฐ๊ฟ์ ๋๋ ค์ฃผ๋ ๊ฐ๋จํ ์๋น์ค
→SayHello("hello")
→HELLO
๐งฑ 1๋จ๊ณ: .proto ํ์ผ ์์ฑ
hello.proto
ํ์ผ์ ์์ฑํฉ๋๋ค:
syntax = "proto3";
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string message = 1;
}
message HelloResponse {
string message = 1;
}
SayHello
๋ ํด๋ผ์ด์ธํธ๊ฐ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ฉด ์๋ฒ๊ฐ ์๋ตํ๋ ๋จ๋ฐฉํฅ RPCHelloRequest
,HelloResponse
๋ ์์ฒญ/์๋ต ๋ฉ์์ง ๊ตฌ์กฐ
โ๏ธ 2๋จ๊ณ: Python ์ฝ๋ ์๋ ์์ฑ
โ protoc ์ค์น (ํ ๋ฒ๋ง)
python -m pip install grpcio grpcio-tools
โก ์๋ ์์ฑ ์คํ
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. hello.proto
์คํ ๊ฒฐ๊ณผ:
hello_pb2.py
(๋ฉ์์ง ์ ์)hello_pb2_grpc.py
(gRPC ์๋ฒ/ํด๋ผ์ด์ธํธ ์ฝ๋)
๐ฅ๏ธ 3๋จ๊ณ: gRPC ์๋ฒ ๊ตฌํ
server.py
:
from concurrent import futures
import grpc
import hello_pb2
import hello_pb2_grpc
class HelloService(hello_pb2_grpc.HelloServiceServicer):
def SayHello(self, request, context):
reply = request.message.upper()
return hello_pb2.HelloResponse(message=reply)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
hello_pb2_grpc.add_HelloServiceServicer_to_server(HelloService(), server)
server.add_insecure_port('[::]:50051')
server.start()
print("Server started on port 50051.")
server.wait_for_termination()
if __name__ == '__main__':
serve()
๐ป 4๋จ๊ณ: gRPC ํด๋ผ์ด์ธํธ ๊ตฌํ
client.py
:
import grpc
import hello_pb2
import hello_pb2_grpc
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = hello_pb2_grpc.HelloServiceStub(channel)
response = stub.SayHello(hello_pb2.HelloRequest(message="hello grpc"))
print("Response from server:", response.message)
if __name__ == '__main__':
run()
โ ์คํ ์์
- ์๋ฒ ๋จผ์ ์คํ:
python server.py
- ํด๋ผ์ด์ธํธ ์คํ:
python client.py
- ๊ฒฐ๊ณผ:
Response from server: HELLO GRPC
๐ Python์ผ๋ก ๊ตฌํํ๋ gRPC ์๋ฐฉํฅ ์คํธ๋ฆฌ๋ฐ ์์
๐ฏ ๋ชฉํ ์๋๋ฆฌ์ค
ํด๋ผ์ด์ธํธ์ ์๋ฒ๊ฐ ์ฑํ ํ๋ฏ ๋์์ ๋ฉ์์ง๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด ๋ด ๋๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ๋ฌธ์ฅ์ ํ ์ค์ฉ ๋ณด๋ด๋ฉด, ์๋ฒ๋ ๊ทธ๊ฒ์ ๋๋ฌธ์๋ก ๋ฐ๊ฟ์ ๋ฐ๋ก๋ฐ๋ก ์๋ตํฉ๋๋ค.
์ฌ๋ฌ ์ค์ ์ฃผ๊ณ ๋ฐ๋ ๋์ ์ฐ๊ฒฐ์ ๊ณ์ ์ ์ง๋ฉ๋๋ค.
๐ฆ 1๋จ๊ณ: .proto
ํ์ผ ์ ์
chat.proto
syntax = "proto3";
service ChatService {
rpc Chat(stream ChatMessage) returns (stream ChatMessage);
}
message ChatMessage {
string sender = 1;
string message = 2;
}
rpc Chat(...) returns (...)
๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด ์๋ฐฉํฅ ์คํธ๋ฆฌ๋ฐ์์ ์ ์ ์์ต๋๋ค.ChatMessage
๋ ์ฑํ ์ ๊ธฐ๋ณธ ๋จ์ ๋ฉ์์ง
โ๏ธ 2๋จ๊ณ: Python ์ฝ๋ ์๋ ์์ฑ
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. chat.proto
→ chat_pb2.py
, chat_pb2_grpc.py
์์ฑ๋จ
๐ฅ๏ธ 3๋จ๊ณ: ์๋ฒ ๊ตฌํ
chat_server.py
import grpc
from concurrent import futures
import time
import chat_pb2
import chat_pb2_grpc
class ChatService(chat_pb2_grpc.ChatServiceServicer):
def Chat(self, request_iterator, context):
for chat in request_iterator:
print(f"[{chat.sender}]: {chat.message}")
response = chat_pb2.ChatMessage(
sender="Server",
message=chat.message.upper()
)
yield response
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
chat_pb2_grpc.add_ChatServiceServicer_to_server(ChatService(), server)
server.add_insecure_port('[::]:50051')
server.start()
print("Server listening on port 50051...")
server.wait_for_termination()
if __name__ == '__main__':
serve()
๐ป 4๋จ๊ณ: ํด๋ผ์ด์ธํธ ๊ตฌํ
chat_client.py
import grpc
import chat_pb2
import chat_pb2_grpc
def generate_messages():
sender_name = input("Enter your name: ")
while True:
msg = input("You: ")
if msg.lower() == 'exit':
break
yield chat_pb2.ChatMessage(sender=sender_name, message=msg)
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = chat_pb2_grpc.ChatServiceStub(channel)
responses = stub.Chat(generate_messages())
for res in responses:
print(f"{res.sender}: {res.message}")
if __name__ == '__main__':
run()
๐งช ์คํ ์์
- ์๋ฒ ์คํ
python chat_server.py
- ํด๋ผ์ด์ธํธ ์คํ
python chat_client.py
- ์ฌ์ฉ ์
Enter your name: Alice You: hello Server: HELLO You: grpc is cool Server: GRPC IS COOL
- ์ข
๋ฃ๋
exit
์ ๋ ฅ์ผ๋ก.
โ ์ค๋ฌด์์ ์ด๋ ๊ฒ ์์ฉ๋ฉ๋๋ค
์ค๋ฌด ์ฌ๋ก | ํ์ฉ ๋ฐฉ์ |
---|---|
์ค์๊ฐ ์ฑํ | ์ฌ์ฉ์ ๋ฉ์์ง๋ฅผ ์๋ฒ๊ฐ ๋ณํ/์ค๊ณ |
์์ฑ ์ฒ๋ฆฌ | ์์ฑ ์คํธ๋ฆผ์ ์๋ฒ์ ๋ณด๋ด๊ณ , ์ค์๊ฐ ํ ์คํธ๋ก ๋ฐ์ |
๊ฒ์ ์๋ฒ | ํ๋ ์ด์ด ์ํ๋ฅผ ์คํธ๋ฆฌ๋ฐ์ผ๋ก ์ฃผ๊ณ ๋ฐ์ |
IoT ์ฅ๋น | ์ผ์ ↔ ์ ์ด ๋ช ๋ น์ ์ฐ์์ ์ผ๋ก ์ก์์ |
๐ง ๋ง๋ฌด๋ฆฌ ์์ฝ
- gRPC ์๋ฐฉํฅ ์คํธ๋ฆฌ๋ฐ์ ๋จ์ผ ์ฐ๊ฒฐ๋ก ์ํธ ์์ฉํ๋ ๊ตฌ์กฐ์ ๊ฐ๋ ฅํจ
yield
๋ฅผ ํตํด ๋ฉ์์ง๋ฅผ ์ค์๊ฐ์ผ๋ก ์ฃผ๊ณ ๋ฐ์- REST API๋ณด๋ค ํจ์จ์ ์ด๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋จ
'AI ๊ฐ๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Gemini CLI ํ์ฉ ์ฌ๋ก (0) | 2025.06.28 |
---|---|
Gemini CLI ์ค์น & ์ด๊ธฐ ์ค์ (0) | 2025.06.28 |
Protobuf๋ ๋ฌด์์ธ๊ฐ? โ ์ฌ์ฉ ์ฌ๋ก์ ์ค๋ฌด ์ฌ์ฉ๋ฒ (0) | 2025.06.17 |
MCP ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ๋ฐ ๋ฐฉ๋ฒ (2) | 2025.06.06 |
Cursor์์ Supabase MCP ์ฐ๋ํ๊ธฐ - ์์ฐ์ด๋ก DB ํ ์ด๋ธ ์์ฑ (0) | 2025.06.06 |