提问者:小点点

火炮JavaScript堆内存不足


laodtest在将到达率从10更改为100后无法运行。

Artillery: 1.6.0-27 Artillery Pro: not installed Node.js: v10.15.0 OS: darwin/x64
:test $ artillery run -o report.json artillery.yml
Started phase 0, duration: 10s @ 10:01:42(+0000) 2019-03-10
.
<--- Last few GCs --->

[62621:0x102803200] 9478 ms: Mark-sweep 1392.4 (1401.5) -> 1392.3 (1401.5) MB, 20.1 / 0.0 ms (average mu = 0.439, current mu = 0.002)

请求旧空间中的最后一种GC[626221:0x102803200]9498毫秒:标记扫描1392.3(1401.5)-

<--- JS stacktrace --->

==== JS stack trace =========================================

0: ExitFrame [pc: 0x38a6205dbe3d]

Security context: 0x1da57481e6e1
1: byteLength [0x1da5274066f1] [buffer.js:526] [bytecode=0x1da597d26509 offset=126](this=0x1da5d7c5fbc1 <JSFunction

缓冲器(sfi = 0x1da573a14251)

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: 0x10003b125 node::Abort() [/Users//.nvm/versions/node/v10.15.0/bin/node]
2: 0x10003b32f node::OnFatalError(char const*, char const*) [/Users//.nvm/versions/node/v10.15.0/bin/node]
3: 0x1001a8e85 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char

const*, bool) [/Users//.nvm/versions/node/v10.15.0/bin/node] 4: 0x1005742a2 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Users//.nvm/versions/node/v10.15.0/bin/node] 5: 0x10057d7a4 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users//.nvm/versions/node/v10.15.0/bin/node] 6: 0x10054f055 v8::internal::Factory::NewRawOneByteString(int, v8::internal::P retenureFlag) [/Users//.nvm/versions/node/v10.15.0/bin/node] 7: 0x1006811a8 v8::internal::String::SlowFlatten(v8::internal::Handlev8::internal::ConsString, v8::internal::P retenureFlag) [/Users//.nvm/versions/node/v10.15.0/bin/node] 8: 0x1001c6c1d v8::String::Utf8Length() const [/Users//.nvm/versions/node/v10.15.0/bin/node] 9: 0x10004eaac node::Buffer::(匿名命名空间)::ByteLengthUtf8(v8::FunctionCallbackInfov8::Value const

我的测试看起来像这样。

.yml

config:
  target: "<URL_REMOVED"
  processor: "./getData.js"
  phases:
    - duration: 10
      arrivalRate: 100
scenarios:
  - flow:
      - function: "getData"
      - post:
          url: "/api/v2/auth"
          json:
            productId: "56729b6b77c82288f746c0cf"
          capture:
            json: "$.data.token"
            as: "token"
      - post:
          url: "/api/v2/sessions"
          headers:
            Authorization: 'Bearer {{token}}'
          json:
            productId: "56729b6b77c82288f746c0cf"
            jobId: "{{jobId}}"
          capture:
            json: "$.data.session._id"
            as: "sessionId"
      - post:
          url: "/api/v2/sessions/{{sessionId}}/document"
          headers:
            Authorization: "Bearer {{token}}"
          json:
            side: "front"
            payload: "{{frontDocument}}"
      - get:
          url: "/api/v2/sessions/{{sessionId}}/metrics/front"
          headers:
            Authorization: "Bearer {{token}}"
      - get:
          url: "/api/v2/sessions/{{sessionId}}/classification"
          headers:
            Authorization: "Bearer {{token}}"
      - get:
          url: "/api/v2/sessions/{{sessionId}}/end"
          headers:
            Authorization: "Bearer {{token}}"

getData.js

'use strict';
var faker = require('faker');
var FRONT_ID = require("./resources/id/front.json");

module.exports = {
    getData
};

function getData(userContext, events, done) {

    let jobId = faker.random.uuid()
    userContext.vars.jobId = jobId;
    userContext.vars.frontDocument = FRONT_ID.base64;
    return done();
}

共1个答案

匿名用户

运行cannon的实例nodejs内存不足。其默认上限约为1.4G。

在*nix上,当您使用< code>npm install -g安装cannon时,可能会从< code >/usr/bin/cannon 启动它。

文件的第一行很可能是,

#!/usr/bin/env node

试着把它改成

#!/usr/bin/env node  --max-old-space-size=8192

获取 8G 的堆空间。但是不要占用比运行火炮的机器具有物理 RAM 更多的堆空间,否则你会摔倒。阅读这个: 如何增加nodejs默认内存?

编辑:问题仍然存在:为什么你的大炮进程会炸掉它的堆。看起来它在崩溃前运行了大约9秒。可能是你的被测系统跟不上你以100的到达率放置在上面的负载。可能是大炮一直在内存中创建和排队发布请求,但它们没有完成,所以它们没有被释放。你的性能日志对此有什么提示吗?

负载测试的全部目的是找到被测系统的突破点。你不会在一艘船上装十个沙袋,然后说“酷,它能工作”,然后再往里面倒100个沙袋来测试它。船会沉的。为什么要这样测试服务器?你只知道它的容量在10到100之间。相反,加大负荷,一个沙袋接一个沙袋,直到系统开始出错。

这就是为什么火炮(实际上是大多数负载测试系统)有办法增加负载的原因。

为什么不试试这样的方法:

- duration: 120
  arrivalRate: 10
  name: "Two minutes, ten arrivals/sec"
- duration: 600
  arrivalRate: 10
  rampTo: 100
  name: "Ten minutes, gradual ramp to 100 arrivals/sec"

一旦您知道系统出现故障的到达率,您就可以根据需要进行更详细的测试。而且,如有必要,您可以尝试返工代码以使其更快。

此外,10秒的测试通常不足以收集有价值的数据。您想知道系统在稳定高负载下的容量。