Rumah  >  Artikel  >  Java  >  Membina Aplikasi Pengguna Spring Boot dengan Amazon SQS: Persediaan Infrastruktur Menggunakan Kit Pembangunan Awan (CDK)

Membina Aplikasi Pengguna Spring Boot dengan Amazon SQS: Persediaan Infrastruktur Menggunakan Kit Pembangunan Awan (CDK)

Susan Sarandon
Susan Sarandonasal
2024-10-07 22:08:30564semak imbas
Hari 017 - 100HariAWSIaCDevopsChallenge

Hari ini dalam siri cabaran kod 100 hari saya, saya akan menunjukkan kepada anda cara mengasingkan perkhidmatan mikro yang dibangunkan dengan springboot menggunakan Amazon SQS.

Apakah Amazon SQS?

Amazon SQS (Simple Queue Service) ialah perkhidmatan awan yang membantu aplikasi berkomunikasi dengan menghantar, menyimpan dan menerima mesej dalam baris gilir. Ia seperti barisan menunggu yang disimpan sehingga pengguna bersedia untuk memprosesnya. Ini menghalang sistem daripada dikalahkan dan memastikan tiada mesej yang hilang.

Gunakan Mesej SQS menggunakan aplikasi Springboot

Untuk menunjukkan cara menggunakan mesej SQS dengan mencipta apl Spring Boot yang memproses setiap mesej daripada baris gilir SQS. Infrastruktur, dibina menggunakan CDK (Java), akan termasuk:

  • VPC dengan Subnet awam untuk mengehoskan tika EC2 di mana apl Spring Boot akan dijalankan.
  • Satu Gerbang Internet untuk contoh EC2 untuk mengakses Internet dan memuat turun kebergantungan.
  • Satu Baris Gilir SQS dan Baris Gilir Surat Mati untuk penyimpanan mesej.
  • Satu Instance EC2 untuk mengehos Apl SpringBoot.
  • Satu Peranan IAM untuk membenarkan tika EC2 mendapatkan semula mesej daripada baris gilir SQS (sangat penting).

Buat Infrastruktur

Sediakan infrastruktur yang diperlukan menggunakan CDK (Java)

Building a Spring Boot Consumer Application with Amazon SQS: Setup Infrastructure Using Cloud Development Kit (CDK)

VPC & Gerbang Internet Subne


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


Pembinaan cdk ini akan mencipta:
?? VPC bernama my-vpc dan dayakan nama hos DNS didayakan.
?? Subnet awam bernama Public-Subnet yang membenarkan sumber melampirkan IP awam (jika dikonfigurasikan dengan IP).
?? Gerbang Internet untuk mendayakan trafik internet.

Baris SQS & Baris Surat Mati


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


Konstruk CDK di atas akan mencipta sumber berikut:

  • Baris gilir bernama my-queue, yang akan digunakan dalam apl Spring Boot.
  • Satu Baris Gilir Huruf Mati bernama my-queue-dlq yang menangkap mesej yang gagal supaya ia boleh dianalisis dan diperbaiki kemudian, tanpa menyekat baris gilir utama.

Contoh EC2 untuk Mengehos Aplikasi Spring Boot


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


Konstruk CDK di atas akan mencipta sumber berikut:

  • Kumpulan Keselamatan bernama Webserver-security-group yang membenarkan trafik masuk pada Port 22 untuk sambungan SSH dan membenarkan trafik masuk pada Port 8089, iaitu port sambungan aplikasi.
  • Pasangan Kunci bernama ws-keypair yang akan digunakan untuk menyambung ke hos apl melalui SSH. Memandangkan kami menggunakan CDK untuk membina infrastruktur, jika anda perlu memuat turun kunci persendirian (fail PEM) selepas penggunaan, rujuk artikel saya sebelum ini tentang Cara mendapatkan semula fail kunci persendirian PEM selepas penciptaan timbunan Cloudformation atau CDK[↗].
  • Instance Ec2 bernama Webserver-Instance.
  • Peranan IAM untuk Instance Ec2 bernama webserver-role, yang membenarkan aplikasi Spring Boot yang dihoskan pada Ec2 Instance untuk mewujudkan sambungan dengan Amazon SQS Queue (sudah dibuat) dan melakukan tindakan: Padam Mesej, Terima Mesej, Hantar Mesej , Dapatkan Atribut Baris dan Dapatkan Url Baris.

Buat timbunan


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


Cipta Aplikasi Pengguna SpringBoot

Untuk memastikan perkara mudah dan mengelakkan merumitkan hidup saya, saya akan menggunakan Spring Cloud AWS Docs[↗]

Spring Cloud AWS memudahkan penggunaan perkhidmatan terurus AWS dalam Rangka Kerja Spring dan aplikasi Spring Boot. Ia menawarkan cara yang mudah untuk berinteraksi dengan perkhidmatan yang disediakan AWS menggunakan simpulan bahasa dan API Spring yang terkenal.

Untuk mengkonfigurasi perkhidmatan SQS dalam projek saya, saya akan menambah kacang berikut dalam kelas konfigurasi:


@Configuration
public class ApplicationConfiguration {
    @Bean
    public AwsRegionProvider customRegionProvider() {
        return new InstanceProfileRegionProvider();
    }
    @Bean
    public AwsCredentialsProvider customInstanceCredProvider() {
        return  InstanceProfileCredentialsProvider.builder()
                .build();
    }
}


Dan pendengar yang menangkap semua mesej baharu dan mencetak kandungannya.


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


Anda boleh menemui projek penuh dalam repo GitHub saya[↗]

Kerahan

⚠️⚠️ Sebelum menjalankan arahan penggunaan pastikan anda telah memasang java pada mesin hos anda. Saya menggunakan Java 21 di bawah MacOs untuk membina infrastruktur ini.

Buka terminal di mana-mana sahaja dan jalankan arahan berikut:


<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>




Resut

Building a Spring Boot Consumer Application with Amazon SQS: Setup Infrastructure Using Cloud Development Kit (CDK)


Anda boleh mendapatkan kod sumber penuh di GitHub Repo↗

Atas ialah kandungan terperinci Membina Aplikasi Pengguna Spring Boot dengan Amazon SQS: Persediaan Infrastruktur Menggunakan Kit Pembangunan Awan (CDK). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn