Spring Boot整合Amazon SNS实战
- 引言
- 配置服务
- 总结
新用户可获得高达 200 美元的服务抵扣金
亚马逊云科技新用户可以免费使用亚马逊云科技免费套餐(Amazon Free Tier)。注册即可获得 100 美元的服务抵扣金,在探索关键亚马逊云科技服务时可以再额外获得最多 100 美元的服务抵扣金。使用免费计划试用亚马逊云科技服务,最长可达 6 个月,无需支付任何费用,除非您选择付费计划。付费计划允许您扩展运营并获得超过 150 项亚马逊云科技服务的访问权限
引言
在当下的软件开发中,事件驱动架构和消息系统早已成为不可或缺的基础设施,而在这一领域,亚马逊云科技的简单通知服务无疑是一位实力强劲的选手。它让消息的发布与订阅变得高效、灵活又易于扩展,尤其适合需要即时通知的业务场景,比如交易提醒、温度监控、库存预警等。今天,我们就用一个基于 Spring Boot 的实战项目,带你从零到一构建一个邮件订阅通知系统,让你真切感受到 Amazon SNS 的魅力。
在正式开工之前,我们先搞清楚几个核心概念。所谓“主题”,你可以把它想象成消息的“频道”或“标签”,发布者把消息投递到主题中,而订阅者则对自己感兴趣的主题保持监听,一旦有新消息就会收到通知。这样一来,发布者无需关心接收者是谁、在哪里,接收者也只会拿到自己关心的内容。Amazon SNS 的主题有两种类型:一种是标准主题,支持高吞吐量传输,并且保证消息至少被投递一次;另一种是 FIFO 主题,顾名思义,它能保证消息的严格顺序,并且只会投递一次,适合那些对顺序和唯一性要求很高的场景。
为了让主题上的消息真正触达到接收者,Amazon SNS 支持多种订阅目标,比如应用程序、Amazon SQS 队列、Lambda 函数、HTTP(S) 端点,甚至直接发送邮件。本次示例中,我们选择了 Email-JSON 协议,通过电子邮件来接收通知,方便直观,也便于测试。
配置服务
第一步是配置 IAM 用户,这是所有亚马逊云科技服务的“门禁卡”。在 亚马逊 控制台里选择 IAM 服务,为新用户添加 AmazonSNSFullAccess 权限策略,并生成访问密钥对。这些凭证就像是你的账号密码,必须妥善保存,因为稍后我们会在 Spring Boot 的监听器里用到它们,让应用具备访问 Amazon SNS 的能力。
接下来,我们进入 Amazon SNS 控制台创建主题。在 Topics 页面点击“Create topic”,选择标准类型,输入一个便于识别的名称并确认创建。完成后,你会得到一个 Topic ARN,它是整个系统里识别该主题的唯一标识符。然后为这个主题添加订阅,选择 Email-JSON 作为协议,并填写接收邮件的地址。订阅创建后,亚马逊云科技会向这个邮箱发送一封确认邮件,你需要点击邮件里的确认链接,这样才能开始接收消息。
项目的技术栈非常清晰:Java 17 作为运行环境,Spring Boot 提供 Web、校验、监控等基础功能,Lombok 简化代码,另外引入了
package rs.karajovic.milan.controller;import rs.karajovic.milan.model.Message;
import rs.karajovic.milan.model.SnsResponse;
import rs.karajovic.milan.service.MessagePublisher;import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;/*** * @author Milan Karajovic <milan.karajovic.rs@gmail.com>**/@RestController
public class MessageController {private final MessagePublisher messagePublisher;public MessageController(MessagePublisher messagePublisher) {this.messagePublisher = messagePublisher;}@PostMapping(value = "/publish")@ResponseStatus(HttpStatus.CREATED)public SnsResponse publishMessage(@RequestBody Message message) {return messagePublisher.publish(message);}@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)@ExceptionHandler(RuntimeException.class)private String handleException(RuntimeException e) {return e.getMessage();}
}
提供的 SNS SDK 来和服务端交互。我们在 application.properties 中配置 SNS 所需的参数,包括区域和主题 ARN。这样一来,项目启动时就能根据配置自动连接到对应的 Amazon SNS 主题。
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency><dependency><groupId>software.amazon.awssdk</groupId><artifactId>sns</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>
在代码结构上,我们先定义一个 Amazon Properties 类,通过 @ConfigurationProperties 注解将 application.properties 中的配置绑定到 Java 对象上,确保 region 和 topicArn 不能为空。然后创建一个 SnsConfig 配置类,生成一个基于指定区域的 SnsClient,这个客户端就是我们与 Amazon SNS 通信的桥梁。
#### AWS ### -
aws.sns.region=fill with region where you crated sns
aws.sns.topicArn=fill with created arn for test-top-arnmanagement.endpoints.web.exposure.include=*
接下来是业务逻辑部分。为了让订阅者能够接收到具体的业务信息,我们定义了一个 Message 类和一个 EventType 枚举,描述事件类型(比如温度上升或下降)以及事件的详细数据。然后用 RequestBuilder 构建消息的发布请求,将业务字段转换成 Amazon SNS 支持的消息属性,这样订阅者就可以按需过滤消息,比如只接收某个国家或某个城市的温度变化提醒。这种灵活性正是 Amazon SNS 的一大优势。
package rs.karajovic.milan.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;/*** * @author Milan Karajovic <milan.karajovic.rs@gmail.com>**/@Configuration
public class SnsConfig {@Autowiredprivate AwsProperties awsProperties;@Beanpublic SnsClient snsClient() {return SnsClient.builder().region(Region.of(awsProperties.getRegion())).build();}
}package rs.karajovic.milan.model;/*** * @author Milan Karajovic <milan.karajovic.rs@gmail.com>**/public enum EventType {DROP, INCREASE
}
发布消息的入口在 MessageController 控制器中。我们暴露了一个 /publish 的 POST 接口,接收 JSON 格式的消息对象,将它转成 PublishRequest,然后调用 SNS 客户端发布到指定主题。如果成功,返回一个包含状态码、消息内容和唯一消息 ID 的 SnsResponse 对象;如果失败,则捕获异常并返回详细错误信息。这样的设计既符合 RESTful API 的最佳实践,也让前端或其他系统能明确知道消息是否成功送达。
package rs.karajovic.milan.controller;import rs.karajovic.milan.model.Message;
import rs.karajovic.milan.model.SnsResponse;
import rs.karajovic.milan.service.MessagePublisher;import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;/*** * @author Milan Karajovic <milan.karajovic.rs@gmail.com>**/@RestController
public class MessageController {private final MessagePublisher messagePublisher;public MessageController(MessagePublisher messagePublisher) {this.messagePublisher = messagePublisher;}@PostMapping(value = "/publish")@ResponseStatus(HttpStatus.CREATED)public SnsResponse publishMessage(@RequestBody Message message) {return messagePublisher.publish(message);}@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)@ExceptionHandler(RuntimeException.class)private String handleException(RuntimeException e) {return e.getMessage();}
}
项目完成后,你可以用 Postman 向 /publish 发送一条消息,比如温度变化的数据。
运行中的 Spring Boot 应用会将这条消息发布到 Amazon SNS 主题上,SNS 会根据订阅规则将它推送到你设置的邮箱。几秒钟内,你就能在收件箱看到通知,这种即时反馈在实际业务中非常有价值。
更棒的是,这个应用不仅能在本地运行,还可以轻松容器化部署。通过项目中的 Dockerfile 和 docker-compose.yml,我们可以把整个服务打包进容器中运行,无论是在测试环境还是生产环境,都能保证一致的运行效果。这对于需要快速部署、随时扩展的企业来说,简直是一种“即插即用”的便利。
总结
回顾整个流程,从配置 IAM 用户,到创建 SNS 主题和订阅,再到 Spring Boot 项目的开发与部署,每一步都相对直观。Amazon SNS 的发布/订阅模型帮我们解耦消息发送与接收,让系统的可扩展性和灵活性大大提升。你完全可以在这个基础上延伸出更多玩法,比如用 Lambda 自动处理消息、结合 SQS 做消息队列缓冲,或者用 HTTP 端点和第三方系统对接。
如果你也在寻找一种稳定、灵活且易于集成的消息通知方案,那么基于 Spring Boot 和 Amazon SNS 的组合无疑是个值得尝试的选择。它不仅能帮你快速搭建起一个高可用的通知系统,还能随着业务需求的变化而轻松扩展。从开发到部署的体验,会让你深刻体会到“简单”与“强大”可以兼得。
以上就是本文的全部内容啦。最后提醒一下各位工友,如果后续不再使用相关服务,别忘了在控制台关闭,避免超出免费额度产生费用~