RoR部署方案深度分析

初始化服务器

RoR的布置方案可谓五花八门,有Apache/Fastcgi方式的,有Nginx/Mongrel方式的,还有lighttpd/Fastcgi方式,也有人利用HAProxy/Mongrel,各种部署方式还是群说纷纭,让人搞不清楚哪种方式还好一些。我的立首稿子就是期待整合我们运营JavaEye网站一年多来说的经历(通过统计Rails的production.log,JavaEye网站目前每日处理越70万200
OK状态的Ruby动态请求,应该是境内目前负载量最酷的RoR应用了),为大家剖析RoR部署方案的上下,帮助大家挑选适合自己生产条件之RoR部署方式。 


当谈论配备方案之前,先为咱看一下RoR网站部署的大概架构: 

自打起步 Redis 服务器,到服务器可以领外来客户端的网络连接这段时光,Redis
需要实施同一多元初始化操作。

图片 1 

凡事初始化过程可分成以下六个步骤:

浏览器的HTTP访问请求首先达到Web服务器,充当Web服务器的形似是Lighttpd/Apache/Nginx,如果看请求包含静态资源,那么Web服务器即会一直打地面硬盘读取静态资源文件,例如图片,JavaScript,CSS等等,返回给客户端浏览器;如果访问请求是动态请求,那么Web服务器将URL请求转发到后端的FastCGI/Mongrel来拍卖,等到FastCGI/Mongrel处理完毕要,将变的页面数据返回给Web服务器,最后Web服务器将页面数据发送至客户端的浏览器。 

  •  初始化服务器全局状态。
  •  载入配置文件。
  •  创建 daemon 进程。
  •  初始化服务器功能模块。
  •  载入数据。
  •  开始事件循环

自打RoR的安排方式来拘禁,主要出于前端的Web服务器和后端的应用服务器构成:前端的Web服务器可以运用Apache,Lighttpd,Nginx和Litespeed,后端平的应用服务器可以行使FastCGI和Mongrel,下面我们分门别类的介绍与剖析: 

 

一、介绍Web服务器 
Web服务器的要害意图有少点:一是处理静态资源,二凡是以动态请求分发到后端应用服务器,然后接收后端应用服务器生成的页面数据,将其回来浏览器,充当了一个信息沟通的桥作用,在本文中我们要分析后者的用意。 

初始化服务器全局状态

1、Apache
2.2 

 

Apache是海内外互联网采用最广的Web服务器,但以拍卖静态资源文件上也休是性最好完美之Web服务器,不过貌似情况下,静态资源的拜访并无是RoR网站的瓶颈,因此也不要过于在了这或多或少。 

redis.h/redisServer结构记录了和服务器相关的兼具数据,这个结构主要包含以下信息:

Apache
2.2既支持HTTP
Proxy方式连接后端的Mongrel应用服务器,也得通过mod_fastcgi/mod_fcgid来连接FastCGI应用服务器:当为HTTP
Proxy方式连接Mongrel的时段,Apache接收Mongrel返回的页面数据的buffer
size最要命仅会开始到8KB(默认是4KB或者8KB),因此当页面数据超过8KB的当儿,可能用Apache和Mongrel之间发生数互;当为mod_fastcgi方式连接FastCGI应用服务器的上,接收返回数据的Buffer
size仍然只是出8KB而已,如果下mod_fcgid,那么buffer
size为64KB,有了那个挺之改善。 

  • 服务器被的富有数据库。
  • 命令表:
    • 以执行命令时,根据字符来寻觅相应命令的实现函数。
  • 事件状态。
  • 服务器的网络连接信息:
    • 学接字地址
    • 端口,以及套接字描述称。
  • 具都连续客户端的信息。
  • Lua脚本的运作环境和有关选项。
  • 兑现订阅与颁布(pub/sub)功能所需要的数据结构。
  • 日记(log)和减缓查询日志(slowlog)的选项和相关信息。
  • 数持久化(AOF和RDB)的部署以及状态。
  • 服务器配置选:
    • 依要创多少个数据库,
    • 是不是以服务器进程作为daemon进程来运转,
    • 最为深连接多少个客户端,
    • 减结构(zip structure)的实体数量,等等。
  • 统计信息:比如键有些许坏命令、不命中,服务器的周转时,内存占用,等等。

