问题标签 [concurrency-limits]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
206 浏览

java - 当 GC 暂停持续时间超过平均响应时间时,如何限制 webapp 中的并发?

我正在尝试在平均响应时间为5 ms的 Web 应用程序中实现并发限制器。

我的实现基于“负载下的性能”,分叉了项目并发限制,并使用了令人惊叹的技术演讲“停止速率限制!容量管理完成”中解释的概念。

我测量了我的应用程序在正常条件下的并发请求量(每秒正常请求量,正常响应时间),我得到以下结果:

1) 平均值为1,7 2) Perc 95 为3.2 3) 最大值达到45,50,60,具体取决于样品。

有了这些数字,我决定将并发请求的最大容量配置为45。在这一点上,我还没有问自己为什么最大值与平均值如此不同。

然后,我开始测试并发限制器,我发现由于达到我配置的阈值45,某些请求最终被拒绝。

值得一提的是,我正在使用AIMDLimit 实现来动态修改最大容量。但我也测量了每个值,最大容量的值永远不会低于 40。

因此,我对我的应用程序进行了一些研究,并发现了以下内容。每次我的应用程序执行 Minor GC 或 Major GC(使用 CMS)时,N 的值都会增加很多。测量值从 1、2 甚至 3 变为 10、11、12,当执行完整的 GC 时,测量值甚至上升到 40、50、60(这是 N 高于我的阈值和请求被拒绝)。

这种行为是有道理的,因为当执行 Minor 或 Major GC 时,由于我的应用程序位于 tomcat 容器后面,并且 tomcat 容器使用 SO 队列来轮询挂起的请求(请参阅“ Tuning Tomcat For A High Throughput, Fail Fast System ” ),所以没问题N的值也增加了。

例如,让我们分析以下情况。

1) 应用程序正在处理 3 个并发请求

2) 执行一次 GC,耗时 30ms

3) 还有 10 个请求到达并保留在 SO 队列中,等待 tomcat 轮询它们

4)GC完成

5)轮询10个请求,N(并发请求)的值现在上升到13

这里的问题是我还使用 jstat 测量了我的应用程序的 gc 时间,它们看起来并不那么糟糕:

这些措施来自执行的年轻收集,可见年轻收集时间不会持续这么长时间。

368.077 -> 368.178 ( 101 毫秒) 318.084 -> 318.135 ( 51 毫秒)

我也测量了完整的 gc 时间

22.432 -> 23.066 ( 634 ms ) 我相信完整 gc 的测量并不意味着在整个持续时间内停止世界暂停

我所做的另一件事是让 Jstat 在一个选项卡中运行,并在另一个选项卡中跟踪 N(并发请求)的值的日志。正如我所预料的那样,每次触发年轻或完整的 gc 时,N 都会上升很多。

所以,在这个序言之后......我的问题是。

有没有什么好的方法可以限制 gc 暂停时间超过平均响应时间的应用程序的并发能力?

还值得一提的是,我们的 gc 暂停对于我们的往返请求时间来说不是问题。换句话说,对于客户来说没有问题,我也不打算开始讨论如何改进它们或是否不推荐使用 CMS 等。

提前致谢!

0 投票
1 回答
51 浏览

javascript - 使用 rxjs 6 如何创建带有缓存的可取消 Web 请求管道,并限制同时发生的请求数量

我希望有人能够指出我正确的方向,因为我正在努力结合并发和取消rxjs 中排队请求的能力。我将尝试在连续事件中解释这一点。假设我们有 observable A,它接收一个字符串数组。

事件:A 观察到:['dog', 'cat', 'elephant', 'tiger'] 下游检查字符串网络响应是否被缓存,如果它存在于缓存中则从缓存中获取它,如果没有则从缓存中请求它web 并使用 publishReplay / shareReplay 将 observable 保存到缓存中。一次发生 2 个网络请求的限制,因此它尝试从 api 获取“狗”和“猫”(此操作需要 2000 毫秒以上)。1000 毫秒后,A 观察到另一组值:['dog', 'rat', 'horse', 'rabbit']。

接下来应该发生以下情况。我不希望取消“狗”和“猫”请求,我希望他们完成他们的请求,但我想忽略第一个请求中的“大象”和“老虎”。一旦 'dog' 和 'cat' 从第二帧得到他们的响应'rat' 和 'horse' 应该从网络请求,最后一旦其中任何一个解析 'rabbit' 被请求。

这是我当前的代码。我尝试在 networkObservable 的 defer 和 from 之间切换,但行为不同,这也不是我想要的。

这导致输出:

这接近想要的行为,但有一个明显的缺陷。Rat and horse 被请求并且不等待 dog 和 cat 在被处决之前解决。但是,“老虎”和“大象”已被妥善处理,因此功能正常。

我是否必须创建一个单独的主题来处理请求?

0 投票
1 回答
4816 浏览

concurrency - gunicorn uvicorn worker.py 如何遵守 limit_concurrency 设置

FastAPI 使用 gunicorn 启动 uvicorn 工作者,如https://www.uvicorn.org/settings/中所述

但是 gunicorn 不允许使用自定义设置启动 uvicorn,如https://github.com/encode/uvicorn/issues/343中所述

该问题建议覆盖源文件中的 config_kwargs,例如https://github.com/encode/uvicorn/blob/master/uvicorn/workers.py

我们尝试过,但 uvicorn 不limit_concurrency支持源中多个 uvicorn 文件中的设置:

https://github.com/encode/uvicorn/blob/master/uvicorn/workers.py

https://github.com/encode/uvicorn/blob/master/uvicorn/main.py

uvicorn怎么能被迫尊重这个设置?我们仍然从 FastAPI 收到 503 错误

-------UPDATE------------ gunicorn 设置--worker-connections 1000在发出 100 个并行请求时仍会导致 503,这些请求分发给许多工作人员。

但是,我认为这是一个更复杂的问题:我们的 API 端点做了很多繁重的工作,通常需要 5 秒才能完成。

2核2工人压力测试:

  • A. 100+ 并发请求,端点重负载 --worker-connections 1
  • B. 100+ 并发请求,端点重负载 --worker-connections 1000
  • C. 100+ 并发请求,端点低负载 --worker-connections 1
  • D. 100+ 并发请求,端点低负载 --worker-connections 1000

两个实验 A 和 B 都产生了 503 响应,因此假设 worker-connections 设置确实有效,太多的模拟连接似乎不会导致我们的 503 错误。

我们对这种行为感到困惑,因为我们期望 gunicorn/uvicorn 将工作排队,而不是抛出 503 错误。