2010 年 04 月

浏览模式: 标准 | 列表 | 图文
来自PHP研究室的:大型高性能网站的十项规则

来自PHP研究室的:大型高性能网站的十项规则

本文来自PHP5研究室,里面用【】包含的内容是我的个人见解,并非一定就是正确,如果有不同意见,或者忽略,或者请给我点建议。

原文地址是http://www.phpv.net/html/1710.html

在我们公司ChinaNetCloud,见 过多种不同类型的网站和系统,有好也有差。其中有些系统拥有良好的服务器/网络架构,并且进行了合理的调整和监控 ;然而一般的系统都会有安全和性能上的问题,不能良好运行,也无法变得更流行。

在中国,开源的LAMP栈是最流行的网络架构,它使用PHP开发,运行在Apache服务器上,以MySQL作为数据库,所有这些都运行在Linux上。它是个可靠的平台,运行良好,是现在全球最流行的Internet系统架构。然而,我们很难对其规模进行正确的扩展并保持安全性,因为每个应用层都有其自身的问题、缺陷和最佳实践。我们的工作就是帮助企业用最低的操作成本来创建并运行高性能的、可伸缩的、安全的系统,因此对于这类问题我们有很丰富的经验。

当前的实际情况是,很多网站都是由开发人员快速而廉价地创建【说实话还真没有办法,上面催下面逼,还能怎么做?】,通常没有任何IT人员或者经理,只是由程序员来管理系统。造成的结果是,虽然花费很低的成本网站就可以开始运行,但是当拥有大量用户、需要扩展规模的时候,通常就会面临真正的问题。毕竟,中国拥有三亿八千万的Internet用户,如果其中的0.01%访问这个站点,就很容易引发25 万~50万的页面访问量。这些问题在各个级别上都会产生,下面总结的规则是对最一般的问题进行概述,并且说明为什么这些规则如此重要,以及最好采用什么方法来修正它们。遵循这些建议的站点会提高它的可伸缩性、安全性以及操作上的稳定性。

1、使用合适的会话管理

第一个想到的扩展系统的方法就是添加更多硬件。例如,使用两台服务器而不是一台。这听着合理,但会产生潜在问题:会话管理。这对Java程序来说是很严重的问题,在PHP中也会产生可延展性问题, 对于数据库的负载尤其如此。

会话被定义为单独的最终用户登录或者连接一段时间,其中通常会包含多个TCP/IP的HTTP连接、几个Web页面,通常还包括几十个甚至上百个页面元素,如框架、菜单、Ajax更新等。所有这些 HTTP请求都需要知道用户是谁,才能满足安全的要求,并向用户传送适当的内容,因为这些都是会话的组成部分。通常每个会话都会包括相互关联的会话数据,如用户名、用户ID、历史、购物车、统计资料等等信息。

问题在于,在有两台Web服务器和多个HTTP连接的情况下,用户流量会在两台服务器之间分配和移动,服务器很难知道用户是谁,并对所有数据进行跟踪,因为每个页面或者页面的组成部分都可能来自不同的服务器。在PHP中,通常是这样解决的,在第一次连接或登录的时候就创建一个会话ID并将其放在Cookie中,然后这个Cookie会和每个 HTTP请求一起发送。

这样做带来一个问题,接下来每段PHP脚本都需要基于ID来查找会话数据。由于PHP无法在执行过程之间保持状态(这与Java不同),这个会话数据需要存储在某个地方,通常是在数据库中。但是,如果复杂的页面需要在每个页面载入过程中对其进行十次查找(这是经常要做的),那就意味着每个页面都要执行10次SQL查询,这会导致数据库上很大的负载。

在前面所举的中国 Internet用户 0.01%的例子中,可能很容易在每秒内仅仅为了管理会话就生成上百个查询。解决方法是一直使用位于Cookie中的会话ID,并且使用像 Memcached之类的服务来缓存会话数据以获得高性能。

还要注意其中存在安全性的问题,因为黑客可以伪造另一个用户的会话ID,这是很容易找到或看到的,特别是在公用的Wi-Fi中。解决方法是对会话ID进行恰当的加密或者签名,并将其与时间区间、 IP地址以及其他关键信息 像浏览器或者其他细节相绑定。在Internet上有很多不错的关于良好的会话管理的例子,你可以根据需要找到最适合的。

2、总是要考虑安全性
尽管编写像防止SQL注入和登录安全之类的代码涉及很多安全问题,但不幸的是,几乎没有人考虑过安全性,而那些考虑到的人也没有对其进行很好地理解。而本文要关注的是操作性的系统安全。对于这类安全,我们的焦点集中在三个安全领域:防火墙、运行的用户以及文件访问权限。

除了配置专门的硬件防火墙(像Cisco的ASA)之外,所有服务器都还应该运行像Iptables之类的防火墙,它会保护服务器免受其他威胁和攻击。这些威胁和攻击可能来自公共的 Internet、其他服务器或本地服务器,也包括使用VPN或者SSH通道的开发和操作人员。我们仅对指定的IP开放确实需要的端口。Iptables 可能会很复杂,但是有很多不错的模板,我们通常可以使用它们来帮助客户创建Iptables。例如,默认的RedHat或者CentOS防火墙的配置说明只有10行,显然并不实用。我们最佳实践的Iptables配置大概有5页,这其中包含了Linux所能提供的最高级的安全防范。