2、Nginx 

 

Nginx是俄国人数活的轻量级Web服务器,在处理静态资源方面,据说性能还有点超过Lighttpd的10%,而且资源消耗又有些。 

上述过程只含有=Redis服务器单机信息,不含sentinel,cluster等力量。

Nginx内置了精良的HTTP
Proxy和FastCGI支持,因此即使可以接连Mongrel,也可连接FastCGI服务器,在及时片种植状况下,Nginx默认的收受应用服务器返回数据的Buffer
Size也惟有区区的8KB,但是你可自行设置双重甚Buffer Size。 

当 server
变量的初始化完成后,程序上服务器初始化的下同样步:读入配置文件。

3、Lighttpd 

 

Lighttpd是大地互联网排名第五底Web服务器,也是近两年来上升最抢的Web服务器,特别是那个为有知名Web
2.0雅网站的欢迎,例如wikipedia的少数服务器,youtube的视频服务器,在境内,豆瓣网站及JavaEye网站都是Lighttpd的绝对化拥护者。在处理静态资源方面,Lighttpd性能远远超越Apache。 

载入配置文件

Lighttpd既支持HTTP
Proxy连接Mongrel,也支撑FastCGI方式,但是Lighttpd的FastCGI支持在富有流行的Web服务器中或者是不过帅之,所以用FastCGI的网站还很喜欢Lighttpd。Lighttpd在接到后端应用服务器返回数据的计上及Apache/Nginx有死特别之界别: 

 

Apache/Nginx是本着每个应用服务器连接分配固定Size的Buffer,而且默认只开8KB,这个Size对于今网页动辄50-100KB的景象的话,显得过分保守,如果应用服务器的回来数据无法等同不好填满Web服务器的Buffer,那么就算会招致应用服务器和Web服务器之间多次数传,这对于RoR网站的性能会招一部分系的震慑,我们以末端会详细的分析。 

于初始化服务器的及平等步着,程序吗server变量(也就算凡是服务器状态)的依次属性设置了沉默

Lighttpd并无对准应用服务器的每个连分配一定的Buffer,而是尽量的将应用服务器返回的多少一次性收到下来,因此无应用服务器返回多十分之数据量,Lighttpd都是照单全收,胃口特别惊人。 

认值,但这些默认值有时候并无是无比适用的:

4、Litespeed 

  • 用户可能想采取 AOF 持久化,而不是默认的 RDB 持久化。
  • 用户或想用另外端口来运行Redis,以避免端口冲突。
  • 用户可能不思以默认的16独数据库,而是分配更多要另行少多少之数据库。
  • 用户或想对默认的内存限制措施和回收策略做调整。

Litespeed是一个买卖收费的Web服务器,静态资源处理能力仍她好的评测数据比Lighttpd略大。Litespeed也还要支持HTTP
Proxy连接Mongrel和FastCGI连接应用服务器。此外Litespeed专门为单机运行的RoR开发了一个lsapi协议,号称性能最好好之RoR通讯协议,比HTTP
Proxy和FastCGI都如好。但是lsapi的运行方式发生坏怪缺陷:因为lsapi不是web
server启动的时启动固定数目的ruby进程,而是因请求繁忙程度,动态创建和销毁ruby进程,貌似节省资源,实则留下十分充分的黑客攻击漏洞。只要黑客瞬时发起大量动态请求,就见面吃服务器忙于创建ruby进程而致CPU资源耗尽,失去响应。 

 

由Litespeed在运作RoR方面连不曾表现有比Lighttpd优越的处在,而且要收费软件,企业版售价在双核CPU面每年收费499美元,并且也非起源,因此我们便不再将关注点放在Litespeed上面。当然Litespeed收费与否不是白收的,它提供了杀好用的根据Web的服务器管理界面,以及那个多的安全性方面的设置参数。 

