• 1
  • 2
  • 3
  • 4
  • 5
阿里云应用开发 首 页  »  帮助中心  »  云服务器  »  阿里云应用开发
分布式系统的开发
发布日期:2016-8-2 16:8:2

  1、前言

  过去两个月例,深入参与了一个分布式系统的开发,记得之前有人说过“想成为架构师前,都是从微观架构开始的”。虽然我从没想过将来的某一天要成为一个架构师,或领域专家,我只是想萌萌哒的编码,写着自己喜欢的Code,同一群志同道合的朋友做出大家喜欢的商品与产品。但工作久了慢慢的搭架子的事情还是会来到你的面前,由于时间总会把一部分人慢慢推向海边,使得他们成为最早见到阳光的人。

  不扯淡了,为什么要说阳光呢,还是由于过去的两(三)个月可能过的太充实也太痛苦了,完成后,曙光来临的时候整个人是会发光的哦。“深度”参与是由于我终于有机会在搭架子的过程中有了话语权与选择权,同时也会承担70%以上的编码工作。

  之前我的自我认知是我可能在软件方面的积累还行,比如设计模式,程序解耦,架构分层,API入手等方面,但总觉得我在硬件网络方面积累的太少,太薄了。

  比如:

  (1)何时使用关系数据库,什么时候使用Nosql;

  (2)消息队列用擅长的MSMQ还是RabbitMQ.

  (3)怎样有效的和其他部门的同事沟通;

  (4)用什么样的方式去有效调度不同语言开发的系统;

  (5)测试用例对于大系统从零散到完整是多么的重要;

  (6)系统标准,代码原则对于后期的维护余扩展是多么的重要;

  (7)不同操纵系统之间的特点;

  (8)网络端口管理与分发;

  (9)哪些网络协议可以帮助我们更好的完成工作,监控虚拟机的时候是在虚机上加代div理好还是用协议去控制;

  (10)硬件是否支持分布式,在扩展过程中对于.net C#的兼容怎么样;

  (11)什么时候使用多线程,在把线程交给程序调度的时候我们怎么控制和捕捉线程的异常;

  (12)日志系统对于整个分散的系统是多么的重要;

  等;

  2、项目简介

  首先项目详细内容不便多说,简答的说,就是为国内某大型厂商建立一套协调其自身搭建的私有云以及其购买的公有云的一套系统。简单地说:一套混合云系统。


  图1

  3、使用Restful


  图2

  这是在构建完整个系统最大的收获,之前使用web api的经验只是为像阿里云这些电商系统的移动终端提供数据交互的接口,但在这次项目后发现Rest接口的不仅作为我们系统向外部系统提供交互的方式,同时在一些开源工具其暴露出来的接口也是基于rest的,可见全世界的程序员对于json对于rest有多么的喜爱;

  4、为什么装上软件配置完成之后使用不了

  之前的开发经验因为使用的都是微软的技术包括组建,工具。但在项目中使用一些开源工具后,配置成功后却总也跑不起来,同时因为开源工具已将Exception封装起来,我们很难知道具体是什么样的问题,有时调试好久还是跑不起来,很沮丧也很懊恼,结果最后发现是因为公司IT只是将常用的端口打开,其他的都干掉了,若申请开放端口的话还要走流程,所以对于开发人员有时候有一台外网的开发虚拟机也是相当的有必要的。

  5、使用RabbitMq


  图3

  个人是非常的喜欢使用Mq的,之前做电商总喜欢在Application层下面放入一层Service,可不用但是总会强迫症似的不去不写。不用Msmq,原因是有很多了,简单点就是rabbit要比Msmq的协议更加高级,支持的处理功能也更加丰富,最重要的原因是Rabbit在开源语言使用上是占领先地位的,而且我们的系统又要嫁接太多的开源语言系统,最后只能适配他们喽。

  之前知道Mq在企业系统间数据交互使用频繁,不仅能有效的划分层次,解耦依赖,同时数据交互方式上也相当的便捷。总会有消息没有被消费者使用,那我们就需要程序异步的去处理这个消息队列了。

  6、Redis

  图4

  系统中使用了三种数据存储,SqlServer,MySql,Redis,当然前两种适用于开源和C#,而Redis的使用则是为那些总是难以找到有效关系与依赖的数据,比如之前只是知道Reids可作为数据的存储,可分布式,可主从复制,但在这次开发后更真真的发现Reids或Nosql对于一个数据规则难以掌握,数据量大的系统是多么的重要,由于有时一批的Json串过来之后,难以有效的挖出里面的关系与逻辑,索性就一次性将他们放入Redis中吧,使用时再反序列吧。同时建立读写分离的原则,我们主要将读放在了Redis里面,写到了Mysql,并通过Mysql的触发器实现服务器段数据的主从复制同步。

  7、日志系统


  图5

  之前我们的单一系统时,比如只是简单的3层架构的话,我们通过Debug可从头debug到数据库,每一步都是掌握在手底下,每一步都尽收眼底。但对于这一个层次太深,组建调用较多,同时又是多线程的系统来说,挖到雷的机会,时间,成本都是要考虑的。所以有效的使用日志组件,有效的在代码中埋雷就显的尤为迫切与必要,能更好的帮助我们找到问题所在。

  8、组件式开发


  图6

  之前的简单分层系统我们通过Svn或其他的代码管理工具,每次提交都可Merge看的到,但当系统庞杂同时系统独立性很强的时候,分组建,分模块开发就显得很重要。由于不想浪费大家一起Merge的时间,我们习惯性每个人有自己的Branch每周2时提交代码,大家一起参与,这样减少了好多由于代码管理浪费的时间。

  9、测试用例


  图7


  之前小的系统使用测试用例基本就是装B用的,本来小小的系统整套流程脑子一想就可知道怎么做啦,为什么还要浪费时间。但在这次开发中充分理解了测试用例的重要性。比如我需要你给我提供多台服务器的监控数据包括IO信息,CPU信息,NEt信息等等,但你还没有想到怎么样去抓取虚拟信息,不能由于你的问题去影响其他人的进度的,最好的方式从使用者角度获知他希望使用什么样的数据,为其建立API,同时为API建立测试用例并且保证测试稳定。而后期我有了监控虚机的方式后我在建立对应的适配方法适配到对应的API上。

  因此首先肯定要保证API的稳定,由于他之上的东西已经稳定了吗,你只好辛苦啦,有效的测试用例可帮助我们更好的剥离项目逻辑与协调组件系统。

  10、编码原则


  图8

  这个主要是每周有时间大家一起参与Code Review,因为开发人员的能力不同资历不同,因此总会在代码的编写上与建立出现太多的不统一。比如命名啦,变量声明啦,有的时候会发现刚毕业的小朋友会将好多的私有变量放在类的顶部,同时一个类里写太多的方法,而且有的方法好长,还没有注释。于是有时你想了解一个方法的真正含义,要鼠标各种滚动,到变量声明去了解真正用途,好烦的。

  有时代码的职责不明确,总是瀑布的思想方式去写代码,比如我们两个功能:

  (1)发送API请求建立虚拟机,

  (2)在虚拟机建立成功时候将操作Log写入db

  他们习惯性的将写DB的逻辑放在了发送HTTPRequst的方法里面,这完全是两个逻辑。另一个问题是由于创建虚拟机是需要时间的,同时尽管虚拟机操作成功有可能你写DB的时候网络原因DB失败了。我认为这应该是个原子的操作,两者的状态必须统一,就像是你在手机充值的时候显示银行卡扣金额成功,可是手机充值是出现问题,钱不是白花了吗。所以在这些有特殊逻辑的地方要建立特殊的统一的机制,不能每个人有各自的实现。

  11、之后就是沟通了


  图9

  因为项目涉及到多个项目组,我们并不是同一个部门,相互也不熟悉,因此沟通上就会有一些需要注意的。首先要了解“对手”,主要是因为若对方是个技术高手,你不能像个白痴小孩,要有所准备,最起码知道他们用什么开发语言,他们需要关注的业务逻辑,等等,不能让他们得到你是个菜鸟的结论。

  因为口头的好多东西可能是没有经过检验的东西,所以前几次达成的协议我们只是做个参考,需多次沟通之后才能确定结果,比如我们的项目中我们需要和Python组Java组协调消息接口,消息格式的时候。你要知道协调RabbitMQ时候我们需要定义下交互的Exchange,queue name 或者RoteKey等等,同时因为消息格式比较大,需要定义一些关键字或预设字段的话,需要发邮件进行确认与沟通,避免开发过程中产生误会影响完成的功能返工。

  总之这次搭架子的过程收获很多,一时半会也不能想的全面,以后慢慢聊,因为是第一次资历尚浅,好多的技术选型,问题考虑可能不成熟,也希望大家知道更多的能够纠错指导。


  图10

  下面就说一些我们在架构中使用的一些东西:

  (1) 开发语言:C#,java,Python;

  (2) 数据存储:缓存,文件(xml),MSsql,Mysql,Redis;

  (3) 数据交互:rest,json,RabbitMq;

  (4) 操作系统:ubuntu,windows;

  (5) 虚拟机监控:zabbix;

  (6) 搜索:solr;

  (7) 多线程,多层架构,模块式开发,组件式开发;