存档

2011年1月 的存档

百万级访问量网站的技术准备工作

2011年1月28日 1 条评论

百万级访问量网站的技术准备工作
作者 刘志一 发布于 2010年12月22日 上午12时0分

社区运维,架构 主题NoSQL , 互联网 标签文件I/O , 框架 , 数据存储 , 数据库
分享  | 当今从纯网站技术上来说,因为开源模式的发展,现在建一个小网站已经很简单也很便宜,所以很多人都把创业方向定位在互联网应用。这些人里大多数不是很懂技术,或者不是那么精通,而网站开发维护方面的知识又很分散,学习成本太高,所以这篇文章将这些知识点结合起来,系统的来说,一个从日几千访问的小小网站,到日访问一两百万的小网站,中间可能会产生什么问题,以及怎么才能在一开始做足工作尽量避免这些问题。

你的网站因为努力经营,访问量逐渐升高,在升高的过程中,问题也可能开始显现了。因为带宽的增加、硬件的扩展、人员的扩张所带来的成本提高是显而易见的,而还有相当大的一部分成本是因为代码重构、架构重构,甚至底层开发语言更换引起的,最坏的情况就是数据丢失,所有努力付之一炬。这类成本支出大多数在一开始就可以避免,先打好基础,往后可以省很多精力,少操很多心。

对于不同的初期投资成本,技术路线的选择是不同的。这里假设网站刚刚只是一个构想,计划第一年服务器硬件带宽投入5万左右。对于这个资金额度,有很多种方案可选择,例如租用虚拟主机、租用单独服务器,或者流行的私有云,或者托管服务器。前两种选择,网站发展到一定规模时需迁移,那时再重做规划显然影响更大。服务器托管因为配置自主、能完全掌握控制权,所以有一定规模的网站基本都是这种模式。采用自己托管服务器的网站,一开始要注意以下几点——

一、开发语言
一般来说,技术人员(程序员)都是根据自己技术背景选择自己最熟悉的语言,不过不可能永远是一个人写程序,所以在语言的选择上还要是要费些心思。首先明确一点,无论用什么语言,最终代码质量是看管理,因此我们从前期开发成本分析。现在国内流行的适用于网站的语言,大概有java、php、.net、python、ruby这五大阵营。python和ruby因为在国内流行的比较晚,现在人员还是相对难招一些。.net平台的人相对多,但是到后期需要解决性能问题时,对人员技能的要求比较高。剩余的java、php用人可以说是最多的。java和php无法从语言层面做比较,但对于初期,应用几乎都是靠前端支撑的网站来说,php入门简单、编写快速,优势相对大一点。至于后端例如行为分析、银行接口、异步消息处理等,等真正需要时,就要根据不同业务需求来选择不同语言了。

二、代码版本管理
稍微有点规模的网站就需要使用代码版本管理了。代码版本管理两点最大的好处,一是方便协同工作,二是有历史记录可查询比较。代码版本管理软件有很多,vss/cvs/svn/hg等,目前国内都比较流行,其中svn的普及度还是很高的。

假设选了svn,那么有几点考虑。一是采用什么树结构。初期可能只有一条主干,往后就需要建立分支,例如一条开发分支,一条上线分支,再往后,可能要每个小组一个分支。建议一开始人少时选择两条分支,开发和线上,每个功能本地测试无误后提交到开发分支,最后统一测试,可以上线时合并到上线分支。如果每人都建自己的分支,合并时会浪费很大精力,对于几乎每天都要修改几次的WEB应用来说,所费时间太多。

向服务器部署代码,可以手工部署也可以自动部署。手工部署相对简单,一般可直接在服务器上svn update,或者找个新目录svn checkout,再把web root给ln -s过去。应用越复杂,部署越复杂,没有什么统一标准,只是别再用ftp上传那种形式,一是上传时文件引用不一致错误率增加,二是很容易出现开发人员的版本跟线上版本不一致,导致本来想改个错字结果变成回滚。如果有多台服务器还是建议自动部署,更换代码的机器从当前服务池中临时撤出,更新完毕后再重新加入。

