1. סקירה כללית
Spring Integration מספקת לכם מנגנון העברת הודעות להחלפת Messages דרך MessageChannels. הוא משתמש במתאמי ערוצים כדי לתקשר עם מערכות חיצוניות.
בתרגיל הזה ניצור שתי אפליקציות שמתקשרות באמצעות מתאמי הערוצים של Spring Integration שסופקו על ידי Spring Cloud GCP. המתאמים האלה מאפשרים ל-Spring Integration להשתמש ב-Google Cloud Pub/Sub כבק-אנד לחילופי הודעות.
תלמדו איך להשתמש ב-Cloud Shell ובפקודה gcloud של Cloud SDK.
במדריך הזה נעשה שימוש בקוד לדוגמה מתוך המדריך לתחילת העבודה עם Spring Boot.
מה תלמדו
- איך להחליף הודעות בין אפליקציות באמצעות Google Cloud Pub/Sub באמצעות Spring Integration ו-Spring Cloud GCP
מה תצטרכו
- פרויקט ב-Google Cloud Platform
- דפדפן, כמו Chrome או Firefox
- היכרות עם כלים לעריכת טקסט של Linux, כמו Vim, EMACs או Nano
איך תשתמש במדריך הזה?
מה מידת שביעות הרצון שלך מחוויית השימוש ב-HTML/CSS ליצירת אפליקציות אינטרנט?
איזה דירוג מגיע לדעתך לחוויית השימוש שלך בשירותים של Google Cloud Platform?
2. הגדרה ודרישות
הגדרת סביבה בקצב אישי
- נכנסים ל-מסוף Google Cloud ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או Google Workspace, אתם צריכים ליצור חשבון.



- שם הפרויקט הוא השם המוצג של הפרויקט הזה למשתתפים. זו מחרוזת תווים שלא נמצאת בשימוש ב-Google APIs. תמיד אפשר לעדכן את המיקום.
- מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud, והוא קבוע (אי אפשר לשנות אותו אחרי שהוא מוגדר). מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית, ובדרך כלל לא צריך לדעת מה היא. ברוב ה-Codelabs, תצטרכו להפנות למזהה הפרויקט (בדרך כלל מסומן כ-
PROJECT_ID). אם אתם לא אוהבים את המזהה שנוצר, אתם יכולים ליצור מזהה אקראי אחר. אפשר גם לנסות שם משתמש משלכם ולבדוק אם הוא זמין. אי אפשר לשנות את ההגדרה הזו אחרי השלב הזה, והיא תישאר לאורך הפרויקט. - לידיעתכם, יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. במאמרי העזרה מפורט מידע נוסף על שלושת הערכים האלה.
- בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API של Cloud. השלמת ה-codelab הזה לא תעלה לכם הרבה, אם בכלל. כדי להשבית את המשאבים ולמנוע חיובים נוספים אחרי שתסיימו את המדריך הזה, תוכלו למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.
Google Cloud Shell
אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-codelab הזה נשתמש ב-Google Cloud Shell, סביבת שורת פקודה שפועלת בענן.
הפעלת Cloud Shell
- ב-Cloud Console, לוחצים על Activate Cloud Shell
.

אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים עם תיאור של השירות. אם הוצג לכם מסך ביניים, לחצו על המשך.

הקצאת המשאבים והחיבור ל-Cloud Shell נמשכים רק כמה רגעים.

המכונה הווירטואלית הזו כוללת את כל הכלים הדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות ברשת. אפשר לבצע את רוב העבודה ב-codelab הזה, אם לא את כולה, באמצעות דפדפן.
אחרי שמתחברים ל-Cloud Shell, אמור להופיע אימות ושהפרויקט מוגדר לפי מזהה הפרויקט.
- מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שעברתם אימות:
gcloud auth list
פלט הפקודה
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שפקודת gcloud מכירה את הפרויקט:
gcloud config list project
פלט הפקודה
[core] project = <PROJECT_ID>
אם לא, אפשר להגדיר אותו באמצעות הפקודה הבאה:
gcloud config set project <PROJECT_ID>
פלט הפקודה
Updated property [core/project].
3. הקצאת משאבים ב-Pub/Sub
עוברים אל הדף בנושאים של Google Cloud Pub/Sub.
לוחצים על יצירת נושא.

מקלידים exampleTopic בתור שם הנושא ולוחצים על יצירה.

אחרי שיוצרים את הנושא, נשארים בדף 'נושאים'. חפשו את הנושא שיצרתם, לחצו על שלוש הנקודות האנכיות בסוף השורה ואז על New Subscription (מינוי חדש).

