专栏首页Golang语言社区高并发服务器的设计--架构与瓶颈的设计

高并发服务器的设计--架构与瓶颈的设计

做架构设计,难免有时候被人问及系统的瓶颈在哪,那首先来了解下什么是瓶颈?

打个形象的比方,人的嘴巴可以吞下一整个面包,但是却咽不下去,因为食管不给力,它比较细,所以嘴巴能吞下的食物大小要受到食管的粗细限制。

城市内部每天会产生几十万件跨城快递,可是跨城的交通不给力,只允许走小型卡车,一卡车一次就能装几千件,一天下来也不一定能投送的完。

人在一定时间内能咽下多少食物,货运公司在一天运送多少货物,物理上叫做吞吐量,系统整体的吞吐量等于最小区域的吞吐量。

下面这张图能够反映:

土黄色管子的流量要受到红色部分的制约。

服务器上也是这样,好一点的设计框架结合物理高配可以处理高达几十万的并发,像土黄色的管子,可是偏偏有一些模块像图中红色的管子那样,一秒中只能同时处理几百次,这样就严重拖慢了服务器的性能,成了瓶颈。

现实开发中有时可能会要加上数据库模块,如mysql,虽然mysql号称每秒处理几十万的查询根本没问题,但那只是运算能力。

服务器连mysql 是要通过tcp网络的,有连接就需要时间,再加上数据量如果大点,自然就成了瓶颈。

相似的情况,一些特殊的业务,比如加解密服务,密钥和随机数的产生依赖加密机,中间件的性能就是我们图中的红管子。

有些开发还会涉及到跨网服务器查询,比如腾讯电商会调用QQ服务器的登录网关,跨网查询的速度肯定没有本地执行的快。

系统架构的设计是争对业务的,业务里如果存在这些红管子,就必须要有相应的解决办法。

不同人的处理方法不同,据我经验,可以将瓶颈子分成两类:

1.阻塞串行处理

2.异步并行处理

mysql,中间件的处理属于第一类,异步网关查询属于第二类。

对于第一类,一种通用的解决方法是增加处理进程,其实是横向扩容的思想,打个比方,一个进程的并发是600,10个进程就可以达到6000了,如何才能将请求均匀地分配到这10个进程是关键。

多个进程同时监听一个端口,负载均衡的方法很多,这里介绍nginx的做法,直接上代码:

[cpp] view plain copy print?

  1. //接收握手后连接
  2. void ngx_event_accept(ngx_event_t *ev)
  3. {
  4. ...
  5. ngx_accept_disabled = ngx_cycle->connection_n / 8
  6. - ngx_cycle->free_connection_n;
  7. ...
  8. }
  9. //事件模型处理函数
  10. void ngx_process_events_and_timers(ngx_cycle_t *cycle)
  11. {
  12. ...
  13. if (ngx_use_accept_mutex) {
  14. if (ngx_accept_disabled > 0) {
  15. ngx_accept_disabled--;
  16. } else {
  17. if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
  18. return;
  19. }
  20. if (ngx_accept_mutex_held) {
  21. flags |= NGX_POST_EVENTS;
  22. } else {
  23. if (timer == NGX_TIMER_INFINITE
  24. || timer > ngx_accept_mutex_delay)
  25. {
  26. timer = ngx_accept_mutex_delay;
  27. }
  28. }
  29. }
  30. ...
  31. }
  32. //取得端口监听的锁
  33. ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
  34. {
  35. ...
  36. if (ngx_enable_accept_events(cycle) == NGX_ERROR) {
  37. ngx_shmtx_unlock(&ngx_accept_mutex);
  38. return NGX_ERROR;
  39. }
  40. ...
  41. }
  42. //启动端口监听
  43. static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle)
  44. {
  45. ngx_uint_t i;
  46. ngx_listening_t *ls;
  47. ngx_connection_t *c;
  48. ls = cycle->listening.elts;
  49. for (i = 0; i < cycle->listening.nelts; i++) {
  50. c = ls[i].connection;
  51. if (c->read->active) {
  52. continue;
  53. }
  54. if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
  55. if (ngx_add_conn(c) == NGX_ERROR) {
  56. return NGX_ERROR;
  57. }
  58. } else {
  59. if (ngx_add_event(c->read, NGX_READ_EVENT, 0) == NGX_ERROR) {
  60. return NGX_ERROR;
  61. }
  62. }
  63. }
  64. return NGX_OK;
  65. }