所有公用的服务,都应该运行在专门的用户下,如Apache。切记永远都不要使用Root用户运行,因为这会让任何闯入到Apache的用户接管整个服务器。如果Apache只是运行在 Apache用户下或者运行在Nobody下,那么闯入Apache就不是一件容易的事情了。

Web服务器运行或者服务的文件(像.php和.html文件)对于Web服务器的用户应该是不可写的。这意味着Apache或者Nginx用户不应该拥有Web目录的写权限。有很多方法都可以做到这一点,而最简单的就是将这些文件为其他用户所有,然后让Apache/Nginx等用户归属于能够使用640权限读取文件的组中。这会防范几乎所有的黑客和针对页面的攻击。

此外,永远不要使用Ftp来上传文件,特别是在公用的Wi-Fi环境中,因为在其中黑客很容易盗取用户名和密码。取而代之的是使用Sftp会更加安全。另外,每个雇员都应该拥有自己的用户ID和随机密码。【其实并非是所谓的SFTP安全,我倒是认为,多开通一个功能,相应的就会多一个漏洞】

3、使用标准的路径和安装配置

一个令人讨厌的部署问题是,开发者很少考虑他们的软件会被部署到生产Web服务器的什么位置,以及如何部署。我们看到过许多大型的系统将它们的PHP代码部署在/home/xiaofeng或者 /web/code路径下。事实上,这两个路径都是非常不标准的,并且会带来操作和安全性的问题。当这些系统从开发环境转移到测试环境再到生产环境中时,因为每个安装配置都是非标准的,所以经常会出现问题,这时就需要开发者调整才能够正常工作。

你应该总是使用标准的安装包和二进制文件来 安装像Apache之类的服务器。不要从源代码编译或者安装Tarball,因为这会导致长期稳定性和管理上的问题,另外在服务器上安装多个不同的版本也 会造成混淆。

Web站点应该总是在指定的平台和 Linux发布的标准路径下进行测试和部署,像RedHat 或者CentOS下的/var/www/html路径。这有助于对系统进行有效的权限管理、备份、配置、监控以及其他操作。

Web 服务器的日志应该存放在/var/logs或者/var/logs/app_name下,而不应该位于主代码区域。这样做的原因不仅仅是因为这些标准的路径很重要,更应该关注的是,恰当地配置服务器会将/var配置为分离的文件系统。如果应用程序突然写入了大量日志并占用所有磁盘空间,由于我们做了以上的配置就不会导致系统崩溃,或者其他严重的问题。如果日志位于其他位置,就可能会产生问题。【分区真的很重要,不管是因为网站还是因为日志,单独的分区真的很有用,哪怕是重装系统还不会影响这个分区】

4、总是使用日志

在Web系统中做多少日志都不为过。所有系统都应该将重要的数据写入到日志中,不管是它们自己的日志还是系统的Syslog。Cron的Job以及其他Shell脚本或者C语言的程序,对日志都有相应标准以及简单的函数。在Shell脚本中,只需要使用 Logger命令就可以实现日志的写入。在脚本启动/停止、重要的脚本执行以及实时数据产生的情况下都要执行写入日志操作。这样出现问题的时候,查看主要的系统日志就可以很容易地看到发生了什么。

大型系统经常会使用专门的工具如 Local5来记录日志,并配置Syslog或者Syslog-ng来将其存放在单独的文件中,这样会更容易使用。需要注意的是,Syslog工具和 Logger(以及任何Syslog调用)默认优先使用user.notice,如有必要,你可以对其进行调整。

一个好的系统会对程序进行配置,用来打开或者关闭日志,并可以选择在每模块或者功能的级别上应用不同级别的日志。这使得我们可以记录非常详细和强大的日志,用来分析和调试在生产操作中所发生的问题。【日志这玩意让人爱让人恨,爱是因为他可以让我们查出很多潜在问题,恨是因为,访问量过大的网站LOG几天就可以把磁盘撑满】

highlightsearchkeywords.rar
大型高性能网站的十项规则


5、使用良好的数据库设计和SQL

在任何系统中,数据库通常是最大的性能瓶颈。而影响数据库性能的最大两个问题是数据库设计和SQL代码质量。很多系统都拥有良好的或者至少是可用的数据库设计,但由于没有经过适当的性能测试,SQL代码质量通常都会很差。这样的SQL代码在开发环境中可能运行很快,因为其中只有小数据集和最小的负载。但是当成千上万的用户同时读取数据库中上百万条记录的时候,它就很可能会崩溃。

不幸的是,这些问题一开始并不明显,直到系统增大、突然开始崩溃的时候才会显现出来。在增大的过程中,数据库系统看起来运行得很快(因为数据都位于内存中,而且很少有并发的查询),并且对用户的响应也很快,但实际上它的内部运行效率很低。这并不重要,我们关注的是在系统增大并遇到性能问题之前找到这些问题并加以解决。

关于这个问题有很多不错的书和站点进行了解析,其中的关键工具包括慢查询日志、INNODB状态系统,以及描述当前性能的MySQL统计信息。我们见到过很多系统每秒会读取500,000条数据,这是出现SQL问题的明显预兆,但公司往往对其一无所知直到服务器开始崩溃。

MySQL系统应该对所有数据使用 INNODB存储引擎,因为INNODB与之前的MyISAM相比,运行得更快、更稳定,并且管理性能和备份工作也更加容易和快捷。在主配置文件中,INNODB应该被设置为默认的数据库引擎,并且系统应该不时地进行检查,看是否意外创建了MyISAM的表。【这点好象和很多人的想法是相反的吧?很多人都认为应该是创建MYISAM表,而不是INNODB,妖了。。。】

