EMR Serverless ListJobRuns分页请求中nextToken验证失败,无法获取后续结果
EMR Serverless ListJobRuns分页请求中nextToken验证失败,无法获取后续结果
我之前排查过类似的EMR Serverless分页token失效问题,结合你的代码和token示例,大概率能定位到几个核心原因,给你一步步分析:
最可能的问题:分页请求参数不一致
AWS的分页nextToken是和当前请求的所有非分页参数严格绑定的——只要后续请求的参数(比如createdAtAfter、states、maxResults等)和第一次请求有任何差异,即使token本身是对的,也会被判定为无效。
看你的代码,createdAtAfter是在循环内部每次调用Instant.now().minus(days, ChronoUnit.DAYS)计算的:
var builder = ListJobRunsRequest.builder() .maxResults(MAX_RESULTS) .applicationId(applicationId) .createdAtAfter(Instant.now().minus(days, ChronoUnit.DAYS)); // 这里每次循环都会重新计算!
第一次请求时createdAtAfter是T0时间减days,等循环执行到第二次请求时,Instant.now()已经变成了T1(哪怕只过了几毫秒),导致createdAtAfter的值和第一次不一样,直接触发token失效。
修复方法:提前固定createdAtAfter的值
把时间计算移到循环外面,确保所有分页请求的该参数完全一致:
// 提前计算好截止时间,循环内复用 Instant cutoffTime = Instant.now().minus(days, ChronoUnit.DAYS); try (var client = EmrServerlessClient.builder().region(AwsUtils.getRegion()).build()) { String token = null; do { var builder = ListJobRunsRequest.builder() .maxResults(MAX_RESULTS) .applicationId(applicationId) .createdAtAfter(cutoffTime); // 用固定的截止时间 if (token != null) { builder.nextToken(token); } if (status != null) { builder.states(status); } var response = client.listJobRuns(builder.build()); jobRuns.addAll(response.jobRuns()); token = response.nextToken(); } while (token != null); }
其他可能的排查方向
如果上面的修复还没解决问题,可以再检查这几点:
- SDK版本兼容性:旧版本的AWS SDK for Java v2可能存在EMR Serverless分页的bug,建议升级到最新稳定版(比如2.25.x以上)。如果用Maven,更新依赖:
<dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>emrserverless</artifactId> <version>2.25.0</version> </dependency> - 参数一致性验证:确认
states、maxResults、applicationId这些参数在循环中没有被意外修改——哪怕是states从非空变成空(或者反过来),都会导致token失效。 - token完整性检查:在循环中加日志打印每次的
nextToken,确认传递给下一次请求的token和上一次响应返回的完全一致(没有被截断、转义或修改):System.out.println("Received nextToken: " + response.nextToken()); System.out.println("Sending nextToken: " + token);
内容来源于stack exchange
相关产品推荐
相关产品推荐