三、服务器硬件
在各个机房里,靠一台服务器孤独支撑的网站数不清,但如果资金稍微充足,建议至少三台的标准配置,分别用作web处理、数据库、备份。web服务器至少要8G内存,双sata raid1,如果经济稍微宽松,或静态文件或图片多,则15k sas raid10。数据库至少16G内存,15k sas raid 10。备份服务器最好跟数据库服务器同等配置。硬件可以上整套品牌,也可以兼容机,也可以半品牌半组装,取决于经济能力。当然,这是典型的搭配,有些类型应用的性能瓶颈首先出现在web上,那种情况就要单独分析了。

web服务器可以既跑程序又当内存缓存,数据库服务器则只跑主数据库(假如是MySQL的话),备份服务器所承担就相对多一些,web配置、缓存配置、数据库配置都要跟前两台一致,这样WEB和数据库任意一台出问题,很容易就可以将备份服务器切换过去临时顶替,直到解决完问题。要注意,硬件是随时可能坏掉的,特别是硬盘,所以宁可WEB服务器跟数据库服务器放在一起,也一定不能省掉备份,备份一定要异机,并且有异步,电力故障、误操作都可能导致一台机器上的所有数据丢失。很多的开源备份方案可选择,最简单的就是rsync,写crontab里,定时同步。备份和切换,建议多做测试,选最安全最适合业务的,并且尽可能异地备份。

四、机房
三种机房尽量不要选:联通访问特别慢的电信机房、电信访问特别慢的联通机房、电信联通访问特别慢的移动或铁通机房。机房要尽可能多的实地参观,多测试,找个网络质量好,管理严格的机房。机房可以说是非常重要,直接关系到网站访问速度,网站访问速度直接关系到用户体验,访问速度很慢的网站,很难获得用户青睐。

五、架构
在大方向上,被熟知的架构是web负载均衡+数据库主从+缓存+分布式存储+队列。在一开始,按照可扩展的原则设计和编程就可以。只是要多考虑缓存失效时的雪崩效应、主从同步的数据一致性和时间差、队列的稳定性和失败后的重试策略、文件存储的效率和备份方式等等意外情况。缓存失效、数据库复制中断、队列写入错误、电源损坏,在实际运维中经常发生,如果不注意这些,出现问题时恢复期可能会超出预期很长时间。

六、服务器软件
操作系统Linux很流行。在没有专业运维人员的情况下,应倾向于择使用的人多、社区活跃、配置方便、升级方便的发行版,例如RH系列、debian、ubuntu server等,硬件和操作系统要一起选择,看是否有适合的驱动,如果确定用某种商业软件或解决方案,也要提前知晓其对哪种操作系统支持最佳。web服务器方面,apache、nginx、lighttpd三大系列中,apache占有量还是最大,但是想把性能调教好还是需要很专业的,nginx和lighttpd在不需要太多调整的情况下可以达到一个比较不错的性能。无论选择什么软件,除非改过这些软件或你的程序真的不兼容新版本,否则尽量版本越新越好,版本新,意味着新特性增多、BUG减少、性能增加。一个典型的php网站,基本上大多数人都没改过任何服务器软件源代码,绝大多数情况是能平稳的升级到新版本的。类似于jdk5到 jdk6,python2到python3这类变动比较大的升级还是比较少见的。看看ChangeLog,看看升级说明,结合自己情况评估测试一下,越早升级越好,升级的越晚,所花费的成本越高。对于软件包,尽量使用发行版内置的包管理工具,没有特殊要求时不建议自己编译,那样对将来运维不利。

七、数据库
几乎所有操作最后都要落到数据库身上,它又最难扩展(存储也挺难)。数据库常见的扩展方法有复制、分片,设计时要考虑到每种应用的数据如何复制、分片,当然这种考虑一般会推迟到技术设计时期。在初期进行数据库结构设计时,要根据不同的业务类型和增长量预期来考虑是否要分库、分区,并且尽量不要使用联合查询、不使用自增ID以方便分片。复制延时问题、主从数据库数据一致性问题,可以自己写或者用已有的运维工具进行检测。

用存储过程是比较难扩展的,这种情形多发生于传统C/S,特别是OA系统转换过来的开发人员。低成本网站不是一两台小型机跑一个数据库处理所有业务的模式,是机海作战。方便水平扩展比那点预分析时间和网络传输流量要重要的多的多。

