неожиданное поведение при использовании zip-stream NPM в Google k8s - PullRequest
0 голосов
/ 29 февраля 2020

Я работаю над созданием архива из нескольких файлов на сервере и передачей его клиенту во время создания. Первоначально я использовал 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...