מקלידים exampleSubscription בתיבת הטקסט של שם המינוי ולוחצים על יצירה.

4. אתחול אפליקציות Spring Boot
אחרי ההפעלה של Cloud Shell, אפשר להשתמש בשורת הפקודה כדי ליצור שתי אפליקציות חדשות של Spring Boot באמצעות Spring Initializr:
$ curl https://start.spring.io/starter.tgz \
-d bootVersion=3.0.5 \
-d dependencies=web,integration,cloud-gcp-pubsub \
-d type=maven-project \
-d baseDir=spring-integration-sender | tar -xzvf -
$ curl https://start.spring.io/starter.tgz \
-d bootVersion=3.0.5 \
-d dependencies=web,integration,cloud-gcp-pubsub \
-d type=maven-project \
-d baseDir=spring-integration-receiver | tar -xzvf -
5. יצירת אפליקציה לשליחת הודעות
עכשיו ניצור את האפליקציה לשליחת הודעות. עוברים לספרייה של האפליקציה לשליחה.
$ cd spring-integration-sender
אנחנו רוצים שהאפליקציה שלנו תכתוב הודעות בערוץ. אחרי שההודעה מגיעה לערוץ, היא נאספת על ידי מתאם הערוץ היוצא, שממיר אותה מהודעת Spring כללית להודעת Google Cloud Pub/Sub ומפרסם אותה בנושא Google Cloud Pub/Sub.
כדי שהאפליקציה שלנו תוכל לכתוב לערוץ, אנחנו יכולים להשתמש ב-Spring Integration messaging gateway. באמצעות עורך טקסט מ-vim, emacs או nano, מכריזים על ממשק PubsubOutboundGateway בתוך המחלקה DemoApplication.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.integration.annotation.MessagingGateway;
@SpringBootApplication
public class DemoApplication {
...
@MessagingGateway(defaultRequestChannel = "pubsubOutputChannel")
public interface PubsubOutboundGateway {
void sendToPubsub(String text);
}
}
יש לנו עכשיו מנגנון לשליחת הודעות לערוץ, אבל לאן ההודעות האלה מגיעות אחרי שהן בערוץ?
אנחנו צריכים מתאם של ערוץ יוצא כדי לצרוך הודעות חדשות בערוץ ולפרסם אותן בנושא Google Cloud Pub/Sub.
src/main/java/com/example/demo/DemoApplication.java
...
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.outbound.PubSubMessageHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.MessageHandler;
@SpringBootApplication
public class DemoApplication {
...
@Bean
@ServiceActivator(inputChannel = "pubsubOutputChannel")
public MessageHandler messageSender(PubSubTemplate pubsubTemplate) {
return new PubSubMessageHandler(pubsubTemplate, "exampleTopic");
}
}
ההערה @ServiceActivator גורמת לכך שההגדרה MessageHandler תחול על כל ההודעות החדשות ב-inputChannel. במקרה הזה, אנחנו קוראים למתאם של הערוץ היוצא, PubSubMessageHandler, כדי לפרסם את ההודעה בנושא exampleTopic של Google Cloud Pub/Sub.
אחרי שמוסיפים את מתאם הערוץ, אפשר לחבר אוטומטית אובייקט PubsubOutboundGateway ולהשתמש בו כדי לכתוב הודעה לערוץ.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.view.RedirectView;
@SpringBootApplication
public class DemoApplication {
...
@Autowired
private PubsubOutboundGateway messagingGateway;
@PostMapping("/postMessage")
public RedirectView postMessage(@RequestParam("message") String message) {
this.messagingGateway.sendToPubsub(message);
return new RedirectView("/");
}
}
בגלל ההערה @PostMapping, יש לנו עכשיו נקודת קצה (endpoint) שמקשיבה לבקשות HTTP POST, אבל רק אחרי שמוסיפים גם את ההערה @RestController למחלקה DemoApplication כדי לסמן אותה כבקר REST.
src/main/java/com/example/demo/DemoApplication.java
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
...
}
מוודאים שגרסת JAVA_HOME מוגדרת בצורה הנכונה.
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
מפעילים את אפליקציית השולח.
# Set the Project ID in environmental variable
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw spring-boot:run
האפליקציה מאזינה לבקשות POST שמכילות הודעה ביציאה 8080 ובנקודת הקצה /postMessage, אבל נגיע לזה בהמשך.
6. יצירת אפליקציה לקבלת הודעות
הרגע יצרנו אפליקציה ששולחת הודעות דרך Google Cloud Pub/Sub. עכשיו ניצור אפליקציה נוספת שתקבל את ההודעות האלה ותעבד אותן.
לוחצים על + כדי לפתוח סשן חדש ב-Cloud Shell.

