העברת הודעות עם שילוב אביב ו-Google Cloud Pub/Sub

השילוב של Spring מעניק לך מנגנון להעברת הודעות שאפשר להעביר אליו את Messages עד MessageChannels. היא משתמשת במתאמי ערוצים כדי לתקשר עם מערכות חיצוניות.

בתרגיל הזה, ניצור שתי אפליקציות שמקיימות תקשורת באמצעות מתאמים לערוץ שילוב Spring שמסופקים על ידי Spring Cloud GCP. המתאמים האלה משלבים את Spring ב-Google Cloud Pub/Sub כקצה העורפי של החלפת ההודעות.

תלמדו איך להשתמש ב-Cloud Shell ובפקודת Cloud SDK של Cloud.

המדריך הזה מבוסס על הקוד לדוגמה מתוך המדריך לתחילת העבודה באביב.

מה תלמדו

  • איך מעבירים הודעות בין אפליקציות עם Google Cloud Pub/Sub באמצעות Spring Integration ו-Spring Cloud GCP

מה צריך?

  • פרויקט של Google Cloud Platform
  • דפדפן, למשל Chrome או Firefox
  • היכרות עם עורכי טקסט רגילים של Linux, כמו Vim , EMAC או Nano

איך תשתמשו במדריך הזה?

לקרוא אותו בלבד לקרוא אותו ולהשלים את התרגילים

איך היית מדרג את החוויה שלך בעת בניית אפליקציות אינטרנט מסוג HTML/CSS?

מתחילים מתחילים בקיאים

איזה דירוג מתאים לדעתך לחוויית השימוש בשירותי Google Cloud Platform?

מתחילים מתחילים בקיאים

הגדרת סביבה בקצב עצמי

אם עדיין אין לכם חשבון Google (Gmail או Google Apps), עליכם ליצור חשבון. נכנסים למסוף ב-Google Cloud Platform (console.cloud.google.com) ויוצרים פרויקט חדש:

צילום מסך מ-2016-02-10 12:45:26.png

חשוב לזכור את מזהה הפרויקט הוא שם ייחודי בכל הפרויקטים ב-Google Cloud (השם הקודם כבר תפוס, והוא לא יעבוד בשבילך.) נתייחס אליו מאוחר יותר ב-codelab הזה בתור PROJECT_ID.

לאחר מכן, עליך להפעיל חיוב ב-Cloud Console כדי להשתמש במשאבים של Google Cloud.

התהליך של קוד Lab זה לא אמור לעלות יותר מדולר אחד, אבל יכול להיות שתצטרכו לשלם על משאבים נוספים או להשאיר אותו פעיל (עיינו בקטע "cleanup" בסוף המסמך).

משתמשים חדשים ב-Google Cloud Platform זכאים לתקופת ניסיון בחינם בשווי 300$.

Google Cloud Shell

ניתן להפעיל את Google Cloud מרחוק מהמחשב הנייד שלך, אבל במעבדה זו נעשה שימוש ב-Google Cloud Shell, סביבת שורת פקודה שפועלת ב-Cloud.

הפעלת Google Cloud Shell

במסוף GCP, לוחצים על הסמל של Cloud Shell בסרגל הכלים שבפינה השמאלית העליונה:

לאחר מכן לוחצים על "Start Cloud Shell":

יחלפו רק כמה רגעים עד שההקצאה והחיבור לסביבת העבודה יושלמו:

המכונה הווירטואלית הזו נטענת באמצעות כל כלי הפיתוח הדרושים לך. יש בה ספריית בית בנפח עקבי של 5GB, והיא פועלת ב-Google Cloud, וכך משפרת באופן משמעותי את הביצועים ואת האימות של הרשת. את רוב העבודה שלכם בשיעור ה-Lab הזה (אם לא כולם) אפשר לבצע בדפדפן או ב-Google Chromebook.

לאחר החיבור ל-Cloud Shell, אתם אמורים לראות שכבר בוצע אימות, ושהפרויקט כבר מוגדר ב-PROJECT_ID.

מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שאתם מאומתים:

gcloud auth list

פלט הפקודה

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

פלט הפקודה

[core]
project = <PROJECT_ID>

אם לא, אפשר להגדיר אותה באמצעות הפקודה הבאה:

gcloud config set project <PROJECT_ID>

פלט הפקודה

Updated property [core/project].

עוברים אל דף הנושאים של Google Cloud Pub/Sub ומפעילים את ה-API.

לוחצים על יצירת נושא.

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

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

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

לאחר ההשקה של Cloud Shell, תוכלו להשתמש בשורת הפקודה כדי ליצור שתי אפליקציות חדשות של Spring Boot עם Spring Initializr:

$ curl https://start.spring.io/starter.tgz \
  -d bootVersion=2.0.6.RELEASE \
  -d dependencies=web \
  -d baseDir=spring-integration-sender | tar -xzvf -
$ curl https://start.spring.io/starter.tgz \
  -d bootVersion=2.0.6.RELEASE \
  -d baseDir=spring-integration-receiver | tar -xzvf -

עכשיו אפשר ליצור את אפליקציית שליחת ההודעות שלנו. כדאי לשנות לספרייה של האפליקציה ששולחת.

$ cd spring-integration-sender

אנחנו רוצים שהאפליקציה שלנו תכתוב הודעות בערוץ. אחרי שהודעה נמצאת בערוץ, היא תיאסף על ידי מתאם הערוץ היוצא, שממיר אותה מהודעת אביב כללית להודעת Google Cloud Pub/Sub ומפרסמת אותה לנושא ב-Google Cloud Pub/Sub.

