请求量过大,这谁顶得住啊!

本贴最后更新于 1535 天前,其中的信息可能已经时移世易

这谁顶得住啊!

自从上次项目拆分的优化后,用户的体验好了很多,流量自然是有所增长。对公司对这个项目来说,有增长是好事。但服务器却有些顶不住了。

图片源于网络

好在,上次有一名叫 小李 的程序员,在休息时间摸鱼时了解到了一个新的名词 集群。听说使用集群能解决单台服务器资源不足的问题,在把原来单台服务器的项目,同时部署在另外一台服务器上。

新服务器

小李简单的看了看集群,发现能解决当前服务器顶不住的问题。马上就跑去老板说:“老板!我发现了能解决我们我们项目经常会出现访问繁忙的问题。就是花钱买新的服务器!”。老板一听,发现竟然要花钱,便马上说到:“要花钱?花多少钱,买多少钱台?” “不多不多,只需要再买一台同样配置的服务器就可以了。”。老板听后便呼了一口气,再买一台同样的配置的服务器毕竟也不会贵,一个个月的续费,要是后面要是用不到还可以退了。

新的服务器

老板,通知财务给云服务账号充钱并新买了一台服务器,之后便通知了小李。让小李去完成后续的工作。

小李把这个消息告诉了大家,并让大家把项目打一个稳定版本的包,发给小李。小李需要部署在新的服务器上,很快小李便部署好了。可新的问题是,项目已经在新的服务器部署好了。但,这台服务器上并没有任何的请求量啊。小李被这个问题给难住了,他觉得貌似还缺少了些什么?一拍脑袋发现,是啊!那篇文章我还没有看完。便继续往下翻了翻,发现需要安装一个 Nginx,并且需要在 Nginx 的配置文件里面配置 负载均衡,在实现负载均衡的同时还可以做 高可用

小李看到了 负载均衡 以及 高可用 后,皱了皱眉说到什么是 负载均衡高可用?便继续往下看了看。

Nginx 的负载均衡

关于文章中,负载均衡 是这么解释的:负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布多台服务器上,来提高网站、应用、数据库或者其他服务的性能和可靠性。,高可用:在实现负载均衡后,Nginx会将流量分别分发到两台不同的服务器中,当一台服务器出现宕机后,新的流量都会分发到剩下的服务器。来保证服务的质量。

负载均衡

小李一看便明白了,原来这就是负载均衡和高可用啊!就像谈恋爱一样,谈一个对象随时可能会分手,一点也不稳定不可靠,想要可靠点就要做 负载均衡和高可用。当现任出现情绪不满时,马上去联络备胎维持下感情。

但,还需要再买一台服务器专门用来做负载均衡和高可用才行。小李小心翼翼的跑去跟老板说明情况,老板却意味深长的看了看小李一眼,说到:“再买新的服务器,没问题但一定要尽快解决。要是解决不了,就给我一天想一百个方案出来。”。小李点了点头,便一溜烟的跑了———去配置 Nginx

Nginx 负载均衡配置

Nginx 的负载均衡算法一共有五种,分别如下:

  • 轮询(默认)——每个请求按时间顺序逐一分配到不同的服务器中,如果其中有一台服务器宕机,会自动剔除。
  • 指定权重——通过 weight 指定轮询几率,weight 和访问比率成正比,weight 数值越大权重越高。对于某些性能不够强劲的机器可以把权重调低。
  • ip_hash——对 ip 进行 hash 计算,可以用于把不同的 ip 分配到上次访问的服务器中,比如上次访问的是 A,下次再次访问还是 A 而不会去 B 服务器。
  • fair(第三方)——按服务器响应时间来分配请求,响应时间短的优先分配。
  • url_hash(第三方)——对访问的 url 进行 hash 计算,按照计算结果来指定服务器。

为了足够真实,我花了巨资买了两块 树莓派 3b+ 来当作部署项目的服务器,笔记本 当作 Nginx 的服务器。

至于 Nginx 怎么安装,这里便不去详细的说明了,可自行看官网文档

编写负载均衡的配置

配置文件可以写在 nginx 目录的 conf.d 下,这里我只采用 轮询 方式的负载均衡算法:

api-conf

