我有一个Firebase Functions项目,其中包含70多个功能。它在节点8上运行。
5-7次完整部署后,我得到一个错误:
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(mediaType)) {
exchange.getRequest().getBody().collectList().flatMap(dataBuffers -> {
final byte[] totalBytes = dataBuffers.stream().map(dataBuffer -> {
try {
final byte[] bytes = IOUtils.toByteArray(dataBuffer.asInputStream());
return bytes;
} catch (IOException e) {
throw new RuntimeException(e);
}
}).reduce(this::addBytes).get();
final ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return Flux.just(buffer(totalBytes));
}
};
final ServerCodecConfigurer configurer = ServerCodecConfigurer.create();
final Mono<MultiValueMap<String, Part>> multiValueMapMono = repackageMultipartData(decorator, configurer);
return multiValueMapMono.flatMap(part -> {
for (String key : part.keySet()) {
// read parameters
}
return chain.filter(exchange.mutate().request(decorator).build());
});
});
}
private DataBuffer buffer(byte[] bytes) {
final NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
final DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes);
return buffer;
}
@SuppressWarnings("unchecked")
private static Mono<MultiValueMap<String, Part>> repackageMultipartData(ServerHttpRequest request, ServerCodecConfigurer configurer) {
try {
final MediaType contentType = request.getHeaders().getContentType();
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) {
return ((HttpMessageReader<MultiValueMap<String, Part>>) configurer
.getReaders()
.stream()
.filter(reader -> reader.canRead(MULTIPART_DATA_TYPE, MediaType.MULTIPART_FORM_DATA))
.findFirst()
.orElseThrow(() -> new IllegalStateException("No multipart HttpMessageReader.")))
.readMono(MULTIPART_DATA_TYPE, request, Collections.emptyMap())
.switchIfEmpty(EMPTY_MULTIPART_DATA)
.cache();
}
} catch (InvalidMediaTypeException ex) {
// Ignore
}
return EMPTY_MULTIPART_DATA;
}
public byte[] addBytes(byte[] first, byte[] second) {
final byte[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
目前尚不清楚原因是什么?我达到了哪个限制?配额何时续签?
几分钟后部署无法正常工作。
答案 0 :(得分:3)
我已请求Firebase社区松弛的帮助,现在我了解发生了什么。谢谢,@ katowulf。
此处描述了配额: https://firebase.google.com/docs/functions/quotas#quota_limits_for_firebase_cli_deployment
我们有3个与部署相关的配额:
要查看已命中哪一个,可以转到配额管理员: https://console.cloud.google.com/projectselector2/projectselector/iam-admin/quotas?service=cloudfunctions.googleapis.com&usage=ALL&supportedpurview=project
就我而言,我的命中配额3. Max build time
每天限制为12000秒(默认)。经过一些实验,我注意到一个功能部署会增加大约70秒的构建时间(在您的情况下可能是不同的数字!)。因此12000/70每天大约部署170个功能。
在“配额”管理页面(第二个链接)上,您可以要求使用Edit Quota
选项增加任何配额。在没有任何其他批准的情况下,可提供36000 sec的构建时间,在我看来,增加的单个功能每天可部署500多个。
在UTC-07:00 0:00左右,配额已重置为0,我的功能已部署到us-central1。因此,一天似乎有固定的时间段(不是最近24小时的移动窗口)。
对于较大的项目,您不应一次全部部署整个项目,而应像https://firebase.google.com/docs/cli/#deploy_specific_functions链接中所述的单个功能
答案 1 :(得分:3)
您的功能有70多种,因此在短时间内部署5-7次将超出此处提到的限制之一:https://firebase.google.com/docs/cli/#deployment_quotas
对于Firebase CLI部署的每个功能,以下类型的速率和时间限制会受到影响:
API calls (READ) - 1 call per deployment, no matter how many functions
Limit: 5000 per 100 seconds
API calls (WRITE) - 1 call per function
Limit: 80 per 100 seconds
Max build time - A few minutes per function depending on size
Limit: 120 minutes per day
以下是一个可能与您的错误有关的示例:https://firebase.google.com/docs/cli/#deployment_quotas
很可能(尽管不太可能)您超过了一个配额 限制Firebase部署操作的速度或数量。对于 例如,当部署大量功能时,您可能 收到HTTP 429配额错误消息。要解决此类问题,请尝试 使用部分部署或请求增加特定的配额 Firebase服务。例如,称为“每个请求的写入请求”的配额 每个用户100秒可能有助于解决Cloud Functions 429 上面引用的错误。
您可以做的是创建一个脚本,如果您要部署每个功能,将为每个功能调用deploy。这将确保您不会超出生产的限制。
在开发中,您知道哪些功能将根据代码更改进行更改,因此您只能部署修改后的功能并进行测试。
答案 2 :(得分:0)