6、总要拥有良好的DB配置和备份

很多公司都没有良好的备份机制,也不知道如何恰当地完成这项工作。MySQL的Dump是不够的,因为最好的备份方法是使用LVM快照和INNODB对系统进行热备份,从而得到超快的速度和超高的可靠性。

另外,在将所有备份文件从服务器上转移出来之前要进行压缩和加密。另外还要确保拥有设计合理的MySQL配置。MySQL默认安装使用说明中只有5~10行关于配置的说明,这根本不适合开发使用。而我们提供给客户的最佳实践文档足足有10页那么长。文档中大约有100种有用的关于安全、性能和稳定性问题的设定,包括防止数据败坏,其中很多设定都是非常重要的。【很验难配,真的,想配置的好真的很难】

7、使用读/写数据库分离

随着系统变得越来越庞大,特别是当它们拥有很差的SQL时,一台数据库服务器通常不足以处理负载。但是多个数据库意味着重复,除非你对数据进行了分离。更一般地,这意味着建立主/从副本系统,其中程序会对主库编写所有的Update、Insert和Delete变更语句,而所有Select的数据都读取自从数据库(或者多个从数据库)。

尽管概念上很简单,但是想要合理、精确地实现并不容易,这可能需要大量的代码工作。因此,即便在开始时使用同一台数据库服务器,也要尽早计划在PHP中使用分离的DB连接来进行读写操作。如果正确地完成该项工作,那么系统就可以扩展到2台、3台甚至12台服务器,并具备高可用性和稳定性。【我不知道这篇文章是几年前的,我相信,目前所谓的读写分离好象用的不多了,更多的会采用前置处理,然后由数据库自动分发,以及采用更好的缓存功能。读写其实并不能增强多少性能。当然如果是电子商务网站,或许可以。但对于PHP来说,真的没多大意义 ,因为PHP没有连接池功能,读和写发生交互的时候,相当于连接了两个数据库,还不能互相同时使用】

8、使用类似Memcached之类的数据库缓存


即便有了好的数据库设计、SQL和读写分离,大型的系统仍然需要更快的性能,特别是对会话状态、好友列表以及BBS文字之类的东西。为了达到这个目的,我们可以使用像MemCached之类的数据缓存,它是一个高性能的简单数据缓存,已经被所有最大型的站点使用。但是要小心的是,不要100%依赖于一台Memcache服务器来提高性能,因为如果那台服务器崩溃了,就会破坏整个系统的性能。在这种情况下,应该使用2~3台Memcache服务器形成簇集架构,并且有选择地包含一个缓存准备过程,如果缓存服务器重启,需要重新载入数据,它能够快速地载入缓存。【推荐】

9、构建测试和开发环境

很多公司只有开发者的桌面系统和他们的生产服务器。当系统变得越来越大、越来越复杂时,测试和管理代码就会导致严重的问题。最佳的实践是拥有两个测试系统,一个用于开发者的代码和功能的整合测试,另一个要与生产环境完全一致,从而更容易向生产环境平滑地过渡。幸运的是,现在使用云计算(或者私有云)可以轻松达到这一点。一个5~10台服务器的生产环境,可以很容易地在办公室或者IDC中使用一台服务器来复制,从而用于测试,而这台服务器我们可以用于多个客户的项目。【正如文章开头所说的,哪有空来做这事啊。。。】

10、使用版本控制

最后,要对一切使用版本控制,包括测试和生产环境的部署。很多开发者都使用SVN或者类似的方法。在理想状态下,这些方法可以被用于所有代码、脚本、HTML、图片、配置、文档和测试。版本控制应该是代码转移到测试环境的必经之路,而不是简单地复制或者使用tar文件,因为这二者都是不可靠的。开发者应该将所有一切都签入,打上标签,然后将它们签出到测试系统。如果所有都没问题,那么它们会将该版本签出到生产环境。【多人开发的时候非常有必要。从最初CVS到SVN到现在的GIT,经历了很多了,好象linus推荐是采用GIT,好象是可以直接在本地就可以创建版本库】

总 结:
不管是在开发还是在运营过程中,创建可靠的 高性能Web系统都有很多应该注意的事项。本文试图从可操作性和可靠性的角度讨论最重要的几点。当你构建和管理站点的时候,请不要忘了这些重要的问题。遵 循这些规则会有助于确保系统长久、良好地运行。

作者简介:
Steve Mushero,ChinaNetCloud 公司联合创始人、CEO兼CTO,拥有全球20多年的技术管理经验。曾担任土豆网、Intermind和 Advanced Management Systems等多家企业CTO

译者简介:
侯伯薇,生于凤城,学在春城,做过国内和对 日项目,现在大连某保险公司工作。乐于钻研技术,同时注重业务知识,勤于思考,愿意与人交流和分享。

雅虎JavaScript架构师:网页开发技术安全优先

雅虎JavaScript架构师:网页开发技术安全优先

html5 越来越近了,HTML5可能给我们带来很大的改变,就象新的标签可以支持视频了。看看javascript的架构师能够做什么吧。原文来自http://www.cnbeta.com/articles/109538.htm

