今天,我想谈谈如何在不同的促销、高峰时间和突发的用户流量期间处理数百万个请求。我们谈论的是整个平台的延迟,您需要记住,系统只与最慢的组件一样快。对于最终用户,如果用户需要等待几秒钟才能看到主页上的内容,那么您的服务器有多强大并不重要。此外,请为一些意想不到的问题做好准备,例如如果您没有足够的带宽来满足需求。在这种情况下,无需寻找应用程序本身的问题。
让我们从简单的步骤开始。一般来说,关注系统性能总是有用的,但也要注意——过早的优化是万恶之源。从了解当前应用程序中最慢的部分开始。
了解什么是慢的
如果您是第一次进行优化,您可能可以很快识别出问题组件。从在后端和前端拆分我们的应用程序开始。
默认前端优化
至于前端,请检查前端(HTML/js/CSS)的标准缓存实践:
- 在响应中使用缓存标头(Etag、缓存等)
- 如果可以,将所有静态数据存储在 CDN 上
- 使用 tinypng 服务优化您的图像
- 检查您的 javascript 库。确保您不使用具有相同功能的不同库
- Gzip 所有 HTML/js/CSS 内容。所有现代浏览器都支持 gzipping
- 尝试减少对 3rd 方服务的请求数量。包括不同的指标、分析和广告工具
简单的后端优化
至于后端,这里有一个简单的列表,可以帮助您增加应用程序响应时间:
- 确保您使用的是数据库连接池
- 检查您的 SQL 查询并为它们添加缓存
- 为整个响应添加缓存
您需要保持缓存更新,但在很多情况下,您可以显着改善这种情况。
代码和架构发生了变化
为了更深入,我建议从一些基准测试或加载测试开始。根据您的架构,您将需要使用不同的工具。使用无头 chrome 应用程序(testcafe 和类似应用程序)进行端到端基准测试。
基本wrk用法:
wrk -t12 -c400 -d30s http://127.0.0.1:8080/
Running 30s test @ http://127.0.0.1:8080/
12 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 635.91us 0.89ms 12.92ms 93.69%
Req/Sec 56.20k 8.07k 62.00k 86.54%
22464657 requests in 30.00s, 17.76GB read
Requests/sec: 748868.53
Transfer/sec: 606.33MB
测试最流行的端点并查看总体情况并了解瓶颈所在。
探索细节
一旦我们获得有关现有瓶颈的信息,我们就需要更深入地挖掘并了解如何解决。在大多数情况下,最慢的操作是网络请求和读/写 I/O 操作。无论可能 - 尝试使用非阻塞操作或轻线程进行网络和 i/o 操作。您可以从使用不同的分析解决方案(如 New Relic 的线程分析器、Stackdriver Profiling 或简单地将 pprof 用于 golang/c++ 应用程序)中获得很多好处。
下一步是什么?
在解决了一般瓶颈之后,您可能会发现自己已经消除了所有主要问题,但仍然没有您需要的响应时间。您可以采取的下一步是更新应用程序架构,设置具有自动缩放功能的 Kubernetes,并开始使用云提供商。
微服务
典型情况 - 当您有几个组件在高峰时间消耗 80% 的资源时。这两个组件核心功能的原因是运行速度不够快并且项目失去了用户。一个可靠且强大的解决方案是按部分拆分您的应用程序,这样每个部分都可以独立工作并仅在需要的地方添加资源。使用微服务,您可以归档:
- 通过模块化更好地管理
- 大规模部署和更新软件
使用 Kubernetes 和自动缩放
可能,如果您还没有,您应该开始使用 Kubernetes。它确实使您能够在需要时添加更多资源,并在选择消失后将其关闭。K8s 提供了很好的、经过良好测试的容器编排解决方案,并添加了容错更新,具有跨集群的内置通信等等。但缺点之一是维护起来既困难又费时。
使用云提供商
AWS、谷歌云、Azure——这些都是很棒的解决方案,它们将为您提供和管理先进的技术。虽然您将为所有这些花里胡哨的东西付出更多,但其中一些有助于轻松构建可扩展、可靠的解决方案。如果您预计每秒有数百万个请求,那么您可能应该从一开始就考虑使用云提供商。