从上面的代码可以看出,nginx用一个全局变量ngx_accept_disabled 来控制单个进程的负载,当负载达到一定值的时候,不再接受新的负载。

对于第二类情况,解决的方法就像名字一样,异步并行解决。

拿跨网查询为例:

创建一个查询的请求,将请求放进事件模型中,等待服务端的返回,异步处理。

熟悉nginx的就知道nginx的upstream反向代理,这个解决方案跟反向代理很像,只不过在与上游服务器交互的前后分别还有其他的业务处理,而且可能还会有多次交互。

相应的流水图是这样的:

当客户端请求量大时,事件模型的容量会成为瓶颈,这样仍然需要横向扩容的方式来解决,增加处理进程。

这两种情况的处理方法大致如此,有时候特殊问题特殊对待,比哪数据库的瓶颈可以借助缓存解决,有些高配服务器的内存128G,甚至几台高配服务器只为一个业务,这样的情况下,不吃点内存难免对不起老板的money.

  • 3

本文分享自微信公众号 - Golang语言社区(Golangweb)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-09-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 关于如何从Go 1到Go 2进行不兼容的更改,而尽可能少地进行破坏的建议。

    A proposal for how to make incompatible changes from Go 1 to Go 2 while breaking...

    李海彬
  • golang 垃圾回收 gc

    摘要 在实际使用go语言的过程中,碰到了一些看似奇怪的内存占用现象,于是决定对go语言的垃圾回收模型进行一些研究。本文对研究的结果进行一下总结。 什么是垃圾回收...

    李海彬
  • Golang语言--运算符

    运算符是一个符号,告诉编译器执行特定的数学或逻辑操作。 Go语言有丰富的内置运算符和运算符提供的以下几种类型: 算术运算符 关系运算符 逻辑运算符 位运算符 赋...

    李海彬
  • nginx lua api解读

    标识response结束,ngx.eof()只是结束响应流的输出,中断HTTP连接,后面的代码逻辑还会继续在服务端执行

    codecraft
  • nginx0.1.0之http模块初始化源码分析(2)

    本文讲解http各个模块create_srv_conf和create_loc_conf钩子,还有指令的解析。 各模块的create_srv_conf和creat...

    theanarkh
  • nginx的timeout(基于nginx1.17.9)

    nginx中使用timeout的地方非常多,本文主要分析客户端和nginx通信时涉及到的几个timeout。

    theanarkh
  • nginx0.1.0之event模块初始化源码分析(4)

    event的配置解析相关的代码已经分析完毕。下面分析一下另一个流程中event模块的实现。即在nginx创建进程,并且开始执行进程里的代码的时候。入口函数是ng...

    theanarkh
  • 公开版"小五物联源码"

    杨奉武
  • 腾讯云Serverless架构安装Python依赖的小工具(包括对外的API,基于SCF)

    很久很久之前,做了一个在线下载依赖包的工具,但是由于是放在了CVM上,收费比较高昂,而自己比较清贫,所以没能坚持多久,那个工具就被我下掉了,后来有小伙伴就给我留...

    Dfounderliu
  • 牙尖上的大数据:从牙齿看美国经济滑坡

    世纪钟声刚过不久,大数据威力初显。大数据与云计算的关系就像一枚硬币的正反面一样密不可分。如今我们的生活已经和数据分析息息相关,无论是美剧《纸牌屋》的火热...

    CDA数据分析师

扫码关注云+社区

领取腾讯云代金券