gRPC (gRPC Remote Procedure Calls) הוא מסגרת RPC (Remote Procedure Call) מודרנית, תואמת קוד פתוח וביצועית גבוהה שפותחה על ידי Google. היא מיועדת לקידום תקשורת יעילה בין מערכות מבוזרות, מה שהופך אותה למתאימה במיוחד לארכיטקטורת מיקרו־שירותים. להלן הסבר על gRPC והתפקיד שלה בתקשורת שירותים מיקרו:
מהו gRPC?
gRPC היא פרוטוקול שמאפשר לאפליקציות לקוח ושרת לתקשר באופן שקוף, מה שהופך את בניית המערכות המבוזרות לקלה יותר. היא משתמשת ב־HTTP/2 לתחבורה, Protocol Buffers (Protobuf) כשפת הגדרת הממשק (IDL) שלה, ומספקת יכולות כמו אימות, איזון עומסים ועוד.
הנה כמה תכונות של gRPC:
- מגדיר תוך תוכנה. gRPC תומך במספר שפות תכנות, כולל Java, Python, Go, C++ ועוד.
- תקשורת יעילה. היא משתמשת בסידור נתונים בינארי עם Protobuf, שהוא מהיר וממוצע יותר מפורמטים מבוססי טקסט כמו JSON.
- מבוסס על HTTP/2. gRPC משתמשת ב־HTTP/2, מאפשרת יכולות כמו מולטיפלקסינג, סטרימינג והפחתת לטנציה.
- מסוגל לסוגים. שירותים והודעות מוגדרים באמצעות Protobuf, מבטיחים בטיחות מסוגה ומפחיתים שגיאות.
- תמיכה בזרימה. gRPC תומך בארבעה סוגים של זרימה: יחידת משמע, זרימת שרת, זרימת לקוח, וזרימה דו-כיוונית.
איך פועל gRPC
1. הגדרת שירותים והודעות
באמצעות Protobuf, אתה מגדיר את ממשק השירות (שיטות) ואת מבנה ההודעות שיתקבלו וישלחו.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
2. יצירת קוד
המהדר של Protobuf (protoc) יוצר קוד ללקוח ולשרת בשפת התכנות שבחרת.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
3. מימוש שרת
מיישום הלוגיקה בצד השרת עבור השירות שהוגדר.
4. יצירת לקוח
השתמש בקוד הלקוח שנוצר כדי לקרוא לשיטות השרת.
תפקידו של gRPC בתקשורת בין שירותים קטנים
ארכיטקטורות של שירותים קטנים משתייכות לפיצול אפליקציות לשירותים קטנים ועצמאיים שמתקשרים דרך הרשת. gRPC משמש תפקיד מרכזי בהקשר זה בגלל יעילותו וגמישותו.
1. ביצועים גבוהים
- gRPC משתמש בסידור בינארי עם Protobuf, שהוא מהיר וקומפקטי יותר מפורמטים מבוססי טקסט כמו JSON או XML.
- HTTP/2 מפחית את ההשהייה ומשפר את הכושר כפילי על ידי אפשרות לכפל וכיווץ של כותרות.
2. הגדרת חוזה חזקה
- Protobuf מאכזב חוזה מחמיר בין השירותים, מוריד את הסיכוי לשגיאות תקשורת.
- שינויים בהגדרת השירות ניתנים לניהול באמצעות גרסאות, מבטיחים תאימות לאחור.
3. יכולויות הזרמה
- gRPC תומך בזרימה דו-כיוונית, מה שהופך אותו לאידיאלי לתקשורת בזמן אמת, כמו יישומי צ'אט או זרמי נתונים חיים.
- זרימה בצד השרת ובצד הלקוח מאפשרת טיפול יעיל בסטים נתונים גדולים או זרמי נתונים רציפים.
4. תאימות
- gRPC הוא אגוריתם תלת-לשוני, המאפשר לשירותים קטנים שנכתבו בשפות שונות לתקשר בצורה חלקה.
- תכונה זו נחוצה במיוחד בסביבות שירותים קטנים פוליגלוטיות.
5. תכונות מובנות
- gRPC מספק תמיכה מובנית בתכונות כמו אימות, הצפנה (דרך TLS) ואיזון משאבים, מה שמפחית את הצורך בספריות או כלים נוספים.
6. קידומיות
- טבע קל של gRPC ותקשורת יעילה הופכים אותו למתאים לפיתוח שירותים קטנים בקני מידה גדולים.
- הוא משתלב היטב עם פלטפורמות אורקסטרציה של תוכניות כמו Kubernetes.
מקרים של שימוש ב-gRPC בשירותים קטנים
- תקשורת בין שירותים. gRPC הוא אידיאלי לתקשורת בין שירותים קטנים, במיוחד בתרחישים בהם הביצועים חיוניים.
- מערכות בזמן אמת. היכולות של הזרמה שלו הופכות אותו למתאים ליישומים בזמן אמת כמו משחקים, IoT או ניתוחים חיים.
- סביבות פוליגלוטיות. כאשר שירותים קטנים נכתבים בשפות שונות, gRPC מבטיח תקשורת חלקה.
- יישומים ענן-ניים. gRPC משתלב היטב עם טכנולוגיות ענן-ניים כמו Kubernetes ורשתות שירות (לדוגמה, Istio).
יתרונות של gRPC
- יעילות. סידור בינארי ו-HTTP/2 הופכים את gRPC למהיר וליעיל במשאבים יותר.
- בטיחות סוגים. Protobuf מבטיח סוגים חזקים שמפחיתים שגיאות בזמן ריצה.
- תמיכה חוצת שפות. עובד על מספר שפות תכנות.
- זרימה. תומך בתבניות זרימה מתקדמות לתקשורת בזמן אמת.
אתגרים של gRPC
- מורכבות. הגדרת gRPC עשויה להיות יותר מורכבת מאשר REST בגלל הצורך בהגדרות Protobuf ובייצור קוד.
- כלים. איתור באגים ובדיקת שירותי gRPC עשויים להיות קשות יותר בהשוואה ל-REST, מאחר שכלים כמו Postman אינם מותאמים באופן טבעי ל-gRPC.
- תמיכת דפדפן. gRPC אינו נתמך באופן טבעי בדפדפנים, ודורש כלים כמו gRPC-Web עבור לקוחות מבוססי רשת.
למה להשתמש ב-gRPC עם Spring Boot?
Spring Boot היא סביבת עבודה פופולרית לבניית יישומים ב-Java, ובשילוב עם gRPC מאפשרת למפתחים ליצור שירותים בעלי ביצועים גבוהים, קלים להרחבה ובר-תקשורתיים. עם התצורה האוטומטית והזרימת תלות של Spring Boot, שילוב של gRPC הופך להיות פשוט.
שלבים לבניית היישום
נבנה שירות gRPC פשוט בשם Greeter
שמאפשר ללקוח לשלוח שם לשרת ולקבל תגובה "שלום, {שם}!". כך נבצע את זה:
- הגדר את שירות ה-gRPC באמצעות Protocol Buffers.
- צור מחלקות Java מהקובץ
.proto
. - מיישם את השרת gRPC ב-Spring Boot.
- מיישם את הלקוח gRPC ב-Spring Boot.
- הוסף בקר REST כדי לקרוא ללקוח gRPC לצורך בדיקה.
- הפעל את היישום ובדוק את התקשורת.
1. הגדר את שירות ה-gRPC (.proto File)
הצעד הראשון הוא להגדיר את שירות ה-gRPC באמצעות Protocol Buffers. צור קובץ בשם greeter.proto
בתיקיית src/main/proto
:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.example.grpc";
option java_outer_classname = "GreeterProto";
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
קובץ זה מגדיר:
- שירות
Greeter
עם שיטת RPCSayHello
. - הודעת
HelloRequest
המכילה שדהname
. - הודעת
HelloResponse
המכילה שדהmessage
.
2. הוסף תלות
כדי להשתמש ב-gRPC עם Spring Boot, הוסף את התלויות הבאות לקובץ pom.xml
:
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Spring Boot Web for REST Controller -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- gRPC dependencies -->
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version>2.14.0.RELEASE</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.54.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.54.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.54.0</version>
</dependency>
<!-- Protobuf Java Format -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.22.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Protobuf Compiler Plugin -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.22.2:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.54.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
התלויות אלו כוללות:
- Spring Boot Starter להגדרה בסיסית של היישום.
- Spring Boot Web לתמיכה בבקר REST.
- ספריות gRPC ליישום שרת ולקוח.
- Protobuf לסידור ופירוק.
3. הפקת מחלקות Java
הפעל את הפקודה של Maven הבאה כדי להפיק מחלקות Java מהקובץ .proto
:
mvn clean compile
זה יפיק את ה-GreeterGrpc
ואת המחלקות הקשורות בתיקיית target/generated-sources
.
4. ליישם את שרת ה-gRPC
לבצע את שרת ה-gRPC ב-Spring Boot. יש ליצור מחלקה בשם GreeterService
:
package com.example.grpc.server;
import com.example.grpc.GreeterGrpc;
import com.example.grpc.GreeterProto.HelloRequest;
import com.example.grpc.GreeterProto.HelloResponse;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
@GrpcService
public class GreeterService extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest request, StreamObserver responseObserver) {
String name = request.getName();
String message = "Hello, " + name + "!";
HelloResponse response = HelloResponse.newBuilder().setMessage(message).build();
// לשלוח את התגובה
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
מחלקה זו מרחיבה את ה-GreeterGrpc.GreeterImplBase
שנוצר ומיישם את השיטה sayHello
כדי לטפל בבקשות נכנסות.
5. ליישם את הלקוח של gRPC
כעת, יש ליישם את הלקוח של gRPC ב-Spring Boot. יש ליצור מחלקה בשם GreeterClient
:
package com.example.grpc.client;
import com.example.grpc.GreeterGrpc;
import com.example.grpc.GreeterProto.HelloRequest;
import com.example.grpc.GreeterProto.HelloResponse;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.springframework.stereotype.Service;
@Service
public class GreeterClient {
private final GreeterGrpc.GreeterBlockingStub blockingStub;
public GreeterClient() {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9090)
.usePlaintext()
.build();
this.blockingStub = GreeterGrpc.newBlockingStub(channel);
}
public String sayHello(String name) {
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
HelloResponse response = blockingStub.sayHello(request);
return response.getMessage();
}
}
הלקוח הזה מתחבר לשרת ה-gRPC ושולח בקשה לשיטת SayHello
.
6. להוסיף בקר REST לצורך בדיקות
כדי להקל על בדיקת הלקוח של gRPC, נוסיף בקר REST שמספק נקודת גישה לקריאה ל-GreeterClient
. יש ליצור מחלקה בשם GreeterController
:
package com.example.grpc.controller;
import com.example.grpc.client.GreeterClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreeterController {
private final GreeterClient greeterClient;
@Autowired
public GreeterController(GreeterClient greeterClient) {
this.greeterClient = greeterClient;
}
@GetMapping("/greet")
public String greet(@RequestParam String name) {
return greeterClient.sayHello(name);
}
}
בקר זה מספק נקודת גישה /greet
שמקבלת פרמטר name
ומחזירה את התגובה מהשרת gRPC.
7. ליצור את היישום של Spring Boot
לבסוף, יש ליצור אפליקציית Spring Boot להפעלת השרת והלקוח:
package com.example.grpc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GrpcApplication {
public static void main(String[] args) {
SpringApplication.run(GrpcApplication.class, args);
}
}
8. להגדיר את פורט השרת
להוסיף את התצורה הבאה ל-application.properties
:
# פורט שרת gRPC
grpc.server.port=9090
# פורט שרת Spring Boot
server.port=8080
9. להריץ את היישום
- להתחיל את אפליקציית Spring Boot.
- השרת gRPC יתחיל בפורט
9090
. - בקר ה-REST יהיה זמין בפורט
8080
.
ניתן לבדוק את היישום על ידי שליחת בקשת GET לנקודת הקצה /greet
:
curl http://localhost:8080/greet?name=World
התשובה תהיה:
"Hello, World!"
בחירת הספריית gRPC הנכונה עבור Spring Boot
כאשר מבצעים בניית יישומי Spring Boot שדורשים אינטגרציה עם gRPC, מפתחים נתקלים לעתים תקופות בבחירה בין מספר ספריות. האפשרויות הנפוצות ביותר לדיון הן net.devh.grpc
, org.lognet.grpc
, ו-org.springframework.grpc
.
כל אחת מהספריות הללו יש לה מוטיבים, חולשות ומקרים שימושיים משלה. בואו נבדוק את ההבדלים בין הספריות הללו, התכונות שלהן, ואיזו מתוכן כדאי להשתמש בהעבודה שלך.
1. net.devh.grpc (grpc-spring-boot-starter)
net.devh.grpc
, הידוע גם בשם grpc-spring-boot-starter
, היא ספריית פופולרית לאינטגרציה של gRPC עם Spring Boot. היא נתמכת פעיל ומספקת סט עמיד של תכונות לבניית שרתי gRPC ולקליינטים ביישום Spring Boot.
תכונות מרכזיות
- הגדרה אוטומטית. מקלה על הגדרת שרתי וקליינטי gRPC.
- אינטגרציה עם Spring. תומכת בהזרמת תלות ותכונות אחרות של Spring.
- אבטחת Spring. משתלבת בקלות עם אבטחת Spring לתקשורת מאובטחת.
- בדיקות בריאות. מספקת בדיקות בריאות דרך Spring Boot Actuator.
- תקשורת סינכרונית ואסינכרונית. תומך בשני סגנונות תקשורת.
למה להשתמש בזה?
- תחזוקה פעילה. הספרייה מתוחזקת ומתעדכנת באופן פעיל.
- תיעוד מקיף. מתועד היטב ויש קהילה גדולה לתמיכה.
- מוכן לייצור. משמש בצורה נרחבת בסביבות ייצור.
מתי להשתמש בזה?
- אם אתה בונה אפליקציית Spring Boot חדשה ואתה זקוק לאינטגרציה אמינה ועשירה בתכונות של gRPC.
- אם ברצונך באינטגרציה חלקה עם תכונות Spring Boot כמו הזרמת תלות, אבטחה ובדיקות בריאות.
2. org.lognet.grpc (grpc-spring-boot-starter)
org.lognet.grpc
היא ספרייה נוספת לאינטגרציה של gRPC עם Spring Boot. אף על פי שהיא מתוחזקת בצורה פחות פעילה מאשר net.devh.grpc
וחסרת חלק מהתכונות המתקדמות שמציעה האחרונה.
תכונות מרכזיות
- הגדרת gRPC בסיסית. מספק תמיכה בסיסית לשרתים וללקוחות של gRPC.
- אינטגרציה עם Spring Boot. עובד עם Spring Boot אך עם פחות תכונות.
למה להשתמש בזה?
- שימוש היסטורי. הייתה אחת מהספריות המוקדמות לאינטגרציה של gRPC וSpring Boot.
- פשטות. מתאימה למקרים פשוטים.
מתי להשתמש בזה?
- אם אתה עובד על פרוייקט ישן שכבר משתמש בספרייה זו.
- לא מומלץ לפרויקטים חדשים עקב תחזוקה מוגבלת ופחות יכולות.
3. org.springframework.grpc (Spring gRPC)
org.springframework.grpc
הוא מאמץ ניסיוני או מוביל על ידי הקהילה לשלב את gRPC עם Spring. זה אינו פרויקט רשמי של Spring ועשוי שלא להיות כהשכב או עשיר ביכולות כמו net.devh.grpc
.
תכונות עיקריות
- שילוב בסיסי של gRPC. מספק תמיכה בסיסית לשרתים וללקוחות של gRPC.
- יישום קרוב עם אקוסיסטמת Spring. מותאם להתאמה קרובה עם אקוסיסטמת Spring.
למה להשתמש בזה?
- שימוש ניסיוני. מתאים לניסויים או לתרומה לפרויקט.
- התאמה ל-Spring. אם אתה מעדיף להשתמש במשהו שמתאים קרוב עם Spring.
מתי להשתמש בזה?
- רק אם אתה חוקר או מתרומם לפרויקט.
- לא מומלץ לשימוש בייצור עקב טבעו הנסיוני.
איזה ממנם להשתמש בו?
לפרויקטים חדשים
השתמש ב-net.devh.grpc
(grpc-spring-boot-starter). זהו האפשרות הכי מבוגרת, מתוחזקת באופן פעיל, ועשירה ביכולות לשילוב gRPC עם Spring Boot. השילוב החלק שלו עם תכונות Spring Boot הופך אותו לבחירה הכי טובה לפרויקטים חדשים.
לפרויקטים קיימים
אם אתה כבר משתמש ב־org.lognet.grpc
, שקול לעבור ל־net.devh.grpc
לתמיכה ותכונות טובות יותר. בעוד org.lognet.grpc
עשוי לעבוד עבור פרויקטים ישנים, חסרות לו התחזוקה הפעילה והתכונות המתקדמות של net.devh.grpc
.
לשימוש ניסיוני
אם אתה חוקר או תורם לאינטגרציה של Spring עם gRPC, תוכל לבחון את org.springframework.grpc
. אולם, אין מומלץ לשימוש בפרקטיקה בשל טבעו הניסיוני.
שיקולים מרכזיים
- תמיכה בקהילה. ל־
net.devh.grpc
יש קהילה גדולה יותר ותיעוד טוב יותר, מה שהופך את העזרה והמשאבים לקלים יותר למציאה. - הכנה לפרודוקשן.
net.devh.grpc
משמש בסביבות פרודוקשן ברחבי העולם ומתפקד כמובן ואמין. - נוחות השימוש.
net.devh.grpc
מספק תצורה אוטומטית ואינטגרציה חלקה עם Spring Boot, מה שמפחית את המורכבות של התקנה.
מסקנה
gRPC הוא כלי עוצמתי לתקשורת בין שירותים המציע ביצועים גבוהים, סוגון חזק ותכונות מתקדמות כגון סטרימינג. על אף שהוא מחייב התקנה ראשונית יותר בהשוואה ל־REST, היעילות והסקאלביליות שלו הופכות אותו לבחירה מצוינת למערכות מודרניות ומבוזרות.
ככל שמערכות מיקרו-שירותים הולכות ומסובכות יותר, gRPC משחק תפקיד הולך וגדל בהנעת תקשורת חלקה בין שירותים. במאמר זה, בנינו יישום פשוט של לקוח ושרת gRPC באמצעות Spring Boot 3, הגדרנו שירות gRPC עם Protocol Buffers, יצרנו מחלקות Java, יישמנו את השרת ואת הלקוח, והוספנו בקר REST לבדיקות קלות. דוגמה זו מציגה את הכוח ואת הפשטות של gRPC לבניית שירותים בעלי ביצועים גבוהים, ניתנים להרחבה, ואינטרופראביליים. ניתן להרחיב זאת עוד עם שירותים מורכבים יותר, סטרימינג, או טיפול בשגיאות. קידוד מהנה!
מאגר GitHub: grpc-client-and-server-with-spring-boot.
Source:
https://dzone.com/articles/understanding-grpc-and-its-role-in-microservices-c