由于当前技术仍偏向功能强化为主要思维,指令码趋向庞杂的结果,容易产生更多安全漏洞,且失去快速因应攻击调整架构的灵活性。
身 为JavaScript网路技术重要推手的雅虎(Yahoo!)架构设计师Douglas Crockford表示,现行网页开发技术思维仍偏重多媒体功能或浏览效能的提升,未来应以安全为第一优先。 Crockford 现为Yahoo!资深JavaScript架构师,负责YUI(Yahoo! User Interface)的架构设计,并且担任ECMA JavaScript 2.0技术委员会成员,为JavaScript开发社群大师级人物,此次受邀来台参加OSDC(Open Source Developer's Conference Taiwan)进行专题演讲,向国内开发者介绍ECMA JavaScript的发展。

Crockford向媒体阐述网络技术发展时指出,当前的网络技术仍然不脱过去的思维,网页开发技术仍以功能强化、浏览网页效能提升为主,虽然强 化了网络开发的丰富性,但未将网络安全列为开发优先考虑因素的结果,致使网络安全事件层出不穷。

延续过去网络开发思维的结果,现今网络技 术强调强大的互动、多媒体功能,但也让一些攻击手法兴起,以XSS(Cross-Site Scripting)为例,由于内嵌多个不同来源的脚本,容易让黑客借指令集趁虚而入,窃取用户端计算机的数据。

虽然也有新的技术,如 Google推动的Caja,用以防范XSS跨站攻击手法,但整体技术发展方向仍是朝功能、效能提升前进。

以HTML 5技术为例,Crockford表示,虽然HTML5增加了许多功能,但让整个脚本变得更为庞大且复杂,容易产生漏洞遭到攻击;另外,支持存取使用者电 脑、手机的终端数据,将数据被窃的安全风险扩大至手机上,而过于庞大复杂的结果,不容易因应日新月异的攻击手法改变,长期而言易形成安全风险。

对 于当前浏览器业者形成速度竞赛,纷纷强化JavaScript引擎加速网页浏览速度,号称最快的浏览速度,他认为,浏览器加速网页浏览速度虽是好事,但这 样改善方式有限,只在5至10%的终端浏览器部份加速,若能同时改善服务器端,加速的效果更大。

对于制定中的新标准ECMA Script 5,他乐观预期未来将成为主要的网络开发标准,虽然Apple、Chrome还不明确,但包括IE、FireFox、Opera都倾向ECMA Script 5,今年应会看到新的浏览器应用。
--EOF--
HTML5已经被越来越多的浏览器所支持,IE还能挺多久?是否又会创造出什么新标准?从IE4开始,多少网页设计师为了兼容所有的浏览器而痛苦?以后又会怎么样?IE6还有这么多用户,怎么办?这一些都让人迷惘啊。HTML5来了,对于前端工程师的压力就要更大一点了。代码没写好,很可能就直接被人利用了。以前的XSS漏洞可能会被更加扩大、放大。还是需要多学一点安全了

机器管家

机器管家

一般来说,讲机器人的往往到最后都会讲人机恋,当然那部《我,机器人》(i,robot)不太一样。机器人三守则是不会遗忘的事,被遗忘的嘛,那就是经典的《终结者》了。
《机器管家》这部片子挺老了,但是讲的故事有点感人,讲的是机器人成长的过程,和人的成长差不多,只是遇到的问题不一样。
当机器人越来越想成为人的时候,他不可避免的就是,时间对于他们来说是没有意义的。
内容大致如下:
马丁一家买来一个机器人当管家,可男主人马丁很快发现:这个名叫安德鲁的机器人,不仅有非凡的创造力,甚至还能表达情感。安德鲁一直称男主人的小女儿为 “小小姐”,并和她建立了深厚的感情;几十年过去了,安德鲁已经成为马丁家族的一员,在一个工程师的帮助下,他从内到外一点点的,几乎变成了一个真正的 人,安德鲁还发现自己陷入了爱情-——爱上了“小小姐“的孙女,外貌酷似“小小姐”的波西娅。这段机器人与人的科幻爱情将面临什麽样的考验?

事实上,这种爱情故事现在确实不多见。以前的人机恋都是男主人公恋上个女机器人。再来上一点女机器人为救爱人命怎么怎么样,偶尔有一部女主人爱上男机器人的确实很少。而且,确实可以算是跨度为二百年,爱上小小姐,爱上小小姐的孙女,并为之赴死。遗憾的是,直到最后也没有看到法庭宣判他可以成为人这个消息。他一直是想成为人,可到死也没有看到这个消息。其实他也算是想给自己的老婆一个名份吧。不想她有内疚?最后的护士机器人也不错,也有了人形了,是不是在暗示那位医生也会尝试和护士一起生活?

情节有点老套,但内容 和表演确实不错

在非IE浏览器中实现“灰阶化[1]”

在非IE浏览器中实现“灰阶化[1]”

原文:http://james.padolsey.com/javascript/grayscaling-in-non-ie-browsers/

在非IE浏览器中实现“灰阶化[1]”

这个问题看似简单,实际上要付出很大的努力[2]。要的结果很简单:在所有非IE浏览器中模拟Internet Explorer浏览器的grayscale(灰度)滤镜。然而,它的解决方法并非你想得那么简单,这也让我着实大大地吃了一惊。

在 IE中,grayscale滤镜可以应用到任意一个元素中,它会很直观地将元素转变为灰度。可以使用下面 这行复杂且专有的CSS来实现grayscale滤镜。

elem.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)';

如上所示,在IE中实现这种效果简单是小菜一碟;然而,在其他的浏览器中,需要引起很大的关注。

需要有两件情况值得考虑:图片元素和非图片元素。“非图片”类元素实现十分简单:在当前文档中遍历每个元素,寻找类似“backgroundColor”和 “color”的色彩属性,将它的RGB颜色值转换为灰度值。有不少方法可以实现;注意我们这里不是说降低图片的饱和度;“灰阶化”很明显跟它不一样。

