پیام رسانی با Spring Integration و Google Cloud Pub/Sub

Spring Integration مکانیزمی برای تبادل Messages از طریق MessageChannels در اختیار شما قرار می دهد. از آداپتورهای کانال برای ارتباط با سیستم های خارجی استفاده می کند.

در این تمرین، ما دو برنامه ایجاد می کنیم که با استفاده از آداپتورهای کانال Spring Integration ارائه شده توسط Spring Cloud GCP با هم ارتباط برقرار می کنند. این آداپتورها باعث می‌شوند که Spring Integration از Google Cloud Pub/Sub به‌عنوان پشتیبان تبادل پیام استفاده کند.

نحوه استفاده از Cloud Shell و Cloud SDK gcloud را یاد خواهید گرفت.

این آموزش از کد نمونه راهنمای شروع راه‌اندازی بهار استفاده می‌کند.

چیزی که یاد خواهید گرفت

  • نحوه تبادل پیام بین برنامه ها با Google Cloud Pub/Sub با استفاده از Spring Integration و Spring Cloud GCP

آنچه شما نیاز دارید

  • یک پروژه Google Cloud Platform
  • یک مرورگر، مانند کروم یا فایرفاکس
  • آشنایی با ویرایشگرهای متن استاندارد لینوکس مانند Vim، EMACs یا Nano

چگونه از این آموزش استفاده خواهید کرد؟

فقط از طریق آن را بخوانید آن را بخوانید و تمرینات را کامل کنید

تجربه خود را با ساختن برنامه های وب HTML/CSS چگونه ارزیابی می کنید؟

تازه کار حد واسط مسلط

تجربه خود را در استفاده از خدمات پلتفرم Google Cloud چگونه ارزیابی می کنید؟

تازه کار حد واسط مسلط

تنظیم محیط خود به خود

اگر قبلاً یک حساب Google (Gmail یا Google Apps) ندارید، باید یک حساب ایجاد کنید . به کنسول Google Cloud Platform ( consol.cloud.google.com ) وارد شوید و یک پروژه جدید ایجاد کنید:

اسکرین شات از 10/02/2016 12:45:26.png

شناسه پروژه را به خاطر بسپارید، یک نام منحصر به فرد در تمام پروژه های Google Cloud (نام بالا قبلاً گرفته شده است و برای شما کار نخواهد کرد، متأسفیم!). بعداً در این آزمایشگاه کد به عنوان PROJECT_ID خواهد شد.

در مرحله بعد، برای استفاده از منابع Google Cloud، باید صورتحساب را در کنسول Cloud فعال کنید.

گذراندن این کد نباید بیش از چند دلار هزینه داشته باشد، اما اگر تصمیم به استفاده از منابع بیشتری داشته باشید یا اگر آنها را در حال اجرا رها کنید، ممکن است بیشتر باشد (به بخش "پاکسازی" در انتهای این سند مراجعه کنید).

کاربران جدید Google Cloud Platform واجد شرایط استفاده آزمایشی رایگان 300 دلاری هستند.

Google Cloud Shell

در حالی که Google Cloud را می توان از راه دور از لپ تاپ شما کار کرد، در این کد لبه از Google Cloud Shell استفاده خواهیم کرد، یک محیط خط فرمان که در Cloud اجرا می شود.

Google Cloud Shell را فعال کنید

از کنسول GCP روی نماد Cloud Shell در نوار ابزار بالا سمت راست کلیک کنید:

سپس روی "Start Cloud Shell" کلیک کنید:

تهیه و اتصال به محیط فقط چند لحظه طول می کشد:

این ماشین مجازی با تمام ابزارهای توسعه که شما نیاز دارید بارگذاری شده است. این یک فهرست اصلی 5 گیگابایتی دائمی را ارائه می دهد و در Google Cloud اجرا می شود و عملکرد و احراز هویت شبکه را بسیار افزایش می دهد. اگر نگوییم تمام کارهای شما در این آزمایشگاه را می توان به سادگی با یک مرورگر یا 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 را به عنوان نام موضوع تایپ کنید و سپس روی Create کلیک کنید.

پس از ایجاد موضوع، در صفحه Topics باقی بمانید. به دنبال موضوعی باشید که ایجاد کرده اید، سه نقطه عمودی در انتهای خط را فشار دهید و روی اشتراک جدید کلیک کنید.

در کادر متنی نام اشتراک، 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

ما می خواهیم برنامه ما برای یک کانال پیام بنویسد. پس از اینکه یک پیام در کانال قرار گرفت، توسط آداپتور کانال خروجی دریافت می‌شود، که آن را از یک پیام عمومی Spring به یک پیام Google Cloud Pub/Sub تبدیل می‌کند و آن را به یک موضوع Google Cloud Pub/Sub منتشر می‌کند.

برای اینکه برنامه ما در یک کانال بنویسد، می‌توانیم از دروازه پیام‌رسانی Spring Integration استفاده کنیم. با استفاده از یک ویرایشگر متن از 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 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 ، تماس می گیریم تا پیام را در موضوع نمونه موضوعی Google Cloud Pub/Sub منتشر exampleTopic .

با آداپتور کانال، اکنون می‌توانیم یک شی 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 ، ما اکنون یک نقطه پایانی داریم که به درخواست‌های 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 {
  ...
}

برای اینکه برنامه اجرا شود، فقط باید وابستگی های مورد نیاز را اضافه کنیم.

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

در این مورد، ما فقط بار پیام را ثبت می کنیم.

ما باید وابستگی های لازم را اضافه کنیم.

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 Boot راه‌اندازی می‌کنید که از آداپتورهای کانال ادغام Spring برای Google Cloud Pub/Sub استفاده می‌کنند. آنها بدون اینکه با Google Cloud Pub/Sub API تعاملی داشته باشند، بین خود پیام رد و بدل می کنند.

شما یاد گرفتید که چگونه از آداپتورهای کانال ادغام Spring برای Google Cloud Pub/Sub استفاده کنید!

بیشتر بدانید

مجوز

این اثر تحت مجوز Creative Commons Attribution 2.0 Generic مجوز دارد.