注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

软件大铺的博客

IT技术共享

 
 
 

日志

 
 

对.NET系统架构改造的一点经验和教训  

2013-06-03 22:30:20|  分类: 架构 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

文/范凯

  在互联网行业,基于 Unix/Linux 的网站系统架构毫无疑问是当今主流的架构解决方案,这不仅仅是因为 Linux 本身足够的开放性,更因为围绕传统 Unix/Linux 社区有大量的成熟开源解决方案,覆盖了网站应用扩展的方方面面。

  我记得十几年前第一波互联网浪潮的时代,采用 Windows/.NET 架构的大型网站是非常普及的,而如今采用 .NET 架构的知名网站已经凤毛麟角了。特别是除了微软自身旗下的网站 MSN 和 Hotmail,其他采用 .NET 架构的大型网站很多都面临了架构上的扩展问题,让 .NET 架构的扩展性成了一个比较有争议的问题:

  例如国外的 SNS 网站 MySpace 网站面临过很严重的性能扩展问题,国内电商网站京东也不止一次受困于架构扩展带来了性能瓶颈。因此,一些 .NET 架构为主的网站,不得不考虑“去 .NET 化”,抛弃 .NET,全面迁移到以 Java 为主的架构上。

  但是大型网站的架构迁移,本身也是伤筋动骨的事情,风险极高,成功案例尚不多见,失败案例俯拾皆是,这是因为:

  1. 架构迁移是在现有业务系统上进行的,并不是从容的开发新产品,有足够的时间测试和完善,相当于给正在高空飞行的客机换引擎,必须一次切换成功,没有第二次机会,稍有差池,就会机毁人亡。而我们都知道,新开发一个大型系统,没有上线磨合和完善过,无法做到一次 100% 完美。

  2. 架构迁移意味着老的研发团队将被淘汰,而往往老团队体系随着公司壮大已经掌握了足够话语权,新架构的团队在公司又根基未稳,出于维护自身利益的本能,新旧团队之间很容易爆发政治斗争,相互排挤,导致迁移失败。

  5173“去 .NET 化”的教训

  5173 网站以游戏装备交易起家,曾经在客户端网络游戏发展黄金时期,迎来了业务爆发性的增长期。此时,用 .NET 架构开发的网站已经不堪重负,由于现有的 .NET 研发团队长期无法解决网站的性能问题,5173 决定将网站从 .NET 架构全面迁移到 Java 为主的架构上。为此,5173 花了很大的代价,从淘宝和 SUN 公司挖了很多工程师,组成了一个六七十人的 Java 架构研发部门。

  新的 Java 研发部门开发新的 5173 网站,而老的 .NET 研发部门维护现有的 5173 网站,两个部门并行工作,两个版本的网站并行运行,这带来了公司内部激烈的政治斗争,新开发完成的 Java 版本的 5173 网站从未正式上线过,老的 .NET 研发团队在面临严重生存威胁的情况下,努力解决了一些核心的可用性和稳定性问题。同时随着端游黄金时代的结束,网站性能问题也逐渐显得不再重要。

  在围绕新版本网站是否要正式替换老版本网站的问题上,各个利益方争执不下,反反复复拉锯战,而空降而来的女 CTO 不属于任何派系,态度模棱两可。最终斗争的结果 .NET 利益方战胜了 Java 利益方,Java 研发部门被清洗。

  我的“去 .NET 化”的经验和教训

  3 年前,我刚接手 CSDN 的产品和研发团队的时候,CSDN 的核心系统大约2/3 是 .NET 架构,1/3 是 LAMP 架构。研发人员当时也很少:只有 2 个 .NET 程序员,3 个 PHP 程序员,后来还有 1 个我带过来的 Ruby 程序员。当时的计划是:网站整体架构改造的方向是 Linux 架构,逐渐替换掉现有的 .NET 系统。因此不打算继续招聘和补充 .NET 程序员了,现有的 .NET 程序员负责老的核心系统维护工作。

  但硕果仅存的 2 个 .NET 程序员在随后不到半年时间都走了:一个 .NET 程序员跟着微软出来的高管去创业,另一个 .NET 程序员跳槽去百度做了前端工程师。这中间的道理也很简单:既然公司要去 .NET 化,那 .NET 工程师就会担心等到将来 .NET 系统都换掉之后,自己在公司还有价值吗,不就彻底边缘化了吗?

  当然我在制订架构迁移计划的时候,也考虑到了这一点:我给那个更资深的 .NET 工程师制订的是整个公司总架构师的培养计划,那个精通 JS 的 .NET 工程师制订的是未来前端团队 Leader 的培养计划。不过有不确性的承诺总是不如现实的威胁更迫切,所以我也特别能够理解 .NET 工程师的流失。

  这个时候,我陷入了一个两难的处境:

  • 如果未来还是沿着“去 .NET 化”的计划往下走,就算重新招聘和搭建了 .NET 研发团队,由于 .NET 在公司是注定要被替换掉的,那么新的 .NET 团队是不可能稳定的,很可能来一两个月,一看形势不对,立马走人了。而当时 .NET 的核心系统占整个网站的比重很高,且极端复杂,一旦出问题,根本就束手无策,必须要有好手坐镇维护。当时我已经开始 review 核心系统的 .NET 代码,准备亲自上阵了。

  • 如果未来放弃“去 .NET 化”的计划,也许短期可以解决一些头疼的系统维护的问题,但是对整个网站长期的发展会带来很多不利的方面:例如网站的安全性问题,网站的架构扩展问题,网站服务端软件全面正版化的成本问题等等。如果当时不下定决心去 .NET 化,那么将来再想做这个事情,代价只会越来越高。

  当时,我最初的想法是:招聘 2 名水平尚可,关键是没有太大上进心,可以安于现状,踏踏实实工作的 .NET 程序员来维护老的 .NET 核心系统;同时招聘和搭建 Ruby 研发团队,以我过去用 Ruby 开发网站的惊人开发效率,争取时间,逐一重写老的 .NET 核心系统。但是这样做,风险也很大:

  1. 我来 CSDN 的时间不是很长,当时 CSDN 线上产品又多又杂,足有上百个之多,很多系统我都不清楚干什么的;
  2. 公司领导也不太支持我这么快动手,甚至很担心我大刀阔斧的改造网站,会把当时已经很脆弱的网站彻底搞休克;
  3. 我来北京以后,只带过来 1 个 Ruby 程序员,而搭建 Ruby 团队,磨合团队,开发核心系统,都不是一朝一夕的事情,想快也很难快起来;

  幸运的是,我招聘的过程当中,面试到了两个相当不错的 .NET 工程师,有很强的上进心,编程功底和悟性都很好。虽然不符合我当时招聘想找安于现状的工程师的标准,但我又不太想错过好的人才,所以我临时改变了自己的想法,将他们招过来,组建了新的 .NET 团队。

  为了避免出现之前 .NET 团队流失的问题,给新的 .NET 团队创造在公司发展的机会和空间,我想来想去,决定采取一个折衷的方案:即保留和沿用 .NET 编程语言和框架,但是网站整体架构仍然去 .NET 化,概要说来:

  1. 数据层放弃 SQL Server 数据库和存储过程,全部迁移到 Linux 平台上的 MySQL 数据库上;
  2. 缓存不再依赖 .NET 自身提供的缓存机制,迁移到部署在 Linux 平台上的分布式的 Redis 上;
  3. 服务之间的调用,避免使用 .NET 自身专有协议,改成 Restful 的 HTTP Web API 调用;
  4. 静态资源请求,不再让 IIS 自己处理,分离到 Linux 平台上的 Nginx 去处理;
  5. 需要读取的文件系统,也改成访问 Linux 平台上的分布式文件系统;
  6. 部署 .NET 代码的 Windows 服务器放在 LVS 后面,用 LVS 做负载均衡和故障切换。

  简单说来,就是单纯让 .NET 做应用层的编程语言和框架,其他都交给 Linux 平台的开源解决方案。而 .NET 框架单纯做应用层,无论 ASP.NET MVC 的开发效率,还是 .NET CLR 虚拟机的运行效率都非常好,目前我们单台 Windows 服务器上跑几百万的动态请求毫无压力,而且应用层架构是可以横向扩展的:如果请求负载非常高,只需要添加更多 Windows 服务器即可。总之,做到了扬长避短。

  此外,我也比较注重不同编程语言研发团队之间的交流,鼓励 .NET 工程师熟悉 Linux 操作系统,培养 .NET 工程师整体架构意识。我们现在的主力 .NET 骨干和我说,感觉来到这里以后技术上最大的提升就是视野一下被打开了。

  在后来两年的整个网站改造过程中,也证明了这样的做法是相当成功的:

  1. .NET 团队稳定的延续了下来,而且成为整个研发部门表现一直非常突出的团队;
  2. 整个系统改造的过程非常稳健和平滑,没有碰到过什么风险;
  3. 对网站用户的冲击很小,基本上都是在潜移默化当中,不知不觉的完成了整个网站产品的翻新;
  4. 对公司线上业务也没有造成任何影响,而且随着系统不断改造,对业务的支持越来越好;

  当网站架构全面 Linux 化,并且架构解决方案全部统一以后,其实在应用层用什么编程语言来写,就不是一件重要的事情了,我们目前应用层现有产品线,既有 .NET,也有 PHP 和 Ruby 写的,但是架构都是统一的,用什么编程语言,主要取决于研发团队资源的调配情况而定。

  总之,以我的经验来说,一个传统上严重依赖微软解决方案架构的网站,如果要进行架构改造,迁移到 Linux 平台,甚至用其他编程语言重写,从来都不是一个单纯的技术问题,它至少涉及如下几个层面的问题:

  1. 如何保障旧系统的研发团队的利益问题,如何做到激励老团队参与架构改造,分享成功。这是最重要的,往往也是架构迁移最容易出现的致命问题,如果架构改造注定要牺牲老团队,完全不考虑和保障他们的利益,我认为一定会产生残酷的政治斗争,最终必然失败;
  2. 现有业务系统如何保持正常运转和平滑过渡的问题,如果架构改造影响到了业务,那一定会夭折;
  3. 如何保证网站用户体验的平滑过渡和改善的问题,如果架构改造影响了用户基本使用体验,那也一定会被叫停;
  4. 领导对架构改造当中出现风险的容忍度问题,以及领导对架构改造周期拉长以后的耐心问题;

  一点题外话

  我感觉我们互联网行业有一个不太好的现象:有些网站在促销期间瘫痪了,有些网站经常出现访问不稳定的现象,公司老板就喜欢跑到微博上来放狠话,请下属喝茶,或者急就章的嚷嚷百万年薪招 CTO。这就好比一个人,平常生活习惯差,花天酒地,从不注意养生,结果长年累月下来,终于病倒了。在这个时候狠狠的挥舞支票嚷嚷,哪个名医能给我药到病除,我给谁百万报酬。

  所以,当一个网站出现严重的技术问题,其根源往往都不是单纯的技术问题,也不是单纯换个 CTO 就可以药到病除的,要反思公司企业文化是不是从来没有重视过研发,对技术团队的激励到位了吗?对架构师的意见重视过吗?对未来可能面临的技术门槛是否有过长期的研发投入?

  关于这个现象,我记得 Fenng 说过一句很精辟的话:“技术问题,总是在短期被高估,在长期被低估”,我也想补充一句:“技术出现了问题,从来都不单纯是技术导致的问题”。

来自: robbinfan.com  

转自:http://news.cnblogs.com/n/177636/

-----------------------------------------------------------------------------------------------------------------

上面,JavaEye创始人范凯robbin的一篇博客引起了大讨论,里面提到了京东“去.Net化”、“CSDN去.Net化”之类的词刺激到了一些人的神经,有的人在评论中破口大骂“.Net最牛逼,.Net搞不好是你技术不行”,有的人则骂“.Net就是垃圾,上不了大台面”。所以我还是来谈谈所谓的“去.Net化”吧。

         其实只要认真看robbin的文章,就会知道他并不是在说“去.Net化”而是在说“怎样搭建合适的网站框架”。注意看这段话:

  1. 数据层放弃SQL Server数据库和存储过程,全部迁移到Linux平台上的MySQL数据库上;
  2. 缓存不再依赖.net自身提供的缓存机制,迁移到部署在Linux平台上的分布式的Redis上;
  3. 服务之间的调用,避免使用.net自身专有协议,改成Restful的HTTP Web API调用;
  4. 静态资源请求,不再让IIS自己处理,分离到Linux平台上的nginx去处理;
  5. 需要读取的文件系统,也改成访问Linux平台上的分布式文件系统;
  6. 部署.net代码的Windows服务器放在LVS后面,用LVS做负载均衡和故障切换; 

简单说来,就是单纯让.net做应用层的编程语言和框架,其他都交给Linux平台的开源解决方案。而.net框架单纯做应用层,无论ASP.net MVC的开发效率,还是.net CLR虚拟机的运行效率都非常好,目前我们单台Windows服务器上跑几百万的动态请求毫无压力,而且应用层架构是可以横向扩展的:如果请求负载非常高,只需要添加更多Windows服务器即可。总之,做到了扬长避短。

         熟悉大型互联网技术架构的人应该很容易的发现,这个重构过程其实就是一个“让合适的东西干合适的事情”这样一项工作:

  1. 把过多业务逻辑写到存储过程中必然导致数据库服务器压力的增大,而且不利于负载均衡,因此去“存储过程”是必要的;
  2. SQLServer实现集群的能力很差,用MYSQL之类的数据库是一个不错的选择;
  3. 缓存还是用.Net内置的InProc缓存机制对于高并发的网站来讲是一个灾难,用Redis之类分布式缓存来代替是必然的过程;
  4. 使用.Net Remoting之类的私有协议不利于异构系统集成,改成webservice、REST也是必须的;
  5. 静态文件的请求也经过IIS有点太劳烦IIS了,扔给nginx才更合适;
  6. Windows服务器的文件系统很不灵活,换成更加灵活的Linux下的分布式文件系统是聪明的;
  7. 采用LVS、nginx之类做负载均衡也是最合适的。

          其实任何一个大型互联网基本都是这样一个架构:前端使用nginx等做负载均衡,使用Redis、memcached等做分布式缓存,使用数据库集群进行读写分离之类的优化,使用分布式文件系统处理图片等静态文件。

         请问,使用PHP、Java等做web服务器开发的大型互联网,哪个使用JSP内置的Session对象做Session的,不都要换用redis吗?哪个把图片和php放到一个服务器的,不都放到文件服务器中吗?哪个一个apache服务器就可以扛起来的,不都是nginx之类的挡在前面做负载均衡的吗?  怎么不说“去php化”、“去java化”呢?要知道redis、memcached、ngix之类的可都不是java、php写的呀,一个java项目竟然用其他语言写的东西,难道不丢面子?

         其实一个大型的系统中,根据项目的不同特点来组合搭配不同的产品、组件是一个必然的过程,去了解一下这些系统中“混搭”是常见的现象。单一产品中提供能的功能只能满足普通项目的需求,要想满足复杂的项目,必须把这些产品中提供的一些傻瓜化的简单组件用更专业的组件来替换,就像做小项目php中的Session足够了,但是大项目必须用c/c++开发的memcached来替换。

        【此评论转自:http://www.cnblogs.com/rupeng/archive/2013/06/02/3114496.html        

  评论这张
 
阅读(662)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017