创建daemon进程

5、HAProxy 

 

HAProxy并无是一个Web服务器,他既是未克处理静态资源,也不可知充当浏览器和应用服务器之间的休养冲桥梁,他只是当了一个伸手分发的软件网关作用。ThoughtWorks公司之RubyWorks选择使用HAProxy

Redis默认以daemon进程的方运行。

  • Mongrel
    Cluster的措施来布局RoR应用,不能不说是一个傻乎乎的方案。这种方案其实一定给将n个Mongrel应用服务器捆绑起来,直接当Web服务器,而Mongrel毕竟是一个Ruby写的服务器,无论是网络IO能力,还是静态资源的处理速度,无法与诚的Web服务器相提并论,让Mongrel直接处理静态资源以及调度网络IO,会造成服务器资源毫无必要的偌大开销,因此HAProxy也未以咱们的设想的列。 

当服务器初始化进行到即同步时,程序将创 daemon 进程来运作 Redis
,并创建相应的 pid文件。

亚、分析应用服务器的处理方式 

 

不管Mongrel还是FastCGI,都能够出色的运行Rails服务器,但是他们当与Web服务器之间的多寡传输方式上是一些距离,而正是这些差异,对部署方式来第一的震慑: 

初始化服务器功能模块

1、Mongrel 

 

Mongrel本身可以直接充当Web服务器,但于这种景象下性能并无见面哼。因为Mongrel只出HTTP协议的辨析部分是用C语言编写的,其余具备代码都是纯Ruby的。在处理静态资源下载者,Mongrel的实现方式大小效率,他只是简单的因为16KB为单位,依次读入文件内容,再写有至网Socket端口,其性质远远比非达传统的Web服务器调用操作系统的read()和write()库实现之静态文件下载速度,如果和当代Web服务器实现之sendfile方式的“零拷贝”下载相比,简直就是自愧不如。 

以及时无异于步,初始化程序完成两件事:

Mongrel使用了Ruby的用户线程机制来兑现多线程并发,并且使了一个fastthread补丁,改善了Ruby用户线程的一块互斥锁问题。但是Ruby并无是本地线程,我们呢毫无对Mongrel的网络IO负载能力得到来什么不切实际的臆想。同时Rails本身为未是线程安全的,因此Mongrel在执行Rails代码的过程被,完全是加锁之状态,那与单进程其实为未曾最好可怜差异。 

  • 为server变量的数据结构子属性分配内存。
    • 也数结构分配内存,并初始化这些数据结构,等同于对相应的机能拓展初始化
    • 比如,当也订阅与公布所需要的链表分配内存之后,订阅与颁布意义就处在就绪状态,随时可以呢
      Redis 所用了。
  • 初始化这些数据结构。

就此,当我们使用Mongrel的早晚,一般会在前端放置Web服务器,通过HTTP
Proxy方式拿要转发让后端的Mongrel应用服务器。在这种景象下,Mongrel只处理动态请求,在运作Rails框架生成页面数据以后,把多少返回给Web服务器即足以了。但是以这种安排方案下,有一个好重大的底细让我们忽略了,Mongrel运行Rails生成的页面数据是怎回给Web服务器的吗?通过细致钻研源代码我们得以将懂Mongrel处理Rails请求的底细: 

 

1) 
Mongrel接收至要后,启动一个ruby线程解析请求信息 
2) 
加锁,调用Rails Dispatcher启动Rails框架 
3) 
Rails处理完毕,创建一个StringIO对象,把Rails生成的页面数据写入到StringIO中 
4) 
解锁,把StringIO的数据flush到Web服务器 

以当下同步,程序完成的第一动作如下:

本条StringIO对象实际生重要!它充当了一个输出缓冲区的图,我们考虑一下,当Mongrel作为独立的Web服务器的早晚,如果Rails生成的页面比较充分,而客户端浏览器下载页面的速度又于慢,假设没有这个StringIO对象,会来啊问题?
Rails线程在履render方法的下就会受吊起住!同步互斥锁没有解锁,Mongrel再为无法处理下一个动态请求了。 

  • 初始化 Redis 进程的信号作用。
  • 初始化日志功能。
  • 初始化客户端功能。
  • 初始化共享对象。
  • 初始化事件功能。
  • 初始化数据库。
  • 初始化网络连接。
  • 初始化订阅与颁布意义。
  • 初始化各个统计变量。
  • 论及服务器常规操作(cron
    job)到日事件,关联客户端对处理器到文件事件。
  • 要是AOF功能曾开拓,那么打开或创AOF文件。
  • 设置内存限制。
  • 初始化Lua脚本环境。
  • 初始化慢查询功能。
  • 初始化后台操作线程。

当Mongrel仅仅作为应用服务器的当儿,这个StringIO仍然异常重要,为什么?我们眼前提到过了,Apache/Nginx的接收缓冲区都仅仅开了8KB,如果页面比较老,Mongrel就从不法一次性将数量总体推给Web服务器,必须顶交Web服务器将接收缓冲区的8K数据推到客户浏览器端以后,清空缓冲区,才能够接过下一个8KB的数码。这种状态下,Mongrel必须和Web服务器之间进行频繁多少传,才会得整个Web响应的历程,显然并未一次性把页面数据总体推给Web服务器快。如果Web服务器使用Lighttpd的语,情况会无雷同。当Mongrel把StringIO的数目flush出去的时刻,Lighttpd是一次性全部收受下来了,不需要频繁互相,因此Lighttpd+Mongrel的RoR网站的实际速度要赶紧为Apache/Nginx+Mongel。 

 

Mongrel使用StringIO对象缓存输出结果,在某些特殊的情况下会带来大死之安全隐忧。我们如果以劳务器端程序控制带权限的文书下载,某用户下载的凡一个100MB的公文,该用户采取了大多线程下载工具,他开始了10只线程并作下载,那么每个线程Mongrel在应后,都见面拿任何文件读入到内存的StringIO对象中,所以总共会创建出来10独StringIO对象保存10卖文件内容,所以Mongrel的内存会一下暴涨到1GB以上。而且太吓人的是,即使当用户下载了后,Mongrel的内存都未会见飞速降低,而是径直维持这么高之内存占用,这是坐Ruby的GC机制不好,不能够立刻进行垃圾回收。 

做到就等同步后,服务器打印出 Redis 的 ASCII LOGO
、服务器版本等消息,表示所有机能

或你晤面当不太可能下载100MB那么坏之附件,但是以JavaEye网站为例,圈子的共享文件最酷允许10MB,只要用户以差不多宝机械上面,每台机器开始100单线程下载圈子共享文件,每个Mongrel的内存占用都见面立刻超过1GB,用无了几分钟,服务器的情理内存就见面吃耗尽,网站去响应。这个毛病非常容易被奸的黑客利用,攻击网站。这吗是JavaEye网站为什么一直毫无mongrel的故有。 

模块已就绪,可以等被下了:

由此地方的辨析,我们领略Mongrel在使用Lighttpd的时,可以高达最好抢之RoR执行进度,但是Lighttpd当前之1.4.18版本的HTTP
Proxy的负载均衡和故障切换功能有部分bug,因此一般生少有人会利用这种办法。大多数人还见面采用Mongrel搭配Apache2.2要么Nginx,但是比较我们地方做分析的那样,Apache/Nginx的Buffer
Size实在是一个颇讨厌的限量,特别是Apache只能最要命开8KB的Buffer,因此自建议用Nginx搭配Mongrel,并且将Nginx的Proxy
Buffer
Size设置的不可开交组成部分,比如说设置为64KB,以管大多数页面输出结果好一次性flush到Web服务器去。 

虽说具有机能都就绪,但这时服务器的数据库还是一片空白,程序还索要拿服务器上平等蹩脚施行

2、FastCGI 

摩登记录的数量载入到眼前服务器遭到,服务器的初始化才算是真正好。

过多人数对FastCGI谈虎色变,仿佛FastCGI就是内存泄漏,性能故障的主犯祸首,又要嫌弃FastCGI太古老了,已经于淘汰掉的技艺了,其实就是一个那个挺之误解。FastCGI本质上单独是一律种进程之中通讯的情商,虽然是一个较古老的商谈,但是还是于HTTP协议年轻多了,HTTP协议不是仍现在老盛为? 

 

每当PHP/ASP/JSP流行之前,FastCGI曾经非常普及,只不过那个时期的FastCGI程序是为此C语言编写的,写起来最为难,而PHP/ASP/JSP相比之下,写起就顶简单了,所以FastCGI就渐渐被扔到了史之故纸堆中。但是绝近两年来,由于Ruby和Python的霎时Web开发框架的强势崛起,FastCGI仿佛又咸鱼翻身了。 

载入数据

当我们以FastCGI方式运行Rails应用服务器的早晚,每个FastCGI进程都是单线程运行的,考虑到Rails本身不是线程安全之,所以与Mongrel运行Rails的实际效果是同样的,都是每个过程只能跑一个Rails实例。但是FastCGI在Rails生成页面数据返回给Web服务器的方式以及Mongrel截然不同: 

于即时同样步,程序用以持久化在 RDB 或者 AOF
文件里之多少,载入到服务器进程中。

前面我们说及Mongrel自己开了出口缓冲区,而FastCGI则一心无上马任何缓冲区,当Rails执行render方法的时候,FastCGI实际执行的是FCGI::Stream.write方法调用,直接拿数量形容为Web服务器了。此时而Web服务器是Apache/Nginx,会有啊? 

 

如果我们以mod_fastcgi模块,那么Apache的接收缓冲区就是8KB; 
设若我们采取mod_fcgid模块,那么Apache的接收缓冲区就是64KB;(mod_fcgid是神州人开之代表mod_fastcgi的开源项目,在Apache社区很受欢迎,谁胆敢说中华人数单纯是开源“消费”国?) 
万一我们使用Nginx服务器,那么默认的接收缓冲区就是8KB,但是可改变得再特别; 

设服务器发启用AOF功能的话,那么下AOF文件来平复数据;

若果页面数据较特别,超过8KB,会如何?
FastCGI进程被高悬在render方法上!必须等交Web服务器的缓冲区清空,把页面数据总体收受下来之后,FastCGI进程才能够收本次Rails调用,处理下一个请求!所以绝对别用Apache/Nginx搭配FastCGI应用服务器,否则你的RoR应用会死的万分难看。根据本人个人的测试数据表明,同样的测试负载,Apache搭配70只FastCGI进程挂掉,但是Lighttpd搭配30只FastCGI进程轻松跑了! 

再不,程序采取RDB文件来过来数据。

当FastCGI搭配Lighttpd的上,我们解Lighttpd会一次性照单全收FastCGI送过来的页面数据,所以FastCGI进程并无会见给高悬住。如果我们相比一下Lighttpd搭配Mongrel和FastCGI会发现,Lighttpd搭配FastCGI性能最好,为什么吗? 

 

Mongrel首先自己会因此StringIO缓冲页面数据,然后推送给Lighttpd以后,Lighttpd也当内存当中缓冲了同样卖页面数据,造成了不用必要的double
buffer的支付。这本来不如FastCGI不做任何缓冲,直接推进为Lighttpd性能来得愈,内存消耗掉了。 

当行了马上等同步时,服务器打印出同样段落载入完成信息:

我们的方案分析及这边,大家应该好心中发生结论了,Lighttpd+FastCGI是性质最佳,服务器资源消耗最少之RoR部署方案,事实上目前RoR网站部署下最多尽盛的吗是Lighttpd+FastCGI方式,而JavaEye网站,自然也是这种办法的布置。因此我们得针对各种方案进行一个性能优劣的排队: 