另外,现在流行一种概念叫NoSQL,可以理解为非传统关系型数据库。实际应用中,网站有着越来越多的密集写操作、上亿的简单关系数据读取、热备等,这都不是传统关系数据库所擅长的,于是就产生了很多非关系型数据库,比如Redis/TC&TT/MongoDB/Memcachedb等,在测试中,这些几乎都达到了每秒至少一万次的写操作,内存型的甚至5万以上。在设计时,可根据业务特点和性能要求来选择是否使用这类数据库。例如MongoDB,几句配置就可以组建一个复制+自动分片+failover的环境,文档化的存储也简化了传统设计库结构再开发的模式。但是当你决定采用一项技术时,一定要真正了解其优劣,例如可能你所选择的技术并不能支持你所需要的事务和数据一致性要求。

八、文件存储
存储的分布几乎跟数据库扩展一样困难,不过只有百万的PV的情况下,磁盘IO方面一般不会成大问题,一两台采用SATA做条带RAID的机器可以应付,反而是自己做异步备份比较复杂,因为小文件多。如果只有一台机器做存储,可以做简单的优化,例如放最小缩略图的分区和放中等缩略图的分区,根据平均大小调整一下块大小。存储要规划好目录结构,否则文件增多后维护起来复杂,也不利于扩展。同时还要考虑将来扩容,例如采用LVM,或者把文件根据不同规则散列到不同机器。磁盘IO繁重的情况下更容易出现故障,所以要做好备份,若发现有盘坏掉,要马上行动更换,很多人的硬盘都是坏了一块之后,接二连三的坏下去。

为了将来图片走cdn做准备,一开始最好就将图片的域名分开,且不用主域名。因为很多网站都将cookie设置到了.domain.ltd,如果图片也在这个域名下,很可能因为cookie而造成缓存失效,并且占多余流量,还可能因为浏览器并发线程限制造成访问缓慢。

九、程序
一定硬件条件下,应用能承载多少访问量,很大一部分也取决于程序如何写。程序写的不好,可能一万的访问都承载不了,写的好,可能一两台机器就能承担几百万PV。越是复杂、数据实时性要求越高的应用,优化起来越难,但对普通网站有一个统一的思路,就是尽量向前端优化、减少数据库操作、减少磁盘IO。向前端优化指的是,在不影响功能和体验的情况下,能在浏览器执行的不要在服务端执行,能在缓存服务器上直接返回的不要到应用服务器,程序能直接取得的结果不要到外部取得,本机内能取得的数据不要到远程取,内存能取到的不要到磁盘取,缓存中有的不要去数据库查询。减少数据库操作指减少更新次数、缓存结果减少查询次数、将数据库执行的操作尽可能的让你的程序完成(例如join查询),减少磁盘IO指尽量不使用文件系统作为缓存、减少读写文件次数等。程序优化永远要优化慢的部分,换语法是无法“优化”的。

然而编程时不应该把重点放在优化上,应该关注扩展性。当今的WEB应用,需求变化非常之快,适应多种需求的架构是不存在的,我们的扩展性就要把要点放在跟底层交互的架构上,例如持久化数据的存取规则、缓存的存取规则等,还有一些共用服务,例如用户信息等。先把不变的部分做完善,剩下的部分就很容易将精力放在业务逻辑上面了。

关于作者

刘志一,从1999年做个人网站开始一直专注于互联网,目前就职于一家垂直行业C2C网站,做产品和开发方面工作。新浪微博:http://t.sina.com.cn/liuzhiyi

分类: linux 标签: , ,

服务器端编程的十大性能问题

2011年1月28日 没有评论

服务器端编程的十大性能问题

服务器端编程的十大性能问题
作者 张龙 发布于 2010年8月27日 上午12时59分

社区.NET,Java主题性能和可伸缩性 标签性能评估 , 性能和扩展性 , 性能调优
分享  | 今年5月底,瑞士计算机世界杂志上刊登了Web性能诊断专家Bernd Greifeneder的一篇文章,文章列举了其在过去几年工作中所遇到的服务器端编程的十大性能问题。Andreas Grabner则在自己的博客上对这些性能问题给出了进一步阅读的链接。希望这些问题与相关的延伸阅读能为广大的InfoQ读者带来一定的启示。

问题一:过多的数据库调用

我们发现经常出现的一个问题就是在每次请求/事务中存在过多的数据库查询。有如下三个场景作为佐证:

•在一次事务上下文中所请求的数据比实际需要的数据多出很多。比如说:请求所有的账户信息而不是仅仅查询出当前需要显示的信息。
•多次请求同样的数据。这种情况通常发生在相同事务中的不同组件之间是彼此独立的,而每个组件都会请求同样的数据。我们并不清楚当前上下文中已经加载了哪些数据,最后只得多次发出同样的查询。
•发出多个查询语句以获得某一数据集。通常这是由于没有充分利用到复杂的SQL语句、存储过程等在一次批处理中获取需要的数据所导致的。
延伸阅读:Blog on Linq2Sql Performance Issues on Database、Video on Performance Anti-Patterns

问题二:过多地使用同步

毫无疑问,同步对于应用中共享数据的保护来说是至关重要的举措。但有很多开发者却过度使用同步,比如在超大段的代码中使用同步。在低负载的情况下,这么做倒没什么问题;但在高负载或是产品环境下,过度的同步会导致严重的性能与可伸缩性问题。

延伸阅读: How to identify synchronization problems under load

问题三:过度使用远程调用

很多库都使用了远程通信。对于开发者来说,远程调用与本地调用似乎没什么区别,但如果不清楚远程调用的本质就会铸成大错,因为每一次远程调用都会涉及到延迟、序列化、网络堵塞以及内存使用等问题。如果没有经过深思熟虑而盲目使用这些远程技术就会导致严重的性能与可伸缩性问题。

延伸阅读: Performance Considerations in Distributed Applications

问题四:错误地使用对象关系映射

对象关系映射为开发者解决了很多负担,比如从数据库中加载对象以及将对象持久化到数据库中。但与其他任何框架一样,对象关系映射也有很多配置选项需要优化,只有这样才能适应于当前应用的需要。错误的配置与不正确的使用都会导致始料不及的性能问题。在使用对象关系映射框架前,请务必保证熟悉所有的配置,如果有机会,请深入到所用框架的内核,这样使用起来才有保障。

延伸阅读:Understanding Hibernate Session Cache、Understanding the Query Cache、Understanding the Second Level Cache

问题五:内存泄漏

托管的运行时环境(如Java和.NET)可以通过垃圾收集器进行内存管理。但垃圾收集器无法避免内存泄漏问题。“被遗忘”的对象依旧会占据着内存,最终将会导致内存泄漏问题。当对象不再需要时,请尽快释放掉对象引用。

延伸阅读:Understanding and finding Memory Leaks

问题六:使用有问题的第三方代码/组件

没有人会从头编写应用的全部功能。我们都会使用第三方程序库来加快开发进程。这么做不仅会加速产出,也增加了性能上的风险。虽然大多数框架都具有良好的文档并且经过了充分的测试,但没人能够保证这些框架在任何时候都会像预期的那样好。因此,在使用这些第三方框架时,事先一定要做好充分的调研。

延伸阅读: Top SharePoint Performance Mistakes

问题七:对稀缺资源的使用存在浪费的情况

内存、CPU、I/O以及数据库等资源属于稀缺资源。在使用这些资源时如果存在浪费的情况就会造成严重的性能与可伸缩性问题。比如说,有人会长时间打开数据库连接而不关闭。连接应该只在需要的时候才使用,使用完毕后就应该放回到连接池中。我们经常看到有人在请求一开始就去获取连接,直到最后才释放,这么做会导致性能瓶颈。

延伸阅读: Resource Leak detection in .NET Applications

问题八:膨胀的Web前端

由于现在的Web速度越来越快,用户的网络体验也越来越好。在这个趋势下,很多应用的前端都提供了太多的内容,但这么做会导致差劲的浏览体验。很多图片都太大了,没有利用好或是错误地使用了浏览器缓存、过度地使用JavaScript/AJAX等,所有这一切都会导致浏览器的性能问题。

延伸阅读: How Better Caching would help speed up Frankfurt Airport Web Site、Best Practices on Web Performance Optimization

问题九:错误的缓存策略导致过度的垃圾收集

将对象缓存在内存中可以避免每次都向数据库发出请求,这么做可以提升性能。但如果缓存了太多的对象,或是缓存了很多不常使用的对象则会将缓存的这种优势变成劣势,因为这会导致过高的内存使用率及过多的垃圾收集活动。在实现缓存策略前,请想好哪些对象需要缓存,哪些对象不需要缓存,进而避免这类性能与可伸缩性问题。

延伸阅读:Java Memory Problems、Identify GC Bottlenecks in Distributed Applications

