应用系统架构演变初探

背景

    近几年的互联网创业风潮持续在高涨中,所涉及的行业从涵盖了社交、资讯、电商、生活服务等方方面面。其中也涌现很多优秀的APP,而这些产品或平台的特色都包含了"快速",即更新快,迭代快的特性。
    然而做为一名软件工程师的角度,按之前软件工程的理论来讲,系统在设计初期应考虑更多的复杂度、良好的扩展性,尽量达到以不变应万变的结果,而这些快速变动的新秀产品,在系统架构上如何作到灵活扩展、快速演进的呢? 这即是如下要开始探讨的内容。
 
 

1、初定系统架构

    在最开始的时候,产品经理(或项目经理)找到你,在唠唠叨叨叙述完整个系统的功能需求后,要求你一个月内就开发出来。
    
经理: "领导那边催得要命,一个月内必须上线!" "这些功能都很常规呢,须要开发这么久吗!" 你: ...

 

    固然,以上的场景稍显夸张,但在互联网思惟方式的APP开发场景下,这样的节奏其实很常见。
    研发经理都是不辞辛苦的角儿,因而乎,大脑开始高速运转:
"这么短的的时间" .. "好吧,先不考虑性能问题了!" "单元测试也能够省了,作好自测就能够,能省下很多时间呢"

   

    通过一轮挣扎和思考,研发经理推断出了产品的第一代系统架构html

    
    
 
    架构特色
        单点,以知足功能为主,简单、轻量级架构。
 
    数据流
        来自多种场景的的http请求直接由单个server接入、完成业务逻辑处理、输出计算结果。
 
    组件介绍 

         1    App Server,应用系统的服务端节点,能够有不少种选择,以Java系列为例java

             tomcatmysql

             最流行不过的j2ee容器,官网 http://tomcat.apache.org/nginx

             jettyweb

             一款更为轻量级的servlet容器,轻量小巧,提供可编程server的实现(容易嵌入),在continuation机制也有比较良好的表现。redis

             详细参见 http://www.eclipse.org/jetty/sql

             playframework数据库

             此前最为喜好的一款非主流应用服务器,应该是首个java版本的"ruby on rails"的实现。其摒弃了j2ee繁重的各类理念枷锁,让编程变得更加简单、可依赖。
             playframework框架目前已经主推2.x (同时支持java和scala)版本,然而学习曲线相较1.2.x版本更加陡峭,建议可从1.2.5版本开始入门使用。
                   
             值得一提的是该框架内置了netty以支持http请求的接入及处理。
             netty是一款基于NIO实现的轻量级http服务器,
                         关于netty的实现原理可参考: http://stonexmx.blog.163.com/blog/static/122158587201061331614536/
             play框架的官网:https://www.playframework.com/
             
            2  mysql,流行的开源数据库,应用基于JPA/JDBC进行访问,以实现数据持久化
 
            3  memcached, 高速的内存服务器系统,支持KV数据流的快速读写,用做数据缓存及加速访问
                官网地址:http://memcached.org/
 
 

2、演变的开始

       好的,通过一个月的努力,系统上线了。
       运营也开始干活,紧接着是对线上各类问题的紧急修复。
 
       系统渐渐有了一些活跃度,在几个月内,产品经理和研发经理开始听到了一些抱怨:
 
"系统怎么老挂啊,动不动就访问不了,这什么破玩意啊"
 "我这都已经换成wifi了,图片怎么仍是一直加载不了呢?"
.....

     所谓积少成怨,团队终于顶不住压力,下决心开始优化系统。针对上述的问题,分析以下:apache

       1  可用性;
           单点发生崩溃,整个系统直接不可用,全部用户将受到影响;
           JVM的内存溢出,系统进程意外终止均可能致使这样的问题。
 
       2  带宽;
           应用系统在初期设计时更多的考虑了网络调用、html动态页面的输出,而针对图片的访问并未作过多考虑,所以文件资源访问很快出现了瓶颈。
 
         研发经理决定将架构优化以下
 
         
     
         负载均衡
         使用nginx提供应用服务器的负载均衡,提供两个应用服务器节点,保证单点崩溃时而系统仍然可用。
 
         文件访问分离
         使用单独的web服务器(nginx)用做文件访问服务器,全部的静态图片地址将指向独立域名。
 
         

3、加速进化

       继上一次优化以后,用户的抱怨已经明显减小,产品经理和领导都对这次工做表示满意。
       研发经理开始感觉到了史无前例的成就感。
 
       然而好景不长,在几个月后公司重点引入了营销团队。这是至关给力的团队,在短短的时间内,在各大网络平台布置了多个入口。
      各类推广活动、事件营销接踵而来。最可观的如在微信朋友圈的一次事件营销直接引入了好几倍的用户量。
      这样的状况在互联网产品的发展轨迹上至少也能够称得上一次小小的爆发式增加了。
 
       固然,领导、产品经理都开心和兴奋起来了。但此次,研发经理心里开始发愁了:
 
      1  访问压力;
          一个server的并发处理能力很容易达到上限,一旦超过负载阈值,将直接致使访问时长加大,甚至系统崩溃、没法访问等情形;
 
      2  数据存取;
          数据量的扩充,单个数据库表不断增大,查询速度将产生降低;
          此外数据库的单点也成为隐患
      
      3  缓存空间;
          与数据库同理,为加速更多数据的访问,须要提供更大容量缓存空间;
 
      此次,研发经理将系统架构作了一次较为完全的改进:
 
            
 
       负载均衡
       增长负载均衡的服务器节点,提升总体处理能力;
       
       数据库扩展
       采起水平切分的方式,实现基于Shard的分布式数据库集群;
      
       memcached集群
       开启多个memcached节点,组成高可用的缓存集群,同时可支持更大的缓存空间
 
       其中对于服务端程序改造最大的在于分布式Shard数据的实现,通常可从数据量较大的局部表开始切分,在数据存取上加入水平分库的机制;
       固然此时的数据迁移工做也是一个重点。
 
 

4、将来的展望

       至此,系统优化已经告一段落。当前的后台架构已经处在一个表现稳定,容易扩展的一个状态。
       性能指标方面大体已经能够达到百万级用户量,日PV过百万,甚至还可能更好。
       然而这还仅仅是一个雏形,应用系统的场景是多种多样的,在将来须要解决的问题每每不只仅这些,好比:
 
    
      1  系统存在全文搜索、或是标签式搜索的场景,为了提升搜索性能,你可能会引入sphinx中间件;
          sphinx的中文版本为coreseek(可支持中文全文搜索),。
          详见官网:http://www.coreseek.cn/
 
      2  为了提升事务处理的效率,你须要队列服务器来解决,这个能够是ttserver + worker的模式;
 
      3  频繁的处理缓存数据的解析在开发上会比较麻烦,你还能够更换redis来直接支持数据结构式的缓存...
          redis为一款支持数据结构缓存及数据持久化的优秀的nosql中间件,
          官网地址:http://redis.io/
 

 备注

        架构设计需秉承的"适用"原则,不一样业务场景所采起的架构都会有些差别, 此处仅仅讨论最多见的扩展思路,关于读写分离、数据主备等作法在此不作讨论。
        本文所说起的故事情节均属杜撰,若有雷同,实属巧合。
相关文章
相关标签/搜索