- 浏览: 4820550 次
- 性别:
- 来自: 上海
博客专栏
-
robbin谈管理
浏览量:137001
文章分类
最新评论
-
xly1981:
领导者是团队的灵魂。深入一线的过程,包括代码review,能帮 ...
robbin谈管理:改造团队的经验(2) -
jiehuangwei:
像这种总结比较性的ppt文档可以多发啊
Web并发模型粗浅探讨 -
linux1308:
看完学习到了很多东西,感谢推荐!
推荐一篇很好的RoR部署方案性能评测 -
zweite:
直接对搜索的结果进行缓存是不是会更快一点呢
漫谈应用缓存的命中率问题 -
kaogua:
现在已经是ruby2.0了, 不知道这个的效率是怎么样的, 是 ...
Ruby作为服务器端应用已经成熟了
JavaEye网站从2006年9月11日上线基于RoR的2.0版本开始,到现在已经运行了将近一年半了。在这一年半的时间里,JavaEye网站的每日PV从最开始的5万,缓慢增长到了现在的60万。随着网站负载的不断增加,我们也在不断尝试和调整网站的性能,积累了不少第一手RoR应用性能优化的实战经验。虽然我们并不是RoR性能优化的权威专家,我们所积累的经验也许并不是最优实践,但是作为国内最早涉足RoR商业运营的互联网网站之一,我们非常乐意分享和交流我们的实战经验,以帮助后来者节省必要的摸索时间。
RoR惊人的开发速度恐怕是每个互联网创业者都梦寐以求的,但是随着网站流量的不断增大,可能大多数采用RoR的网站或迟或早会遇到RoR的性能瓶颈,我的一个朋友capitian说过一句很有意思的话:“RoR应用做到后来,总有自己修改底层的冲动”。就我所了解和掌握的情况来看,很多RoR网站都过早的遇到了性能瓶颈,一个很普遍的现象就是:RoR应用的CPU负载要远远高于数据库的负载。这是一个有点违背常理的现象,因为我们知道,硬盘IO速度要比内存慢得多,所以一般Web应用的性能瓶颈往往会出现在数据库IO上,因此优化数据库访问,进行对象缓存是非常有效的性能优化手段。但是一旦应用服务器负载比数据库还高的话,单纯的对象缓存就无用武之地了。下面我们从几个方面分别谈一谈如何进行RoR的性能优化:
应用的部署
RoR应用的部署包括操作系统,Web服务器,应用服务器和数据库四个方面:
一、操作系统
1、发行版本
RoR适合于部署在Unix类操作系统上面,通常比较多的人使用RHEL/CentOS/Ubuntu,我们比较偏爱SuSE Linux,对于我们服务器使用的AMD Opteron x86_64的CPU来说,SLES要比RHEL有更多的优化。另外应该尽量使用64位版本操作系统,以充分发挥x86_64 CPU的性能,并且x86_64的Linux很多Kernel参数也大很多,代价就是需要更多的物理内存。
2、文件系统
Linux最常用的文件系统是ext3,但我们使用的是Reiserfs文件系统。Reiserfs在读写大量小文件的目录性能非常高,即使处理目录下面直接存放10万个文件,性能仍然不会下降。我们知道默认情况Rails会对每个浏览器会话在硬盘生成session文件,一个繁忙的网站,临时文件目录下面有上万乃至几万个session文件是很常见的现象。对于这种目录下面几万个小文件的存取,reiserfs要比ext3性能高一个数量级。如果希望对session文件有更好的存取性能,可以把临时目录链接到Linux的内存文件系统/dev/shm目录下面,这样实际上session文件的存取都是直接内存操作了,这种方式唯一的问题在于不能支持群集部署。如果你已经升级到了Rails2.0,可以采取把session保存到Cookie里面的方式,既可以避免服务器处理session的开销,而且还支持群集部署,是大规模网站部署的首选方式。
3、内核的网络参数调整
对于流量很大的网站来说,默认的Linux内核网络参数偏小,因此如果你的网站流量非常大,或者上传下载大文件比较多,可以针对性的调整内核网络参数,扩大内核的TCP接收数据和发送数据的Buffer缓冲区大小,比方说:
参数具体调整,可以Google相关的Linux内核参数的文档,这里不展开详谈。
二、Web服务器
Web服务器首选Lighttpd,因为Lighttpd在和后端的应用服务器通讯方式上做了足够的优化:当POST大数据量的时候,Lighttpd在完整的接收客户端浏览器的数据之后,才会一次性发送给应用服务器;同样的,Lighttpd也是一次性把应用服务器处理的页面数据全部接收,不设置Buffer Size的限制。因此Lighttpd能够尽最大可能的减轻应用服务器的负担,减少应用服务器用于处理数据传输的延迟,更加有效的利用应用服务器资源。这方面的详细的论述请看:RoR部署方案深度剖析。
关于Lighttpd的安装可以参考在Linux平台上安装和配置Ruby on Rails详解,这里仅谈Lighttpd的性能优化的几个要点:
1、网络IO调度方式
Linux Kernel 2.6支持sysepoll方式调度网络IO,能够处理极高的并发连接请求,Lighttpd可以通过配置文件打开sysepoll支持:
2、网络IO传输方式
Linux Kernel 2.6支持sendfile方式传输数据,Lighttpd可以通过配置文件打开sendfile支持:
此外Lighttpd还支持应用服务器参与的文件下载控制X-sendfile,详细的论述请看:RoR网站如何利用lighttpd的X-sendfile功能提升文件下载性能
3、文件状态缓存
Lighttpd通过stat()调用获得文件被修改的信息,来决定当请求同一个静态文件资源的时候,是否需要再次读取硬盘文件。但是每次stat()调用也有一定的开销,Lighttpd支持通过Fam Server来减少stat调用。即每次当文件被修改之后,Kernel会发送一个消息通知Fam Server,而Lighttpd会通过进程间通讯连接Fam Server,可以知道文件是否被修改的信息,不必再每次调用stat()。
4、限定POST Size
为了避免黑客恶意的攻击服务器,伪造超大Post数据包轰炸Web服务器和应用服务器,可以限制Request请求的大小,例如限制为10MB:
5、日志文件
Lighttpd是单进程单线程的服务器,调度网络IO性能是极高的,但是在某些极端情况下,单进程服务器也有风险,即一旦被某操作系统调用挂住,整个服务器就没有办法响应请求了。比方说服务器其他进程导致的IO WAIT很高,操作系统的buffer又不够的时候,Lighttpd在大量的写access log就有被挂住的可能性。因此如果Lighttpd日志对你的参考价值不大,可以考虑关闭掉。像JavaEye网站每天Lighttpd产生430万条log,对硬盘IO也是一个不小的负担,既然已经开着Rais的production.log,那么Lighttpd的access log没什么参考价值了,那就关掉它。
Lighttpd的性能优化请看其作者写的文章:
http://trac.lighttpd.net/trac/wiki/Docs%3APerformance
三、应用服务器
Ruby的应用服务器可以使用FastCGI,或者Mongrel,如果我们使用Lighttpd的话,FastCGI是最好的搭配。
1、FastCGI和Lighttpd的通讯方式
如果FastCGI和Lighttpd是在同一台服务器,那么建议采用Unix Socket通讯,这种通讯方式比TCP要快一些,FastCGI可以通过Lighttpd自带的spawn-fcgi命令行工具启动,创建socket文件,而Lighttpd监听socket文件。如果两者不在同一台服务器,需要群集部署,那就必须采用TCP Socket通讯,方式是一样的。
2、FastCGI进程应该开多少个合适?
Rails是单进程方式运行的,理论上来说,开几个FastCGI进程,就只能并发响应几个请求。对于繁忙的网站来说,峰值期间每秒有几十个动态请求是很正常的事情,但实际上FastCGI进程并不需要开那么多。这是因为前端的Web服务器在处理用户浏览器连接,发送Request请求需要相当长的时间,在FastCGI处理完请求释放该连接以后,Web服务器还需要相当长的时间才能把页面数据完整的发送到客户端浏览器。用户在点击一个链接以后,等待1-2秒,页面内容就显示出来,这对用户的感觉来说已经是非常快的了,而FastCGI用于处理该请求可能只需要0.1秒,那么一个FastCGI进程虽然并不能够真正的并发运行,但实际上的效果是他可以在1秒之内处理10个请求,让10个用户在同时访问网站的过程当中感觉不到明显的延迟。
因此FastCGI需要开多少个,取决于你的网站峰值期间每秒有多少个用户请求过来,而你的FastCGI又能够以多快的速度处理请求。比方说你的网站峰值期间每秒有50个动态请求,FastCGI在峰值期间处理每个请求需要0.2秒,那么实际上你只需要开10个FastCGI进程就足够了,为了应付突发的峰值请求,你可以在这个计算量上面增加一些余量,比方说15-20个进程,肯定是绰绰有余了。
关于FastCGI的性能优化,可以参考Lighttpd作者的文章,虽然他是针对PHP跑FastCGI写的,但对RoR也有参考价值:
http://trac.lighttpd.net/trac/wiki/Docs%3APerformanceFastCGI
四、数据库
JavaEye网站使用MySQL5.0.XX版本,数据库引擎是InnoDB。关于MySQL数据库的调优,推荐大家看MySQL Performance Blog,作者是一个MySQL性能调优方面的专家,并且提供MySQL咨询服务。他的博客上面有很丰富的关于MySQL调优的文章和演讲文稿,特别是关于InnoDB方面,非常深入。JavaEye的数据库调优就是根据他的InnoDB演讲文稿来调整的,一般说来,有几个需要调整的参数:
innodb_buffer_pool_size
这个参数很重要,越大越好,对于专用的数据库服务器一般建议开服务器内存的50%以上。
query_cache_size
查询缓存,对于查询的性能提高有很大帮助,但不宜开得过大,查询缓存的过期可能很频繁,过大查询缓存反而降低性能,增加服务器开销
innodb_flush_method = O_DIRECT
针对InnoDB的数据文件,关闭操作系统的文件缓冲,由于InnoDB自己有巨大的Buffer Pool,操作系统对文件的读写缓冲功能反而会降低MySQL的InnoDB的IO性能。
最后针对数据库的SQL优化来说有两点原则:
1、对数据库表要适当的创建索引
特别是出现在where查询条件当中字段,和关联查询当中的外键,要高度注意。
2、尽量避免大表的全表扫描和数据库的硬盘IO
查询比较慢的SQL要explain一下,看看是否发生了全表扫描,采取各种措施减少或者避免大表的全表扫描问题,例如拆分表等等。
最后针对MySQL数据库运行情况,我们可以用show status; 和 show innodb status\G 来监测。
Rails应用程序的优化
Rails应用程序优化包括ruby解析器的优化,缓存的使用,以及应用代码级别的优化。Stefans Kaes曾经在Railsconf 2006有一个Rails应用程序优化的演讲,他的演讲PPT是极好的Rails性能优化指南,可以在这里下载:http://www.iteye.com/topic/24508。他还编写了一个用于Rails性能测试的软件包RailsBench,大家可以参考。由于Stefans Kaes的代码优化文档已经写的非常详细了,因此我就不在一一复述,只提出几点对性能影响比较大的方面:
一、ruby解析器的优化
ruby的解析器性能是很糟糕的,ruby早期的主要用途是取代perl写批量处理的脚本的,并不是为服务器应用编写的,因此在内存分配策略上非常不适合服务器应用。Stefans Kaes编写了一个ruby GC的补丁文件,在railsbench下载包里面提供了。虽然当前Railsbench提供的GC补丁只有针对ruby 1.8.4和1.8.5版本的,但是在ruby 18,6上面使用1.8.5的GC补丁也完全没有问题。GC补丁的作用主要是针对Rails应用开大了ruby的内存堆,可以有效提高内存堆的利用率,降低GC的频率。根据Stefans Kaes提供的测试数据,打补丁并且调整参数以后,GC的频率下降到只有原来的1/10还不到。降低GC频率尽管并不能够提高单个请求的执行速度,但是可以增加整体应用的负载能力。
我们在JavaEye的服务器上也使用了GC补丁,并且根据推荐参数进行了调整。在使用GC补丁之后,Web服务器的CPU负载下降了大概15%左右,效果非常显著。当然开大内存堆的代价就是ruby进程会多消耗内存,在我们的服务器上,ruby打补丁之后多消耗了50%左右的物理内存。
二、缓存的使用
1、对象缓存
JavaEye上面关于对象缓存的讨论很多,我们也提供了JavaEye这方面很多数据,因此不展开了。RoR可以使用两个对象缓存,一个是CachedModel,类似Hibernate,比较简单,对Model的CRUD操作自动进行缓存;另外一个是cache_fu,需要自己编码来添加对象缓存,但提供了更多高级机制,目前我们使用的是cache_fu。在使用对象缓存的情况下,应该把查询方法的:include去掉,避免关联查询无法利用缓存的现象。
2、查询缓存
对于统计类耗时查询,如果不要求实时性,那么可以使用memcache-client将查询结果缓存到memcached里面,例如博客排行榜之类。
3、页面局部缓存
对象缓存和查询缓存都是降低数据库访问负载的,但如果RoR的负载很高,那么只能依靠页面局部缓存了。传统的互联网web1.0网站很流行采用动态页面静态化技术来提高网站的负载,但是对于web2.0网站来说,每个页面都带有登陆用户的个人信息,页面的很多部分需要实时更新,例如投票,点击统计,digg,显示用户在线状态等等,动态页面静态化非常困难。当然如果你非要采用动态页面静态化,技术上也不是实现不了,可以通过AJAX请求来处理静态页面的动态部分,但是这种解决方案的开发成本过高,而且性能未必会有明显的改善,大家看看新浪和搜狐博客就知道这种技术被应用的有多糟糕了。
web2.0网站比较常用使用页面局部缓存,一种情况是页面不需要实时更新的,那么只需要设置一个合理的过期时间就行了,这种情况我们目前使用的比较多;另外一种情况是虽然不需要实时更新,但是会在用户执行某些操作后需要缓存过期,比方说博客个人主页的很多页面,这种情况下缓存过期策略会比较复杂,考虑到合理的开发成本,我们尚未对这样的页面使用局部缓存。
此外,Rails的页面局部缓存有一个缺点,就是和页面查询结果对应的Action当中的查询语句要放在View里面,否则每次action里面的查询还是会被执行,但是这样做会破坏程序代码良好的MVC结构。这种情况下,也可以采用另外一个Cache插件: better rails caching,在缓存页面的同时可以缓存Action当中的查询语句。
三、应用代码的优化
Stefans Kaes的文档里面对应用代码的优化进行了非常详细的介绍,因此我这里只提两个比较重要的注意事项:
1、link_to
Rails的link_to是非常慢的,它的代码实现过于复杂,特别是Rails1.2引入了REST以后,大量的命名路由被使用,这些命名路由还需要通过一次method_missing,那就更加缓慢了。因此对于被频繁使用的内部URL地址,一定要自己用字符串拼接方式改写,可以很明显提高View的render性能。此外类似的helper还有很多,例如button_tag,image_tag啥啥的,如非必要,尽量不用他的helper
2、正则表达式
ruby的正则表达式也是极慢,例如auto_fix这个helper的正则表达式就比较复杂,造成的结果就是一但大量使用auto_fix,View的render就明显变慢,类似依赖正则表达式进行字符串过滤的helper有很多,如果需要频繁大量使用,请先自行做benchmark。
Rails应用程序的内存泄漏问题和解决
内存泄漏是服务器端程序经常遇到的,有时候内存泄漏问题会让人很头疼,总体来说,Rails的内存泄漏问题比Java要少得多,这是因为Java内存泄漏最常见的三种情况在Rails当中不存在:
1、HttpSession导致的内存泄漏
Java程序员喜欢往session里面丢很多东西,最糟糕的是竟然有很多框架软件也肆无忌惮往session里面丢状态数据,但Rails的session是不放在内存里面的,所以无此烦恼。
2、数据库连接释放不彻底
Java的数据库连接池释放不彻底,以及查询游标释放不彻底,都必然导致内存泄漏。Rails没有数据库连接池,而是每个进程持有一个长连接,因此不存在这个问题,而且由于持有长连接,也不存在Java里面的OpenSessionInView的烦恼。
3、用静态变量持有全局共享数据
Java程序员很喜欢通过静态全局变量来持有共享数据,但共享数据忘记清理的话,也很容易导致内存泄漏,Ruby是SNA架构,多进程服务器模式,进程间无法共享数据,反而避免了全局共享数据带来的麻烦。
但是Rails应用有一种情况:在Ruby代码中调用C写的第三方ruby类库的时候,很容易导致内存泄漏,但这种内存泄漏反而在Java中极其罕见。Ruby本身有GC来管理内存堆,但是代码一旦调用C写的第三方ruby类库,内存堆的分配权就掌握在第三方C库的实现上面了,如果这个C库的代码质量不够好,内存泄漏就不可避免。由于ruby本身性能很差,因此计算量大的功能往往依赖底层的C库来实现,这下内存泄漏的潘多拉魔盒就打开了!而Java性能比较好,功能都是纯Java编写,基本上看不到需要依赖第三方C库的情况,因此比较安全。
JavaEye也面临着内存泄漏的困扰,这方面困扰主要来自于Rmagic。Rmagick调用ImageMagick的C库来完成图片的操作,从我们的监测来看,RMagick大多数情况下会缓慢的泄漏内存,在某些特定的图片操作上会急剧的泄漏内存。解决办法就是用mini_magick替代Rmagick,mini_magick是直接调用ImageMagick的mogrify命令,另起一个进程来操作图片,操作完进程就结束了,绝无后患,由于Linux的fork进程开销不大,因此也不必担心性能问题。
此外,调用第三方C库的ruby代码编写都需要高度小心,比方说JavaEye使用ferret实现全文检索,根据应用的需要调用ferret的API来编写自己的analyzer,其中在实现token_stream方法上面使用了XXXAnalyzer.new和XXXToken.new,XXXFilter.new,结果内存急剧泄漏,经过检查发现是Analyzer对象不能被反复创建,改成创建后缓存该对象就好了,但是Filter和Token对象却必须每次创建,此外ferret的PerAnalyzerFilter也有内存泄漏问题。由于类库是用C编写的,单纯看API文档或者看源代码片断一般无法判断出里面的内存泄漏陷阱的。
当遇到了难以解决和定位的内存泄漏问题,Ruby也有类似Java的内存Profiler工具:
1、Memory Profiler
一个纯ruby编写的内存探测器,原理很简单,就是用ruby的对象引用计数器ObjectSpace.each_object去遍历内存堆中的每个ruby对象,进行统计和分析。用起来很简单,非常适合于开发环境下侦测内存泄漏问题,但不能用在生产环境下,极度影响Rails性能。
2、Bleak_house
Bleak_house给Ruby解析器打了补丁,插入相关的指令,可以从底层探测整个ruby内存堆中对象的情况,然后你可以定期dump出来完整的内存堆里面的所有对象,再用bleak工具去分析dump文件,他比上面的工具分析的信息要全面,可以在测试环境和预发布环境下使用,但在生产环境下,也会对应用的性能产生很大的影响,要慎用。
JavaEye网站在RoR性能方面的经验就全部分享给大家了,也希望做RoR的朋友都拿出来自己的经验和大家分享,共同学习和促进RoR的应用和普及。
和你其他语言的经验有关系吧,
我是先使用Ruby大概半年多时间了。才开始使用rails的。
基本上上手是很快的。
以前我一个同事做过测试,用lighttpd的fastCGI方式跑php,确实更节省内存,
不过在性能上中等访问量时反而比apache慢,小访问量和超大访问量时确又比apache快,这是在内存足够的情况下测试的。
JavaEye2.0上线之前,我曾经用Lighttpd跑过半个月的JavaEye 1.0(PHPBB论坛),在此前我自己做的压力测试表明大负载量下面,Apache的module运行PHP比Lighttpd的FastCGI运行PHP要快不少,这一点和你的同事测试结果是吻合的。但实际上部署上线以后,Lighttpd以FastCGI方式运行PHP,比原来的Apache明显要快很多,所以测试不能等同于实际生产环境。
你要考虑到一个很重要的因素,在实际互联网环境下,用户浏览器发起请求,用户浏览器在接受页面数据的这两个过程一般都需要1-2秒延迟,而PHP程序处理往往只需要0.1-0.2秒,所以FastCGI方式下,你可以用很少的PHP进程去响应很大的并发量。但在测试环境下,这两个和用户交互的重要延迟时间被彻底抹杀了,FastCGI开了几个进程,就只能同时响应几个请求,其他测试请求就必须等待,当然会比Apache慢了。
例如你用ab并发100个请求,Apache会在很短的时间内fork出来100个进程同时处理,但是FastCGI只有10个进程,他只能同时处理10个请求,其他请求必须等待,因此在测试环境下大并发量FastCGI就显得慢得多。但实际互联网环境下并不是这么回事,除了浏览器的请求和页面下载的延迟作用可以导致FastCGI显得更有效率之外,一个动态请求还会附带n个js,css,图片的请求,对于apache来说,都需要fork进程处理这些静态资源,而这些负载在ab测试当中都无法被体现出来。
这是两种不同的运行方式不可一概而论的。Apache以module的方式加载PHP,的确一个httpd不过20多MB内存,但是对于JavaEye这样访问量的网站来说,峰值访问期,apache需要fork出来150个httpd进程来处理,那么你算一下,150*20M = 3GB内存,是不是更加恐怖呢?同样的情况Lighttpd+FastCGI(Ruby),Lighttpd仅仅占用30MB内存,FastCGI开10 个就够了,总共需要30+180*10=1.8GB,你觉得哪种方式节省内存?
顺便说一句,Lighttpd+FastCGI(PHP)是比Apache更好的PHP部署环境,根据我的经验,FastCGI方式下的每个PHP进程保持在40-50MB左右的内存,总共需要30+50*10=530MB,比Apache的3GB,简直不可同日而语阿!
以前我一个同事做过测试,用lighttpd的fastCGI方式跑php,确实更节省内存,
不过在性能上中等访问量时反而比apache慢,小访问量和超大访问量时确又比apache快,这是在内存足够的情况下测试的。
RoR惊人的开发速度恐怕是每个互联网创业者都梦寐以求的,但是随着网站流量的不断增大,可能大多数采用RoR的网站或迟或早会遇到RoR的性能瓶颈,我的一个朋友capitian说过一句很有意思的话:“RoR应用做到后来,总有自己修改底层的冲动”。就我所了解和掌握的情况来看,很多RoR网站都过早的遇到了性能瓶颈,一个很普遍的现象就是:RoR应用的CPU负载要远远高于数据库的负载。这是一个有点违背常理的现象,因为我们知道,硬盘IO速度要比内存慢得多,所以一般Web应用的性能瓶颈往往会出现在数据库IO上,因此优化数据库访问,进行对象缓存是非常有效的性能优化手段。但是一旦应用服务器负载比数据库还高的话,单纯的对象缓存就无用武之地了。下面我们从几个方面分别谈一谈如何进行RoR的性能优化:
应用的部署
RoR应用的部署包括操作系统,Web服务器,应用服务器和数据库四个方面:
一、操作系统
1、发行版本
RoR适合于部署在Unix类操作系统上面,通常比较多的人使用RHEL/CentOS/Ubuntu,我们比较偏爱SuSE Linux,对于我们服务器使用的AMD Opteron x86_64的CPU来说,SLES要比RHEL有更多的优化。另外应该尽量使用64位版本操作系统,以充分发挥x86_64 CPU的性能,并且x86_64的Linux很多Kernel参数也大很多,代价就是需要更多的物理内存。
2、文件系统
Linux最常用的文件系统是ext3,但我们使用的是Reiserfs文件系统。Reiserfs在读写大量小文件的目录性能非常高,即使处理目录下面直接存放10万个文件,性能仍然不会下降。我们知道默认情况Rails会对每个浏览器会话在硬盘生成session文件,一个繁忙的网站,临时文件目录下面有上万乃至几万个session文件是很常见的现象。对于这种目录下面几万个小文件的存取,reiserfs要比ext3性能高一个数量级。如果希望对session文件有更好的存取性能,可以把临时目录链接到Linux的内存文件系统/dev/shm目录下面,这样实际上session文件的存取都是直接内存操作了,这种方式唯一的问题在于不能支持群集部署。如果你已经升级到了Rails2.0,可以采取把session保存到Cookie里面的方式,既可以避免服务器处理session的开销,而且还支持群集部署,是大规模网站部署的首选方式。
3、内核的网络参数调整
对于流量很大的网站来说,默认的Linux内核网络参数偏小,因此如果你的网站流量非常大,或者上传下载大文件比较多,可以针对性的调整内核网络参数,扩大内核的TCP接收数据和发送数据的Buffer缓冲区大小,比方说:
引用
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=262144
net.core.wmem_max=262144
net.ipv4.tcp_rmem=4096 65536 524288
net.ipv4.tcp_wmem=4096 65536 524288
net.core.wmem_default=262144
net.core.rmem_max=262144
net.core.wmem_max=262144
net.ipv4.tcp_rmem=4096 65536 524288
net.ipv4.tcp_wmem=4096 65536 524288
参数具体调整,可以Google相关的Linux内核参数的文档,这里不展开详谈。
二、Web服务器
Web服务器首选Lighttpd,因为Lighttpd在和后端的应用服务器通讯方式上做了足够的优化:当POST大数据量的时候,Lighttpd在完整的接收客户端浏览器的数据之后,才会一次性发送给应用服务器;同样的,Lighttpd也是一次性把应用服务器处理的页面数据全部接收,不设置Buffer Size的限制。因此Lighttpd能够尽最大可能的减轻应用服务器的负担,减少应用服务器用于处理数据传输的延迟,更加有效的利用应用服务器资源。这方面的详细的论述请看:RoR部署方案深度剖析。
关于Lighttpd的安装可以参考在Linux平台上安装和配置Ruby on Rails详解,这里仅谈Lighttpd的性能优化的几个要点:
1、网络IO调度方式
Linux Kernel 2.6支持sysepoll方式调度网络IO,能够处理极高的并发连接请求,Lighttpd可以通过配置文件打开sysepoll支持:
引用
server.event-handler = "linux-sysepoll"
2、网络IO传输方式
Linux Kernel 2.6支持sendfile方式传输数据,Lighttpd可以通过配置文件打开sendfile支持:
引用
server.network-backend = "linux-sendfile"
此外Lighttpd还支持应用服务器参与的文件下载控制X-sendfile,详细的论述请看:RoR网站如何利用lighttpd的X-sendfile功能提升文件下载性能
3、文件状态缓存
Lighttpd通过stat()调用获得文件被修改的信息,来决定当请求同一个静态文件资源的时候,是否需要再次读取硬盘文件。但是每次stat()调用也有一定的开销,Lighttpd支持通过Fam Server来减少stat调用。即每次当文件被修改之后,Kernel会发送一个消息通知Fam Server,而Lighttpd会通过进程间通讯连接Fam Server,可以知道文件是否被修改的信息,不必再每次调用stat()。
引用
server.stat-cache-engine = "fam"
4、限定POST Size
为了避免黑客恶意的攻击服务器,伪造超大Post数据包轰炸Web服务器和应用服务器,可以限制Request请求的大小,例如限制为10MB:
引用
server.max-request-size = 10240
5、日志文件
Lighttpd是单进程单线程的服务器,调度网络IO性能是极高的,但是在某些极端情况下,单进程服务器也有风险,即一旦被某操作系统调用挂住,整个服务器就没有办法响应请求了。比方说服务器其他进程导致的IO WAIT很高,操作系统的buffer又不够的时候,Lighttpd在大量的写access log就有被挂住的可能性。因此如果Lighttpd日志对你的参考价值不大,可以考虑关闭掉。像JavaEye网站每天Lighttpd产生430万条log,对硬盘IO也是一个不小的负担,既然已经开着Rais的production.log,那么Lighttpd的access log没什么参考价值了,那就关掉它。
Lighttpd的性能优化请看其作者写的文章:
http://trac.lighttpd.net/trac/wiki/Docs%3APerformance
三、应用服务器
Ruby的应用服务器可以使用FastCGI,或者Mongrel,如果我们使用Lighttpd的话,FastCGI是最好的搭配。
1、FastCGI和Lighttpd的通讯方式
如果FastCGI和Lighttpd是在同一台服务器,那么建议采用Unix Socket通讯,这种通讯方式比TCP要快一些,FastCGI可以通过Lighttpd自带的spawn-fcgi命令行工具启动,创建socket文件,而Lighttpd监听socket文件。如果两者不在同一台服务器,需要群集部署,那就必须采用TCP Socket通讯,方式是一样的。
2、FastCGI进程应该开多少个合适?
Rails是单进程方式运行的,理论上来说,开几个FastCGI进程,就只能并发响应几个请求。对于繁忙的网站来说,峰值期间每秒有几十个动态请求是很正常的事情,但实际上FastCGI进程并不需要开那么多。这是因为前端的Web服务器在处理用户浏览器连接,发送Request请求需要相当长的时间,在FastCGI处理完请求释放该连接以后,Web服务器还需要相当长的时间才能把页面数据完整的发送到客户端浏览器。用户在点击一个链接以后,等待1-2秒,页面内容就显示出来,这对用户的感觉来说已经是非常快的了,而FastCGI用于处理该请求可能只需要0.1秒,那么一个FastCGI进程虽然并不能够真正的并发运行,但实际上的效果是他可以在1秒之内处理10个请求,让10个用户在同时访问网站的过程当中感觉不到明显的延迟。
因此FastCGI需要开多少个,取决于你的网站峰值期间每秒有多少个用户请求过来,而你的FastCGI又能够以多快的速度处理请求。比方说你的网站峰值期间每秒有50个动态请求,FastCGI在峰值期间处理每个请求需要0.2秒,那么实际上你只需要开10个FastCGI进程就足够了,为了应付突发的峰值请求,你可以在这个计算量上面增加一些余量,比方说15-20个进程,肯定是绰绰有余了。
关于FastCGI的性能优化,可以参考Lighttpd作者的文章,虽然他是针对PHP跑FastCGI写的,但对RoR也有参考价值:
http://trac.lighttpd.net/trac/wiki/Docs%3APerformanceFastCGI
四、数据库
JavaEye网站使用MySQL5.0.XX版本,数据库引擎是InnoDB。关于MySQL数据库的调优,推荐大家看MySQL Performance Blog,作者是一个MySQL性能调优方面的专家,并且提供MySQL咨询服务。他的博客上面有很丰富的关于MySQL调优的文章和演讲文稿,特别是关于InnoDB方面,非常深入。JavaEye的数据库调优就是根据他的InnoDB演讲文稿来调整的,一般说来,有几个需要调整的参数:
innodb_buffer_pool_size
这个参数很重要,越大越好,对于专用的数据库服务器一般建议开服务器内存的50%以上。
query_cache_size
查询缓存,对于查询的性能提高有很大帮助,但不宜开得过大,查询缓存的过期可能很频繁,过大查询缓存反而降低性能,增加服务器开销
innodb_flush_method = O_DIRECT
针对InnoDB的数据文件,关闭操作系统的文件缓冲,由于InnoDB自己有巨大的Buffer Pool,操作系统对文件的读写缓冲功能反而会降低MySQL的InnoDB的IO性能。
最后针对数据库的SQL优化来说有两点原则:
1、对数据库表要适当的创建索引
特别是出现在where查询条件当中字段,和关联查询当中的外键,要高度注意。
2、尽量避免大表的全表扫描和数据库的硬盘IO
查询比较慢的SQL要explain一下,看看是否发生了全表扫描,采取各种措施减少或者避免大表的全表扫描问题,例如拆分表等等。
最后针对MySQL数据库运行情况,我们可以用show status; 和 show innodb status\G 来监测。
Rails应用程序的优化
Rails应用程序优化包括ruby解析器的优化,缓存的使用,以及应用代码级别的优化。Stefans Kaes曾经在Railsconf 2006有一个Rails应用程序优化的演讲,他的演讲PPT是极好的Rails性能优化指南,可以在这里下载:http://www.iteye.com/topic/24508。他还编写了一个用于Rails性能测试的软件包RailsBench,大家可以参考。由于Stefans Kaes的代码优化文档已经写的非常详细了,因此我就不在一一复述,只提出几点对性能影响比较大的方面:
一、ruby解析器的优化
ruby的解析器性能是很糟糕的,ruby早期的主要用途是取代perl写批量处理的脚本的,并不是为服务器应用编写的,因此在内存分配策略上非常不适合服务器应用。Stefans Kaes编写了一个ruby GC的补丁文件,在railsbench下载包里面提供了。虽然当前Railsbench提供的GC补丁只有针对ruby 1.8.4和1.8.5版本的,但是在ruby 18,6上面使用1.8.5的GC补丁也完全没有问题。GC补丁的作用主要是针对Rails应用开大了ruby的内存堆,可以有效提高内存堆的利用率,降低GC的频率。根据Stefans Kaes提供的测试数据,打补丁并且调整参数以后,GC的频率下降到只有原来的1/10还不到。降低GC频率尽管并不能够提高单个请求的执行速度,但是可以增加整体应用的负载能力。
我们在JavaEye的服务器上也使用了GC补丁,并且根据推荐参数进行了调整。在使用GC补丁之后,Web服务器的CPU负载下降了大概15%左右,效果非常显著。当然开大内存堆的代价就是ruby进程会多消耗内存,在我们的服务器上,ruby打补丁之后多消耗了50%左右的物理内存。
二、缓存的使用
1、对象缓存
JavaEye上面关于对象缓存的讨论很多,我们也提供了JavaEye这方面很多数据,因此不展开了。RoR可以使用两个对象缓存,一个是CachedModel,类似Hibernate,比较简单,对Model的CRUD操作自动进行缓存;另外一个是cache_fu,需要自己编码来添加对象缓存,但提供了更多高级机制,目前我们使用的是cache_fu。在使用对象缓存的情况下,应该把查询方法的:include去掉,避免关联查询无法利用缓存的现象。
2、查询缓存
对于统计类耗时查询,如果不要求实时性,那么可以使用memcache-client将查询结果缓存到memcached里面,例如博客排行榜之类。
3、页面局部缓存
对象缓存和查询缓存都是降低数据库访问负载的,但如果RoR的负载很高,那么只能依靠页面局部缓存了。传统的互联网web1.0网站很流行采用动态页面静态化技术来提高网站的负载,但是对于web2.0网站来说,每个页面都带有登陆用户的个人信息,页面的很多部分需要实时更新,例如投票,点击统计,digg,显示用户在线状态等等,动态页面静态化非常困难。当然如果你非要采用动态页面静态化,技术上也不是实现不了,可以通过AJAX请求来处理静态页面的动态部分,但是这种解决方案的开发成本过高,而且性能未必会有明显的改善,大家看看新浪和搜狐博客就知道这种技术被应用的有多糟糕了。
web2.0网站比较常用使用页面局部缓存,一种情况是页面不需要实时更新的,那么只需要设置一个合理的过期时间就行了,这种情况我们目前使用的比较多;另外一种情况是虽然不需要实时更新,但是会在用户执行某些操作后需要缓存过期,比方说博客个人主页的很多页面,这种情况下缓存过期策略会比较复杂,考虑到合理的开发成本,我们尚未对这样的页面使用局部缓存。
此外,Rails的页面局部缓存有一个缺点,就是和页面查询结果对应的Action当中的查询语句要放在View里面,否则每次action里面的查询还是会被执行,但是这样做会破坏程序代码良好的MVC结构。这种情况下,也可以采用另外一个Cache插件: better rails caching,在缓存页面的同时可以缓存Action当中的查询语句。
三、应用代码的优化
Stefans Kaes的文档里面对应用代码的优化进行了非常详细的介绍,因此我这里只提两个比较重要的注意事项:
1、link_to
Rails的link_to是非常慢的,它的代码实现过于复杂,特别是Rails1.2引入了REST以后,大量的命名路由被使用,这些命名路由还需要通过一次method_missing,那就更加缓慢了。因此对于被频繁使用的内部URL地址,一定要自己用字符串拼接方式改写,可以很明显提高View的render性能。此外类似的helper还有很多,例如button_tag,image_tag啥啥的,如非必要,尽量不用他的helper
2、正则表达式
ruby的正则表达式也是极慢,例如auto_fix这个helper的正则表达式就比较复杂,造成的结果就是一但大量使用auto_fix,View的render就明显变慢,类似依赖正则表达式进行字符串过滤的helper有很多,如果需要频繁大量使用,请先自行做benchmark。
Rails应用程序的内存泄漏问题和解决
内存泄漏是服务器端程序经常遇到的,有时候内存泄漏问题会让人很头疼,总体来说,Rails的内存泄漏问题比Java要少得多,这是因为Java内存泄漏最常见的三种情况在Rails当中不存在:
1、HttpSession导致的内存泄漏
Java程序员喜欢往session里面丢很多东西,最糟糕的是竟然有很多框架软件也肆无忌惮往session里面丢状态数据,但Rails的session是不放在内存里面的,所以无此烦恼。
2、数据库连接释放不彻底
Java的数据库连接池释放不彻底,以及查询游标释放不彻底,都必然导致内存泄漏。Rails没有数据库连接池,而是每个进程持有一个长连接,因此不存在这个问题,而且由于持有长连接,也不存在Java里面的OpenSessionInView的烦恼。
3、用静态变量持有全局共享数据
Java程序员很喜欢通过静态全局变量来持有共享数据,但共享数据忘记清理的话,也很容易导致内存泄漏,Ruby是SNA架构,多进程服务器模式,进程间无法共享数据,反而避免了全局共享数据带来的麻烦。
但是Rails应用有一种情况:在Ruby代码中调用C写的第三方ruby类库的时候,很容易导致内存泄漏,但这种内存泄漏反而在Java中极其罕见。Ruby本身有GC来管理内存堆,但是代码一旦调用C写的第三方ruby类库,内存堆的分配权就掌握在第三方C库的实现上面了,如果这个C库的代码质量不够好,内存泄漏就不可避免。由于ruby本身性能很差,因此计算量大的功能往往依赖底层的C库来实现,这下内存泄漏的潘多拉魔盒就打开了!而Java性能比较好,功能都是纯Java编写,基本上看不到需要依赖第三方C库的情况,因此比较安全。
JavaEye也面临着内存泄漏的困扰,这方面困扰主要来自于Rmagic。Rmagick调用ImageMagick的C库来完成图片的操作,从我们的监测来看,RMagick大多数情况下会缓慢的泄漏内存,在某些特定的图片操作上会急剧的泄漏内存。解决办法就是用mini_magick替代Rmagick,mini_magick是直接调用ImageMagick的mogrify命令,另起一个进程来操作图片,操作完进程就结束了,绝无后患,由于Linux的fork进程开销不大,因此也不必担心性能问题。
此外,调用第三方C库的ruby代码编写都需要高度小心,比方说JavaEye使用ferret实现全文检索,根据应用的需要调用ferret的API来编写自己的analyzer,其中在实现token_stream方法上面使用了XXXAnalyzer.new和XXXToken.new,XXXFilter.new,结果内存急剧泄漏,经过检查发现是Analyzer对象不能被反复创建,改成创建后缓存该对象就好了,但是Filter和Token对象却必须每次创建,此外ferret的PerAnalyzerFilter也有内存泄漏问题。由于类库是用C编写的,单纯看API文档或者看源代码片断一般无法判断出里面的内存泄漏陷阱的。
当遇到了难以解决和定位的内存泄漏问题,Ruby也有类似Java的内存Profiler工具:
1、Memory Profiler
一个纯ruby编写的内存探测器,原理很简单,就是用ruby的对象引用计数器ObjectSpace.each_object去遍历内存堆中的每个ruby对象,进行统计和分析。用起来很简单,非常适合于开发环境下侦测内存泄漏问题,但不能用在生产环境下,极度影响Rails性能。
2、Bleak_house
Bleak_house给Ruby解析器打了补丁,插入相关的指令,可以从底层探测整个ruby内存堆中对象的情况,然后你可以定期dump出来完整的内存堆里面的所有对象,再用bleak工具去分析dump文件,他比上面的工具分析的信息要全面,可以在测试环境和预发布环境下使用,但在生产环境下,也会对应用的性能产生很大的影响,要慎用。
JavaEye网站在RoR性能方面的经验就全部分享给大家了,也希望做RoR的朋友都拿出来自己的经验和大家分享,共同学习和促进RoR的应用和普及。
评论
31 楼
sinoyster
2008-02-13
好文章,学习了
30 楼
halfmile
2008-02-12
一点经验
中心思想:让ror处理越少的工作,网站就越快
1. 全文检索让ferret作, 渲染之前加个处理,把常用关键字cache起来
2. 统计,特别是blog等不需要很强实效的,可以写一个rake task然后加入cron job在负载低的时候生成到public目录 json数据格式,然后客户端ajax拉回来渲染结果
3. 正文内容避免用ajax,因为如果算上在搜索引擎上的损失,ajax拉正文内容的成本是非常高的
4. memcache, memcache, memcache!
5. 我始终看不到 ajax 作的内容提交和用户登录的有点
6. 插件 simple_captcha 里面有一个 rake task 移除过期的图片,可以改一改,放一个cron job移除过期的session
中心思想:让ror处理越少的工作,网站就越快
1. 全文检索让ferret作, 渲染之前加个处理,把常用关键字cache起来
2. 统计,特别是blog等不需要很强实效的,可以写一个rake task然后加入cron job在负载低的时候生成到public目录 json数据格式,然后客户端ajax拉回来渲染结果
3. 正文内容避免用ajax,因为如果算上在搜索引擎上的损失,ajax拉正文内容的成本是非常高的
4. memcache, memcache, memcache!
5. 我始终看不到 ajax 作的内容提交和用户登录的有点
6. 插件 simple_captcha 里面有一个 rake task 移除过期的图片,可以改一改,放一个cron job移除过期的session
29 楼
chenqiutang
2008-02-12
sdsdsdsdsdsdsd
28 楼
toostupid
2008-02-11
这个文章很好,拜读了。
27 楼
bencode
2008-02-06
xiaolin0105 写道
想了解一下,从学习ror(无roby基础)到具体应用到项目,最短需要多久?
和你其他语言的经验有关系吧,
我是先使用Ruby大概半年多时间了。才开始使用rails的。
基本上上手是很快的。
26 楼
netco
2008-01-24
谢谢robbin能把如此宝贵的经验分享出来,对我目前的工作有很大的帮助。
25 楼
s00n
2008-01-24
感谢robbin的分享,我们在开发3user.com时,robbin的文章给了我们很多的帮助,非常感谢!
24 楼
foxgst
2008-01-23
好文,谢谢分享经验。
23 楼
eicesoft
2008-01-23
不错的好文章,请问一下,java web服务器用什么软件最好啊!
22 楼
花花公子
2008-01-21
rmagick优化可以见此篇http://rubyforge.org/forum/forum.php?thread_id=10975&forum_id=1618
现在RMagick基本上都是自己编译的
Installing RMagick on Linux, *BSD, or Cygwin systems
RMagick号称可以自己删除不需要的对象,还没有试过。
About RMagick 2
现在RMagick基本上都是自己编译的
Installing RMagick on Linux, *BSD, or Cygwin systems
RMagick号称可以自己删除不需要的对象,还没有试过。
About RMagick 2
21 楼
vincent253
2008-01-21
十分感谢robbin,受益匪浅。
20 楼
dingyuan
2008-01-21
robbin的学习能力,对问题的定位,分析能力,不尽另我们这些后辈佩服,向你多学习了
19 楼
afly
2008-01-21
呵呵,这的确是神贴!
如此神贴,需要我等细细的读,做,体会,再回来写,拿出自己的分享与贡献
如此神贴,需要我等细细的读,做,体会,再回来写,拿出自己的分享与贡献
18 楼
DigitalSonic
2008-01-21
感谢Robbin最近的几篇文章,受益匪浅~~
17 楼
9esuLuciano
2008-01-21
好帖子,感谢robbin的分享,对于后来人而言少走了很多弯路,再次感谢robbin的分享精神。
16 楼
robbin
2008-01-21
yzx110 写道
以前我一个同事做过测试,用lighttpd的fastCGI方式跑php,确实更节省内存,
不过在性能上中等访问量时反而比apache慢,小访问量和超大访问量时确又比apache快,这是在内存足够的情况下测试的。
JavaEye2.0上线之前,我曾经用Lighttpd跑过半个月的JavaEye 1.0(PHPBB论坛),在此前我自己做的压力测试表明大负载量下面,Apache的module运行PHP比Lighttpd的FastCGI运行PHP要快不少,这一点和你的同事测试结果是吻合的。但实际上部署上线以后,Lighttpd以FastCGI方式运行PHP,比原来的Apache明显要快很多,所以测试不能等同于实际生产环境。
你要考虑到一个很重要的因素,在实际互联网环境下,用户浏览器发起请求,用户浏览器在接受页面数据的这两个过程一般都需要1-2秒延迟,而PHP程序处理往往只需要0.1-0.2秒,所以FastCGI方式下,你可以用很少的PHP进程去响应很大的并发量。但在测试环境下,这两个和用户交互的重要延迟时间被彻底抹杀了,FastCGI开了几个进程,就只能同时响应几个请求,其他测试请求就必须等待,当然会比Apache慢了。
例如你用ab并发100个请求,Apache会在很短的时间内fork出来100个进程同时处理,但是FastCGI只有10个进程,他只能同时处理10个请求,其他请求必须等待,因此在测试环境下大并发量FastCGI就显得慢得多。但实际互联网环境下并不是这么回事,除了浏览器的请求和页面下载的延迟作用可以导致FastCGI显得更有效率之外,一个动态请求还会附带n个js,css,图片的请求,对于apache来说,都需要fork进程处理这些静态资源,而这些负载在ab测试当中都无法被体现出来。
15 楼
whb
2008-01-21
真的是不错,实践中总结的经验尤为宝贵。谢谢robbin共享经验。
14 楼
neodoxy
2008-01-21
很难想像Apache会比Lighttpd快,处理静态资源的话绝对是Lighttpd的强项,而转发的动态请求的瓶颈不在Web Server而是Ruby.可能是php挂载的方式不同造成的,不能用来说明Lighttd与Apache之间的优劣
13 楼
yzx110
2008-01-21
robbin 写道
这是两种不同的运行方式不可一概而论的。Apache以module的方式加载PHP,的确一个httpd不过20多MB内存,但是对于JavaEye这样访问量的网站来说,峰值访问期,apache需要fork出来150个httpd进程来处理,那么你算一下,150*20M = 3GB内存,是不是更加恐怖呢?同样的情况Lighttpd+FastCGI(Ruby),Lighttpd仅仅占用30MB内存,FastCGI开10 个就够了,总共需要30+180*10=1.8GB,你觉得哪种方式节省内存?
顺便说一句,Lighttpd+FastCGI(PHP)是比Apache更好的PHP部署环境,根据我的经验,FastCGI方式下的每个PHP进程保持在40-50MB左右的内存,总共需要30+50*10=530MB,比Apache的3GB,简直不可同日而语阿!
以前我一个同事做过测试,用lighttpd的fastCGI方式跑php,确实更节省内存,
不过在性能上中等访问量时反而比apache慢,小访问量和超大访问量时确又比apache快,这是在内存足够的情况下测试的。
12 楼
carpenter
2008-01-21
虽不是ror程序员,仍然收获不少,好贴
发表评论
-
《松本行弘的程序世界》推荐序
2011-07-21 13:47 15251在流行的编程语言中,ruby是一个比较另类的存在,这是因为大多 ... -
从Rails聊聊小公司的研发团队建设
2011-03-23 10:49 37211首先分享一点数据吧: JavaEye的PV到了140万了,一 ... -
Ruby作为服务器端应用已经成熟了
2009-11-17 14:55 15923JavaEye网站在过去的Ruby on rails实践当中, ... -
基于资源的HTTP Cache的实现介绍
2009-09-05 00:27 17045我们都知道浏览器会缓 ... -
请注意Rails2.3自带的memcache-client有性能问题
2009-03-23 18:05 14468Rails2.3版本发布了,这个版本内部的改动非常大,相关介绍 ... -
监视Rails进程内存泄漏的技巧
2008-12-30 21:56 10947Rails应用比较容易遇到的两类性能问题:一类是Rails执行 ... -
ruby MBARI大补丁性能评测报告
2008-12-23 12:19 5068JavaEye之前的新闻ruby内存泄漏的罪魁祸首 - 幽灵指 ... -
在top监视窗口显示Rails当前正在执行的请求URL
2008-12-01 14:15 9853这是一个从PragDave的博客上面学来的技巧,很实用,很co ... -
对Ruby VM的GC的思考
2008-09-02 23:41 8970Ruby虽然是动态脚本语言 ... -
推荐一篇很好的RoR部署方案性能评测
2008-07-08 11:55 9627今年年初的时候,我写了一篇RoR部署方案深度剖析的文章,分析了 ... -
Ruby和Rails的缺点
2008-06-25 21:08 17400有人说,robbin你说了那么多RoR的优点,你啥时候说说Ro ... -
Skynet --- ruby的类Google Map/Reduce框架
2008-06-02 00:39 8292Skynet是一个很响亮的名 ... -
rmmseg-cpp - 简洁高效的ruby中文分词程序
2008-05-27 00:47 11230我在前一篇文章向大家 ... -
使用libmmseg实现Ruby的中文分词功能
2008-05-24 21:43 11317用Ruby on Rails开发web2.0网站的人都知道,r ... -
mod_rails尝鲜
2008-04-13 14:32 8078Passenger(俗称mod_rails)是 ... -
Lighttpd和RoR安装配置的疑难解答
2008-03-07 11:09 14839之前写过一篇在Linux平 ... -
RoR部署方案深度剖析
2008-01-14 03:10 14775RoR的部署方案可谓五花八门,有Apache/Fastcgi方 ... -
RoR网站如何利用lighttpd的X-sendfile功能提升文件下载性能
2008-01-12 17:45 10249传统的Web服务器在处理文件下载的时候,总是先读入文件内容到应 ... -
Ruby为什么会受程序员的欢迎?
2008-01-07 20:08 15751孟岩最近写了一篇博客 ... -
Ruby on Rails 2.0的新特性介绍
2007-12-10 21:32 15607万众瞩目的Ruby on Rails 2.0已经发布了,Rai ...
相关推荐
在本文中,我们将探讨一些RoR性能优化的关键方面,主要基于JavaEye网站在使用RoR过程中积累的实际经验。 首先,RoR性能优化涉及到多个层面,包括应用程序的部署、服务器配置以及代码优化。在部署方面,操作系统的...
网站性能技术是优化用户体验、提高系统效率的关键领域。在当今互联网时代,用户对网页加载速度和响应时间的要求越来越高,因此,了解并掌握网站性能优化技术至关重要。本文将围绕"谈谈网站性能技术"这一主题,结合...
javaeye被黑 大家看看
JavaEye热点阅读是JavaEye论坛推出的2009年2月特辑,旨在为Java学习者和开发者提供最新的知识及行业动态。这份资料包含了多个Java相关的主题,包括但不限于并发编程、开源项目、设计模式、框架应用以及软件开发实践...
### JavaEye3.0开发手记之开发环境搭建详解 #### 一、开发环境搭建概述 随着JavaEye3.0开发计划的启动,本篇文章将详细介绍如何为该项目搭建高效的开发环境。开发过程中不仅需要考虑软件的选择,还需要针对操作...
【JavaEye月刊2008年4月总第2期】主要涵盖了多个与Java相关的技术和行业动态。以下是对这些内容的详细解析: 1. **Spring创始人Rod Johnson再次发飙—“传统Java应用服务器正在没落”** Rod Johnson是Spring框架的...
JavaEye+技术架构,讲述java框架的应用
javaeye的信息提示框代码之css,application.js
7. **性能优化**:对于大量数据的PDF生成,可能需要考虑性能优化,比如批量处理,异步生成,或者利用缓存策略。 8. **PDF安全**:了解如何设置PDF的安全属性,如限制打印、复制内容等,以保护生成的PDF文件。 9. *...
在使用JavaEye API时,应遵循最佳实践,如合理使用设计模式、注意性能优化、遵循代码规范,以及及时更新到最新API版本以获取安全修复和新特性。此外,参与社区讨论和分享经验也是提升技术水平的有效方式。 总之,...
JavaEye是一款知名的面向开发者的技术社区,它提供了丰富的代码展示功能,其中包括代码高亮显示。在WordPress等博客平台中,为了使代码段...在实际应用中,你可能还需要考虑兼容性、性能优化以及用户体验等方面的问题。
【JavaEye论坛热点月报 总第5期】是一份汇集了2008年10月期间IT技术热点的报告,主要关注Java及其相关领域的发展。这份月报涵盖了多种技术和话题,包括但不限于: 1. **Javarebel**:Javarebel是一款强大的工具,它...
JavaEye新闻月刊2009年3月第13期内容涉及了当时软件开发领域内的一系列重要话题,包括IBM拟收购Sun Microsystems公司的新闻报道、Java社区对此的看法以及各种编程语言、开发工具和技术的新动态。 首先,新闻月刊...
缓存技术是一种关键的性能优化手段,它通过存储常用数据的副本以加快访问速度,缓解不同硬件或软件组件之间速度不匹配的问题。在Javaeye Robbin的讨论中,他提到了缓存技术在多种场景下的应用和重要性。 **缓存的...
JavaEye Client SourceCode是一个开源项目,专为Android平台设计,提供了JavaEYE的客户端实现。这个项目的源代码为我们提供了一个深入了解Android应用开发以及Java编程在移动设备上的实践的宝贵资源。接下来,我们将...