问题十:间歇性问题

间歇性问题很难发现。通常这类问题与特定的输入参数有关,或是发生在某个负载条件下。完全的测试覆盖率及负载与性能测试能在这些问题产生前就发现他们。

延伸阅读:Tracing Intermittent Errors by Lucy Monahan from Novell、How to find invisible performance problems

分类: linux 标签: ,

系统运维秘诀:变化,监控,扩展

2011年1月27日 没有评论

为变化而设计

◆Google的秘诀是正确的——“为变化而设计”。“变化”就是不得不部署新的软件,升级现有的软件,进行扩展,设备损坏,以及人员流动等。
◆每一件事情都是在寻找平衡点。你也许会认为把你的系统和某个操作系统或某个Linux发行版牢牢地绑定在一起是一个好主意,但事实上这跟把它们完全隔离一样糟。如果实在有必要,你可以进行分层,并使用一点间接性。
◆这并不意味着你的系统必须是平台无关的。其实我们的目的很简单:一变二,二变二十,一个系统必须可以应对各种突发事件。也就是说,如果一个系统管理员被公共汽车撞了,你有应对的方案!如果挂载的硬盘出现故障了,你有应对的方案!如果某些人运行了rm -rf /,你也有应对的方案!增量的进行变更。记得安全更新,以及保持内容更新。

使用自动的,可重复的构建过程
◆不要手动构建任何东西。如果你一定需要手动构建,那么就做两遍,在做第二遍的时候把用到所有的命令都提取出来。
◆下面这一点十分重要:将新硬件上线到生产环境的过程不应该超过15分钟,而且这个过程必须足够简单。否则,当一个服务器出现故障,而没有人知道如何更换它的时候,你就该倒霉了。
◆下面这一条是普世真理:这个世界上不存在“一次性”的服务器构建。即使你的服务器只需要构建一次,但只要你构建过一次,就一定会有第二次。比如,当它损坏的时候,或者你必须进行一次重大的升级才能让它在在接下来的两年时间里更加稳定的时候。
◆测试,检查新构建好的服务器。这应该是比较容易的,因为你的构建过程都是自动化的,对吧!
◆脚本化的构建,意味着从某个Linux发行版的V3升级到V4应该是很快的。安装
V4,对脚本进行测试。如果有问题,参考文档并修复它,直到它可以再次正常工作。这最多应该是一个星期的工作,而不是一个长达一年的浩大工程(因为那时,刚刚完成的V5已经发布了!)

使用冗余

◆容易重新构建,并不意味着你可以忽视冗余。跳转盒,邮件服务器,计费网关,等等。如果其中的一半挂掉了却并不造成客户的宕机,生活将会变得更加简单。
◆按照以上方针来做的话,当某个设备在凌晨3点出现故障的时候,你可以“以后再处理那个出现故障的设备!”,把冗余的机器先替换上去。
◆下面这一条是个聊胜于无的解决方案:Rsync。DRBD也许也不是一个完美的解决方案,但是它可以提供令人称奇的服务。(参考阅读:DRBD笔记,DRBD实例1,DRBD实例2)

使用备份

◆备份是个严肃的话题。使用硬盘,烧录磁带。压缩它们,移动它们,并行地运行。对每一样东西进行备份!
◆如果你的构建过程是自动的,整个过程都可以被备份。如果到目前为止的几条你都做到了,那么一个真正的“灾难恢复”计划也许并不是那么遥不可及的。
监控正确的东西
◆监控你能监控的所有东西,而且要用正确的方法来进行监控。如果你的NFS服务器挂掉了,不要让你的监控工具发送1000条警报。如果对你的系统来说,超时的警报没有什么实际意义,那就别让它发。要针对各种具体的情况进行成功性测试:是的,这个服务可以进行一个新的TCP连接,它甚至可以响应,但是它还记得它要做什么工作吗?
◆如果你有500个Web服务器,其中一个挂掉了,你可能不必马上知道这个情况。但是,如果负载均衡器没有把这台机子踢出去,导致错误报告出现在了用户的屏幕上,那么你必须知道这个情况!

有关数据图形化,历史数据

