【架构入门 - 可扩展篇】

Posted by 王天一 on 2019-05-18

随着服务的壮大,使用人数的增多,业务的递增,服务的扩展性尤为关键,在不影响现有架构的情况下如何增加机器、扩展功能?

基本思想和模式

一个字:。把大的系统拆为小的系统,下面是拆分的几个不同方法,也是拆分依赖的不同维度,以学生信息管理系统为例:

  • 面向流程拆分。将整个业务流程拆分为几个阶段,比如展示层、业务层、数据层、存储层
  • 面向服务拆分。将系统提供的服务拆分,比如注册登录服务、信息管理服务
  • 面向功能拆分。将系统提供的功能拆分,比如将注册登录服务拆得更细致,从而有手机号注册登录、邮箱注册登录

那么我们作为架构师,应该如何选择呢?就是需要明白不同拆分方式的优缺点,适用的场景:

  • 面向流程拆分。扩展时大部分情况只需要修改某一层的时候。比如将存储层从MySQL扩展为同时支持Oracle,就只需要扩展存储层和数据层即可
  • 面向服务拆分。扩展时大部分情况只需要对某个服务扩展,或增加新的服务时。比如要增加身份证注册功能,只需要修改注册服务
  • 面向功能拆分。扩展时大部分情况只需要对某个功能扩展,或增加新的功能时。比如要增加身份证注册功能,无需修改任何服务,只需要增加一个新的功能模块即可

面向流程拆分:分层

很常见的架构模式,也叫N层架构,N至少是2,比如:

1)C/S、B/S架构

划分的对象时整个业务系统,将和用户交互的部分独立为一层,后台作为另外一层,如图:

2)MVC架构

划分的对象是单个业务系统,将不同的职责划分开

3)逻辑分层架构

划分的对象可以是单个业务子系统,也可以是整个业务系统,将不同的职责划分开,与MVC架构不同在于逻辑分层架构中的层是自顶向下依赖的。比如操作系统内核架构、TCP/IP架构,比如安卓操作系统:

分层架构的核心在于:保证各层之间的职责差异足够清晰。之所以能够支撑系统扩展,本质在于隔离关注点,就是每层中的组件只处理本层的逻辑。这样就可以支持系统在某层上的快速扩展

但是除开分层,还需要保证层与层之间的依赖是稳定的,才能真正支撑快速扩展,这个依赖就是接口

Linux内核为支撑不同的文件系统格式,抽象出来VFS文件系统接口,如上。如果没有VFS,那么即使增加一个文件系统,也无法将依赖文件系统的系统应用上新的文件系统,因为并不知道接口是什么,而VFS统一了

优势:各层之间自顶而下结构清晰、强制约束层之间的关系是两两依赖,依赖的数量固定
缺点:如果层级多,强制两两依赖将导致性能、实现上的浪费,架构也会混乱
场景:适用互联网架构整体分层、操作系统分层,不适合互联网架构后台服务

面向服务拆分:SOA、微服务

SOA

Service Oriented Architecture,面向服务的架构,是上世纪90年代就已经出现的架构模式:

  1. 服务。所有业务都是一项服务,服务就要对外提供开发的能力,其他系统可以直接使用
  2. ESB,Enterprise Service Bus,企业服务总线,类似于计算机总线,ESB将企业中各个不同的服务连接在一起,并对外提供各式各样需要的接口。功能强大,但需要完成非常多的协议和数据格式的相互转换,工作量巨大,且耗费大量计算性能,容易成为系统的性能瓶颈

微服务

微服务这几年很火,但也在早就出来了,只不过Martin Fowler将它发扬光大

与SOA的区别:

  1. 服务粒度。微服务更细,SOA对应的是"员工管理系统",微服务是"员工管理系统-员工信息管理"服务
  2. 服务通信。微服务仅仅使用统一的消息格式如RESTFul、RPC就好了,而SOA的ESB将服务定义、路由、消息转换、传递都给实现了,是重量级的
  3. 服务交付。微服务的交付理念是"持续交付",需要使用自动化测试、持续集成、自动化部署的敏捷最佳时间,而SOA没有要求
  4. 应用场景。微服务适合快速、轻量级的Web互联网系统,而SOA适合庞大、复杂、异构的企业级系统

但微服务的坑是相当的多,稍有不慎就会陷入焦油坑,最后发现某些情况下几个单体应用的架构甚至甩了微服务好几条街

比如:服务划分过细导致服务关系复杂、团队开发效率下降、调用链太长性能下降、定位问题困难、对运维自动化要求极高、微服务数量递增管理难度极大…从而步了SOA的后尘

更多微服务资料可参看:https://www.wangtianyi.top/blog/2017/04/16/microservies-1-introduction-to-microservies/

面向功能拆分:微内核

包含两类组件:

  1. 核心系统。负责系统的功能组件如模块加载,模块间通信
  2. 插件模块。实现具体的业务逻辑比如手机号注册功能

比如在规则引擎架构上有以下体现,比如电商促销中会有很多规则,不可能把规则都写到代码里,那样完全无法有效扩展,架构如下:

设计关键点在于:

  1. 插件管理。数据库
  2. 插件连接。自己开发的规则引擎维护连接方式
  3. 插件通信。数据流或事件流,规则之间不需要相互依赖,只要向规则引擎输出内容

参考

https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/

号外号外

最近在总结一些针对Java面试相关的知识点,感兴趣的朋友可以一起维护~
地址:https://github.com/xbox1994/2018-Java-Interview