1. ภาพรวม
การผสานรวม Spring มีกลไกการรับส่งข้อความเพื่อแลกเปลี่ยน Messages
ผ่าน MessageChannels
โดยใช้อะแดปเตอร์ช่องในการสื่อสารกับระบบภายนอก
ในแบบฝึกหัดนี้ เราจะสร้างแอป 2 แอปที่สื่อสารกันโดยใช้อะแดปเตอร์ช่องทางการรวม Spring จาก Spring Cloud GCP อะแดปเตอร์เหล่านี้ทำให้ Spring Integration ใช้ Google Cloud Pub/Sub เป็นแบ็กเอนด์ของการแลกเปลี่ยนข้อความ
คุณจะได้ดูวิธีใช้ Cloud Shell และคำสั่ง gcloud ของ Cloud SDK
บทแนะนำนี้จะใช้โค้ดตัวอย่างจากคู่มือเริ่มต้นใช้งานการเปิดเครื่องช่วงฤดูใบไม้ผลิ
สิ่งที่คุณจะได้เรียนรู้
- วิธีแลกเปลี่ยนข้อความระหว่างแอปด้วย 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 Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี
- ชื่อโครงการคือชื่อที่แสดงของผู้เข้าร่วมโปรเจ็กต์นี้ เป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ โดยคุณจะอัปเดตวิธีการชำระเงินได้ทุกเมื่อ
- รหัสโปรเจ็กต์จะไม่ซ้ำกันในทุกโปรเจ็กต์ของ Google Cloud และจะเปลี่ยนแปลงไม่ได้ (เปลี่ยนแปลงไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ปกติแล้วคุณไม่สนว่าอะไรเป็นอะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยปกติจะระบุเป็น
PROJECT_ID
) หากคุณไม่ชอบรหัสที่สร้างขึ้น คุณสามารถสร้างรหัสแบบสุ่มอื่นได้ หรือคุณจะลองดำเนินการเองแล้วดูว่าพร้อมให้ใช้งานหรือไม่ คุณจะเปลี่ยนแปลงหลังจากขั้นตอนนี้ไม่ได้และจะยังคงอยู่ตลอดระยะเวลาของโปรเจ็กต์ - สำหรับข้อมูลของคุณ ค่าที่ 3 คือหมายเลขโปรเจ็กต์ ซึ่ง API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 ค่าเหล่านี้ในเอกสารประกอบ
- ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของระบบคลาวด์ การใช้งาน Codelab นี้จะไม่มีค่าใช้จ่ายใดๆ หากมี หากต้องการปิดทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินที่นอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่คุณสร้างหรือลบโปรเจ็กต์ได้ ผู้ใช้ Google Cloud ใหม่มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรี$300 USD
Google Cloud Shell
แม้ Google Cloud จะทำงานจากระยะไกลได้จากแล็ปท็อป แต่ใน Codelab นี้ เราจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมแบบบรรทัดคำสั่งที่ทำงานในระบบคลาวด์
เปิดใช้งาน Cloud Shell
- คลิกเปิดใช้งาน Cloud Shell จาก Cloud Console
หากเริ่มต้นใช้งาน 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
เราต้องการให้แอปเขียนข้อความถึงช่อง หลังจากที่ข้อความอยู่ในแชแนลแล้ว ข้อความจะได้รับการเลือกโดยอะแดปเตอร์ช่องทางขาออก ซึ่งจะแปลงข้อความนั้นจากข้อความ 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 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
ตอนนี้เรามีปลายทางที่ฟังคำขอ 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
และฟังข้อความใหม่จากการสมัครใช้บริการ 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);
}
}
ตรวจสอบว่าตั้งค่า 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 แอปที่ใช้อะแดปเตอร์แชนเนลการรวมฤดูใบไม้ผลิสำหรับ Google Cloud Pub/Sub และแลกเปลี่ยนข้อความกันเองโดยไม่โต้ตอบกับ Google Cloud Pub/Sub API
9. ยินดีด้วย
คุณรู้วิธีใช้ Spring Integration Channel Adapters สำหรับ Google Cloud Pub/Sub แล้ว
ดูข้อมูลเพิ่มเติม
- Google Cloud Pub/Sub: https://cloud.google.com/pubsub/
- ฤดูใบไม้ผลิในโปรเจ็กต์ GCP: http://cloud.spring.io/spring-cloud-gcp/
- Spring ในที่เก็บ GitHub ของ GCP: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Java บน Google Cloud Platform: https://cloud.google.com/java/
ใบอนุญาต
ผลงานนี้ได้รับอนุญาตภายใต้ใบอนุญาตทั่วไปครีเอทีฟคอมมอนส์แบบระบุแหล่งที่มา 2.0