◆图形的作用是让趋势可视化。历史数据的作用是让你对数据进行精确的分析。不要把这两者混为一谈!对图形进行目测,很容易获得错误的数值。许多站点都使用rrd类型的系统或其他的数据聚合系统,此类系统按照时间对数据进行平均化处理,然后保存在存储空间中。这不仅仅是难以阅读的问题:这根本是错误的!
◆如果你要浏览数百张图才能精确地对一个问题进行定位,那真是糟透了。想要找出极值?请使用脚本提取数据。
◆如果你必须使用图形来解决问题,尽量把各种高级的概念整合到一个单一的页面中,然后让这个页面链接到拥有具体信息的子页面中。如果你在数据库负载中可以看到一个峰值,你可以点击这个页面对那些数据库进行概览,然后找到那一两台可疑的机器。基本的理念是尽快地缩小范围,尽可能的减少猜测。

日志记录,使用多个数据流

◆无论是独立工作还是与开发部门合作,都要把尽可能多的有用的信息记录到日志中。无论是分析之后再保存,还是直接扔进数据库中生成报告,这些都无所谓。信息终归是有用的。
◆有用的例子:页面呈现时间(哪个页面?哪个设备?),面向用户的错误,数据库和内部服务错误,带宽使用率等。
◆建立图表,报告,并对产生的历史数据进行比较。
◆报告是十分重要的。每周或每天对你的基础设施变更进行汇总。

数据存储方式,数据库

◆诚然,数据库运维是一套完整而独立的知识体系。但是有时,你不能把一切都丢给你的DBA。
◆拥有多个冗余的数据库会给你带来很多好处。对于一个庞大的Oracle实例来说,从前,很多运维工作需要好几个小时的关机维护时间;而现在,完全可以在服务运行的同时进行。MySQL和数据库复制功能是一件奇妙的事情。
◆和DBA们一起努力,尽量为可能会发生问题的数据库争取到最好的硬件。RAID 10,大量的RAM,高速硬盘,乃至于强悍的RAM磁盘和SSD。运维人员对提供商要货比三家,这样可以减轻DBA对硬件的恐惧。从长远来看,找出哪个品牌的硬件更加优秀会节省大量的资金。
◆数据库配置一直在改变。现在出现了HiveDB,MySQL Proxy,DPM这些软件。我们绝对应该对巨大的数据集进行分割。我们也可以考虑一下像starling和Gearman这样具有一定创新性的软件。了解一下这些软件的用途,同时,了解一下并不是一切东西都要保存在一个数据库中的。
◆善用你的过滤器!如果这些数据很重要,应该对它们进行备份!单片的NFS服务器的快照很奇妙,它并不是一个备份!
◆可以虑一下替代的解决方案。MogileFS现在变得越来越好了(参考阅读:分布式文件系统试用比较)。实际上,还有其他类似的项目可以免费(或廉价)地维护大量的存储文件。类似的系统基本上都是是为youtube.com、archive.org等站点而开发的。我们最终会让廉价的NFS过滤器成为标准!

多一些横向扩展,少一些纵向扩展

◆横向扩展是我们应该走的路。应该使用常规的(即:可用的,价格适中的,标准的。而不是特便宜的!)硬件,然后和大家一起努力,确保各方面都可以进行横向扩展。
◆横向扩展从两台机子开始。另外,进行冗余的时候也会涉及到横向扩展。
◆尽可能的横向扩展,但是不要傻乎乎的扩展。在MySQL复制中有一个经典的白痴扩展的例子:使用一个master对很多个slave。所有的slave必须完成全部的写入,而写入次数是与读取次数成比例增加的(大多数应用都是这样)。也就是说,你添加的slave越多,通过添加slave扩展的资源就越少。
◆留意一下替代的解决方案。按照用户或区域对多个数据库进行划分,同时避免增加过多的slave。实际上,有许多种方法可以达到这个目的。
◆一切都可能扩展!路由器,交换机,负载均衡器,Web服务器,数据库,等等。
◆记得纵向扩展吗?以前那些邪恶的大型机们有很多核,很多IO板,配备了非常昂贵的存储设备。而现在,多核这个概念开始蔓延了。
◆RAM是廉价的。

◆将以上两点合并起来,这意味着你只需要再次合并服务就可以了。这儿有一个负载均衡器,那儿有一个Web服务器……如果一个应用程序可以使用许多个CPU(比如apache),那么这是完美的。如果它不能(比如memcached),那么你最终可能会由于离散的服务太多而浪费掉大量的可用资源。
◆作业系统(job systems)也许可以填补这个鸿沟。哪里的核心的越多,哪里的工作线程就越多。

