1. 개요
Spring Integration은 MessageChannels
를 통해 Messages
를 교환하는 메시지 메커니즘을 제공합니다. 채널 어댑터를 사용하여 외부 시스템과 통신합니다.
이 연습에서는 Spring Cloud GCP에서 제공하는 Spring Integration 채널 어댑터를 사용하여 통신하는 두 개의 앱을 만들어 보겠습니다. 이러한 어댑터를 사용하면 Spring Integration에서 Google Cloud Pub/Sub를 메시지 교환 백엔드로 사용하게 됩니다.
Cloud Shell 및 Cloud SDK gcloud 명령어를 사용하는 방법을 알아봅니다.
이 튜토리얼에서는 Spring Boot 시작 가이드의 샘플 코드를 사용합니다.
학습할 내용
- Spring Integration 및 Spring Cloud GCP를 사용하여 Google Cloud Pub/Sub로 앱 간에 메시지를 교환하는 방법
필요한 항목
이 튜토리얼을 어떻게 사용하실 계획인가요?
HTML/CSS 웹 앱 빌드 경험을 평가해 주세요.
귀하의 Google Cloud Platform 서비스 사용 경험을 평가해 주세요.
<ph type="x-smartling-placeholder">2. 설정 및 요구사항
자습형 환경 설정
- Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.
- 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
- 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud 콘솔은 고유한 문자열을 자동으로 생성합니다. 일반적으로는 신경 쓰지 않아도 됩니다. 대부분의 Codelab에서는 프로젝트 ID (일반적으로
PROJECT_ID
로 식별됨)를 참조해야 합니다. 생성된 ID가 마음에 들지 않으면 다른 임의 ID를 생성할 수 있습니다. 또는 직접 시도해 보고 사용 가능한지 확인할 수도 있습니다. 이 단계 이후에는 변경할 수 없으며 프로젝트 기간 동안 유지됩니다. - 참고로 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참고하세요.
- 다음으로 Cloud 리소스/API를 사용하려면 Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼이 끝난 후에 요금이 청구되지 않도록 리소스를 종료하려면 만든 리소스 또는 프로젝트를 삭제하면 됩니다. Google Cloud 신규 사용자는 300달러(USD) 상당의 무료 체험판 프로그램에 참여할 수 있습니다.
Google Cloud Shell
Google Cloud를 노트북에서 원격으로 실행할 수도 있지만 이 Codelab에서는 Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.
Cloud Shell 활성화
- Cloud Console에서 Cloud Shell 활성화를 클릭합니다.
Cloud Shell을 처음 시작하는 경우에는 무엇이 있는지 설명하는 중간 화면이 표시됩니다. 중간 화면이 표시되면 계속을 클릭합니다.
Cloud Shell을 프로비저닝하고 연결하는 데 몇 분 정도만 걸립니다.
가상 머신에는 필요한 개발 도구가 모두 들어 있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab에서 대부분의 작업은 브라우저를 사용하여 수행할 수 있습니다.
Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 자신의 프로젝트 ID로 설정된 것을 확인할 수 있습니다.
- 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 Initializr로 두 개의 새로운 Spring Boot 애플리케이션을 생성할 수 있습니다.
$ 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
의 텍스트 편집기를 사용하여 DemoApplication
클래스 내에서 PubsubOutboundGateway
인터페이스를 선언합니다.
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
를 호출하여 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 요청을 수신 대기하지만 DemoApplication
클래스에 @RestController
주석을 추가하여 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
앱은 포트 8080과 엔드포인트 /postMessage
에서 메시지가 포함된 POST 요청을 수신 대기하고 있지만 나중에 살펴볼 예정입니다.
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
구독에서 새 메시지를 리슨합니다.
받은 메시지를 게시하는 채널이 있는데 이러한 메시지는 어떻게 처리해야 할까요?
새 메시지가 pubsubInputChannel
에 도착하면 트리거되는 @ServiceActivator
를 사용하여 처리하겠습니다. 이 경우에는 메시지 페이로드만 기록합니다.
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. 요약
Google Cloud Pub/Sub용 Spring Integration 채널 어댑터를 사용하는 Spring Boot 앱 2개를 설정합니다. Google Cloud Pub/Sub API와 상호작용하지 않고 서로 간에 메시지를 교환합니다.
9. 축하합니다.
지금까지 Google Cloud Pub/Sub용 Spring Integration 채널 어댑터를 사용하는 방법을 알아봤습니다.
자세히 알아보기
- Google Cloud Pub/Sub: https://cloud.google.com/pubsub/
- GCP의 Spring 프로젝트: http://cloud.spring.io/spring-cloud-gcp/
- GCP의 Spring GitHub 저장소: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Google Cloud Platform의 자바: https://cloud.google.com/java/
라이선스
이 작업물은 Creative Commons Attribution 2.0 일반 라이선스에 따라 사용이 허가되었습니다.