第 10 周总结 + 作业
总结
本周课程内容是微服务和DDD。除了概念上的讲解,更多的是案列分享和引导思考。
巨无霸单体应用的问题
随着业务的发展,应用也会从小到大成长为一个巨无霸,而且多半是一个单体巨无霸。所谓单体巨无霸就是一个大而全的独立部署的应用,比如word就是一个典型的桌面单体应用。成功的互联网应用多会经历单体巨无霸阶段,也就是一个应用包含几乎所有功能,甚至模块划分都不清晰,依赖混乱。
构建的困难
说到单体巨无霸,脑海里浮现的第一个是当年用友实习时接触到的ERP。当时NC5就是CS模式下的单体巨无霸,前端是一个Swing桌面客户端,后端是一个单体EJB应用。按功能分,NC5中有用户模块,财务模块,库存模块,物料模块,权限管理,报表模块等等。无论前后端构建打包都是小时级的过程。另一个例子是EMC的VNX Unisphere,一次打包7小时,所以打包只能在晚上通过CI完成,任何一次打包失败都意味着要推迟一天测试。
构建缓慢是单体的一个重要缺陷,为此催生了许多新技术,比如三位大牛在Google等待系统构建时,一时兴起就发明了Go语言。
SCM的困难
巨无霸的开发需要很多人力。代码多,人多,必然版本冲突也不少,使得SCM也不是件容易的事。往往一个小改动,可能要多次合并分支,因为构建时间很长,不能很快得发现构建错误,需要多次修改再合并。而且即使一切顺利,等待上次构建的时候,其它更改抢先,你也不得不一再推迟合并。
资源浪费
各种资源,比如内存,线程池,缓存,连接池等等,因为各个部门在分别开发时很可能各自为政,独立发展一些实现,造成资源浪费。
变更困难
对巨大的单体,任何修改都有潜在的风险。哪怕修改一个bug,都可能在意想不到的地方造成新问题,更遑论要增加新需求。依赖混乱很容易造成bug影响的扩散,而且不易发现。
拆分模块
对于以上问题,解决办法就是拆分模块,独立部署。分开部署可以降低耦合,也限定了边界,不至于扩散。对模块的升级回滚也相对容易,从而提高应用的可用性。由此发展出SOA体系。但是由于web service等技术过于复杂低效,很难在大规模互联网应用中使用,而以IBM为代表的SOA只在企业级开发中占一席之地。
微服务
SOA体系复杂,对核心组件微型化后,就诞生了微服务架构。微服务架构保留了服务注册,服务和服务请求。所用协议简化为HTTP或轻量的RPC,所以ESB的协议转换职能消失,而消息队列成为可选组件。
微服务框架
为了实现微服务架构,即使每个微服务可以使用不同的技术栈,但是实践中还是会采用某种框架,至少开发组会采用特定的框架,以达到稳定的开发和工程的标准化。Java语言有大量的框架,国外有Spring Cloud,国内有Dubbo。
框架通常要支持:
服务注册
服务调用
失效转移
客户端负载均衡
Service Mesh
Service Mesh也常常被称为微服务架构2.0。第一代的框架需要自主集成限流,降级和熔断等通用,加上服务注册,发现和调用,框架对平台的绑定,导致微服务不微,反而相当庞杂。Service Mesh就是帮助分离微服务架构中的关注点,让服务本身可以采用合适的技术栈而专注于业务,由SideCar负责公共关注点。这样,服务只需和SideCar做简单通信,由SideCar完成SDN。
领域驱动开发
DDD是一种软件开发流程,不仅仅是软件设计方法论。DDD的理念让人耳目一新,但是很多落地尝试都失败了。
事务脚本+贫血模型
无状态的control+service+dao是经典的事务脚本结合贫血模型。service没有状态,本质是一个事务脚本,操作没有业务方法的业务对象完成事务。
这种开发方法造就出CRUD程序员,但是其优点是可行,简单。
领域模型+充血模型
领域模型是对领域中实体和业务的模型。充血模型的对象内部封装数据,具有业务方法。这种方式是对业务领域的映射,是正确的面向对象,但是实现复杂。DDD的战略和战术设计,实体,值对象,聚合根的划分等,都是为了能更容易的实现正确的面向对象的充血模型,进而在领域模型上完成业务。
作业
Dubbo的一次服务调用过程
版权声明: 本文为 InfoQ 作者【林毋梦】的原创文章。
原文链接:【http://xie.infoq.cn/article/03bb541e8b0858a32d64654ce】。
本文遵守【CC BY-NC】协议,转载请保留原文出处及本版权声明。
评论