1. บทนำ
ในโค้ดแล็บนี้ คุณจะได้ใช้ gRPC-Python เพื่อสร้างไคลเอ็นต์และเซิร์ฟเวอร์ซึ่งเป็นรากฐานของแอปพลิเคชันการแมปเส้นทางที่เขียนด้วย Python
เมื่อจบบทแนะนำนี้ คุณจะมีไคลเอ็นต์ที่เชื่อมต่อกับเซิร์ฟเวอร์ระยะไกลโดยใช้ gRPC เพื่อรับชื่อหรือที่อยู่ไปรษณีย์ของสิ่งที่อยู่ ณ พิกัดที่เฉพาะเจาะจงบนแผนที่ แอปพลิเคชันที่สมบูรณ์อาจใช้การออกแบบไคลเอ็นต์-เซิร์ฟเวอร์นี้เพื่อแจงนับหรือสรุปจุดที่น่าสนใจตามเส้นทาง
บริการนี้กำหนดไว้ในไฟล์ Protocol Buffers ซึ่งจะใช้เพื่อสร้างโค้ดมาตรฐานสำหรับไคลเอ็นต์และเซิร์ฟเวอร์เพื่อให้สื่อสารกันได้ ซึ่งจะช่วยประหยัดเวลาและแรงในการติดตั้งใช้งานฟังก์ชันดังกล่าว
โค้ดที่สร้างขึ้นนี้ไม่เพียงแต่จัดการความซับซ้อนของการสื่อสารระหว่างเซิร์ฟเวอร์และไคลเอ็นต์เท่านั้น แต่ยังจัดการการซีเรียลไลซ์และการดีซีเรียลไลซ์ข้อมูลด้วย
สิ่งที่คุณจะได้เรียนรู้
- วิธีใช้ Protocol Buffers เพื่อกำหนด API ของบริการ
- วิธีสร้างไคลเอ็นต์และเซิร์ฟเวอร์ที่ใช้ gRPC จากคำจำกัดความของ Protocol Buffers โดยใช้การสร้างโค้ดอัตโนมัติ
- ความเข้าใจเกี่ยวกับการสื่อสารระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ด้วย gRPC
Codelab นี้มีไว้สำหรับนักพัฒนา Python ที่เพิ่งเริ่มใช้ gRPC หรือต้องการทบทวน gRPC หรือผู้ที่สนใจสร้างระบบแบบกระจาย ไม่จำเป็นต้องมีประสบการณ์เกี่ยวกับ gRPC มาก่อน
2. ก่อนเริ่มต้น
สิ่งที่คุณต้องมี
- Python 3.9 ขึ้นไป เราขอแนะนำให้ใช้ Python 3.13 ดูวิธีการติดตั้งเฉพาะแพลตฟอร์มได้ที่การตั้งค่าและการใช้งาน Python หรือจะติดตั้ง Python ที่ไม่ใช่ระบบโดยใช้เครื่องมืออย่าง uv หรือ pyenv ก็ได้
- pip เพื่อติดตั้งแพ็กเกจ Python
- venv เพื่อสร้างสภาพแวดล้อมเสมือนของ Python
แพ็กเกจ ensurepip
และ venv
เป็นส่วนหนึ่งของไลบรารีมาตรฐานของ Python และมักจะพร้อมใช้งานโดยค่าเริ่มต้น
อย่างไรก็ตาม การกระจายที่อิงตาม Debian บางรายการ (รวมถึง Ubuntu) เลือกที่จะยกเว้นเมื่อแจกจ่าย Python อีกครั้ง หากต้องการติดตั้งแพ็กเกจ ให้เรียกใช้คำสั่งต่อไปนี้
sudo apt install python3-pip python3-venv
รับโค้ด
Codelab นี้มีโครงร่างซอร์สโค้ดที่สร้างไว้ล่วงหน้าเพื่อช่วยให้คุณเริ่มต้นใช้งานได้ง่ายขึ้น ขั้นตอนต่อไปนี้จะแนะนําวิธีสมัครให้เสร็จสมบูรณ์ รวมถึงการสร้างโค้ด gRPC โดยใช้ปลั๊กอินคอมไพเลอร์ grpc_tools.protoc
Protocol Buffer
grpc-codelabs
ซอร์สโค้ดโครงร่างสำหรับ Codelab นี้อยู่ในไดเรกทอรี codelabs/grpc-python-getting-started/start_here หากไม่ต้องการติดตั้งใช้งานโค้ดด้วยตนเอง คุณจะดูซอร์สโค้ดที่เสร็จสมบูรณ์ได้ในไดเรกทอรี completed
ก่อนอื่น ให้สร้างไดเรกทอรีการทำงานของ Codelab แล้วใช้คำสั่ง cd เพื่อเข้าไปในไดเรกทอรีดังกล่าว
mkdir grpc-python-getting-started && cd grpc-python-getting-started
ดาวน์โหลดและแตกไฟล์ Codelab โดยทำดังนี้
curl -sL https://github.com/grpc-ecosystem/grpc-codelabs/archive/refs/heads/v1.tar.gz \
| tar xvz --strip-components=4 \
grpc-codelabs-1/codelabs/grpc-python-getting-started/start_here
หรือคุณจะดาวน์โหลดไฟล์ .zip ที่มีเฉพาะไดเรกทอรี Codelab แล้วแตกไฟล์ด้วยตนเองก็ได้
3. กำหนดบริการ
ขั้นตอนแรกคือการกำหนดบริการ gRPC ของแอปพลิเคชัน เมธอด RPC และประเภทข้อความคำขอและการตอบกลับโดยใช้ภาษาคำจำกัดความอินเทอร์เฟซ Protocol Buffers บริการของคุณจะให้ข้อมูลต่อไปนี้
- เมธอด RPC ที่ชื่อ
GetFeature
ซึ่งเซิร์ฟเวอร์นำมาใช้และไคลเอ็นต์เรียกใช้ - ประเภทข้อความ
Point
และFeature
คือโครงสร้างข้อมูลที่ไคลเอ็นต์และเซิร์ฟเวอร์แลกเปลี่ยนกันเมื่อใช้เมธอดGetFeature
ไคลเอ็นต์จะระบุพิกัดแผนที่เป็นPoint
ในคำขอGetFeature
ไปยังเซิร์ฟเวอร์ และเซิร์ฟเวอร์จะตอบกลับด้วยFeature
ที่เกี่ยวข้องซึ่งอธิบายสิ่งที่อยู่ในพิกัดเหล่านั้น
วิธีการ RPC นี้และประเภทข้อความของวิธีการนี้จะกำหนดไว้ในไฟล์ protos/route_guide.proto
ของซอร์สโค้ดที่ระบุ
Protocol Buffers เรียกกันโดยทั่วไปว่า protobuf ดูข้อมูลเพิ่มเติมเกี่ยวกับคำศัพท์ gRPC ได้ที่แนวคิดหลัก สถาปัตยกรรม และวงจรของ gRPC
ประเภทข้อความ
ในprotos/route_guide.proto
ไฟล์ของซอร์สโค้ด ให้กำหนดPoint
ประเภทข้อความก่อน Point
แสดงคู่พิกัดละติจูดและลองจิจูดบนแผนที่ สำหรับ Codelab นี้ ให้ใช้จำนวนเต็มสำหรับพิกัด
message Point {
int32 latitude = 1;
int32 longitude = 2;
}
หมายเลข 1
และ 2
เป็นหมายเลขรหัสที่ไม่ซ้ำกันสำหรับแต่ละฟิลด์ในโครงสร้าง message
จากนั้นกำหนดFeature
ประเภทข้อความ Feature
ใช้ฟิลด์ string
สำหรับชื่อหรือที่อยู่ไปรษณีย์ของสิ่งหนึ่งๆ ในสถานที่ที่ระบุโดย Point
ดังนี้
message Feature {
// The name or address of the feature.
string name = 1;
// The point where the feature is located.
Point location = 2;
}
วิธีการบริการ
ไฟล์ route_guide.proto
มีโครงสร้าง service
ชื่อ RouteGuide
ซึ่งกำหนดวิธีการอย่างน้อย 1 วิธีที่บริการของแอปพลิเคชันมีให้
เพิ่มrpc
method GetFeature
ภายในคำจำกัดความของ RouteGuide
ดังที่อธิบายไว้ก่อนหน้านี้ วิธีนี้จะค้นหาชื่อหรือที่อยู่ของสถานที่จากชุดพิกัดที่กำหนด ดังนั้นให้ GetFeature
แสดง Feature
สำหรับ Point
ที่กำหนด
service RouteGuide {
// Definition of the service goes here
// Obtains the feature at a given position.
rpc GetFeature(Point) returns (Feature) {}
}
นี่คือเมธอด RPC แบบเอกภาค ซึ่งเป็น RPC อย่างง่ายที่ไคลเอ็นต์ส่งคำขอไปยังเซิร์ฟเวอร์และรอให้เซิร์ฟเวอร์ส่งการตอบกลับกลับมา เหมือนกับการเรียกฟังก์ชันในเครื่อง
4. สร้างโค้ดไคลเอ็นต์และเซิร์ฟเวอร์
จากนั้นสร้างโค้ด gRPC มาตรฐานสำหรับทั้งไคลเอ็นต์และเซิร์ฟเวอร์จากไฟล์ .proto
โดยใช้คอมไพเลอร์ Protocol Buffer
เราได้สร้าง grpcio-tools สำหรับการสร้างโค้ด gRPC Python แอปประกอบด้วย
- คอมไพเลอร์ protoc ปกติที่สร้างโค้ด Python จากคำจำกัดความ
message
- ปลั๊กอิน Protobuf ของ gRPC ที่สร้างโค้ด Python (ต้นขั้วไคลเอ็นต์และเซิร์ฟเวอร์) จาก
service
เราจะติดตั้งgrpcio-tools
แพ็กเกจ Python โดยใช้ pip มาสร้างสภาพแวดล้อมเสมือนของ Python (venv) ใหม่เพื่อแยกการอ้างอิงของโปรเจ็กต์ออกจากแพ็กเกจของระบบกัน
python3 -m venv --upgrade-deps .venv
วิธีเปิดใช้งานสภาพแวดล้อมเสมือนใน Bash/Zsh Shell
source .venv/bin/activate
สำหรับ Windows และเชลล์ที่ไม่ใช่แบบมาตรฐาน โปรดดูตารางที่ https://docs.python.org/3/library/venv.html#how-venvs-work
จากนั้นติดตั้ง grpcio-tools (ซึ่งจะติดตั้งแพ็กเกจ grpcio ด้วย)
pip install grpcio-tools
ใช้คำสั่งต่อไปนี้เพื่อสร้างโค้ดบอยเลอร์เพลต Python
python -m grpc_tools.protoc --proto_path=./protos \
--python_out=. --pyi_out=. --grpc_python_out=. \
./protos/route_guide.proto
การดำเนินการนี้จะสร้างไฟล์ต่อไปนี้สำหรับอินเทอร์เฟซที่เรากำหนดไว้ใน route_guide.proto
route_guide_pb2.py
มีโค้ดที่สร้างคลาสแบบไดนามิกซึ่งสร้างจากคำจำกัดความของmessage
route_guide_pb2.pyi
คือ "ไฟล์ Stub" หรือ "ไฟล์คำแนะนำประเภท" ที่สร้างจากคำจำกัดความของmessage
โดยจะมีเฉพาะลายเซ็นที่ไม่มีการติดตั้งใช้งาน IDE สามารถใช้ไฟล์ Stub เพื่อให้การเติมข้อความอัตโนมัติและการตรวจหาข้อผิดพลาดดียิ่งขึ้นroute_guide_pb2_grpc.py
สร้างขึ้นจากคำจำกัดความของservice
และมีคลาสและฟังก์ชันเฉพาะของ gRPC
โค้ดเฉพาะ gRPC มีดังนี้
RouteGuideStub
ซึ่งไคลเอ็นต์ gRPC สามารถใช้เพื่อเรียกใช้ RPC ของ RouteGuide ได้RouteGuideServicer
ซึ่งกำหนดอินเทอร์เฟซสำหรับการใช้งานบริการRouteGuide
add_RouteGuideServicer_to_server
ฟังก์ชันที่ใช้เพื่อลงทะเบียนRouteGuideServicer
กับ เซิร์ฟเวอร์ gRPC
5. สร้างบริการ
ก่อนอื่นมาดูวิธีสร้างRouteGuide
เซิร์ฟเวอร์กัน การสร้างและเรียกใช้RouteGuide
เซิร์ฟเวอร์แบ่งออกเป็น 2 รายการงาน ดังนี้
- การติดตั้งใช้งานอินเทอร์เฟซผู้ให้บริการที่สร้างขึ้นจากคำจำกัดความของบริการของเราด้วยฟังก์ชันที่ทำ "งาน" จริงของบริการ
- เรียกใช้เซิร์ฟเวอร์ gRPC ที่พอร์ตที่เฉพาะเจาะจงเพื่อรอรับคำขอจากไคลเอ็นต์และส่งการตอบกลับ
คุณดูเซิร์ฟเวอร์ RouteGuide
เริ่มต้นได้ใน start_here/route_guide_server.py
ใช้ RouteGuide
route_guide_server.py
มีคลาส RouteGuideServicer
ที่เป็นคลาสย่อยของคลาส route_guide_pb2_grpc.RouteGuideServicer
ที่สร้างขึ้น
# RouteGuideServicer provides an implementation
# of the methods of the RouteGuide service.
class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
RouteGuideServicer
จะใช้เมธอดบริการทั้งหมดของ RouteGuide
มาดูรายละเอียดการติดตั้งใช้งาน RPC อย่างง่ายกัน เมธอด GetFeature
จะรับ Point
จากไคลเอ็นต์และส่งคืนข้อมูลฟีเจอร์ที่เกี่ยวข้องจากฐานข้อมูลใน Feature
def GetFeature(self, request, context):
feature = get_feature(self.db, request)
if feature is None:
return route_guide_pb2.Feature(name="", location=request)
else:
return feature
เมธอดจะส่งroute_guide_pb2.Point
คำขอสำหรับ RPC และออบเจ็กต์grpc.ServicerContext
ที่ให้ข้อมูลเฉพาะของ RPC เช่น ขีดจำกัดการหมดเวลา โดยจะแสดงการตอบกลับ route_guide_pb2.Feature
การเริ่มต้นเซิร์ฟเวอร์
เมื่อใช้RouteGuide
เมธอดทั้งหมดแล้ว ขั้นตอนถัดไปคือการเริ่มต้นเซิร์ฟเวอร์ gRPC เพื่อให้ไคลเอ็นต์ใช้บริการของคุณได้จริง
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
RouteGuideServicer(),
server,
)
listen_addr = "localhost:50051"
server.add_insecure_port(listen_addr)
print(f"Starting server on {listen_addr}")
server.start()
server.wait_for_termination()
เมธอดเซิร์ฟเวอร์ start()
จะไม่บล็อก ระบบจะสร้างเธรดใหม่เพื่อจัดการคำขอ โดยปกติแล้ว เธรดที่เรียก server.start()
จะไม่มีงานอื่นใดให้ทำในระหว่างนี้ ในกรณีนี้ คุณสามารถเรียกใช้ server.wait_for_termination()
เพื่อบล็อกเธรดการโทรอย่างสมบูรณ์จนกว่าเซิร์ฟเวอร์จะสิ้นสุด
6. สร้างไคลเอ็นต์
ในส่วนนี้ เราจะมาดูการสร้างไคลเอ็นต์สำหรับบริการ RouteGuide
คุณดูรหัสไคลเอ็นต์เริ่มต้นได้ใน start_here/route_guide_client.py
สร้าง Stub
หากต้องการเรียกใช้เมธอดของบริการ เราต้องสร้างสตับก่อน
เราสร้างอินสแตนซ์ของคลาส RouteGuideStub
ของโมดูล route_guide_pb2_grpc
ซึ่งสร้างจาก .proto
ภายในไฟล์ route_guide_client.py
channel = grpc.insecure_channel("localhost:50051")
stub = route_guide_pb2_grpc.RouteGuideStub(channel)
วิธีการใช้บริการโทร
สำหรับเมธอด RPC ที่ส่งคืนการตอบกลับรายการเดียว ซึ่งเรียกว่าเมธอด response-unary นั้น gRPC Python รองรับทั้งซีแมนทิกส์ของโฟลว์การควบคุมแบบซิงโครนัส (บล็อก) และแบบไม่พร้อมกัน (ไม่บล็อก)
RPC อย่างง่าย
ก่อนอื่น มากำหนด Point
เพื่อเรียกใช้บริการกัน ซึ่งควรจะง่ายเหมือนกับการสร้างออบเจ็กต์จากแพ็กเกจ route_guide_pb2
ที่มีพร็อพเพอร์ตี้บางอย่าง ดังนี้
point = route_guide_pb2.Point(latitude=412346009, longitude=-744026814)
การเรียกแบบซิงโครนัสไปยัง RPC อย่างง่าย GetFeature
นั้นแทบจะตรงไปตรงมาเหมือนกับการเรียกเมธอดในเครื่อง การเรียก RPC จะรอให้เซิร์ฟเวอร์ตอบกลับ และจะแสดงการตอบกลับหรือยกเว้น เราเรียกใช้เมธอดและดูการตอบกลับได้ดังนี้
feature = stub.GetFeature(point)
print(feature)
คุณสามารถตรวจสอบฟิลด์ของออบเจ็กต์ฟีเจอร์และแสดงผลลัพธ์ของคำขอได้โดยทำดังนี้
if feature.name:
print(f"Feature called '{feature.name}' at {format_point(feature.location)}")
else:
print(f"Found no feature at at {format_point(feature.location)}")
7. ลองเลย
เรียกใช้เซิร์ฟเวอร์
python route_guide_server.py
จากเทอร์มินัลอื่น ให้เปิดใช้งานสภาพแวดล้อมเสมือนอีกครั้ง แล้วเรียกใช้ไคลเอ็นต์
python route_guide_client.py
คุณจะเห็นเอาต์พุตลักษณะนี้ โดยระบบจะละเว้นการประทับเวลาเพื่อความชัดเจน
name: "16 Old Brook Lane, Warwick, NY 10990, USA" location { latitude: 412346009 longitude: -744026814 } Feature called '16 Old Brook Lane, Warwick, NY 10990, USA' at latitude: 412346009, longitude: -744026814
8. ขั้นตอนถัดไป
- ดูวิธีการทำงานของ gRPC ในข้อมูลเบื้องต้นเกี่ยวกับ gRPC และแนวคิดหลัก
- ดูบทแนะนำเกี่ยวกับพื้นฐาน
- สำรวจข้อมูลอ้างอิงของ Python API