1. ภาพรวม
Spring Integration มีกลไกการรับส่งข้อความเพื่อแลกเปลี่ยน Messages ผ่าน MessageChannels โดยใช้ Channel Adapter เพื่อสื่อสารกับระบบภายนอก
ในแบบฝึกหัดนี้ เราจะสร้างแอป 2 แอปที่สื่อสารกันโดยใช้ Spring Integration Channel Adapter ที่ Spring Cloud GCP จัดเตรียมไว้ ซึ่ง Adapter เหล่านี้จะทำให้ 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 จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งโดยปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นคืออะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยทั่วไปจะระบุเป็น
PROJECT_ID) หากไม่ชอบรหัสที่สร้างขึ้น คุณอาจสร้างรหัสแบบสุ่มอีกรหัสหนึ่ง หรือจะลองใช้รหัสของคุณเองและดูว่ารหัสนั้นพร้อมใช้งานหรือไม่ก็ได้ โดยรหัสนี้จะเปลี่ยนแปลงไม่ได้หลังจากขั้นตอนนี้และจะคงอยู่ตลอดระยะเวลาของโปรเจ็กต์ - โปรดทราบว่ามีค่าที่ 3 คือหมายเลขโปรเจ็กต์ ซึ่ง API บางรายการใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 นี้ได้ใน เอกสารประกอบ
- จากนั้นคุณจะต้อง เปิดใช้การเรียกเก็บเงิน ในคอนโซล Cloud เพื่อใช้ทรัพยากร/API ของ Cloud การทำตาม Codelab นี้จะไม่เสียค่าใช้จ่ายมากนัก หรืออาจไม่เสียค่าใช้จ่ายเลย หากต้องการปิดทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่สร้างขึ้นหรือลบโปรเจ็กต์ ผู้ใช้ Google Cloud รายใหม่มีสิทธิ์รับโปรแกรมช่วงทดลองใช้ฟรีมูลค่า$300 USD
Google Cloud Shell
แม้ว่าจะใช้งาน Google Cloud จากระยะไกลจากแล็ปท็อปได้ แต่ใน Codelab นี้เราจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์
เปิดใช้งาน Cloud Shell
- จากคอนโซล Cloud ให้คลิก เปิดใช้งาน Cloud Shell


หากเริ่มต้น Cloud Shell เป็นครั้งแรก คุณจะเห็นหน้าจอระดับกลางที่อธิบายว่า Cloud Shell คืออะไร หากเห็นหน้าจอระดับกลาง ให้คลิกต่อไป

การจัดสรรและเชื่อมต่อกับ Cloud Shell จะใช้เวลาไม่นาน

เครื่องเสมือนนี้โหลดเครื่องมือพัฒนาทั้งหมดที่จำเป็น โดยมีไดเรกทอรีแรกขนาด 5 GB แบบถาวรและทำงานใน 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 เป็นชื่อหัวข้อ แล้วคลิกสร้าง

หลังจากสร้างหัวข้อแล้ว ให้ยังคงอยู่ในหน้าหัวข้อ ค้นหาหัวข้อที่เพิ่งสร้าง กดจุด 3 จุดแนวตั้งที่ท้ายบรรทัด แล้วคลิกการสมัครใช้บริการใหม่

พิมพ์ exampleSubscription ในช่องข้อความชื่อการสมัครใช้บริการ แล้วคลิกสร้าง

4. เริ่มต้นใช้งานแอปพลิเคชัน Spring Boot
หลังจากเปิดใช้ Cloud Shell แล้ว คุณสามารถใช้บรรทัดคำสั่งเพื่อสร้างแอปพลิเคชัน Spring Boot ใหม่ 2 แอปด้วย 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
เราต้องการให้แอปเขียนข้อความลงในช่อง หลังจากข้อความอยู่ในช่องแล้ว Channel Adapter ขาออกจะดึงข้อความนั้นออกมา ซึ่งจะแปลงข้อความจากข้อความ 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);
}
}
ตอนนี้เรามีกลไกในการส่งข้อความไปยังช่องแล้ว แต่ข้อความเหล่านั้นจะไปที่ใดหลังจากอยู่ในช่อง
เราต้องมี Channel Adapter ขาออกเพื่อใช้ข้อความใหม่ในช่องและเผยแพร่ไปยังหัวข้อ 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 ในกรณีนี้ เราจะเรียก Channel Adapter ขาออก PubSubMessageHandler เพื่อเผยแพร่ข้อความไปยังหัวข้อ exampleTopic ของ Google Cloud Pub/Sub
เมื่อมี Channel Adapter แล้ว ตอนนี้เราสามารถเชื่อมโยงออบเจ็กต์ 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 Controller ด้วย
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
ในแอปก่อนหน้านี้ การประกาศ Messaging Gateway ได้สร้าง Channel ขาออกให้เรา เนื่องจากเราไม่ได้ใช้ Messaging Gateway เพื่อรับข้อความ เราจึงต้องประกาศ 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();
}
}
เราจะต้องมี Channel Adapter ขาเข้าเพื่อรับข้อความจาก 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;
}
}
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 2 แอปที่ใช้ Spring Integration Channel Adapter สำหรับ Google Cloud Pub/Sub แอปเหล่านี้แลกเปลี่ยนข้อความกันเองโดยไม่ต้องโต้ตอบกับ Google Cloud Pub/Sub API เลย
9. ยินดีด้วย
คุณได้เรียนรู้วิธีใช้ Spring Integration Channel Adapter สำหรับ Google Cloud Pub/Sub แล้ว
ดูข้อมูลเพิ่มเติม
- Google Cloud Pub/Sub: https://cloud.google.com/pubsub/
- โปรเจ็กต์ Spring on GCP: http://cloud.spring.io/spring-cloud-gcp/
- ที่เก็บ Spring on GCP GitHub: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Java บน Google Cloud Platform: https://cloud.google.com/java/
ใบอนุญาต
ผลงานนี้ได้รับอนุญาตภายใต้ Creative Commons Attribution 2.0 Generic License