使用Cloud Run Java客户端库编程拆分流量时遭遇ALREADY_EXISTS错误
看起来你遇到的问题是因为Java客户端库的使用方式和gcloud命令行的行为不一致导致的,我来帮你分析一下可能的原因和解决办法:
不要从零构建Service对象,基于现有Service修改
你当前的代码是新建一个Service对象,只设置name和traffic字段,但这样会丢失原Service对象的元数据(比如etag、服务配置的其他细节)。Cloud Run的Update API在处理这种不完整的Service对象时,可能会误判你的意图,以为你要创建新的修订版本(而不是仅更新流量分配)。正确的做法是先获取现有完整的Service对象,然后在它的基础上修改traffic列表:
// 获取现有服务 Service existingService = serviceClient.getService(...); // 复制现有流量目标并修改百分比 List<TrafficTarget> updatedTrafficTargets = new ArrayList<>(existingService.getTrafficList()); // 在这里修改updatedTrafficTargets中的流量分配,比如找到对应修订版本调整percent // 注意:确保所有流量目标的百分比总和是100% // 构建更新后的服务对象 Service updatedService = existingService.toBuilder() .clearTraffic() .addAllTraffic(updatedTrafficTargets) .build(); // 构建更新请求 UpdateServiceRequest updateRequest = UpdateServiceRequest.newBuilder() .setService(updatedService) .setUpdateMask(FieldMask.newBuilder().addPaths("traffic").build()) .build(); // 执行更新 servicesClient.updateServiceAsync(updateRequest).get();避免不必要的TrafficTarget字段设置
从你给出的请求日志来看,你给TrafficTarget设置了type和tag字段,但你的gcloud命令并没有指定这些参数。除非你确实需要修改修订版本的tag绑定,否则不要设置这些字段:type默认就是TRAFFIC_TARGET_ALLOCATION_TYPE_REVISION,无需显式设置- 如果
custom-B和prod-A这些tag已经绑定到对应的修订版本,重复设置可能会触发不必要的检查;如果tag绑定到其他修订版本,还会导致冲突
简化你的TrafficTarget构建,只保留
revision和percent字段即可。升级Java客户端库版本
你使用的com.google.cloud:google-cloud-run:0.70.0是比较老旧的版本(当前最新版本已经是2.x系列),旧版本可能存在API兼容或序列化的bug,导致请求被错误解析。升级到最新版本可以避免这类问题。验证流量目标的百分比总和
虽然这不是导致当前错误的直接原因,但Cloud Run要求所有流量目标的百分比总和必须是100%,否则会触发其他错误,建议你在构建updatedTrafficTargets时做一下校验。
内容来源于stack exchange

