为Fastify Node js实现负载保护



故事:

作为一名开发人员,我想为Fastify实现负载保护,这样服务器负载就可以防止服务器崩溃。

上下文:

严重性能问题的根本原因分析可能需要时间。在实际部署项目的情况下,值得为服务器或服务添加过载保护。过载保护的理念是监控事件循环延迟(以及其他事项(,并在超过阈值时以"503服务不可用"作为响应。这允许负载平衡器故障转移到其他实例,或者在最坏的情况下意味着用户将不得不刷新。欠压模块可以为Fastify提供最小的开销。

问题:

压力下插件的主要目的是保护服务器免受高负载的影响。我使用autocannon创建了一个假加载,服务器突然开始抛出这个错误:

<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 00007FF7D342A9AC]
Security context: 0x01b3e02408d1 <JSObject>
1: _write [000001EBE7CBA7B1] [_stream_transform.js:~169] [pc=000002737CBBD07D](this=0x02fe03573099 <LineStream map = 00000149AA79E209>,0x00f819d83789 <Uint8Array map = 000002F9BBE3F279>,0x00c0496035d9 <String[#6]: buffer>,0x02fe03575639 <JSBoundFunction (BoundTargetFunction 000003C5D37BC781)>)        
2: ondata [000002FE03577FC9] [_stream_readable.js:~712]...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 00007FF7D28A363F napi_wrap+128063
2: 00007FF7D2842836 v8::base::CPU::has_sse+35142
3: 00007FF7D28434F6 v8::base::CPU::has_sse+38406
4: 00007FF7D3059F4E v8::Isolate::ReportExternalAllocationLimitReached+94
5: 00007FF7D3042021 v8::SharedArrayBuffer::Externalize+833
6: 00007FF7D2F0E57C v8::internal::Heap::EphemeronKeyWriteBarrierFromCode+1436
7: 00007FF7D2F197D0 v8::internal::Heap::ProtectUnprotectedMemoryChunks+1312
8: 00007FF7D2F162F4 v8::internal::Heap::PageFlagsAreConsistent+3204
9: 00007FF7D2F0BB13 v8::internal::Heap::CollectGarbage+1283
10: 00007FF7D2F0A184 v8::internal::Heap::AddRetainedMap+2452
11: 00007FF7D2F31E1F v8::internal::Factory::NewRawTwoByteString+95
12: 00007FF7D2F349CB v8::internal::Factory::NewStringFromUtf8+187
13: 00007FF7D305681A v8::String::NewFromUtf8+298
14: 00007FF7D27A9ABF node::tracing::TraceEventHelper::SetAgent+40751
15: 00007FF7D285A46D v8::internal::Malloced::operator delete+1661
16: 00007FF7D342A9AC v8::internal::SetupIsolateDelegate::SetupHeap+45852
17: 000002737CBBD07D

预期:

本应防止负载的非常挑剔的插件正在破坏挑剔的服务器,需要其他插件或其他方式的帮助来实现负载保护

交叉发布到Github:https://github.com/fastify/under-pressure/issues/64

正如问题中所指出的,所使用的配置是禁用保护。

无论如何,我认为你应该评估它是否是一个外部API。

如果是外部的,那么理想的速率限制是限制每个租户每秒可以对您的端点进行的请求。这对业务也有好处,因为您可以为每个客户提供不同的阈值。

正如你所指出的,内部API可以使用欠压,对于我的经验来说,最好的配置是:

const v8 = require('v8')
console.log(v8.getHeapStatistics())
fastify.register(require('under-pressure'), {
maxEventLoopDelay: 200, // are you using sync method?!
maxHeapUsedBytes: v8.getHeapStatistics().heap_size_limit,
maxRssBytes: v8.getHeapStatistics().total_available_size
})

通过这种方式,插件将适应使用所有默认或自定义内存设置:

node --max-old-space-size=4096 server.js

请注意,Nodejs 12根据其运行的系统调整堆空间,如官方帖子中所述

此更新将根据可用内存配置JavaScript堆大小,而不是使用V8为与浏览器一起使用而设置的默认值。在以前的版本中,除非进行了配置,否则V8默认将32位和64位平台上的最大堆大小分别限制为700 MB或1400 MB。根据可用内存配置堆大小可以确保Node.js不会试图使用超过可用内存的内存,并在内存耗尽时终止。这在处理大型数据集时尤其有用。和以前一样,如果默认值不适合您的应用程序,仍然可以设置--max旧空间大小以使用不同的限制。

最新更新