缓存
◆对于开发者和系统运维人员来说,缓存可是个好东西,值得大力发展!的确,它是不可思议的。它是与众不同的。有时你可能必须要为它做一个权衡。有效地使用缓存可以让系统的整体性能提升10倍之多。对于你当前的系统来说,这是一个巨大的“放大镜”,并且,它的成本在总成本中只占很小的一部分。
◆Memcached。它可以为服务提供缓存,让数据库结构非标准化(这可以提升性能!),对squid缓存进行优化,甚至可以提高操作系统缓存的利用率。
◆测试它,玩弄它,并打破它。使用缓存会带来新的问题。要做好准备。

让工作异步化

◆可以使用Starling, Gearman, The Schwartz等工具。作业系统可以给应用程序提供更多的灵活性。工作线程可以一次性地产生出来,也可以是持久的(载入缓存数据,准备数据等)。它们可以在不同的硬件上,它们的地理位置也可以不同。它们既可以是同步的,也可以是异步的。
◆维护这些东西是一个运维人员的问题。使用它们既是开发者的问题也是运维人员的问题。
◆当用户点击“给我所有的朋友发送邮件”的时候,把这个工作列入计划,然后马上说:“OK,已经完成了!你的朋友马上会收到你的邮件!”——通过异步化的方式来处理这个工作。
◆作业系统是衔接各个服务的一个场所。博客投递-〉IM通知,定期计费-〉收费服务,网关认证等。
◆容易扩展。在请求进入的地方会有一些瓶颈,所有的工作线程必须要做的事情就是“拉”。这个是相对于HTTP中大量推/拉的状态而言的。

安全和巡查

◆一定要安装安全更新!这十分重要!有很多疯狂的网络专家致力于在尽可能短的时间内给你提供这些更新。不要因为你害怕改变而让他们白白地付出劳动。
◆安全性也是分层的。明白你能确保什么,以及不能做什么。MySQL有密码访问机制,并不意味着可以允许直接通过互联网来访问它。
◆在SSH上禁用密码。使用经过加密的passphrase密钥来进行身份验证。远程的用户无法猜出你的私有密钥。他们必须从你这里才能得到它。把它保管好。做好这点,就没必要在防火墙中关闭你的SSH端口了。
◆搞清楚你的应用程序是如何工作的,它具体需要做些什么,并相应的进行调整。比如说,如果你的应用当中,只有付费页面和Twitter投递服务是需要连接外部互联网的,那么就把它们做成工作线程。将这部分工作线程放在特定的设备中,让它们只能访问特定的主机。这可以神不知鬼不觉地把你的网络的其余部分保护起来。
◆对于PHP站点来说,以上这些建议尤其重要,但是在其他地方,它们也可以发挥作用。如果有人要入侵,那么多半是通过你的应用。即使有人从前门入侵了系统,也要让他们花费很大精力才能进入保险箱。你需要确保的是他们无法将数据带走或上传至别的什么服务器上。
◆除了这些具体的建议之外,你还应该多读一些资料。自己判断,自己动手测试。如果你不知道一个安全模型是如何工作的,一时半会儿可能问题不大,但是这就会导致你不知道它的限制在哪里,甚至于无法判断它是否在工作。
◆基于测试,理论,攻击树的安全机制是不会在背后给你一刀的。当人们构想出模糊的安全模型的时候我也很喜欢它,但是像我这样的普通人都可以把它弄的支离破碎。
◆尽可能地进行巡查!登录,退出,以及使用的命令都要进行审查。对面向外部服务的所有访问,包括所有在请求中指定的参数,都要进行审查。对于你的应用程序来说,找出极值,然后彻底禁止输入超出范围的值。做你能做的所有事情,让数据以可追溯的方式工作。
◆如果你怀疑某些东西可能会被破坏,应该采取适当的预防措施,最好懂得一点计算机取证方面的知识(或者聘请一个专门从事这项业务的公司)。通过移除可疑的网络访问来做出响应,通过一系列的控制台或直接通过终端来检查整个系统。在已经被破坏的机器上,避免使用任何的服务,配置文件,或数据。很多人都是“清除了一个木马”,但是不知道它是怎么进来的——这样并不算真正地清除了这个木马。
◆如果你有安全团队,取证专家,或其他人手,那么你尽量不要接触那台机器,把它隔离起来。这意味着不要重新启动它来“清除一些奇怪的进程”。他们需要这些证据。如果你必须这么做,就去做吧,但是要记得把系统彻底地清理干净,打上所有的安全更新,尽量搞清楚他们是否已经破坏了重要的数据。做你能做的所有事情。
◆安全实际上是一种权衡。如果你做错了,开发者和用户们都会“揭竿而起”:他们会找到一些方法来绕过安全机制。如果他们可以绕过它,那说明你的工作并没有做好。如果他们不能绕过它,那么他们也许会放弃,然后离开。
◆紧抓访问控制。这意味着运维人员必须要为已经锁上门的“房间”提供一些窗户。不让开发人员进入生产环境,意味着他们必须抹黑解决难题。你的确不能让开发者们直接对服务进行修改,但是你可以提供日志工具和调试工具等等。对于各种产品来说,这些都是成功的秘诀。