[6717] 22 Feb 11:59:14.830 * DB loaded from disk: 0.068 seconds

引用

 

Lighttpd+FastCGI  >  Lighttpd+Mongrel 
>  Nginx+Mongrel  >  Apache+Mongrel  >  Ngignx+FastCGI  > 
Apache+FastCGI

开班事件循环

其中Lighttpd+FastCGI是性最佳方案,而Apache+FastCGI是性质最差方案。 

顶了当时无异步,服务器的初始化已经完结,程序打开事件循环,开始接受客户端连接。

稍细心的同窗或会见起一个初的谜?你究竟,之所以Lighttpd跑RoR性能最好,还是在于Lighttpd接收数据不限量缓冲区的尺寸,而Apache/Nginx限定了缓冲区大小所至。那为何Nginx要限制也?Lighttpd如果未克以来,会不见面招致Lighttpd内存爆掉? 

 

Nginx限制Proxy
Buffer
Size其实也闹道理,因为Nginx并无是啊RoR量身打造的Web服务器,Nginx最广的用还是高负载大访问量的代理服务器,在Nginx主要的以场合,如果非开这么的范围,那Nginx端的资源消耗就一定强了,有或会见延宕累所摄的劳务进度。 

以下是初始化完成之后,服务器状态及各个模块之间的关系图:

Lighttpd主要用途之一即是提供高性能的FastCGI支持之Web服务器,所以要也FastCGI量身打造。Lighttpd端承担的负荷越强,就更加会使得之增速FastCGI执行进度。其实我们聊心算一下,假而Lighttpd后面挂1000单FastCGI进程,每个FastCGI进程而送过来50KB的页面数据,Lighttpd就是整吃下来,也可单单吃50MB的内存而已,而其实1000单FastCGI进程足以支撑每日上千万之大网站了。 

图片 2

除非当我们使用劳务器端程序控制大文件下载的时光,有或导致Lighttpd内存暴涨,例如有用户用100只线程并作下载JavaEye圈子的共享文件,在没有例外处理的情景下,Lighttpd将全体凭着生100只FastCGI进程送过来的10MB数据,就见面马上暴涨1GB的内存。这种情景怎么处置呢?其实我们呢闹道让Lighttpd一点内存都无吃,
请看自己形容的另外一篇稿子:RoR网站如何使lighttpd的X-sendfile功能升级文件下充斥性能 

 

也许多人数看了自家之章,对结论认为怪奇异,既然Lighttpd+FastCGI这样好,为什么那么基本上人口且讲究Mongrel,否定FastCGI呢?我想,不外乎几只由: 

 

如出一辙、Lighttpd+FastCGI配置起比较专业,而Mongrel配置简单 

客户端连接到服务器

尽管我当下率先破多建筑Lighttpd+FastCGI环境没费什么周折,但是自观察到异常多的Ruby程序员很麻烦成功搭建筑一个Lighttpd+FastCGI的条件下,很多人数连Lighttpd都没法儿独立的运转起来。这说不定是以过剩程序员习惯了Windows开发条件,对于Unix上面通过源代码编译安装的法门过于陌生造成的。而自我打97年起以Unix,至今已有10年历史,因此搭建这样简单的体系,对己来说不造成什么阻力。 


使Mongrel就大概了,gem
install mongrel安装完毕,mongrel_rails
start启动,哪个人不见面?毕竟绝大多数开发人员和配置人员不是权威,他们熟悉哪种方式,自然就会侧重哪种方法。 

当 Redis 服务器就初始化之后,它便准备好得接受外来客户端的连了。

老二、Mongrel可以独立作为Web服务器运行,开发环境以及布局环境统一 

 

一般的话,程序员肯定是拼命三郎保障开发条件以及安排环境之一致性,避免部署到生育环境出现非测的后果。既然在开发环境熟悉了Mongrel,当然更愿意在生条件下Mongrel,而休愿意碰没沾了之Lighttpd。 

当一个客户端通过模拟接字函数 connect 到服务器时,服务器执行以下步骤:

老三、Mongrel支持HTTP协议,因此无论是监控或拼其他服务还比较简单,容易玩出更多之花活。 

 

HTTP协议要比FastCGI协议普及之大半,因此通过HTTP方式的监督工具,群集管理工具,集成其他服务之家伙都是千篇一律抓一那个把。而支持FastCGI的老三方工具就不见得不得了了。你若耍很多花活出来,用FastCGI的说话,就不免得和谐支付相应的家伙,那自然不如用Mongrel方便啦。 

  • 服务器通过文件事件无阂地 accept 客户端连接,并赶回一个拟接字描述符
    fd 。
  • 服务器也 fd 创建一个遥相呼应之 redis.h/redisClient
    结构实例,并以欠实例加入到服务器的既连客户端的链表中。
  • 服务器在事件处理器为该 fd 关联读文件事件。

末,如果你看了就篇稿子,想摩拳擦掌的安装一把Lighttpd+FastCGI的讲话,那么我之当即篇稿子就是是最为好的设置指南: 

 

以Linux平台上设置和配置Ruby on
Rails详解

完这三步后,服务器即足以等客户端发来命令请求了。

 

 

ShiningRay 写道

Redis
为多路复用的主意来拍卖多独客户端,为了吃大多个客户端里独立分开、不相互干扰,

Lighttpd的老三种植方案占据了前面三各类,Lighttpd+FastCGI是性质最高的安排方式。这种措施比较其余一样种植流行方案Nginx+Mongrel的不二法门性能提升了大及50%!FastCGI的功利在是反映出: 

服务器也每个曾接连客户端维持一个 redisClient
结构,从而单独保存该客户端的状态信息。

  • 其次前进制协议,无需HTTP的辨析
  • 同前者可以建立持久链接
  • 不曾锁与上下文切换的开

 

除此以外Lighttpd相对于Nginx的优势在要和响应的接收缓冲区很怪,省去多次接收及发送的开支。 

redisClient 结构主要含有以下信息:

Lighttpd+Thin的法子的性列第三各项,这点似乎飞之外,但实在是盖Lighttpd
1.5支撑对HTTP后端建立HTTP
KeepAlive链接。在针对后端单独的测试着,小并发下的Thin的KeepAlive测试性能并无可比FastCGI差,同时Thin实现了非阻塞
IO,而FastCGI则是死式的。相反,HAproxy和Nginx则都无支持HTTP
KeepAlive。 

  • 如法炮制接字描述称。
  • 客户端正在动的数据库指针和数据库号码。
  • 客户端的查询缓存( query buffer)和死灰复燃缓存( reply buffer)。
  • 一个针对命令函数的指针,以及字符串形式的指令、命令参数和下令个数,这些属于性会在指令执行时用。
  • 客户端状态:
    • 笔录了客户端是不是处在
    • SLAVE 
    • MONITOR
    • 抑或工作状态。
  • 心想事成业务功能(比如 MULTI 和 WATCH)所待的数据结构。
  • 兑现阻塞功能(比如 BLPOP 和 BRPOPLPUSH)所需要的数据结构。
  • 落实订阅与宣布功能(比如PUBLISH和SUBSCRIBE)所用的数据结构。
  • 统计数据和甄选:客户端创建的时日,客户端和服务器最后互相的工夫,缓存的尺寸,等等。

使Swiftiply的章程啊显示有了强劲的性,应该是得益于她的“让后端主动连接至Swiftiply”的这种奇异之布局。 

 

目前被关注的Passenger的布局方式于该案中并无展示有特别的特性达到之优势,不过要将连发链接数放在300以内,则
Apache2.2/Prefork +
Passenger的布方式的平均每秒响应数上升为204.03,这样看来,倘若为Apache进行一些优化安排,依然不失为一栽高效之布置方案。而以Passenger又是无与伦比爱配置的平栽方案,能及这种意义已大满意。 

留意:上面列有之客户端结构信息不分包复制相关属性;

