使用 Amazon SQS 建立 Spring Boot 消費者應用程式:使用雲端開發套件 (CDK) 設定基礎設施
第 017 天 - 100 天AWSIaCDevops 挑戰
今天,在我的 100 天程式碼挑戰系列中,我將向您展示如何使用 Amazon SQS 解耦使用 springboot 開發的微服務。
什麼是亞馬遜 SQS?
Amazon SQS(簡單佇列服務) 是一項雲端服務,可協助應用程式透過 sendyg 進行通信,在佇列中儲存和接收訊息。它就像一條等待隊列,等待消費者準備好處理它們為止。這可以防止系統失控並確保不會遺失訊息。
使用 Springboot 應用程式使用 SQS 訊息
示範如何透過建立一個處理來自 SQS 佇列的每個訊息的 Spring Boot 應用程式來使用 SQS 訊息。使用 CDK (Java) 建置的基礎設施將包括:
- VPC,具有公用 子網路,用於託管將在其中執行 Spring Boot 應用程式的 EC2 執行個體。
- 用於 EC2 執行個體存取網際網路並下載相依性的網際網路閘道。
- 用於訊息儲存的 SQS 佇列 和 死信佇列。
- 用於託管 SpringBoot 應用程式的 EC2 執行個體。
- IAM 角色,允許 EC2 執行個體從 SQS 佇列檢索訊息(非常重要)。
創建基礎設施
使用 CDK (Java) 設定必要的基礎設施
VPC 與子網路網際網路網關
public class NetworkContruct extends Construct { private final IVpc vpc; public NetworkContruct(Construct scope, String id, StackProps props) { super(scope, id); this.vpc = new Vpc( this, "VpcResource", VpcProps.builder() .vpcName("my-vpc") .enableDnsHostnames(true) .enableDnsSupport(true) .createInternetGateway(true) .ipProtocol(IpProtocol.IPV4_ONLY) .ipAddresses(IpAddresses.cidr("10.0.0.1/16")) .maxAzs(1) .subnetConfiguration( List.of( SubnetConfiguration.builder() .name("Public-Subnet") .mapPublicIpOnLaunch(true) .subnetType(SubnetType.PUBLIC) .build())) .build()); } public IVpc getVpc() { return vpc; } }
此 cdk 構造將會建立:
??名為 my-vpc 的 VPC 並啟用 DNS 主機名稱。
??名為 Public-Subnet 的公用子網,允許資源附加公用 IP(如果配置了公用 IP)。
??用於啟用網際網路流量的網際網路閘道。
SQS隊列和死信隊列
public class QueueConstruct extends Construct { private final IQueue queue; public QueueConstruct(Construct scope, String id, IVpc vpc, StackProps props) { super(scope, id); IQueue dlq = new Queue( this, "DeadLetterQueue", QueueProps.builder() .deliveryDelay(Duration.millis(0)) .retentionPeriod(Duration.days(10)) .queueName("my-queue-dlq") .build()); DeadLetterQueue deadLetterQueue = DeadLetterQueue.builder() .queue(dlq) .maxReceiveCount(32) .build(); this.queue = new Queue( this, "SQSQueueResource", QueueProps.builder() .queueName("my-queue") .retentionPeriod(Duration.minutes(15)) .visibilityTimeout(Duration.seconds(90)) .deadLetterQueue(deadLetterQueue) .build()); } public IQueue getQueue() { return queue; } }
上述 CDK 構造將建立以下資源:
- 一個名為 my-queue 的佇列,它將在 Spring Boot 應用程式中使用。
- 一個名為 my-queue-dlq 的死信隊列,它捕獲失敗的訊息以便稍後可以分析和修復它們,而不會阻塞主隊列。
用於託管 Spring Boot 應用程式的 EC2 實例
// ComputerProps.java public record ComputerProps(IVpc vpc, String sqsQueueArn) {} // ComputerConstruct.java public class ComputerConstruct extends Construct { private final IInstance computer; public ComputerConstruct( Construct scope, String id, ComputerProps computerProps, StackProps props) { super(scope, id); SecurityGroup securityGroup = new SecurityGroup( this, "WebserverSGResource", SecurityGroupProps.builder() .allowAllOutbound(true) .securityGroupName("Webserver-security-group") .disableInlineRules(true) .vpc(computerProps.vpc()) .description("Allow trafic from/to webserver instance") .build()); securityGroup.addIngressRule(Peer.anyIpv4(), Port.SSH, "Allow ssh traffic"); securityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(8089), "Allow traffic from 8089 port"); KeyPair keyPair = new KeyPair( this, "KeyPairResource", KeyPairProps.builder() .keyPairName("ws-keypair") .account(Objects.requireNonNull(props.getEnv()).getAccount()) .type(KeyPairType.RSA) .format(KeyPairFormat.PEM) .build()); new CfnOutput( this, "KeyPairId", CfnOutputProps.builder().value(keyPair.getKeyPairId()).build()); Instance ec2Instance = new Instance( this, "WebServerInstanceResource", InstanceProps.builder() .securityGroup(securityGroup) .keyPair(keyPair) .instanceName("Webserver-Instance") .machineImage( MachineImage.lookup( LookupMachineImageProps.builder() .name("*ubuntu*") .filters( Map.ofEntries( Map.entry("image-id", List.of("ami-0e86e20dae9224db8")), Map.entry("architecture", List.of("x86_64")))) .windows(false) .build())) .vpc(computerProps.vpc()) .role(buildInstanceRole(computerProps)) .instanceType(InstanceType.of(InstanceClass.T2, InstanceSize.MICRO)) .associatePublicIpAddress(true) .blockDevices( List.of( BlockDevice.builder() .mappingEnabled(true) .deviceName("/dev/sda1") .volume( BlockDeviceVolume.ebs( 10, EbsDeviceOptions.builder() .deleteOnTermination(true) .volumeType(EbsDeviceVolumeType.GP3) .build())) .build())) .userDataCausesReplacement(true) .vpcSubnets(SubnetSelection.builder().subnetType(SubnetType.PUBLIC).build()) .build()); UserData userData = UserData.forLinux(); userData.addCommands(readFile("./webserver-startup.sh")); ec2Instance.addUserData(userData.render()); this.computer = ec2Instance; } public IInstance getComputer() { return computer; } private String readFile(String filename) { InputStream scriptFileStream = getClass().getClassLoader().getResourceAsStream(filename); try { assert scriptFileStream != null; try (InputStreamReader isr = new InputStreamReader(scriptFileStream, StandardCharsets.UTF_8); BufferedReader br = new BufferedReader(isr)) { StringBuilder content = new StringBuilder(); String line; while ((line = br.readLine()) != null) { content.append(line).append("\n"); } return content.toString(); } } catch (IOException e) { throw new RuntimeException(e.getMessage()); } } private IRole buildInstanceRole(ComputerProps props) { return new Role( this, "WebserverInstanceRoleResource", RoleProps.builder() .roleName("webserver-role") .assumedBy(new ServicePrincipal("ec2.amazonaws.com")) .path("/") .inlinePolicies( Map.ofEntries( Map.entry( "sqs", new PolicyDocument( PolicyDocumentProps.builder() .assignSids(true) .statements( List.of( new PolicyStatement( PolicyStatementProps.builder() .effect(Effect.ALLOW) .actions( List.of( "sqs:DeleteMessage", "sqs:ReceiveMessage", "sqs:SendMessage", "sqs:GetQueueAttributes", "sqs:GetQueueUrl")) .resources(List.of(props.sqsQueueArn())) .build()))) .build())))) .build()); } }
上述 CDK 構造將建立以下資源:
- 名為Webserver-security-group 的安全群組,允許連接埠22 上的SSH 連接的入站流量,並允許連接埠8089(應用程式連接連接埠)上的入站流量。
- 名為 ws-keypair 的金鑰對,將用於透過 SSH 連接到應用程式主機。由於我們使用 CDK 來建立基礎設施,如果部署後需要下載私鑰(PEM 檔案),請參閱我之前的文章如何在 Cloudformation 或 CDK 堆疊建立後檢索私鑰檔案 PEM[↗]。
- 名為 Webserver-Instance 的 Ec2 實例。
- 名為webserver-role 的Ec2 實例的IAM 角色,它允許Ec2 實例上託管的spring Boot 應用程式與Amazon SQS 佇列(已建立)建立連線並執行操作:刪除訊息、接收訊息、傳送訊息,取得隊列屬性並取得隊列Url。
創建堆疊
// MyStack.java public class MyStack extends Stack { public MyStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); IVpc vpc = new NetworkContruct(this, "NetworkResource", props).getVpc(); IQueue queue = new QueueConstruct(this, "QueueResource", vpc, props).getQueue(); IInstance webserver = new ComputerConstruct( this, "ComputerResource", new ComputerProps(vpc, queue.getQueueArn()), props) .getComputer(); } } // Day17App.java public class Day017App { public static void main(final String[] args) { App app = new App(); new MyStack(app,"Day017Stack", StackProps.builder() .env( Environment.builder() .account(System.getenv("CDK_DEFAULT_ACCOUNT")) .region(System.getenv("CDK_DEFAULT_REGION")) .build()) .build()); app.synth(); } }
創建SpringBoot消費者應用程式
為了讓事情變得簡單並避免讓我的生活變得複雜,我將使用 Spring Cloud AWS Docs[↗]
Spring Cloud AWS 簡化了在 Spring 框架和 Spring Boot 應用程式中使用 AWS 託管服務。它提供了一種使用眾所周知的 Spring 習慣用法和 API 與 AWS 提供的服務進行互動的便捷方式。
為了在我的專案中配置SQS服務,我將在配置類別中新增以下bean:
@Configuration public class ApplicationConfiguration { @Bean public AwsRegionProvider customRegionProvider() { return new InstanceProfileRegionProvider(); } @Bean public AwsCredentialsProvider customInstanceCredProvider() { return InstanceProfileCredentialsProvider.builder() .build(); } }
以及捕獲所有新訊息並列印其內容的偵聽器。
@Slf4j @Component public class ExampleSQSConsumer { @SqsListener(queueNames = { "my-queue" }) // ?? public void listen(String payload) { log.info("******************* SQS Payload ***************"); log.info("Message Content: {}", payload); log.info("Received At: {}", Date.from(Instant.now())); log.info("************************************************"); } }
您可以在我的 GitHub 儲存庫中找到完整的專案[↗]
部署
⚠️⚠️ 在執行部署指令之前,請確保您的主機上安裝了 java。我在 MacO 下使用 Java 21 來建置這個基礎架構。
在任意位置開啟終端機並執行以下命令:
<p>git clone https://github.com/nivekalara237/100DaysTerraformAWSDevops.git<br> cd 100DaysTerraformAWSDevops/day_017<br> cdk bootstrap --profile cdk-user<br> cdk deploy --profile cdk-user Day017Stack</p>
結果
您可以在 GitHub Repo 上找到完整的原始碼↗
以上是使用 Amazon SQS 建立 Spring Boot 消費者應用程式:使用雲端開發套件 (CDK) 設定基礎設施的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

公司安全軟件導致部分應用無法正常運行的排查與解決方法許多公司為了保障內部網絡安全,會部署安全軟件。 ...

將姓名轉換為數字以實現排序的解決方案在許多應用場景中,用戶可能需要在群組中進行排序,尤其是在一個用...

系統對接中的字段映射處理在進行系統對接時,常常會遇到一個棘手的問題:如何將A系統的接口字段有效地映�...

在使用IntelliJIDEAUltimate版本啟動Spring...

Java對象與數組的轉換:深入探討強制類型轉換的風險與正確方法很多Java初學者會遇到將一個對象轉換成數組的�...

在使用MyBatis-Plus或其他ORM框架進行數據庫操作時,經常需要根據實體類的屬性名構造查詢條件。如果每次都手動...

Redis緩存方案如何實現產品排行榜列表的需求?在開發過程中,我們常常需要處理排行榜的需求,例如展示一個�...

電商平台SKU和SPU表設計詳解本文將探討電商平台中SKU和SPU的數據庫設計問題,特別是如何處理用戶自定義銷售屬...