原文:Dormando’s [crappy] Operations Mantras

分类: linux 标签: , , ,

网页自动跳转的三种代码

2011年1月24日 没有评论

很多时候我们需要Web页具备有自动跳转功能,例如,论坛中的用户登录、发帖及回复或留言簿中的留言和回复等操作成功后,若用户没有任何鼠标点击操作,过了一定的时间,页面自动跳转到预设的页面。本文讨论网页自动跳转的几种实现方法。

方法一:使用meta标签
meta标签是html不可或缺的标签之一,它负责提供文档的元信息,其参数主要有:

① http-equiv: 与文档中数据相关的HTTP文件首部
② content: 与命名HTTP首部相关的数据
③ name: 文档描述
④ url: 与元信息相联系的URL
当我们定义属性http-equiv为refresh,打开此Web页时系统将根据content规定的值在一定时间内跳转到相应页面,content=”秒数;url=网址”就是定义了过多长时间跳转到指定的网址。以下meta标签告诉系统一秒钟后页面自动跳转:

以上代码需要加在HTTP文档首部中,介于与之间,通常,meta标签是紧跟在之后。若需要有多个meta标签,它们可以各占一行。

此法通用于任何环境,包含静态的网站空间。

方法二:使用header函数
header函数是php内置函数中的HTTP相关函数之一,该函数送出HTTP协议标头到浏览器。使用它可以重定向URL,即令页面转向其他指定的网页。以下例子,执行后将自动打开黑马在线动力首页:

header(“Location: http://daohang.54im.com”);

必须注意,header函数只能用在页面代码中的标签之前,亦即,HTTP首部尚未有其他任何标头()传送给浏览器之前,而且,此前页面也不能print或echo任何内容。换句话说,在页面的出现前,程序只单纯地处理header事件。尽管有如此严格的要求,灵活地使用它,仍然可以达成页面的自动跳转功能,比如登录页面,通过判断用户提交的数据是否合法来决定页面跳转到何处。以下给出一个简单的例子:

<?php

/* 登录程序 – 文件名:login.php
程序作用 – 判断用户登录口令 */

if($_POST[‘Submit’]) {
session_start();
if($_POST[‘pws’]==’123′) { //若密码为 123
$_SESSION[‘passwd’]=’123′; //写入会话数据
header(“Location:index.php”); //跳转到正常页面
}else{
header(“Location:login.php”); //跳转到登录页面
}
}

//表单代码略(也可以用纯html代码写表单,若如此,代码应放在程序之后

?>

<?php

/* 检测会话数据 – 文件名:index.php
程序作用 – 检测会话数据中的密码是否为123,若不是,返回
登录页面 */

session_start();
if($_SESSION[‘passwd’]!=’123′) header(“Location:login.php”);

//其他代码(纯HTML代码应写在程序之后)

?>
此法显然只能用于支持php的空间环境。

方法三:使用JavaScript
JS非常灵活,利用它可以做出功能非常强大的程序脚本,这里仅举一个简单的页面自动跳转的JS例子。以下代码执行后浏览器将自动转到黑马在线动力网站,该代码可放在页面中的任何合法的位置:

<script language=”javascript” type=”text/javascript”>

window.location.href(http://daohang.54im.com);

</script>
此代码适用于任何Web环境。若加入定时器,将更加妙不可言。

分类: webapp 标签: