Nhắn tin bằng Spring Sync và Google Cloud Pub/Sub

Tích hợp mùa xuân cung cấp cho bạn cơ chế nhắn tin để trao đổi Messages qua MessageChannels. Sử dụng bộ chuyển đổi kênh để giao tiếp với hệ thống bên ngoài.

Trong bài tập này, chúng ta sẽ tạo 2 ứng dụng giao tiếp bằng bộ chuyển đổi kênh tích hợp mùa xuân do Spring Cloud GCP cung cấp. Những bộ chuyển đổi này giúp Spring Sync sử dụng Google Cloud Pub/Sub làm phần phụ trợ trao đổi tin nhắn.

Bạn sẽ tìm hiểu cách sử dụng Cloud Shell và lệnh gcloud SDK Cloud.

Hướng dẫn này sử dụng mã mẫu từ Hướng dẫn bắt đầu khởi động mùa xuân.

Kiến thức bạn sẽ học được

  • Cách trao đổi tin nhắn giữa các ứng dụng với Google Cloud Pub/Sub bằng tính năng Tích hợp mùa xuân và Spring Cloud GCP

Bạn cần có

  • Một dự án Google Cloud Platform
  • Một trình duyệt, chẳng hạn như Chrome hoặc Firefox
  • Quen thuộc với các trình chỉnh sửa văn bản Linux tiêu chuẩn, chẳng hạn như Vim, EMAC hoặc nano

Bạn sẽ sử dụng hướng dẫn này như thế nào?

Chỉ đọc qua Đọc qua và hoàn thành các bài tập

Bạn xếp hạng trải nghiệm như thế nào khi xây dựng các ứng dụng web HTML/CSS?

Người mới bắt đầu Trung cấp Đặc biệt

Bạn đánh giá trải nghiệm sử dụng các dịch vụ Google Cloud Platform của mình như thế nào?

Công ty Trung cấp Đặc biệt

Thiết lập môi trường theo tiến độ riêng

Nếu chưa có Tài khoản Google (Gmail hoặc Google Apps), thì bạn phải tạo một tài khoản. Đăng nhập vào bảng điều khiển của Google Cloud Platform (console.cloud.google.com) và tạo một dự án mới:

Ảnh chụp màn hình từ 2016-02-10 12:45:26.png

Hãy ghi nhớ mã dự án, một tên duy nhất trên tất cả các dự án Google Cloud (tên ở trên đã được sử dụng và sẽ không hoạt động cho bạn!). Lớp học này sẽ được gọi sau này trong lớp học lập trình này là PROJECT_ID.

Tiếp theo, bạn sẽ cần bật tính năng thanh toán trong Cloud Console để sử dụng tài nguyên của Google Cloud.

Nếu tham gia lớp học lập trình này, bạn sẽ không mất quá vài đô la, nhưng có thể sẽ hiệu quả hơn nếu bạn quyết định sử dụng nhiều tài nguyên hơn hoặc nếu bạn để các tài nguyên đó hoạt động (xem "cleanup" ở cuối tài liệu này).

Người dùng mới của Google Cloud Platform đủ điều kiện dùng thử 300 đô la dùng thử miễn phí.

Google Cloud Shell

Mặc dù Google Cloud có thể hoạt động từ xa máy tính xách tay của bạn, nhưng trong lớp học lập trình này, chúng ta sẽ dùng Google Cloud Shell, một môi trường dòng lệnh chạy trong Cloud.

Kích hoạt Google Cloud Shell

Từ bảng điều khiển GCP, hãy nhấp vào biểu tượng Cloud Shell trên thanh công cụ trên cùng bên phải:

Sau đó nhấp vào "Start Cloud Shell":

Bạn chỉ cần dành vài phút để cấp phép và kết nối với môi trường:

Máy ảo này được tải bằng tất cả các công cụ phát triển mà bạn cần. cung cấp một thư mục gốc 5GB cố định và chạy trên Google Cloud, qua đó nâng cao đáng kể hiệu suất và khả năng xác thực mạng. Phần lớn công việc của bạn trong phòng thí nghiệm này có thể thực hiện chỉ bằng một trình duyệt hoặc Google Chromebook.

Sau khi kết nối với Cloud Shell, bạn sẽ thấy rằng bạn đã được xác thực và dự án này đã được đặt thành PROJECT_ID của bạn.

Chạy lệnh sau trong Cloud Shell để xác nhận rằng bạn đã được xác thực:

gcloud auth list

Đầu ra lệnh

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

Đầu ra lệnh

[core]
project = <PROJECT_ID>

Nếu chưa, bạn có thể đặt lệnh đó bằng lệnh sau:

gcloud config set project <PROJECT_ID>

Đầu ra lệnh

Updated property [core/project].

Chuyển đến trang chủ đề Google Cloud Pub/Sub và bật API.

Nhấp vào Tạo chủ đề.

Nhập exampleTopic làm tên của chủ đề rồi nhấp vào Tạo.

Sau khi tạo chủ đề, hãy tiếp tục ở trên trang Chủ đề. Tìm chủ đề bạn vừa tạo, nhấn vào biểu tượng ba dấu chấm dọc ở cuối dòng rồi nhấp vào Gói đăng ký mới.

Nhập exampleSubscription vào hộp văn bản tên gói thuê bao rồi nhấp vào Tạo.

Sau khi Cloud Shell khởi chạy, bạn có thể sử dụng dòng lệnh để tạo hai ứng dụng Spring Boot mới với 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 -

Bây giờ, hãy tạo ứng dụng gửi tin nhắn của chúng ta. Hãy thay đổi thư mục của ứng dụng gửi.

$ cd spring-integration-sender

Chúng tôi muốn ứng dụng của chúng tôi viết thông báo lên kênh. Sau khi thông báo có trong kênh, bộ chuyển đổi sẽ nhận được thông báo chuyển đổi cho kênh đi. Thông báo này chuyển đổi thông báo từ thông báo Mùa xuân chung sang thông báo Google Cloud Pub/Sub và xuất bản thông báo đó sang chủ đề Google Cloud Pub/Sub.

Để có thể ghi ứng dụng vào một kênh, chúng ta có thể dùng Cổng thông báo tích hợp mùa xuân. Sử dụng trình chỉnh sửa văn bản từ vim, emacs hoặc nano, khai báo giao diện PubsubOutboundGateway bên trong lớp 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);
        }
}

Chúng ta hiện có một cơ chế để gửi thông báo đến một kênh, nhưng các thông báo đó sẽ chuyển đến đâu sau khi xuất hiện trên kênh?

Chúng tôi cần một bộ chuyển đổi kênh bên ngoài để sử dụng thông báo mới trong kênh và xuất bản thông báo lên chủ đề 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");
        }
}

Chú thích @ServiceActivator khiến MessageHandler này được áp dụng cho bất kỳ thư mới nào trong inputChannel. Trong trường hợp này, chúng tôi sẽ gọi bộ chuyển đổi kênh đi, PubSubMessageHandler, để xuất bản thông báo tới chủ đề exampleTopic của Google Cloud Pub/Sub&

Giờ đây, khi đã có bộ chuyển đổi kênh, chúng ta có thể tự động nối dây đối tượng PubsubOutboundGateway và sử dụng đối tượng đó để viết tin nhắn tới kênh.

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

Do có chú thích @PostMapping, nên chúng ta hiện có một điểm cuối đang lắng nghe các yêu cầu POST HTTP, nhưng cũng không thêm chú thích @RestController vào lớp DemoApplication để đánh dấu đó là bộ điều khiển REST.

src/main/java/com/example/demo/DemoApplication.java

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

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

Để ứng dụng có thể chạy, chúng ta chỉ cần thêm các phần phụ thuộc bắt buộc.

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>

Chạy ứng dụng của người gửi.

# Set the Project ID in environmental variable
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list \
  --format 'value(core.project)'`
$ ./mvnw spring-boot:run

Ứng dụng đang lắng nghe các yêu cầu POST có chứa thông báo trên cổng 8080 và điểm cuối /postMessage nhưng chúng tôi sẽ giải quyết vấn đề này sau.

Chúng tôi vừa tạo một ứng dụng gửi tin nhắn thông qua Google Cloud Pub/Sub. Bây giờ, chúng ta sẽ tạo một ứng dụng khác nhận các thông báo đó và xử lý chúng.

Nhấp vào dấu + để mở một phiên Cloud Shell mới.

Sau đó, trong phiên Cloud Shell mới, hãy thay đổi các thư mục thành thư mục của ứng dụng nhận dữ liệu:

$ cd spring-integration-receiver

Trong ứng dụng trước, việc khai báo cổng nhắn tin đã tạo kênh cho chúng ta. Vì chúng tôi không sử dụng cổng nhắn tin để nhận tin nhắn, nên chúng tôi cần khai báo MessageChannel của riêng mình để nhận tin nhắn.

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

Chúng tôi cần có bộ chuyển đổi kênh đến để nhận tin nhắn từ Google Cloud Pub/Sub và chuyển tiếp tin nhắn đó đến 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;
        }
}

Bộ chuyển đổi này liên kết với pubsubInputChannel và lắng nghe thông báo mới từ gói đăng ký Google Cloud Pub/Sub exampleSubscription.

Chúng tôi có một kênh mà tin nhắn đến sẽ được đăng lên đó, nhưng bạn phải làm gì với những tin nhắn đó?

Hãy xử lý thư bằng @ServiceActivator được kích hoạt khi thư mới được gửi đến 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);
        }
}

Trong trường hợp này, chúng tôi sẽ chỉ ghi lại phần tải thư.

Chúng ta cần phải thêm các phần phụ thuộc cần thiết.

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>

Chạy ứng dụng nhận.

$ ./mvnw spring-boot:run

Bây giờ, mọi tin nhắn bạn gửi đến ứng dụng của người gửi sẽ được ghi lại trên ứng dụng nhận. Để kiểm tra điều đó, hãy mở một phiên Cloud Shell mới và thực hiện yêu cầu POST HTTP tới ứng dụng của người gửi.

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

Sau đó, hãy xác minh rằng ứng dụng đã nhận tin nhắn mà bạn đã gửi!

INFO: Message arrived! Payload: Hello world!

Xóa gói đăng ký và chủ đề được tạo như một phần của bài tập này.

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

Bạn thiết lập 2 ứng dụng Spring Boot sử dụng Bộ chuyển đổi kênh tích hợp mùa xuân cho Google Cloud Pub/Sub. Họ trao đổi thông báo giữa chính họ mà không bao giờ tương tác với API Google Cloud Pub/Sub.

Bạn đã tìm hiểu cách sử dụng Bộ chuyển đổi kênh tích hợp mùa xuân cho Google Cloud Pub/Sub!

Tìm hiểu thêm

Giấy phép

Tài liệu này được cấp phép theo Giấy phép chung Creative Commons 2.0.