设为首页 收藏本站
查看: 805|回复: 0

[经验分享] 应用系统架构演变初探

[复制链接]

尚未签到

发表于 2017-2-28 12:17:14 | 显示全部楼层 |阅读模式
背景


    近几年的互联网创业风潮持续在高涨中,所涉及的行业从涵盖了社交、资讯、电商、生活服务等方方面面。其中也涌现不少优秀的APP,而这些产品或平台的特点都包含了"快速",即更新快,迭代快的特性。

    然而作为一名软件工程师的角度,按以前软件工程的理论来说,系统在设计初期应考虑更多的复杂度、良好的扩展性,尽可能达到以不变应万变的结果,而这些快速变更的新秀产品,在系统架构上如何做到灵活扩展、快速演进的呢? 这便是以下要开始探讨的内容。




一、初定系统架构


    在最开始的时候,产品经理(或项目经理)找到你,在唠唠叨叨叙述完整个系统的功能需求后,要求你一个月内就开发出来。

   


经理:
"领导那边催得要命,一个月内必须上线!"
"这些功能都很常规呢,需要开发这么久吗!"
你:
...
  


    当然,以上的场景稍显夸张,但在互联网思维方式的APP开发场景下,这样的节奏其实很常见。

    研发经理都是任劳任怨的角儿,于是乎,大脑开始高速运转:




"这么短的的时间" .. "好吧,先不考虑性能问题了!"
"单元测试也可以省了,做好自测就可以,能省下不少时间呢"
     
      经过一轮挣扎和思考,研发经理推断出了产品的第一代系统架构


    DSC0000.jpg



DSC0001.jpg



   


    架构特点


        单点,以满足功能为主,简单、轻量级架构。



    数据流

        来自多种场景的的http请求直接由单个server接入、完成业务逻辑处理、输出计算结果。



组件介绍

           1    App Server,应用系统的服务端节点,可以有很多种选择,以Java系列为例:
               tomcat
               最流行不过的j2ee容器,官网 http://tomcat.apache.org/
               jetty
               一款更为轻量级的servlet容器,轻量小巧,提供可编程server的实现(容易嵌入),在continuation机制也有比较良好的表现。
               详细参见 http://www.eclipse.org/jetty/
               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/




二、演变的开始


       好的,经过一个月的努力,系统上线了。

       运营也开始干活,紧接着是对线上各种问题的紧急修复。



       系统渐渐有了一些活跃度,在几个月内,产品经理和研发经理开始听到了一些抱怨:






"系统怎么老挂啊,动不动就访问不了,这什么破玩意啊"
"我这都已经换成wifi了,图片怎么还是一直加载不了呢?"
  .....
  所谓积少成怨,团队终于顶不住压力,下决心开始优化系统。针对上述的问题,分析如下:


       1  可用性;

           单点发生崩溃,整个系统直接不可用,所有用户将受到影响;

           JVM的内存溢出,系统进程意外终止都可能导致这样的问题。



       2  带宽;

           应用系统在初期设计时更多的考虑了网络调用、html动态页面的输出,而针对图片的访问并未做过多考虑,因此文件资源访问很快出现了瓶颈。



         研发经理决定将架构优化如下



          DSC0002.png

     

        负载均衡

         使用nginx提供应用服务器的负载均衡,提供两个应用服务器节点,保证单点崩溃时而系统仍然可用。



         文件访问分离

         使用单独的web服务器(nginx)用作文件访问服务器,所有的静态图片地址将指向独立域名。



         
三、加速进化


       继上一次优化之后,用户的抱怨已经明显减少,产品经理和领导都对此次工作表示满意。

       研发经理开始感受到了前所未有的成就感。



       然而好景不长,在几个月后公司重点引入了营销团队。这是相当给力的团队,在短短的时间内,在各大网络平台布置了多个入口。

      各种推广活动、事件营销接踵而来。最可观的如在微信朋友圈的一次事件营销直接引入了好几倍的用户量。

      这样的情况在互联网产品的发展轨迹上至少也可以称得上一次小小的爆发式增长了。



       当然,领导、产品经理都开心和兴奋起来了。但这次,研发经理内心开始发愁了:





      1  访问压力;

          一个server的并发处理能力很容易达到上限,一旦超过负载阈值,将直接导致访问时长加大,甚至系统崩溃、无法访问等情形;



      2  数据存取;

          数据量的扩充,单个数据库表不断增大,查询速度将产生下降;

          此外数据库的单点也成为隐患

      

      3  缓存空间;

          与数据库同理,为加速更多数据的访问,需要提供更大容量缓存空间;



      这次,研发经理将系统架构做了一次较为彻底的改进:



            



       负载均衡

       增加负载均衡的服务器节点,提高整体处理能力;

      

       数据库扩展

       采取水平切分的方式,实现基于Shard的分布式数据库集群;

      

       memcached集群

       开启多个memcached节点,组成高可用的缓存集群,同时可支持更大的缓存空间



       其中对于服务端程序改造最大的在于分布式Shard数据的实现,一般可从数据量较大的局部表开始切分,在数据存取上加入水平分库的机制;

       当然此时的数据迁移工作也是一个重点。




四、未来的展望


       至此,系统优化已经告一段落。当前的后台架构已经处在一个表现稳定,容易扩展的一个状态。

       性能指标方面大致已经可以达到百万级用户量,日PV过百万,甚至还可能更好。

       然而这还仅仅是一个雏形,应用系统的场景是多种多样的,在未来需要解决的问题往往不仅仅这些,比如:



   

      1  系统存在全文搜索、或是标签式搜索的场景,为了提高搜索性能,你可能会引入sphinx中间件;

          sphinx的中文版本为coreseek(可支持中文全文搜索),。

          详见官网:http://www.coreseek.cn/



      2  为了提高事务处理的效率,你需要队列服务器来解决,这个可以是ttserver + worker的模式;



      3  频繁的处理缓存数据的解析在开发上会比较麻烦,你还可以更换redis来直接支持数据结构式的缓存...

          redis为一款支持数据结构缓存及数据持久化的优秀的nosql中间件,

          官网地址:http://redis.io/


备注


        架构设计需秉承的"适用"原则,不同业务场景所采取的架构都会有些差异,此处仅仅讨论最常见的扩展思路,关于读写分离、数据主备等做法在此不做讨论。

        本文所提及的故事情节均属杜撰,如有雷同,实属巧合。  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348450-1-1.html 上篇帖子: 用Java实现HTTP Multipart的服务端和客户端 下篇帖子: hadoop:将WordCount打包成独立运行的jar包
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表