HAproxy +
Mongrel并限量链接数为1,则是同一栽祥和、保守的配备方式,虽然以这边性能不发不少,但是稳定性好好。 

 

最后,与Nginx相关的老三栽方案还免去在了该榜的最终,由于Nginx的反向代理负载均衡缺少有高档的表征和Rails本身的性状而致使该未抱单独行使在Rails程序的布局及: 

命令的恳求,处理和结果回到

  • 缺到后台服务器端的链接数限制的力量,这招了Mongrel在纳大量请时将日吃在上下文切换和钉的焉用上。
  • 缺失建立及后台服务器端的坚持不懈链接的力量,这导致了在链接的打开、建立、关闭及花了额外的出。

当客户端连上服务器之后,客户端就可以为服务器发送命令请求了。

从今客户端发送命令请求,到令于服务器处理、并拿结果回到客户端,整个过程发生以下步骤:

  • 客户端通过模拟接字向服务器传送命令协议数。
  • 服务器通过读事件来拍卖传入数据,并拿数据保存于客户端对承诺 redisClient
    结构的查询缓存中。
  • 冲客户端询问缓存中之始末,程序于命令表中寻找相应命令的兑现函数。
  • 程序执行命令的实现函数,修改服务器的大局状态 server
    变量,并以下令的实践结果保存至客户端 redisClient
    结构的还原缓存中,然后也该客户端的 fd 关联写事件。
  • 当客户端 fd
    的写照事件便绪时,将卷土重来缓存中的授命结果传到给客户端。至此,命令执行了。

 

 

一声令下请求实例:set 的施行进程

如若现在客户端 C1 是连接受服务器 S 的一个客户端;

当用户执行命令 SET YEAR 2013 时 过程:

 

  • 客户端调用写副函数,将合计内容 写副连接到服务器的拟接字被。
    • 谋内容:*3\r\n$3\r\nSET\r\n$4\r\nYEAR\r\n$4\r\n2013\r\n”
  • 当S的文件事件处理器执行时, 它见面意识到 C1
    所对应之读事件已就绪,于是它用协商文件读入,并保留于询问缓存。
  • 通过对查询缓存进行剖析( parse)
    • 服务器在命令表中觅 SET 字符串所对应之命令实现函数,最终一定到
      t_string.c/setCommand 函数,
    • 除此以外,两个指令参数 YEAR 和 2013
      也会见因字符串的花样保留于客户端结构面临。
  • 跟着,程序将客户端、要实行的下令、命令参数等送入命令执行器:
    • 执行器调用 setCommand函数,将数据库中 YEAR 键的价值修改为 2013
    • 接下来将命的施行结果保存在客户端的回复缓存中
    • 连为客户端 fd 关联写事件,用于将结果回写为客户端
    • 因 YEAR 键的改动,其他同数据库命名空间相关程序
      • 遵 AOF 、 REPLICATION 还有工作安全性检查(是否修改了受
        WATCH 监视的键?)也会受硌
  • 当这些后续程序为尽完毕之后,命令执行器退出,服务器其他程序(比如时间事件处理器)继续运行。
  • 当 C1
    对应的刻画事件就是绪时,程序就算见面以保存在客户端结构恢复缓存中之数回写给客户端
  • 当客户端接收至多少后,它便以结果打印出,显示为用户看

 

小结
• 服务器经过初始化之后,才会开接受命令。
• 服务器初始化可以分成六单步骤:

  1. 初始化服务器全局状态。

  2. 载入配置文件。

  3. 创建 daemon 进程。

  4. 初始化服务器功能模块。

  5. 载入数据。

  6. 开始事件循环。


服务器也每个已接连的客户端维持一个客户端结构,这个布局保留了是客户端的具有
状态信息。

客户端向服务器发送命令,服务器接受命令然后拿命传给命令执行器,执行器执行于

必然命令的兑现函数,执行好后,将结果保存在缓存,最后回传给客户端。

发表评论

电子邮件地址不会被公开。 必填项已用*标注