西门子中国中央研究院首席架构师、图书《架构之美——软件架构的艺术》作者李伟,从架构师的定义和内涵、能力和素质要求、成长途径等方面向您阐述成为一个真正的架构师需要经历的历程。
记者: 您认为具备哪些能力,才算是真正的架构师?
李伟:虽然业界有关什么是“软件架构”有着明确的定义及共识,但是确实没有软件架构师的定义。简单地讲,架构师是一个技术控制的角色。技术控制是从客户或市场开始,一直到交付或服务的整个链条。如果大家对一个应用研发机构或产品研制机构的主要活动熟悉的话,就知道该链条上存在很多需要架构师负责的控制点。以西门子为例,西门子的战略市场部门就会和业务部门的很多架构师进行协作。这主要是由于战略市场部门的职能之一就是对未来十到十五年的技术和创新进行预判。这样的技术预判,如果没有架构师作为技术控制,单凭MBA出身的市场人员,大家能相信这样的技术预判吗?所以架构师需要具备一定程度的技术及创新预判能力。
从一个架构师的日常工作来看,他面对的基本上有七大问题:商业问题、系统问题、子系统问题、构件问题、技术问题、流程问题、项目管理问题。其中,前五项是一个架构师主要负责解决的。这里我尝试提几个问题,让大家检验一下自己是否具备解决这些问题的能力。
如果进行企业应用开发,你知道经典的商业运营手段一般有哪些吗?例如:公司中一般有哪些典型的职能机构?最经典的公司财务部运作是什么样的?最经典的公司纯研究机构的运作是什么样的?或者,最经典的公司纯销售机构是怎样运作的?
如果你负责一个实时系统的架构,经典的架构构建步骤有几步?一个医学CT机系统应该用什么架构风格来构建?军用舰艇上的3C系统又应该使用什么架构风格?除了我们都熟悉的MVC风格的架构,你还知道哪些架构风格?再具体一些,对于系统的并发问题,你知道业界流行的经典解决手段包括哪些?
如果你负责子系统及构件设计,经典的设计步骤有几步?分别又有哪些活动?除了你熟悉的Gang of Four的23个设计模式,你还知道什么设计实践?再具体一些,设计中有关同步、事件、资源管理等,你知道哪些前人的最佳实践呢?
实践工作中,我们遇到的现实是:盲目追随业界通用框架,即对框架或中间件的严重依赖。这些框架或中间件背后实际隐藏了很多技术、设计、应用场景,也就是说为设计开发人员隐藏了很多系统设计开发的复杂性。如果架构师把各项系统级架构质量的要求,想当然统统扔给这些框架或中间件去处理,将会带来灾难性的后果。业界有这样一句话:“框架或中间件是用来帮助你的,而不是代替你去思考和工作的。”所以我们必须根据现实的系统要求,自己动脑筋去构建适合现状的软件架构!
简而言之,架构师需要具备的能力=熟知最佳实践+动脑灵活使用+技术及创新预判。
记者: 在中国,一个程序员如何才能成长为一个职业架构师?
李伟:曾经无意间读过一篇纪事报告《最后的大师》。此文作者是应钱学森先生的邀请,来记录自己的导师,清华大学物理系及清华大学创始人之一的叶企孙先生。叶先生早年在美国留学期间,在物理方面做出过杰出的贡献。虽然大多数后人并不知道叶先生,但是他的学生没有一个会忘记他,其中包括三钱、华罗庚、李政道、杨振宁等等。可以这样说,你所知道的中国大师,大多都是他的学生。阅读完此文,颇受启发:真可谓“大师培养大师”。我非常欣赏这句话。
如果身边有大师,自然是从程序员成长为架构师的捷径了。我身边没有大师,便选择这样的道路:认真反思自己这些年来的学习和实践,并将其上升为智慧。毕竟,智慧既是指导我继续工作的原始动力,也将指导自己未来的创新工作。因此,我选择了阅读、学习和思考。
记者: 您认为在中国的软件企业中,大家在普遍认识中对架构师这一职业有哪些误区?
李伟:误区一,架构师与项目经理没有区别。大家经常在谈论架构师时,混淆了项目经理的职责和架构师的职能。项目经理要对人、流程、钱等内容负责。但是架构师主要是对技术负责。所以我个人不是很喜欢在谈论系统架构时,过多的谈论流程或管理。虽然我也是流程方面和管理方面的专家。
误区二,技术好的人就能成为架构师。其实,职业架构师与职业编程人员有着同样重要的分量,只不过各自负责的工作内容及需要具备的能力各不相同。例如:架构师熟知如何将系统架构构建得适应系统后续国际化/本地化的工作;但是并不一定必须知道界面热键在.NET下调用什么来实现。
误区三,架构师必须懂得业务领域的知识。从本质上来看,软件架构本身就是在模仿人类大脑的问题思考和解决习惯。自然,专业架构师所掌握的知识就是解决那些反复出现的相似问题的最佳手段。所以,业界都知道这样一个著名的故事:一个非航天专业的软件架构人员,可以被美国国家航天局请去做航天系统的架构评审。这一点儿都不奇怪,因为他知道解决系统并发问题时,当今最经典的那么几种手段,你能说航天系统的并发问题与企业应用并发问题本质上不一样吗?由于当前国内软件研发的各种局限,很多软件从业人员的认知还停留在“懂业务+技术好”就是架构师这样的层面上。其实,懂得经典的解决方法,并能从实践中抽象出理论或最佳实践的人,才是架构人员的专业水平。
记者: 在《架构之美——软件架构的艺术》一书中,您认为最创新的理念有哪些?
李伟:一个架构从创建、进化、老化到消亡的整个过程,是此书的核心。如同宇宙万物,架构也存在一个生命周期的概念。即“架构生命周期(Architecture Lifecycle)”。
怎样才是一个真正意义上的软件架构师?
当面临构建一个软件架构时,应该采用怎样的流程去工作呢?
怎么做才能构建出满意的高品质架构及设计呢?
当我们阶段性地完成了架构的构建,如何去评估结果呢?
软件产品在演化,软件架构也会跟随演化,如何应对这种变化?
十年前开发的产品,架构文档残缺不全,设计人员已经离职,怎么把产品的架构从纷繁复杂的头绪中清理出来呢?
如果我们要研发十几个功能相似的产品,该如何高效地工作呢?
上述这些理念,基本上是一个职业架构人员所需具备的专业素养。奉献给大家,以供参考。
(本文来自《程序员》10年05期,更多精彩内容敬请关注10年05期杂志)
Filed under: 软件租用 由 admin on 星期二, 五月 4, 2010
No Comments »
作者:Steve Mushero 译者:侯伯薇
总结了国内网络和游戏公司运行后端服务器过程中所得到的实践经验和教训。这些规则适用于日访问量从一万到上百万的大型系统。
在我们公司ChinaNetCloud,见过多种不同类型的网站和系统,有好也有差。其中有些系统拥有良好的服务器/网络架构,并且进行了合理的调整和监控 ;然而一般的系统都会有安全和性能上的问题,不能良好运行,也无法变得更流行。
在中国,开源的LAMP栈是最流行的网络架构,它使用PHP开发,运行在Apache服务器上,以MySQL作为数据库,所有这些都运行在Linux上。它是个可靠的平台,运行良好,是现在全球最流行的Internet系统架构。然而,我们很难对其规模进行正确的扩展并保持安全性,因为每个应用层都有其自身的问题、缺陷和最佳实践。我们的工作就是帮助企业用最低的操作成本来创建并运行高性能的、可伸缩的、安全的系统,因此对于这类问题我们有很丰富的经验。
当前的实际情况是,很多网站都是由开发人员快速而廉价地创建,通常没有任何IT人员或者经理,只是由程序员来管理系统。造成的结果是,虽然花费很低的成本网站就可以开始运行,但是当拥有大量用户、需要扩展规模的时候,通常就会面临真正的问题。毕竟,中国拥有三亿八千万的Internet用户,如果其中的0.01%访问这个站点,就很容易引发25万~50万的页面访问量。这些问题在各个级别上都会产生,下面总结的规则是对最一般的问题进行概述,并且说明为什么这些规则如此重要,以及最好采用什么方法来修正它们。遵循这些建议的站点会提高它的可伸缩性、安全性以及操作上的稳定性。
使用合适的会话管理
第一个想到的扩展系统的方法就是添加更多硬件。例如,使用两台服务器而不是一台。这听着合理,但会产生潜在问题:会话管理。这对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上有很多不错的关于良好的会话管理的例子,你可以根据需要找到最适合的。
总是要考虑安全性
尽管编写像防止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和随机密码。
使用标准的路径和安装配置
一个令人讨厌的部署问题是,开发者很少考虑他们的软件会被部署到生产Web服务器的什么位置,以及如何部署。我们看到过许多大型的系统将它们的PHP代码部署在/home/xiaofeng或者/web/code路径下。事实上,这两个路径都是非常不标准的,并且会带来操作和安全性的问题。当这些系统从开发环境转移到测试环境再到生产环境中时,因为每个安装配置都是非标准的,所以经常会出现问题,这时就需要开发者调整才能够正常工作。
你应该总是使用标准的安装包和二进制文件来安装像Apache之类的服务器。不要从源代码编译或者安装Tarball,因为这会导致长期稳定性和管理上的问题,另外在服务器上安装多个不同的版本也会造成混淆。
Web 站点应该总是在指定的平台和Linux发布的标准路径下进行测试和部署 ,像 RedHat 或者CentOS下的/var/www/html路径。这有助于对系统进行有效的权限管理、备份、配置、监控以及其他操作。
Web服务器的日志应该存放在/var/logs或者/var/logs/app_name下,而不应该位于主代码区域。这样做的原因不仅仅是因为这些标准的路径很重要,更应该关注的是,恰当地配置服务器会将/var配置为分离的文件系统。如果应用程序突然写入了大量日志并占用所有磁盘空间,由于我们做了以上的配置就不会导致系统崩溃,或者其他严重的问题。如果日志位于其他位置,就可能会产生问题。
总是使用日志
在Web系统中做多少日志都不为过。所有系统都应该将重要的数据写入到日志中,不管是它们自己的日志还是系统的Syslog。Cron的Job以及其他Shell脚本或者C语言的程序,对日志都有相应标准以及简单的函数。在Shell脚本中,只需要使用 Logger命令就可以实现日志的写入。在脚本启动/停止、重要的脚本执行以及实时数据产生的情况下都要执行写入日志操作。这样出现问题的时候,查看主要的系统日志就可以很容易地看到发生了什么。
大型系统经常会使用专门的工具如Local5来记录日志,并配置Syslog或者Syslog-ng来将其存放在单独的文件中,这样会更容易使用。需要注意的是,Syslog工具和Logger(以及任何Syslog调用)默认优先使用user.notice,如有必要,你可以对其进行调整。
一个好的系统会对程序进行配置,用来打开或者关闭日志,并可以选择在每模块或者功能的级别上应用不同级别的日志。这使得我们可以记录非常详细和强大的日志,用来分析和调试在生产操作中所发生的问题。
大型高性能网站的十项规则
使用良好的数据库设计和SQL
在任何系统中,数据库通常是最大的性能瓶颈。而影响数据库性能的最大两个问题是数据库设计和SQL代码质量。很多系统都拥有良好的或者至少是可用的数据库设计,但由于没有经过适当的性能测试,SQL代码质量通常都会很差。这样的SQL代码在开发环境中可能运行很快,因为其中只有小数据集和最小的负载。但是当成千上万的用户同时读取数据库中上百万条记录的时候,它就很可能会崩溃。
不幸的是,这些问题一开始并不明显,直到系统增大、突然开始崩溃的时候才会显现出来。在增大的过程中,数据库系统看起来运行得很快(因为数据都位于内存中,而且很少有并发的查询),并且对用户的响应也很快,但实际上它的内部运行效率很低。这并不重要,我们关注的是在系统增大并遇到性能问题之前找到这些问题并加以解决。
关于这个问题有很多不错的书和站点进行了解析,其中的关键工具包括慢查询日志、INNODB状态系统,以及描述当前性能的MySQL统计信息。我们见到过很多系统每秒会读取500,000条数据,这是出现SQL问题的明显预兆,但公司往往对其一无所知直到服务器开始崩溃。
MySQL系统应该对所有数据使用INNODB存储引擎,因为INNODB与之前的MyISAM相比,运行得更快、更稳定,并且管理性能和备份工作也更加容易和快捷。在主配置文件中,INNODB应该被设置为默认的数据库引擎,并且系统应该不时地进行检查,看是否意外创建了MyISAM的表。
总要拥有良好的DB配置和备份
很多公司都没有良好的备份机制,也不知道如何恰当地完成这项工作。MySQL的Dump是不够的,因为最好的备份方法是使用LVM快照和INNODB对系统进行热备份,从而得到超快的速度和超高的可靠性。
另外,在将所有备份文件从服务器上转移出来之前要进行压缩和加密。另外还要确保拥有设计合理的MySQL配置。MySQL默认安装使用说明中只有5~10行关于配置的说明,这根本不适合开发使用。而我们提供给客户的最佳实践文档足足有10页那么长。文档中大约有100种有用的关于安全、性能和稳定性问题的设定,包括防止数据败坏,其中很多设定都是非常重要的。
使用读/写数据库分离
随着系统变得越来越庞大,特别是当它们拥有很差的SQL时,一台数据库服务器通常不足以处理负载。但是多个数据库意味着重复,除非你对数据进行了分离。更一般地,这意味着建立主/从副本系统,其中程序会对主库编写所有的Update、Insert和Delete变更语句,而所有Select的数据都读取自从数据库(或者多个从数据库)。
尽管概念上很简单,但是想要合理、精确地实现并不容易,这可能需要大量的代码工作。因此,即便在开始时使用同一台数据库服务器,也要尽早计划在PHP中使用分离的DB连接来进行读写操作。如果正确地完成该项工作,那么系统就可以扩展到2台、3台甚至12台服务器,并具备高可用性和稳定性。
使用类似Memcached之类的数据库缓存
即便有了好的数据库设计、SQL和读写分离,大型的系统仍然需要更快的性能,特别是对会话状态、好友列表以及BBS文字之类的东西。为了达到这个目的,我们可以使用像MemCached之类的数据缓存,它是一个高性能的简单数据缓存,已经被所有最大型的站点使用。但是要小心的是,不要100%依赖于一台Memcache服务器来提高性能,因为如果那台服务器崩溃了,就会破坏整个系统的性能。在这种情况下,应该使用2~3台Memcache服务器形成簇集架构,并且有选择地包含一个缓存准备过程,如果缓存服务器重启,需要重新载入数据,它能够快速地载入缓存。
构建测试和开发环境
很多公司只有开发者的桌面系统和他们的生产服务器。当系统变得越来越大、越来越复杂时,测试和管理代码就会导致严重的问题。最佳的实践是拥有两个测试系统,一个用于开发者的代码和功能的整合测试,另一个要与生产环境完全一致,从而更容易向生产环境平滑地过渡。幸运的是,现在使用云计算(或者私有云)可以轻松达到这一点。一个5~10台服务器的生产环境,可以很容易地在办公室或者IDC中使用一台服务器来复制,从而用于测试,而这台服务器我们可以用于多个客户的项目。
使用版本控制
最后,要对一切使用版本控制,包括测试和生产环境的部署。很多开发者都使用SVN或者类似的方法。在理想状态下,这些方法可以被用于所有代码、脚本、HTML、图片、配置、文档和测试。版本控制应该是代码转移到测试环境的必经之路,而不是简单地复制或者使用tar文件,因为这二者都是不可靠的。开发者应该将所有一切都签入,打上标签,然后将它们签出到测试系统。如果所有都没问题,那么它们会将该版本签出到生产环境。
总结
不管是在开发还是在运营过程中,创建可靠的高性能Web系统都有很多应该注意的事项。本文试图从可操作性和可靠性的角度讨论最重要的几点。当你构建和管理站点的时候,请不要忘了这些重要的问题。遵循这些规则会有助于确保系统长久、良好地运行。
作者简介:
Steve Mushero,ChinaNetCloud公司联合创始人、CEO兼CTO,拥有全球20多年的技术管理经验。曾担任土豆网、Intermind和Advanced Management Systems等多家企业CTO
译者简介:
侯伯薇,生于凤城,学在春城,做过国内和对日项目,现在大连某保险公司工作。乐于钻研技术,同时注重业务知识,勤于思考,愿意与人交流和分享。
(本文来自《程序员》杂志2010年4月刊)
Filed under: 软件租用 由 admin on 星期二, 五月 4, 2010
No Comments »