ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

使用 CloudWatch Events/EventBridge 的 cron 表达式定时调度 AWS Lambda Java 函数:aws-doc-sdk-examples 实战指南

使用 CloudWatch Events/EventBridge 的 cron 表达式定时调度 AWS Lambda Java 函数:aws-doc-sdk-examples 实战指南 示例工程教程后端【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples点击查看免费下载本指南以 aws-doc-sdk-examples 仓库中 creating_scheduled_events 教程为骨架完整讲解如何用 Amazon CloudWatch Events现称 Amazon EventBridge的 cron 表达式定时触发 AWS Lambda Java 函数。读完本文你将掌握从 IAM 角色创建、IntelliJ Maven 工程搭建、DynamoDB 增强型客户端扫描、Amazon SNS 短信发送到cron(0 12 ? * MON-FRI *)定时调度配置的全链路实现方法并能在自己的业务中复现员工入职一周年自动祝贺短信这一多服务协作场景。定时事件的业务场景与整体思路CloudWatch Events/EventBridge 是 AWS 的事件总线服务你可以为它配置一条基于 cron 表达式的调度规则Schedule让规则在指定时间点自动触发对 AWS Lambda 函数的调用从而实现无需人工干预、周期性地执行业务逻辑。本教程的典型业务场景如下企业希望在每个工作日向入职满一整年的员工自动发送一条祝贺短信。整个流程分为两段定时触发CloudWatch Events 规则按 cron 表达式例如cron(0 12 ? * MON-FRI *)每周一至周五的 12:00UTC调用 Lambda 函数业务执行Lambda 函数内部读取 Amazon DynamoDB 中的Employee员工表筛选出startDate入职日期恰好为一周年当天的员工再通过 Amazon SNS 的publish方法向员工手机号发送短信。在该业务中Employee表是核心数据源。教程要求创建一个名为Employee的 DynamoDB 表包含以下字段字段含义在代码中的角色Id员工主键表的分区键Partition Keyfirst员工名用于拼接短信文案phone员工手机号SNS 短信接收方startDate入职日期格式yyyy-MM-dd周年判定依据见 Employee.java创建表后请录入正确的测试数据尤其是要填入一个真实可接收短信的手机号以便验证完整链路。前提条件与重要提示跟随本教程动手实践需要准备以下环境一个拥有有效凭证的 AWS 账户Java IDE教程使用 IntelliJ IDEA其余支持 Maven 的 IDE 亦可Java 17 JDK仓库中的 pom.xml 将maven.compiler.source/target与java.version均声明为 17与教程正文保持一致Maven 3.6 或更高版本。同时请注意三点本教程涉及的 Lambda、DynamoDB、SNS 等服务均属于 AWS Free Tier 免费套餐可覆盖范围但不同服务的免费额度与区域可用性存在差异某些 AWS 服务仅在某些特定区域提供请确认你使用的区域支持所需服务运行本教程可能产生 AWS 账户费用请在体验完成后及时终止删除创建的全部资源以免持续计费。在进入编码阶段之前还需要在 DynamoDB 控制台完成Employee表的创建键为Id建议同时将startDate设为排序键以匹配 Employee.java 中DynamoDbPartitionKey与DynamoDbSortKey的映射并填入测试数据。创建执行 Lambda 所需的 IAM 角色Lambda 函数在执行时需要调用 DynamoDB 与 SNS 服务因此必须为其授予一个具备相应权限的 IAM 角色。本教程创建的角色名为lambda-support具体步骤打开 AWS Management Console在搜索框输入IAM并进入 IAM 控制台在左侧导航栏选择Roles角色点击Create Role创建角色可信实体选择AWS service用例选择Lambda在权限策略页面搜索并勾选AWSLambdaBasicExecutionRole允许 Lambda 将日志写入 CloudWatch Logs配合代码中的LambdaLogger使用点击Next下一步命名角色为lambda-support并完成创建进入lambda-support角色详情页选择Attach Policies附加策略搜索并附加AmazonDynamoDBFullAccess授权 Lambda 扫描Employee表搜索并附加AmazonSNSFullAccess授权 Lambda 调用 SNS 发送短信。附加完成后角色详情页会同时列出上述三条策略。这一步是后续 Lambda 能正常读写 DynamoDB 与发送短信的前提——角色权限缺失时函数会在运行时抛出权限相关异常。创建 IntelliJ Maven 项目 LambdaCronFunctions在 IntelliJ IDEA 中完成以下操作创建 Maven 工程选择File→New→Project在 New Project 对话框中工程类型选择Maven点击NextGroupId填写LambdaCronFunctionsArtifactId填写LambdaCronFunctions点击Next→Finish完成创建。仓库中该教程的完整工程包含三个 Java 类全部位于com.aws.example包下类职责Handler.javaLambda 函数入口负责编排整个业务逻辑ScanEmployees.java扫描 DynamoDB 并调用 SNS 发送短信的核心业务类Employee.java与 DynamoDB 增强型客户端配合的数据映射类配置 POM 依赖与打包插件新建项目后需要把依赖配置成与仓库 pom.xml 一致。该文件定义了本示例所需的全部依赖核心部分如下properties java.version17/java.version maven.compiler.target17/maven.compiler.target maven.compiler.source17/maven.compiler.source /properties dependencies !-- Lambda Java 运行时核心 APIContext、LambdaLogger 等 -- dependency groupIdcom.amazonaws/groupId artifactIdaws-lambda-java-core/artifactId version1.2.1/version /dependency !-- DynamoDB 增强型客户端DynamoDbEnhancedClient、Expression、ScanEnhancedRequest -- dependency groupIdsoftware.amazon.awssdk/groupId artifactIddynamodb-enhanced/artifactId version2.21.20/version /dependency !-- DynamoDB Java V2 基础 APIDynamoDbClient、AttributeValue -- dependency groupIdsoftware.amazon.awssdk/groupId artifactIddynamodb/artifactId version2.21.20/version /dependency !-- Amazon SNS Java V2 APISnsClient、PublishRequest -- dependency groupIdsoftware.amazon.awssdk/groupId artifactIdsns/artifactId version2.21.20/version /dependency /dependencies除上述依赖外pom.xml 还引入了gson、log4j等工具库并额外声明了javax.mail相关依赖便于后续在类似场景中扩展邮件发送能力。三个 Java 源文件在 metadata.yaml 中被统一标记为lambda服务用于仓库的自动化检索与校验。在build部分pom.xml 的关键配置是maven-shade-pluginplugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-shade-plugin/artifactId version3.2.2/version configuration createDependencyReducedPomfalse/createDependencyReducedPom /configuration executions execution phasepackage/phase goals goalshade/goal /goals /execution /executions /plugin该插件在package阶段将项目及其全部依赖合并进同一个肥 JARuber JAR。如果缺少这个插件打包出的 JAR 不会包含 DynamoDB/SNS 等第三方依赖部署到 Lambda 后运行时将直接抛出ClassNotFoundException。编写 Lambda 函数的三要素Handler、ScanEmployees 与 EmployeeHandler函数入口与 CloudWatch Logs 日志Handler.java 是 Lambda 的入口类业务逻辑集中在handleRequest方法中package com.aws.example; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.LambdaLogger; /** * This is the entry point for the Lambda function. */ public class Handler { public Void handleRequest(Context context) { LambdaLogger logger context.getLogger(); ScanEmployees scanEmployees new ScanEmployees(); Boolean ans scanEmployees.sendEmployeMessage(); if (ans) logger.log(Messages sent: ans); return null; } }值得注意的实现细节方法签名handleRequest(Context context)使用com.amazonaws.services.lambda.runtime.Context与 Lambda Java 运行时 API 的约定一致通过context.getLogger()获取LambdaLogger调用logger.log(...)即可把日志写入 CloudWatch Logs便于在控制台排查调度执行结果返回值类型为Void函数执行结果通过日志而非返回值对外呈现。EmployeeDynamoDB 增强型客户端的数据映射 BeanEmployee.java 使用DynamoDbBean注解将普通 Java Bean 映射为 DynamoDB 表结构DynamoDbBean public class Employee { private String Id; private String first; private String phone; private String startDate; DynamoDbPartitionKey public String getId() { return this.Id; } DynamoDbSortKey public String getStartDate() { return this.startDate; } // setFirst / getFirst、setPhone / getPhone 等访问器方法略 }从源码可以清晰看到两个关键映射约定getId()被标注为DynamoDbPartitionKey分区键对应表中的Id主键getStartDate()被标注为DynamoDbSortKey排序键因此创建Employee表时建议以Id为分区键、startDate为排序键与 Java Bean 的注解声明保持一致。这四个属性Id、first、phone、startDate与之前创建的 DynamoDB 表字段一一对应是增强型客户端自动完成序列化/反序列化的基础。ScanEmployees扫描匹配员工并发送短信ScanEmployees.java 是本示例的核心业务实现同时使用 DynamoDB Java V2 API 与 SNS Java V2 API主要包含三个方法。sendEmployeMessage扫描并筛选一周年员工Region region Region.US_WEST_2; DynamoDbClient ddb DynamoDbClient.builder() .region(region) .build(); DynamoDbEnhancedClient enhancedClient DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); DynamoDbTableEmployee table enhancedClient.table(Employee, TableSchema.fromBean(Employee.class));这里先用标准的DynamoDbClient构建底层客户端再包装为DynamoDbEnhancedClient最后通过enhancedClient.table(Employee, TableSchema.fromBean(Employee.class))绑定EmployeeBean 与真实表名。注意代码中区域被硬编码为US_WEST_2如果Employee表与 SNS 短信服务不在该区域请同步调整Region常量。筛选条件通过增强型客户端的Expression对象构造——这正是本教程示范的用 Java 逻辑做条件查询的关键AttributeValue attVal AttributeValue.builder() .s(myDate) // 一年前的今天格式 yyyy-MM-dd .build(); MapString, AttributeValue myMap new HashMap(); myMap.put(:val1, attVal); // 占位符绑定实际日期值 MapString, String myExMap new HashMap(); myExMap.put(#startDate, startDate); // 表达式名称转义避免与保留字冲突 Expression expression Expression.builder() .expressionValues(myMap) .expressionNames(myExMap) .expression(#startDate :val1) // 只取入职日期等于目标日的员工 .build(); ScanEnhancedRequest enhancedRequest ScanEnhancedRequest.builder() .filterExpression(expression) .limit(15) // you can increase this value .build(); IteratorEmployee employees table.scan(enhancedRequest).items().iterator();这段代码体现了三个 DynamoDB 增强型客户端的惯用法占位符Placeholder:val1通过expressionValues绑定具体日期避免 SQL 注入式的表达式拼接问题表达式名称转义Expression Names#startDate通过expressionNames映射到真实的属性名startDate防止属性名与 DynamoDB 保留字冲突过滤与限流filterExpression在服务端完成日期过滤limit(15)限制单次扫描返回条数可调大以覆盖更多员工。扫描结果通过IteratorEmployee逐条取出读取first姓名与phone手机号后调用sentTextMessage发送短信并将返回值置为true表示至少成功发送了一条。sentTextMessage通过 SNS 发送文本短信SnsClient snsClient SnsClient.builder() .region(Region.US_WEST_2) .build(); String message first happy one year anniversary. We are very happy that you have been working here for a year! ; PublishRequest request PublishRequest.builder() .message(message) .phoneNumber(phone) // 直接向手机号发布无需先创建 SNS Topic .build(); snsClient.publish(request);这里使用了 SNS 的手机号直发能力PublishRequest只需携带message与phoneNumber两个字段AWS 会自动将消息以 SMS 形式发送到该号码无需预先创建 Topic 或订阅。getDate计算一年前的日期String DATE_FORMAT yyyy-MM-dd; DateFormat dateFormat new SimpleDateFormat(DATE_FORMAT); DateTimeFormatter dateFormat8 DateTimeFormatter.ofPattern(DATE_FORMAT); Date currentDate new Date(); LocalDateTime localDateTime currentDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); localDateTime localDateTime.minusYears(1); String ann dateFormat8.format(localDateTime); return ann;该方法取当前时间并minusYears(1)回退一年输出格式为yyyy-MM-dd的字符串作为Expression中:val1的比对值。由于 Lambda 默认运行在 UTC 时区实际调度时间cron 中的 12:00 也为 UTC与getDate计算的今天保持一致。异常处理方面DynamoDbException与SnsException均被捕获并打印错误信息后System.exit(1)便于在 CloudWatch Logs 中快速定位失败原因。打包项目为可部署的 JAR确认 pom.xml 配置无误后在项目根目录执行 Maven 打包命令mvn package打包完成后JAR 文件位于项目下的target目录例如target/LambdaCronFunctions-1.0-SNAPSHOT.jar。再次强调只有配置了maven-shade-pluginJAR 才会包含 DynamoDB、SNS、aws-lambda-java-core 等全部运行依赖否则部署后执行会报ClassNotFoundException。在 Lambda 控制台部署函数打开 Lambda 控制台选择Create Function创建函数模板选择Author from scratch从头创作在 Basic information 中函数名称填写employeemsgRuntime运行时选择 Java 运行时教程正文原选择Java 8当前仓库源码以 Java 17 为目标编译请以控制台当前可用的 Java 运行时版本为准选择与打包产物兼容的版本Permissions 选择Use an existing role并指定此前创建的lambda-support角色点击Create function完成创建进入函数后Code entry type 选择Upload a .zip or .jar file点击Upload上传 target 目录中的 JARHandler字段填写函数入口的完整限定名com.aws.example.Handler::handleRequest——其格式为包名.类名::方法名Handler是 Lambda 入口类handleRequest是具体执行方法点击Save保存配置。配置 CloudWatch Events 规则实现定时触发部署完成后为employeemsg函数挂接 CloudWatch Events/EventBridge 定时触发规则打开 Lambda 控制台的 Functions函数页面选择employeemsg在 Designer设计器区域点击Add trigger添加触发器触发器类型选择CloudWatch Events/EventBridgeRule 选择Create a new rule新建规则并填写 Rule name 与 Rule descriptionRule type选择Schedule expression调度表达式在Schedule expression输入框中填写 cron 表达式例如cron(0 12 ? * MON-FRI *)点击Add完成添加。cron 表达式解析与调参建议以cron(0 12 ? * MON-FRI *)为例其字段从左至右依次为分钟0、小时12、日?不指定、月*每月、星期MON-FRI周一至周五、年*每年。整体语义是每周一至周五的 12:00UTC触发一次。Lambda 的定时 cron 表达式使用UTC 时区因此如需在本地时间如北京时间 9:00执行需要先换算为对应的 UTC 时间。调整字段即可改变调度周期例如cron(0 9 * * ? *)表示每天 9:00 UTC 触发cron(0/15 * * * ? *)表示每 15 分钟触发一次。创建规则后可以稍等数分钟确认函数是否按预期被调用并在 CloudWatch Logs 中查看Handler通过LambdaLogger写出的执行日志。资源清理教程开始部分已强调过本示例会创建并实际运行 Lambda 函数、DynamoDB 表、SNS 短信与 CloudWatch Events 规则持续运行可能产生费用。体验完成后请务必清理以下资源删除 Lambda 函数employeemsg连同其关联的触发器规则删除EmployeeDynamoDB 表删除 IAM 角色lambda-support。仓库中的对应资源速查本教程的全部源码与配置都位于仓库的javav2/usecases/creating_scheduled_events目录下可直接对照阅读教程文档README.mdMaven 构建配置pom.xml含依赖版本、shade 插件与 Java 17 编译参数Lambda 入口类Handler.java核心业务类ScanEmployees.java数据映射 BeanEmployee.java示例元数据服务标签metadata.yaml更多 AWS 多服务示例usecases至此你已经掌握了CloudWatch Events cron 表达式 Lambda Java DynamoDB SNS的完整组合方案。将Employee表的数据替换为你自己的业务数据、调整ScanEmployees中的过滤表达式与 cron 调度周期即可把这一模式迁移到批量通知、定时报表、数据清洗等更多定时任务场景。赞分享示例工程教程后端【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples点击查看免费下载相关推荐用 Amazon API Gateway 调用 Java Lambda 函数aws-doc-sdk-examples javav2 官方实战教程用 Amazon API Gateway 调用 Java Lambda 函数aws doc sdk examples javav2 官方实战教程 本篇基于 a示例工程教程后端使用 AWS C Lambda Runtime 构建与打包 C Lambda 函数aws-doc-sdk-examples 实战使用 AWS C Lambda Runtime 构建与打包 C Lambda 函数aws doc sdk examples 实战 本文以 aws d示例工程教程后端aws-doc-sdk-examples用 AWS SDK for Java 2.x 开发 Amazon EventBridge Scheduler 定时任务的完整实践aws doc sdk examples用 AWS SDK for Java 2.x 开发 Amazon EventBridge Scheduler 定时任务示例工程教程后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表