לאחר מכן, בסשן החדש של Cloud Shell, משנים את הספרייה לספרייה של אפליקציית המקלט:
$ cd spring-integration-receiver
באפליקציה הקודמת, ההצהרה על שער ההודעות יצרה בשבילנו את הערוץ להודעות יוצאות. מכיוון שאנחנו לא משתמשים בשער להודעות כדי לקבל הודעות, אנחנו צריכים להצהיר על MessageChannel משלנו, שאליו יגיעו הודעות נכנסות.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.context.annotation.Bean;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.MessageChannel;
@SpringBootApplication
public class DemoApplication {
...
@Bean
public MessageChannel pubsubInputChannel() {
return new DirectChannel();
}
}
נצטרך את מתאם הערוץ הנכנס כדי לקבל הודעות מ-Google Cloud Pub/Sub ולהעביר אותן אל pubsubInputChannel.
src/main/java/com/example/demo/DemoApplication.java
...
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.inbound.PubSubInboundChannelAdapter;
import org.springframework.beans.factory.annotation.Qualifier;
@SpringBootApplication
public class DemoApplication {
...
@Bean
public PubSubInboundChannelAdapter messageChannelAdapter(
@Qualifier("pubsubInputChannel") MessageChannel inputChannel,
PubSubTemplate pubSubTemplate) {
PubSubInboundChannelAdapter adapter =
new PubSubInboundChannelAdapter(pubSubTemplate, "exampleSubscription");
adapter.setOutputChannel(inputChannel);
return adapter;
}
}
המתאם הזה נקשר ל-pubsubInputChannel ומאזין להודעות חדשות מהמינוי exampleSubscription של Google Cloud Pub/Sub.
יש לנו ערוץ שבו מתפרסמות הודעות נכנסות, אבל מה עושים עם ההודעות האלה?
בוא נעבד אותן באמצעות @ServiceActivator שמופעל כשמגיעות הודעות חדשות אל pubsubInputChannel. במקרה כזה, נתעד רק את מטען הנתונים של ההודעה.
src/main/java/com/example/demo/DemoApplication.java
...
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.annotation.ServiceActivator;
@SpringBootApplication
public class DemoApplication {
...
private static final Log LOGGER = LogFactory.getLog(DemoApplication.class);
@ServiceActivator(inputChannel = "pubsubInputChannel")
public void messageReceiver(String payload) {
LOGGER.info("Message arrived! Payload: " + payload);
}
}
מוודאים שגרסת JAVA_HOME מוגדרת בצורה הנכונה.
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
מריצים את אפליקציית המקלט.
$ ./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8081"
מעכשיו, כל ההודעות שתשלחו לאפליקציית השולח יתועדו באפליקציית המקבל. כדי לבדוק את זה, פותחים סשן חדש ב-Cloud Shell ושולחים בקשת HTTP POST לאפליקציית השולח.
$ curl --data "message=Hello world!" localhost:8080/postMessage
לאחר מכן, מוודאים שהאפליקציה של הנמען רשמה ביומן את ההודעה ששלחתם.
INFO: Message arrived! Payload: Hello world!
7. הסרת המשאבים
מוחקים את המינוי ואת הנושא שנוצרו כחלק מהתרגיל הזה.
$ gcloud pubsub subscriptions delete exampleSubscription
$ gcloud pubsub topics delete exampleTopic
8. סיכום
הגדרתם שתי אפליקציות Spring Boot שמשתמשות במתאמי הערוצים של Spring Integration ל-Google Cloud Pub/Sub. הם מחליפים ביניהם הודעות בלי ליצור אינטראקציה עם Google Cloud Pub/Sub API.
9. מעולה!
למדתם איך להשתמש במתאמי הערוצים של Spring Integration בשביל Google Cloud Pub/Sub.
מידע נוסף
- Google Cloud Pub/Sub: https://cloud.google.com/pubsub/
- פרויקט Spring ב-GCP: http://cloud.spring.io/spring-cloud-gcp/
- מאגר GitHub של Spring ב-GCP: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Java ב-Google Cloud Platform: https://cloud.google.com/java/
רישיון
עבודה זו מורשית תחת רישיון Creative Commons שמותנה בייחוס 2.0 כללי.