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

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

目前应用的情况如下:

  • 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 时间。

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