// Desaturate:降低饱和度
function RGBtoDesat(r,g,b) {
var average = (r + g + b) / 3;
return {
r: average,
g: average,
b: average
};
}

// Grayscale:灰阶化
function RGBtoGrayscale(r,g,b) {
var mono = parseInt( (0.2125 * r) + (0.7154 * g) + (0.0721 * b), 10 );
return {
r: mono,
g: mono,
b: mono
};
}

因此,每个带颜色属性的元素要使用它来转为灰阶;初始颜色用来重置属性值。

我们的图片能否转为灰阶取决于两个因素;一是浏览器必须要支持HTML5 canvas元素和它getImageData方法,二是主机上的所有图片必须位于同一域名下;除此外,主机上的图片不能脱离getImageData方法而不管它是否支持[3]。Google Chrome浏览器和Safari(4以下版本)由于不支持getImageData,先不作讨论。其他的浏览器支持canvas元素,完全可以做到“灰阶化”图片。

实现这种方式是要“手工”遍历图片中的每一像素,并应用我们用来设置CSS 颜色属性的RGBtoGrayscale函数。真要这样做的话,浏览器绝对吃不消;除非有极其快速的Javascript引擎来承受大图片处理的压力。

鉴于上面提到的原因,因此在任一个元素需要“灰阶化”前,添加一个“预置”函数去运行显得尤为必要,这个函数可以使用零超时递归技术[4]来避免耗死浏览器。如果仅仅是小图片需要转换的话,不必使用“预置”函数,可以直接使用这种暴力转换。

为什么呢,这是为什么呢?

你肯定想知道在“灰阶化”会有哪些应用。那么,比如说:降低色彩以减少用户的视觉焦点,以此来减少用户对你网站上五颜六色东西的关注;比如说,光箱特效。像 vBulletin的论坛系统就使用了这种效果,它会你点击离开时,将页面变灰;然后会弹出确认框,这个确认框非很容易识别,因为它是页面中惟一的带色彩的东西。

“灰阶化”困扰我的真实原因是因为我很想知道是否有可能做到这个目的。我已经知道在IE浏览器里有这个滤镜,我还想看看在其他浏览器中能否模拟实现这种方便的特效。我也知道这种特效可能被认为已经过时了,但这并不重要;我仅仅是对实现它很感兴趣。

示例

我做了一个示例页面,上面有几个格斗士[5]的图片,功能已经在这篇文章中说过了。注意,在Safari(小于4)或才 Chrome(还有可能在Firefox老版本(V.2以前))不起作用;不要忘了它仅仅是一个试验。
http://james.padolsey.com/demos/grayscale/

使用方法

要对一个元素实现“灰阶化”需要调用 grayscale()函数,并将元素作为参数传递,比如:
var el = document.getElementById( 'myEl' );
grayscale( el );
// 也可以传递一个DOM集合
// (这样所有的元素都会得到“灰度效果”)
grayscale( document.getElementsByTagName('div') );
//也可以在jQuery对象集合中使用
grayscale( $('div') );
若要重置元素(返回到原来的颜色状态)必须调用grayscale.reset(),并将需要重置的元素作为参数传递:
grayscale.reset( el );
// reset()同样可以接受DOM对象或jQuery对象集合参数
grayscale.reset( $('div') );
其中的prepare函数,上面已经讲过了,在有大图片要处理的情况下需要使用到,或者即使只是几个小图片。注意大图片需要有一会儿的时间去处理(一张 300×300的PNG格式图片在“预置”方式下需要耗费3秒钟的时间)。
grayscale.prepare( document.getElementById('myEl') );
// 同样可以接受DOM对象或jQuery对象集合参数
grayscale.prepare( $('.gall_img') );

[完]

注:

[1]:灰阶化:原文grayscaling,意为“采取灰度标准”,即灰阶化,将图片由彩色转为灰度;
[2]原文为”This started out as a little experiment and eventually turned into quite an endeavor.“,可能存在翻译问题;
[3]原文为“externally hosted images cannot be passed into ‘getImageData’ regardless of whether it’s supported.”,翻译存疑;
[4]零超时递归技术:原文zero-timeout recursion technique,应为zero-time recursive technique;参见http://en.wikipedia.org/wiki/Recursion_(computer_science);
[5]格斗士:原文blood-thirsty hunters,嗜血的猎人

--EOF--
灰阶化可以用在414或者512,值得用用喽。。。

 

KESO:Google一次的能耗

KESO:Google一次的能耗

好象这次KESO的《Google一次的能耗》引起了很多人的关注,特别是在QQ微勃上面,有人的转贴就是:不知道http://url.cn/0k4vVU消耗多少,硬件软件有重新设计过吗?|| 腾讯科技 keso炮轰人民网

KESO的原文不长,我这里稍转一下,三言二拍:Google一次的能耗:

人民网上有一篇文章,说每次Google搜索的能耗,相当于100瓦灯泡工作一小时。其中充斥着大量的错误,既有原文的错误(原文在此),也有翻译的错误。

比如,翻译中说,“谷歌数据中心拥有近100万台服务器,每台服务器每小时消耗大约1000瓦的电量”。瓦特是功率,不是电量,电量我们一般用度 (千瓦时)来表示。再比如,“这个搜索引擎每小时产生近1000万个搜索结果”,实际上,早在2001年,Google每天的搜索请求量就超过了1亿次, 今天这 一数字早已超过10亿次(Twitter的日查询次数,包括各种客户端的请求,都高达6亿次)。