כדי שהאפליקציה שלנו תכתוב לערוץ, אנו יכולים להשתמש בשער העברת הודעות לשילוב באביב. באמצעות עורך טקסט מ-vim, מ-emacs או מ-nano, יש להצהיר על ממשק PubsubOutboundGateway בכיתה DemoApplication.

src/main/javascript/com/example/demo/DemoApplication.JavaScript

...
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/javascript/com/example/demo/DemoApplication.JavaScript

...
import org.springframework.cloud.gcp.pubsub.core.PubSubTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.cloud.gcp.pubsub.integration.outbound.PubSubMessageHandler;
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/javascript/com/example/demo/DemoApplication.JavaScript

...
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, יש לנו עכשיו נקודת קצה שמאזינים לבקשות HTTP POST, אבל בלי להוסיף הערה אחת (@RestController) לכיתה DemoApplication כדי לסמן אותה כבקר REST.

src/main/javascript/com/example/demo/DemoApplication.JavaScript

import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {
  ...
}

כדי שהאפליקציה תפעל, אנחנו רק צריכים להוסיף את התלות הנדרשות.

pom.xml

<project>
  ...
  <!-- Add Spring Cloud GCP Dependency BOM -->
  <dependencyManagement>
        <dependencies>
                <dependency>
                        <groupId>org.springframework.cloud</groupId>
                        <artifactId>spring-cloud-gcp-dependencies</artifactId>
                        <version>1.0.0.RELEASE</version>
                        <type>pom</type>
                        <scope>import</scope>
                </dependency>
        </dependencies>
  </dependencyManagement>

  <dependencies>
        ...
        <!-- Add Pub/Sub Starter -->
        <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
        </dependency>

        <!-- Add Spring Integration -->
        <dependency>
                <groupId>org.springframework.integration</groupId>
                <artifactId>spring-integration-core</artifactId>
        </dependency>

  </dependencies>

</project>

מריצים את אפליקציית השולח.

# 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, אבל נבדוק את זה מאוחר יותר.

לאחרונה יצרנו אפליקציה ששולחת הודעות דרך Google Cloud Pub/Sub. עכשיו ניצור אפליקציה אחרת שמקבלת את ההודעות האלה ומעבדת אותן.

לוחצים על + כדי לפתוח סשן חדש של Cloud Shell.

לאחר מכן, בסשן החדש של Cloud Shell, משנים את הספריות לספרייה של המקבל/ת:

$ cd spring-integration-receiver

באפליקציה הקודמת, הצהרת השער להעברת הודעות יצרה עבורנו את הערוץ היוצא. אנחנו לא משתמשים בשער לשליחת הודעות כדי להיכנס להודעות, ולכן עלינו להצהיר על מכשיר MessageChannel שלנו שאליו יגיעו הודעות נכנסות.

src/main/javascript/com/example/demo/DemoApplication.JavaScript

...
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/javascript/com/example/demo/DemoApplication.JavaScript

...
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.gcp.pubsub.core.PubSubTemplate;
import org.springframework.cloud.gcp.pubsub.integration.inbound.PubSubInboundChannelAdapter;

@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 והאזנה להודעות חדשות מהמינוי ל-Google Cloud Pub/Sub exampleSubscription.

יש לנו ערוץ שבו מתפרסמות הודעות נכנסות, אבל מה לעשות עם ההודעות האלה?

אנחנו מעבדים אותם עם @ServiceActivator שמופעל כאשר הודעות חדשות מגיעות ב-pubsubInputChannel.

src/main/javascript/com/example/demo/DemoApplication.JavaScript

...
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);
        }
}

במקרה כזה, אנחנו נרשום את המטען הייעודי (payload) של ההודעה.

עלינו להוסיף את התלות הנדרשות.

pom.xml

<project>
  ...
  <!-- Add Spring Cloud GCP Dependency BOM -->
  <dependencyManagement>
        <dependencies>
                <dependency>
                        <groupId>org.springframework.cloud</groupId>
                        <artifactId>spring-cloud-gcp-dependencies</artifactId>
                        <version>1.0.0.RELEASE</version>
                        <type>pom</type>
                        <scope>import</scope>
                </dependency>
        </dependencies>
  </dependencyManagement>

  <dependencies>
        ...
        <!-- Add Pub/Sub Starter -->
        <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
        </dependency>

        <!-- Add Spring Integration -->
        <dependency>
                <groupId>org.springframework.integration</groupId>
                <artifactId>spring-integration-core</artifactId>
        </dependency>

  </dependencies>

</project>

מפעילים את אפליקציית המקבל.

$ ./mvnw spring-boot:run

עכשיו, כל ההודעות שתשלחו לאפליקציית השולח יתועדו באפליקציית המקבל. כדי לבדוק זאת, עליכם לפתוח סשן חדש של Cloud Shell ולשלוח בקשת HTTP POST לאפליקציית השולח.

$ curl --data "message=Hello world!" localhost:8080/postMessage

לאחר מכן, מוודאים שהאפליקציה המקבלת רשמת את ההודעה ששלחת!

INFO: Message arrived! Payload: Hello world!

מחיקת המינוי והנושא שנוצרו במסגרת התרגיל הזה.

$ gcloud beta pubsub subscriptions delete exampleSubscription
$ gcloud beta pubsub topics delete exampleTopic

עליכם להגדיר שתי אפליקציות לאתחול ספרינג שמשתמשות במתאמי הערוצים של Spring ל-Google Cloud Pub/Sub. הם חילופי הודעות ביניהם ללא אינטראקציה עם Google Cloud Pub/Sub API.

איך משתמשים במתאמי הערוצים של Spring ל-Google Cloud Pub/Sub!

למידע נוסף

רישיון

היצירה הזו ברישיון תחת רישיון Creative Commons Attribution 2.0.