Rails 服务器负载过高怎样优化?

wfwdex · 2018年03月07日 · 最后由 noe132 回复于 2018年03月26日 · 5024 次阅读

目前应用的情况如下:

  • API 接口每天要接受大约 1.4 亿次请求
  • 目前 web 服务器由三台 8 核 16GB 的服务器做负载均衡
  • mysql 数据库放在 8 核 16GB 的单台服务器上

目前 web 服务器的负载一直维持 1 以上,如目前: Load average: 1.46 1.07 1.06

puma 配置:

workers 8
threads 16,32
Linux 4.4.0-109-generic (ruby1)     03/07/2018  _x86_64_    (8 CPU)

08:08:00 AM     CPU     %user     %nice   %system   %iowait    %steal     %idle
08:08:01 AM     all     26.99      0.00      5.67      0.00      0.00     67.34
08:08:02 AM     all     22.92      0.00      4.41      0.00      0.00     72.67
08:08:03 AM     all     15.17      0.00      2.40      0.00      0.00     82.43
08:08:04 AM     all     20.65      0.00      3.78      0.00      0.00     75.57
08:08:05 AM     all      9.34      0.00      2.02      0.13      0.00     88.51
08:08:06 AM     all     10.37      0.00      1.77      0.00      0.00     87.86
08:08:07 AM     all     10.81      0.00      1.65      0.00      0.00     87.53
08:08:08 AM     all      7.38      0.00      2.75      0.00      0.00     89.88
08:08:09 AM     all      8.35      0.00      1.87      0.00      0.00     89.78
08:08:10 AM     all      9.80      0.00      1.63      0.00      0.00     88.57
08:08:11 AM     all      9.42      0.00      1.63      0.00      0.00     88.94
08:08:12 AM     all      8.59      0.00      1.26      0.00      0.00     90.15
08:08:13 AM     all     12.61      0.00      2.52      0.00      0.00     84.87
08:08:14 AM     all     18.72      0.00      3.14      0.00      0.00     78.14
08:08:15 AM     all      9.71      0.00      1.26      0.00      0.00     89.03
08:08:16 AM     all      8.79      0.00      1.88      0.00      0.00     89.32
08:08:17 AM     all     10.43      0.00      1.13      0.00      0.00     88.44

API 已经做过缓存优化,请问这种情况除了继续加服务器,还有没有其他优化思路和方向?

可以慢慢拆分, 然后逐步用 Go 替换. 我最近用 Go 重写了几个 Rails/Grape API,内存占用少了差不多 90%…

southwolf 回复

谢谢回复,现在瓶颈不在内存,web 服务器每台的内存占用 3GB 还不到(每台 16GB)。

wfwdex 回复

用 Go 重写以后 CPU 也下降不少. 如果有足够的开发资源, 可以试试逐步替换一些.

计算密集型应用 OR IO 密集型

监控都没有,怎么优化?

southwolf 回复

一言不合就换语言的态度,哪怕用来 Go 改写结果也一样

先要分析好资源耗费在哪里


你 3 台,撑 1 亿多动态请求/天(约 1000 QPS,或者更高峰值),已经很不错了!

加 NewRelic 分析

Terry.Shi 回复

我的 CPU 是 8 核,是说只要是小于 8,就是正常?

hooopo 回复

有做 ELK 日志分析,请求的耗时大部分在 300ms 以下,最高的一个接口耗时平均 2 秒,正打算把个接口分出去单独做。

讲真,三台撑这么多 确实已经不错了。况且你的负载才 1, 暂时应该没必要追求更高的优化吧。如果你的接口逻辑不负杂,考虑试下 openresty 不?哈哈,最后一句是调侃的

pathbox 回复

nginx 确实就是用的 openresty 😂

wfwdex 回复

嗯, 我指的是 把接口逻辑也用 openresty 重写,相对于代替了 rails。 不过 我觉得现在没有必要这样重构

这个负载真的不高。如果是我,我会分类,1.4 亿次请求到底属于哪些 API,请求量和返回时间是多少。对于请求量大或者返回时间高的可以做优化,否则就是白费功夫。

pathbox 回复

嗯,逻辑相当复杂,用 lua 写维护起来会很吃力。

nouse 回复

谢谢回复,那我就先从返回时间长的请求着手优化, 先不加服务器了

三台服务器 1.4 亿每天…我表示很满意,果断加服务器,要把人力成本算进成本。

18 楼 已删除
pathbox 回复

哈哈,想知道有没有人真的在生产环境这么搞过!

我觉得这好像是个炫耀帖。。

没有监控数据,怎么谈优化呢?机器运行状态如何,是否有负载,服务请求数,请求时间,以及最大承载压力是多少有没有办法量化?

MySQL 存储用的什么盘,上 SSD 了吗?

你这负载一点不算高吧!

可以参考一下: https://ruby-china.org/topics/34695#reply-339046

还是加服务器吧....

luikore 回复

多谢指点,很明确的建议,我去尝试优化一下。

28 楼 已删除
gihnius 回复

谢谢回复,这样看负载并不是很高

Terry.Shi 回复

很多人都不会看 load avg, 所以楼主这里负载一点不算高,有点浪费服务器资源了。

luikore 回复

请教下为什么 sentry/newrelic 为什么很耗性能?

楼主的应用性能算不错了, 但当性能优化到一定程度时, 这些追踪的代码就很可能会成为比较大的影响因素了

参考 https://www.tecmint.com/understand-linux-load-averages-and-monitor-performance/ 理论上 8 核要满载 loadavg 得达到 8. 1 的 loadavg 在 8 核心的机器上应该是只用了 1/8 的 cpu 时间。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号