上面是明显的错误,其他错误还包括,按每台服务器功耗1000瓦的标准计算Google服务器的能耗,也是相当不靠谱的。普通PC服务器的功耗,一般在400-500瓦。Google的服务器、机房、电源、甚至冷却系统,都是自己设计生产的,按照Google公开的数据,Google服务器的电能转换效率是业界最高的。

而且,把全部服务器的能耗,平均到每次查询上,也非常不靠谱。Google每天要存储20PB的UGC数据(相当于20,000TB,或者 20,000,000GB),假设每块硬盘的容量是1TB(1000GB),那么用户每天产生的内容要写满2万块硬盘。在Google庞大的数据中心中, 有大量服务器实际上是存储服务器。

按照Google自己的计算,一次搜索查询的能耗,大约只相当于0.0003度(千瓦时),或者1千焦(1千瓦时=3600千焦),如果是100瓦的灯泡,这些能量只能点亮11秒钟。

写到这里,我觉得这种计算其实挺无聊的。Google当然会想尽办法节省能源,毕竟它的百万规模的服务器数量,在节能上哪怕非常微不足道的一点小进步,都意味着巨大的资金节省。能源账到底该怎么算,恐怕不是个简单的算术题。

节能是必要的,也是可能的,但搜索技术带来的巨大的社会进步和其他损耗的减少,是在上面的计算中完全看不到的。能源账到底该怎么算,恐怕不是个简单的算术题。

--EOF--

转载的文章嘛。不多点评,不过我是知道国内大多数的机房,其实有很多都在空转着。大量的电力、网络都被IDC消耗掉了。不过想想也很正常,承租机柜后如果没有业务,机柜怎么办?关掉?而且,即使你用的电源低于标准的400W,也没有减少他们应收的费用。更加让人郁闷的是,国内很多大型网站的老总都是这么认为的:能用钱解决的问题就不是问题(比如,服务器、带宽等)。因此,说google的时候,考虑一下自己才是重要的。

国内,好象就听说阿里有自己的机房,不知道他们在缴纳每年的电费时,是否也在考虑着要节约电力?要思考如何改进架构?至于我们这些P民,用着租来的、托管的机器,或许,想的是真的要少一点吧?

重要的不是语言,是思想

重要的不是语言,是思想

标题这种话已经在被很多人所理解,现在大多数开发人员已经不再把语言当成障碍,而是把思想当成障碍,语言的跨度其实真的很容易解决,但思想不进步,你有着再好的语言又怎么样?即使你用的是所谓的自然语言(即平时生活中的语句),但只要你没有思想,没有逻辑,你又能写出什么样的程序?

以下内容来自老王参加的某大会的记录、摘要。我是看中其中的一小部分,觉得有感触。。原文在这里,点击进入:

部分我认为不错的精华,或者说是我关注的。。。

1、课程:失败来临的征兆(讲师:Michael Nvgard)这一切正是Michael Nvgard先生演讲的主旨:意外的问题总是在不经意间发生,要注意把它们的影响限制在局部,避免拖累整个应用。比如说在SOA中集成若干个服务时,应该 设置好各个服务的Timeout,避免其中一个服务崩溃连带整个系统等待。

2、课程:Twitter的可伸缩性数据架构(讲师:Nick Kallen)

Nick Kallen介绍了Twitter在处理海量数据时的经验,其实总结出来就三条:分区,索引,复制。

着重介绍了Tweets,Timelines,Social Graphs,Search Indices四个基本功能的实现:

Tweets比较简单,就是分区,虽然可以使用id或者user_id来分区,不过目前Twitter使用的是按time分区。

Timelines相对复杂了一些,最开始采用的方法是纯SQL的,大致如下:

SELECT * FROM tweets
WHERE user_id IN (SELECT source_id FROM followers WHERE destination_id = ?)
ORDER BY created_at DESC
LIMIT 20
这当然不是一个高效的解决方案,后来采用了被称作离线计算(Offline Computation)的解决方案,其思路大致就是每当发送一条推的时候,采用队列存储避免峰值瓶颈,同时向所有Followers分发此消息,然后每 个分发 终端在缓存中完成合并计算。乍一听起来这似乎也不是什么好的解决方案,一旦某人有非常多的Followers,即便分区,这个分发操作也会非常耗时,但按 Nick Kallen的介绍,Twitter确实是这么做的,细节操作有待研究。

剩下的问题不多说了,Nick Kallen给了PPT地址:http://www.slideshare.net/nkallen/q-con-3770885

3、课程:构建可扩展的微波系统(讲师:杨卫华)

杨卫华作为新浪微博的架构师,这次的PPT做得很酷,虽然在内容上和Twitter有些重复,但还是很不错。

提到了Memcached的evictions问题,给出了三个守则:

1:规划好cache的容量
2:将永久数据和临时性数据分开
3:不使用随机字符串做Key

至于原因,可以参考杨卫华的博客上的介绍:Memcached数据被踢(evictions>0)现象分析

4、课程:敏捷在中国(讲师:Tom Mellor) 编程工期的催促往往让程序员只考虑眼前的既得利益,却忽视了后期的风险。

5、课程:如何在团队中有效实施TDD(讲师:麦天志)在阐述为什么即便工期紧张也应该使用TDD的时候,他给了一个比喻:医生做手术的时间很紧张,但即便 这样,手术前清洗双手的工作程序也是必不可少的。在讲解重构时,他强调了TDD是重构的基础,只有这样才能保证重构没有改变现有的行为,否则就不是重构,而是重写。

例行维护后引起的故障和桔子的缓存故障

例行维护后引起的故障和桔子的缓存故障

最近javaeye发生一起小故障,是robbin自己说的:

@robbinfan: 昨晚JE所在机房切换电源关机导致网站无法访问。早上恢复后因为数据库和缓存服务器都被清空,巨大流量(QPS将近400,并发连接到1000)直接冲击导致web服务被阻塞,现在正在逐步恢复中。

在mikespook.com看到对待这个问题的分析时,突然想起桔子也遇到过类似的问题,所以把他们两个人的事情贴出来。

先上mikespook的:

显然,这是一次运维事故。事故的原因是分流作用的数据库和缓存出现“故障”,导致数据层响应延迟,web 服务器阻塞。这里我没有用“清空”而是用了“故障”来描述分流数据库和缓存,是因为实质上 javaeye 的这次事故虽然是正常维护(电源切换)后发生的,但是其表象跟分流数据库和缓存宕机是一样的。

这个故事给我的两个启示:

在架构设计上,对于分流数据库或者缓存或许应有一定的持久化能力。比如,在维护时,按照从“外”到“内”的顺序逐步关闭服务。在这个例子里,“外” 就是 web服务,“内”就是数据层。在关闭了“外”服务后,手工或自动将缓存持久化。维护完成,开启顺序从“内”到“外”,并在回复完底层存储后,将持久化数据恢复到缓存。

在运维规范上,在维护后应让系统进入一个的磨合期,在合理的时间内通过分流(比如跳转到一个“系统忙”的页面)或者防火墙封锁的方式。让系统保持在比正常负载低一些的水平。持续一段时间(或者维护后累计访问量达到某个值)后再让系统开足马力去运行。

这样,应该可以避免空缓存大并发导致的宕机事故。

再次感谢 robbin 和 javaeye 为我们带来的启示。

再上桔子的,汗,突然发现桔子的博客上居然没有写,看来是上次在群里看到了,大意如下:

某次更新系统,然后需要重启,结果重启后CPU长时间处于100%(?还是死机了?),后来检查发现,原来故障是出在缓存上。
因为是采用文件缓存,而又设定了过期时间,重启后,所有的缓存都过期了。然后网站访问量又大,突然而来的访问导致缓存重新生成,差点让机器出故障。
所以现在开始要调整缓存架构。
其实上面两个问题都差不多。都是在访问大的时候,缓存频繁生成造成的故障,这确实不容忽略,但如何解决真的是一个问题。很多时候在访问量不大时,我们都考虑使用文件来作为缓存存储。但真正访问量高了后,文件缓存不可避免的就带来IO的消耗,如何批量生成缓存?还是按次生成缓存?还是定有一定的策略?难道还要采用队列?那就夸张了。

所以,一个好的系统架构也是很需要的,不能因为一次宕机就永远起不来。我个人是偏向于队列生成缓存,这样就不用担心一次写入过多文件引起IO的崩溃。但队列是因为有延迟的,如果控制同样的内容不重复生成文件缓存,则需要另外考虑

MySQL和SQL字段截短漏洞

MySQL和SQL字段截短漏洞

这篇文章很有意思,以前注意过,但没仔细考虑过用来注入,或许就象王猛说的:

了解很长一段时间的web安全了,个人觉得世上最聪明的程序员其实是黑客,一次想N步,逻辑超强,技术全面,从操作系统漏洞、到语言本身漏洞、数据库本身漏洞、再到开发者代码,无孔不入。

文章来自寂寞hacker,http://hi.baidu.com/isbx/blog/item/08ef48547ef1ad58574e00bf.html:
当前的Web开发者中肯定有不少人没有注意到作者所提到的这两个问题的。

第一个问题是这样的,MySQL默认有一个配置参数 max_packet_size,这个参数是用于限制MySQL客户端和MySQL服务器端数据通信的数据包大小,MySQL的默认配置是1MB。如果客 户端发送的数据超过了1MB,则MySQL服务器端会忽略掉这个请求数据。作者接下来举了两个利用这个缺陷的例子,第一个是利用超长数据来使MySQL的 日志记录程序失效,第二个是在PHP+MySQL的环境下,PHP的Session清理程序会由于一次发送的清理session数据的请求数据包超过 max_packet_size的限制,而导致清理session失败。

而实际上,由于很多PHP+MySQL的程序都会运行用户上传附件之类,而一般的PHP+MySQL的上传附件限制都是大于1MB的,所以PHP的 程序开发人员一般是会去修改max_packet_size的值为大于1MB。这就给我们的漏洞利用带来了一定的麻烦,毕竟在当前的网络状况下,构造 1MB多的数据去上传还是可以忍受的。但是太大的数据量就比较考验我们的耐心了,呵呵。

第二个问题就比较严重了,MySQL对于超过字段长度的数据插入操作会进行默认的字符串截短。例如一个字段定义的长度为10,如果插入的字符串长度 超过10,MySQL会将长度超过10的部分字符串自动舍去后插入到数据表中。默认配置条件下,MySQL会产生一个警告信息,但是这个警告信息不会被 Web应用程序捕获到。所以,从表面上来看,超长数据也是可以“成功”插入数据表的。作者在下面举的这个例子就很有代表性了,首先是一个场景假设:

  • The application is a forum where new users can register
  • The administrator’s name is known e.g. ‘admin’
  • MySQL is used in the default mode
  • There is no application restriction on the length of new user names
  • The database column username is limited to 16 characters

用户如果尝试注册一个用户名为admin的用户,会由于Web应用程序中的isAlreadyRegistered函数的校验而注册失败。

SELECT * FROM user WHERE username='admin'

但如果用户使用用户名’admin x’来注册(注意admin和x之间有11个空格),则注册流程会是这样的:

isAlreadyRegistered函数会使用上面的SQL语句来检查user表中是否存在相同用户名的用户,查询结果肯定是不存在的。那么用户注册成功!

实际上,真正插入到user表中的用户名是’admin’!也就是说,MySQL不仅会截短超过长度限制部分的字符串,也会对字符串头尾的空白字符进行截短!所以,在user表中,现在存在了两个admin用户!

接下来,用户登陆,他使用的是用户名admin,密码是他刚才设置的’admin x’的密码。假设Web应用程序的登陆认证和授权函数是这样的一段代码:

$userdata = null;
if (isPasswordCorrect($username, $password)) {
$userdata = getUserDataByLogin($username);
...
}

其中isPasswordCorrect函数使用的SQL语句为:

SELECT username FROM users WHERE username = ? AND passhash = ?

getUserDataByLogin函数使用的SQL语句为:

SELECT * FROM users WHERE username = ?

可以看得出,上面的语句使用了预编译的SQL语句,是无法实施SQL注入的。但是由于MySQL的默认字段截短策 略,isPasswordCorrect函数会成功执行并返回用户名admin,接下来的getUserDataByLogin也会正确执行,返回的结果 虽然是一个数组,但是Web应用程序一般是取返回数组中的第一个结果,也就是真正的管理员用户admin的所有数据!

怎么样,不用SQL注入,一样拿到管理员权限!

后记:经过测试,上面的漏洞利用过程在MySQL 4中是确实存在并且可以利用的。但是在MySQL 5中,本机测试失败。失败的关键就在于MySQL 5对于超过字段长度限制的字符串插入会报错,并停止字符串插入操作。

附:MySQL 4的测试过程

mysql> select * from tb_sqltest where name='jason';
+----+-------+--------+------+------+------+------+
| id | name | remark | time | col1 | col2 | col3 |
+----+-------+--------+------+------+------+------+
| 1 | jason | NULL | NULL | NULL | NULL | NULL |
+----+-------+--------+------+------+------+------+
1 row in set

mysql> select * from tb_sqltest where name='jason x';
Empty set

mysql> insert into tb_sqltest (id,name) values (2,'jason x');
Query OK, 1 row affected

mysql> select * from tb_sqltest where name='jason';
+----+-------+--------+------+------+------+------+
| id | name | remark | time | col1 | col2 | col3 |
+----+-------+--------+------+------+------+------+
| 1 | jason | NULL | NULL | NULL | NULL | NULL |
| 2 | jason | NULL | NULL | NULL | NULL | NULL |
+----+-------+--------+------+------+------+------+
2 rows in set
apmxe备份

apmxe备份

说实话,看到Qeephp常年不更新后,也担心这个程序会消失。所以,我自己还是备份一下比较好。在以前的博客里我也作过介绍,但都是给的官方地址,而官方地址从fleaphp.net到fleaphp.org,再到现在的qeephp.com,很多链接都失效了。所以,我还是在本地备份一下较好。

这个版本已经又快一年没更新了,不过想来也没有什么好更新的东西。所以。我还是复制了一下官方的介绍:

APM Express 是一个集成了 Apache 2.2、PHP5、MySQL 5,以及 phpMyAdmin、QeePHP 框架(含示例)的绿色集成运行环境,简称为“APMXE”。解压缩即可使用,不写入任何系统文件,100% 绿色。

版本说明

  • Apache 2.2(完整)
  • PHP 5.2.9–2(完整)
  • XCache 2.0.4
  • MySQL 5.0(服务端和命令行工具)
  • phpMyAdmin 3.2
  • QeePHP 2.1(含示例)

使用说明

下载后可以获得一个 .zip 文件,其中包含安装程序。运行安装程序设置好解压缩目录后,即可通过快捷方式启动。启动后,通过浏览器访问 http://localhost/ 查看 APM Express 的欢迎页面。

注意:默认设置的端口号为 9000,MySQL 端口号为 9066。

配置文件修改说明:
配置文件共有三个:
httpd.conf.tempalte - Apache2 的配置文件
mysql.ini.template - MySQL5 的配置文件
php.ini.template - PHP5 的配置文件


修改这三个文件后,启动 APM Express 时就会以这三个文件为基础生成 apache/mysql/php 的配置文件。所以要自定义设置,就改这三个文件。


配置文件模版

配置文件中所有 %APMXE% 的字符串将会在 APM Express 运行时替换为 apmxe.exe 所在路径。替换后的内容会写入三个新的配置文件,供 Apache/PHP/MySQL 使用。

两个下载地址:

说 明: apmxe-setup-2009-06-17.zip
官 方: apmxe-setup-2009-06-17.zip (11130.92 KB, 上传日期:2009-06-17 22:58)
本 地: apmxe-setup-2009-06-17.zip (11130.92 KB, 上传日期:2010-04-24 12:00)分流

说 明: apmxe-2009-01-20.zip
官 方: apmxe-2009-01-20.zip (7646.35 KB, 上传日期:2009-01-20 07:48)
本 地:apmxe-2009-01-20.zip (7646.35 KB, 上传日期:2010-04-24 12:00)分流