Я работаю над созданием архива из нескольких файлов на сервере и передачей его клиенту во время создания. Первоначально я использовал Archiver Js Он работал нормально, если я добавлял к нему буфер, но он не работает, когда мне нужно добавить в него потоки. Затем, после некоторого обсуждения Github , я переключился на Узел zip-stream , который начал нормально работать благодаря jntesteves . Но когда я развернул код на GKE k8s, я начал получать Network Failed ошибки для больших файлов.
Вот мой пример кода:
const ZipStream = require("zip-stream");
/**
* @summary Adding readable stream provided by https module into zipStreamer using entry method
*/
const handleEntryCB = ({ readableStream, zipStreamer, fileName, resolve }) => {
readableStream.on("error", () => {
console.error("Error while listening readableStream : ", error);
resolve("done");
});
zipStreamer.entry(readableStream, { name: fileName }, error => {
if (!error) {
resolve("done");
} else {
console.error("Error while listening zipStream readableStream : ", error);
resolve("done");
}
});
};
/**
* @summary Handling downloading of files using native https, http and request modules
*/
const handleUrl = ({ elem, zipStreamer }) => {
return new Promise((resolve, reject) => {
let fileName = elem.fileName;
const url = elem.url;
//Used in most of the cases
if (url.startsWith("https")) {
https.get(url, readableStream => {
handleEntryCB({ readableStream, zipStreamer, url, fileName, resolve, reject });
});
} else if (url.startsWith("http")) {
http.get(url, readableStream => {
handleEntryCB({ readableStream, zipStreamer, url, fileName, resolve, reject });
});
} else {
const readableStream = request(url);
handleEntryCB({ readableStream, zipStreamer, url, fileName, resolve, reject });
}
});
};
const downloadZipFile = async (data, resp) => {
let { urls = [] } = data || {};
if (!urls.length) {
throw new Error("URLs are mandatory.");
}
//Output zip name
const outputFileName = `Test items.zip`;
console.log("Downloading using streams.");
//Initialize zip-stream instance
const zipStreamer = new ZipStream();
//Set headers to response
resp.writeHead(200, {
"Content-Type": "application/zip",
"Content-Disposition": `attachment; filename="${outputFileName}"`,
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS"
});
//piping zipStreamer to the resp so that client starts getting response
//as soon as first chunk is added to the zipStreamer
zipStreamer.pipe(resp);
for (const elem of urls) {
await handleUrl({ elem, zipStreamer });
}
zipStreamer.finish();
};
app.post(restPrefix + "/downloadFIle", (req, resp) => {
try {
const { data } = req.body || {};
downloadZipFile(data, resp);
} catch (error) {
console.error("[FileBundler] unknown error : ", error);
if (resp.headersSent) {
resp.end("Unknown error while archiving.");
} else {
resp.status(500).end("Unknown error while archiving.");
}
}
});
Я проверил на 7-8 файлах по ~ 4,5 ГБ каждый на локальном компьютере, он работает нормально, и когда я попробовал то же самое на google k8s, я получил ошибку сетевого сбоя. После еще одного исследования я увеличил время ожидания сервера на k8s t0 3000 секунд, чем он начинает работать нормально, но я думаю, что увеличение времени ожидания не очень хорошо. Есть ли что-то, чего мне не хватает на уровне кода, или вы можете предложить какую-нибудь хорошую конфигурацию развертывания GKE для сервера, который может загружать большие файлы со многими одновременными пользователями? Я застрял на этом в течение последних 1,5 месяцев. пожалуйста, помогите!
Редактировать 1 : Я редактировал тайм-аут во входе, т.е. Сетевые службы-> Балансировка нагрузки -> Редактировать тайм-аут в сервисе ![Backend Service Detail_1](https://i.stack.imgur.com/tpEob.png)