NextJs 应用在大流量下的行为
Behavior of NextJs app under heavy traffic
我正在开发 NextJs 应用程序。它将部署在 Azure 上,我将在其中安装 nodejs 并将 运行 next start -p 4000
命令。
我想知道的是NextJs如何处理大流量?也就是说,如果有大约 2 万用户访问我的网站,这是 Nextjs 可以开箱即用的东西,还是我应该 docker 使用多个 nextjs 应用程序 docker 调整和编排多个 nodejs docker 图像?
或者,Nextjs 是否向我的 CDN 提供静态文件,这样我就不必关心我的 nodejs 的流量压力,而 nextjs 服务器是 运行ning?
希望我的问题有道理。
没有幻数
帽子的容量限制没有固定数量。接下来,Node.js 应用程序通常在处理多个连接方面非常有效,但负载的重量取决于您的站点。您可以“处理”多少个同时连接也取决于您认为可接受的延迟时间。例如,您的服务器可能能够以 1 秒的延迟处理 40k 个并发请求,但只能以 100ms 的延迟处理 5k 个并发请求。
影响容量的因素
您的服务器可以处理多少流量取决于以下因素:
- 您的服务器执行的 IO 量。这包括发送到浏览器的数据,以及从磁盘或数据库读取的数据。如果您要提供大量静态内容(例如大图像、视频),这可能会开始限制您。
- 您的服务器的处理量。这是每次 API 调用 运行 需要多少代码。通常这是很低的,大多数服务器都是 IO-bound,但有时会有很多处理(例如从数据库中检索大型数据集并进行转换)。
- 您的服务器运行所在机器的处理能力。在速度较慢的机器上,您的所有处理速度都会变慢(千兆赫数越少意味着速度越慢),因此您所做的处理(如上所述)将花费更长的时间 运行,这意味着您将阻塞新连接的时间更长,这将降低服务器的容量。
- 您的服务器 运行 所在机器的 IO 速度。如果您的服务器进行任何磁盘访问,这包括磁盘速度,否则它主要与网络速度有关。现在是 2022 年,因此网络速度将不再是限制您的应用程序的因素,因此除非您正在访问磁盘,否则请忽略这一点。
- 您的 OS 支持的连接数。每个 OS 都有一个 built-in 硬限制(不能更改的最大值),有时还有一个软限制(可以增加的默认限制)。
估计容量
从理论上讲,您的开发机器应该比您的生产服务器慢,因此您可以通过对其进行负载测试来获得服务器容量的下限。您可以使用 Autocannon or Loadtest 之类的工具来估计您的容量。如果您从只有几个同时连接开始并逐渐增加,您应该会看到延迟突然增加的点(延迟应该或多或少保持一致)。这是您开始达到极限的时候。
扩展你的能力
线程池
Node.js是single-threaded,但是在Lib UV thread pool中异步调用了运行。当 Node.js 正在等待 IO 时,有一个 LibUV 线程在幕后旋转。当 Lib UV 线程池已满时,Node.js 必须等待另一个线程可用,然后才能启动另一个异步 IO 任务,这会减慢一切。
Node.js 中的默认线程池大小非常小(以前为 4),因此增加它可能非常有益。您可以找到有关调整 LibUV 线程池大小的更多信息 here and here。
其他问题
因为您在问题中特别提到了 Docker,请记住 Docker 只是一种部署策略,它本身并不能帮助减轻任何负载。如果您受到线程池限制的约束,那么在同一台机器上对多个 Docker 实例进行负载平衡将加快您的进程,直到您达到其他上限之一。如果您已经 CPU-bound 或 IO-bound,那么在同一台服务器上 运行 多个实例将无济于事。此时您需要垂直扩展您的服务器计算机或添加更多计算机。
我正在开发 NextJs 应用程序。它将部署在 Azure 上,我将在其中安装 nodejs 并将 运行 next start -p 4000
命令。
我想知道的是NextJs如何处理大流量?也就是说,如果有大约 2 万用户访问我的网站,这是 Nextjs 可以开箱即用的东西,还是我应该 docker 使用多个 nextjs 应用程序 docker 调整和编排多个 nodejs docker 图像?
或者,Nextjs 是否向我的 CDN 提供静态文件,这样我就不必关心我的 nodejs 的流量压力,而 nextjs 服务器是 运行ning?
希望我的问题有道理。
没有幻数
帽子的容量限制没有固定数量。接下来,Node.js 应用程序通常在处理多个连接方面非常有效,但负载的重量取决于您的站点。您可以“处理”多少个同时连接也取决于您认为可接受的延迟时间。例如,您的服务器可能能够以 1 秒的延迟处理 40k 个并发请求,但只能以 100ms 的延迟处理 5k 个并发请求。
影响容量的因素
您的服务器可以处理多少流量取决于以下因素:
- 您的服务器执行的 IO 量。这包括发送到浏览器的数据,以及从磁盘或数据库读取的数据。如果您要提供大量静态内容(例如大图像、视频),这可能会开始限制您。
- 您的服务器的处理量。这是每次 API 调用 运行 需要多少代码。通常这是很低的,大多数服务器都是 IO-bound,但有时会有很多处理(例如从数据库中检索大型数据集并进行转换)。
- 您的服务器运行所在机器的处理能力。在速度较慢的机器上,您的所有处理速度都会变慢(千兆赫数越少意味着速度越慢),因此您所做的处理(如上所述)将花费更长的时间 运行,这意味着您将阻塞新连接的时间更长,这将降低服务器的容量。
- 您的服务器 运行 所在机器的 IO 速度。如果您的服务器进行任何磁盘访问,这包括磁盘速度,否则它主要与网络速度有关。现在是 2022 年,因此网络速度将不再是限制您的应用程序的因素,因此除非您正在访问磁盘,否则请忽略这一点。
- 您的 OS 支持的连接数。每个 OS 都有一个 built-in 硬限制(不能更改的最大值),有时还有一个软限制(可以增加的默认限制)。
估计容量
从理论上讲,您的开发机器应该比您的生产服务器慢,因此您可以通过对其进行负载测试来获得服务器容量的下限。您可以使用 Autocannon or Loadtest 之类的工具来估计您的容量。如果您从只有几个同时连接开始并逐渐增加,您应该会看到延迟突然增加的点(延迟应该或多或少保持一致)。这是您开始达到极限的时候。
扩展你的能力
线程池
Node.js是single-threaded,但是在Lib UV thread pool中异步调用了运行。当 Node.js 正在等待 IO 时,有一个 LibUV 线程在幕后旋转。当 Lib UV 线程池已满时,Node.js 必须等待另一个线程可用,然后才能启动另一个异步 IO 任务,这会减慢一切。 Node.js 中的默认线程池大小非常小(以前为 4),因此增加它可能非常有益。您可以找到有关调整 LibUV 线程池大小的更多信息 here and here。
其他问题
因为您在问题中特别提到了 Docker,请记住 Docker 只是一种部署策略,它本身并不能帮助减轻任何负载。如果您受到线程池限制的约束,那么在同一台机器上对多个 Docker 实例进行负载平衡将加快您的进程,直到您达到其他上限之一。如果您已经 CPU-bound 或 IO-bound,那么在同一台服务器上 运行 多个实例将无济于事。此时您需要垂直扩展您的服务器计算机或添加更多计算机。