Angular Universal + Firebase Cloud Function导致超出内存限制

问题描述 投票:0回答:2

当前,我正在开发一个使用Firebase作为后端的Angular 8应用程序。

我遵循Jeff Delaney's Tutorial并成功部署在名为ssr my cloud Express的云功能上。

一切正常...几乎!部署ssr函数后,我可以看到所有云函数的内存使用量都增加了,即使最小的也是如此(1个带有get的事务和1个在事务中的更新):

functions / src / index.ts

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
import * as functions from 'firebase-functions';
// The Firebase Admin SDK to access Firestore.
import * as admin from 'firebase-admin';

admin.initializeApp();

export const ssr = functions.https.onRequest(require(`${process.cwd()}/dist/server`).app);

export const unsubscribeToMeal = functions.region('europe-west1').https.onCall((data) => {
  const mealDoc = admin.firestore().doc('meals/' + data.meal.uid);
  const adminDoc = admin.firestore().doc('users/' + data.meal.adminId);
  return admin.firestore().runTransaction(t => {
    return t.get(mealDoc)
      .then(doc => {
        const meal = doc.data();
        if (doc.exists && meal) {
          const promises = [];
          const participantIndex = meal.users.findIndex((element: any) => {
            return element.detail.uid === data.userToUnsubscribe.uid;
          });
          meal.users.splice(participantIndex, 1);
          const pendingRequest = meal.users.filter((user: any) => user.status === 'pending').length > 0;
          const p4 = t.update(mealDoc, { 'users': meal.users, 'participantId': admin.firestore.FieldValue.arrayRemove(data.userToUnsubscribe.uid), 'nbRemainingPlaces': meal['nbRemainingPlaces'] + 1, 'pendingRequest': pendingRequest })
          promises.push(p4);
          if (promises.length > 0) {
            return Promise.all(promises)
              .then(() => console.log('user unsubscribed'))
              .catch((err: any) => console.log('error unsubscribing user : ' + data.userToUnsubscribe.first_name + ' ' + data.userToUnsubscribe.last_name + ' of the meal ' + meal.uid + '. Err : ' + err))
          }
          else {
            // doc.data() will be undefined in this case
            throw new functions.https.HttpsError('not-found', 'no such document!');
          }
        } else {
          // doc.data() will be undefined in this case
          console.log('doc does not exist');
          throw new functions.https.HttpsError('not-found', 'no such document!');
        }
      })
  })
});

触发unsubscribeToMeal功能从没有部署ssr功能的60MB内存使用变为240MB的内存使用。

所以我想知道发生了什么事?看来Express Server应用在每个云功能实例上都处于引导状态,这会导致内存使用量增加,从而产生更多计费。

[我限制了全局变量以最小化冷启动,正如道格·史蒂文森(Doug Stevenson)解释的here,所以不应该这样。

server.ts

(global as any).WebSocket = require('ws');
(global as any).XMLHttpRequest = require('xhr2');

import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { enableProdMode } from '@angular/core';
import * as express from 'express';
import { join } from 'path';

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
export const app = express();
import * as cookieParser from 'cookie-parser';
import { from } from 'rxjs';
app.use(cookieParser());

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap } = require('./dist/server/main');


// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', DIST_FOLDER);

// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
  maxAge: '1y'
}));

// All regular routes use the Universal engine
app.get('*', (req: express.Request, res: express.Response) => {
  res.render('index2', {
    req
  });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});

任何解决方案仍然具有较低的内存使用率(而不会增加该功能的内存限制),并且同时具有用于角度通用的Express Server的ssr功能?

angular firebase google-cloud-functions out-of-memory angular-universal
2个回答
0
投票

我认为这增加了内存不足为奇。您的教程中有描述:

Angular是旨在在浏览器中运行应用程序的客户端框架。 Universal是一种可以在服务器上运行Angular应用程序的工具,...

因此,使用SSR解决方案,您正在将运行角度的应用程序形式的客户端移到服务器上,因此所有代码通常都在客户端上运行,现在都在服务器上运行。我认为在不保留所需资源的情况下运行某些内容是不可能的...

也许在这种情况下AppEngine会更好地部署它...我希望它会以某种方式对您有所帮助:)


0
投票

与firebase社区联系后:“使用firebase deploy-仅功能将重新部署所有功能的代码,并且所使用的内存将是所有一起加载的功能的累积总数”。因此,解决方案是将函数拆分为不同的文件,并使用带有if语句的process.env。[functionName]作为explained here,以避免为expressFunction增加内存。

© www.soinside.com 2019 - 2024. All rights reserved.