之后需要在 nginx.conf 中添加一行 include conf.d/*.conf; 即可(默认会有这么一行,Windows 除外):

nginx-conf

添加完后只需要重启一下 Nginx。

测试对比

为了测试负载均衡是否能提升性能,就需要进行压测,这里工具我所使用的是 wrk

测试参数如下:

wrk -t100 -c100 -d1m http://api.codedream.xin
/hello

单台服务器压测

首先进行单台服务器测试(old-server),结果如下:

Running 1m test @ http://api.codedream.xin/hello
  100 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    92.24ms  103.84ms   1.28s    97.01%
    Req/Sec    13.09      4.73    30.00     67.77%
  76143 requests in 1.00m, 11.62MB read
Requests/sec:   1267.53
Transfer/sec:    197.99KB

压测结果:

  • Latency(延迟)
    • Avg: 92.24ms
    • Max: 1.28s
  • Req/Sec(处理中的请求数)
    • Avg: 13.09
    • Max: 30.00
  • Requests In 1m: 76143
  • Timeout: 0
  • QPS: 1267.53

服务器信息:

pi-1

可以看到,这是单台服务器的压测结果,跑了一个 Hello 的接口,但在多次压测中出现了宕机的情况!

双台服务器压测

接下来测试两台机器的性能,测试结果如下:

Running 1m test @ http://api.codedream.xin:8080/hello
  100 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   118.84ms  216.87ms   1.28s    89.58%
    Req/Sec    22.97      6.74    60.00     53.68%
  116910 requests in 1.00m, 17.83MB read
  Socket errors: connect 0, read 0, write 0, timeout 3
Requests/sec:   1946.19
Transfer/sec:    304.00KB

压测结果:

  • Latency(延迟)
    • Avg: 118.84ms
    • Max: 1.28s
  • Req/Sec(处理中的请求数)
    • Avg: 22.97
    • Max: 60.00
  • Requests In 1m: 116910
  • Timeout: 3
  • QPS: 1946.19

服务器信息

pi-1-1

pi-2

可以看到,服务器集群的 CPU 使用情况远比单台服务器要低的多,而且在测试中性能也有一些提高。

由于受限于我的笔记本,无法完全发挥出集群的性能。

后续

虽然小李使用集群解决了请求量过大的问题,而且就算其中一台服务器宕机了也没关系,还有别的服务器能继续处理剩余的请求。老板之后也表扬了小李,并表示要给小李在四月份加薪 250 块,五月份生效,六月份才发到工资里面。小李对这次加薪并不是很在意,他更在意的是技术,或许他在准备着什么。

集群虽好,但小李这观察集群的这段时间,发现在某些场景下会出现一些奇奇怪怪的问题,也许这就是文章后面所说的集群中存在一些 分布式 的问题吧...

由于周六日这两天,有些别的事情耽误了,文章的进度就慢了些

blog:https://www.codedream.xin

上期文章:从一开始的小项目逐渐变成了大项目而得臃肿,怎么办

  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    311 引用 • 546 回帖 • 58 关注
  • 集群
    29 引用 • 65 回帖 • 1 关注
5 操作
Not-Found 在 2020-01-15 11:10:16 更新了该帖
Not-Found 在 2020-01-14 14:13:42 更新了该帖
Not-Found 在 2020-01-13 14:27:11 更新了该帖
Not-Found 在 2020-01-13 11:29:35 更新了该帖 Not-Found 在 2020-01-13 11:27:11 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • Not-Found
    作者

    建议动手试试,比较有趣

    1 回复
  • 其他回帖
  • 您说的这个分布式锁,我可能就会使用 redis 实现,其他 zookeeper 那些的好像有点难。谢谢,我今天下午进行一个测试,然后结果也发出来给您看下,我是用电脑 + 服务器测试,做了一个内网穿透。

  • Not-Found
    作者

    可能会出现这样的问题,比如:

    要插入一条数据库,但是不希望有重复数据,数据库也不好做唯一索引的约束。

    就需要项目在插入之前进行判断,是否有这么一条数据,没有的话就插入有的话,有的话就不插入了。

    这个时候,A 项目接收到了一条插入的请求,接着 B 项目也接收到了插入的请求。它们在判断时都没有查询到有这么一条数据,结果两个项目都插入了这条数据,也就造成了重复的数据。

    这个时候就需要引入第三方中间件来解决这个问题。

  • 我用的一台服务器,可以感觉到提升。虽然效果不明显~~~已经很棒了,我现在要做的就是对并发数据库的一个处理。我担心数据库会顶不住

  • 查看全部回帖