在互联网行业,基于 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 化”中我陷的两难的处境:
1、如果未来还是沿着“去 .NET 化”的计划往下走,就算重新招聘和搭建了
.NET 研发团队,由于 .NET 在公司是注定要被替换掉的,那么新的 .NET 团队是不可能稳定的,很可能来一两个月,一看形势不对,立马走人了。而当时
.NET 的核心系统占整个网站的比重很高,且极端复杂,一旦出问题,根本就束手无策,必须要有好手坐镇维护。当时我已经开始
review 核心系统的 .NET 代码,准备亲自上阵了。
2、如果未来放弃“去 .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 就可以药到病除的,要反思公司企业文化是不是从来没有重视过研发,对技术团队的激励到位了吗?对架构师的意见重视过吗?对未来可能面临的技术门槛是否有过长期的研发投入?
|