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 的組合無疑是個值得嘗試的選擇。它不僅能幫你快速搭建起一個高可用的通知系統,還能隨著業務需求的變化而輕松擴展。從開發到部署的體驗,會讓你深刻體會到“簡單”與“強大”可以兼得。
以上就是本文的全部內容啦。最后提醒一下各位工友,如果后續不再使用相關服務,別忘了在控制臺關閉,避免超出免費額度產生費用~