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

我记得十几年前第一波互联网浪潮的时代,采用Windows平台ASP架构的大型网站是非常普及的,而如今采用Windows平台.net架构的大流量知名网站已经凤毛麟角了。很多采用Windows平台.net架构的大型网站都面临了架构上的扩展问题:

例如国外的SNS网站MySpace网站面临过很严重的性能扩展问题,国内电商网站京东也不止一次受困于架构扩展带来了性能瓶颈。因此,一些Windows平台.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系统架构改造的经验和教训

我2010年接手前公司的产品和研发团队的时候,核心系统大约2/3是Windows平台.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的核心系统占整个网站的比重很高,且极端复杂,一旦出问题,根本就束手无策,必须要有好手坐镇维护。当时我已经开始review核心系统的.net代码,准备亲自上阵了。

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

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

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

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

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

  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 说过一句很精辟的话:“技术问题,总是在短期被高估,在长期被低估”,我也想补充一句:“技术出现了问题,从来都不单纯是技术导致的问题”。

转自:http://robbinfan.com/blog/43/rid-off-dotnet-experience

(转)对.net系统架构改造的一点经验和教训的更多相关文章

  1. [网站性能1]对.net系统架构改造的一点经验和教训

    文章来源:http://www.admin10000.com/document/2111.html 在互联网行业,基于Unix/Linux的网站系统架构毫无疑问是当今主流的架构解决方案,这不仅仅是因为 ...

  2. 对.net系统架构改造的一点经验和教训(转)

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

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

    如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 在互联网行业,基于Unix/Linux的网站系统架构毫无疑问是当今主流的架构解决方案 ...

  4. .NET系统架构改造的经验和教训

    转自: http://robbinfan.com/blog/43/rid-off-dotnet-experience 在互联网行业,基于Unix/Linux的网站系统架构毫无疑问是当今主流的架构解决方 ...

  5. 系统架构:Web应用架构的新趋势---前端和后端分离的一点想法

    最近研究servlet,看书时候书里讲到了c/s架构到b/s架构的演变,讲servlet的书都很老了,现在的b/s架构已经不是几年前的b/s架构,其实b/s架构就是web应用开发,对于这样的架构我们现 ...

  6. 5G 融合计费系统架构设计与实现(一)

    5G 融合计费系统架构设计与实现(一) 随着5G商用临近,5G的各个子系统也在加紧研发调试,本人有兴全程参与5G中的融合计费系统(CCS)的设计.开发.联调工作.接下来将用几篇文章介绍我们在CCS实现 ...

  7. 【Java进阶面试系列之一】哥们,你们的系统架构中为什么要引入消息中间件?

    转: [Java进阶面试系列之一]哥们,你们的系统架构中为什么要引入消息中间件? **这篇文章开始,我们把消息中间件这块高频的面试题给大家说一下,也会涵盖一些MQ中间件常见的技术问题. 这里大家可以关 ...

  8. (系统架构)标准Web系统的架构分层

    标准Web系统的架构分层 1.架构体系分层图 在上图中我们描述了Web系统架构中的组成部分.并且给出了每一层常用的技术组件/服务实现.需要注意以下几点: 系统架构是灵活的,根据需求的不同,不一定每一层 ...

  9. 千万pv大型web系统架构,学习从点滴开始

     架构,刚开始的解释是我从知乎上看到的.什么是架构?有人讲, 说架构并不是一 个很 悬 乎的 东西 , 实际 上就是一个架子 , 放一些 业务 和算法,跟我们的生活中的晾衣架很像.更抽象一点,说架构其 ...

随机推荐

  1. Android 中的 Service 全面总结(转载)

    转载地址:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html 感谢作者 Android 中的 Service 全面总结 1.Ser ...

  2. TIJ读书笔记08-数组的初始化和可变长参数形参

    TIJ读书笔记08-数组的初始化和可变参数形参 数组 数组的声明 数组的初始化和赋值 可变参数列表 数组 相同类型的,用一个标识符名称封装到一起的一个对象序列或者基本数据类型序列叫数组.(多么严谨的概 ...

  3. sqoop job 踩过的坑

    sqoop 执行可以以job形式 也可以执行用命令执行,再用sqoopjob时,踩了几个坑,分享一下 1.服务器重启 由于服务器增加硬盘,需要重启后,发现sqoop job 无法执行,报连接数据库IO ...

  4. SBT 构建scala eclipse开发

    scala eclipse sbt 应用程序开发 搭建Eclipse开发Scala应用程序的一般步骤 一.环境准备: 1.Scala : http://www.scala-lang.org/ 2.Sc ...

  5. 循序渐进Python3(七) --1-- 面向对象

    Python 面向对象 什么是面向对象编程? 面向对象编程是一种程序设计范式 对现实世界建立对象模型 把程序看作不同对象的相互调用 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Py ...

  6. asp.net mvc 如何将controller 里一个action 返回值为list<>的值输出到view

    在controller中:return View(myRole.ToList());在view文件开头加上:@model IEnumerable<LTXYCallCenter.Models.Ro ...

  7. win 7安装 linux

    http://blog.csdn.net/wuwenxiang91322/article/details/23528619

  8. jdk代理和cglib代理

    1.jdk静态代理(静态代理和动态代理) 本质:在内存中构建出接口的实现类. 缺陷:只能对实现接口的类实现动态代理, 使用cglib可以对没有实现接口的类进行动态代理. 2.cglib动态代理     ...

  9. Spring----->projects----->Spring Security

    1.Spring Security概述 Spring Security是spring社区若干projects中的一个 Spring Security用于为基于spring开发的application提 ...

  10. LeetCode OJ 147. Insertion Sort List

    Sort a linked list using insertion sort. Subscribe to see which companies asked this question 解答 对于链 ...