欢迎转载,请支持原创,保留原文链接:blog.ilibrary.me

前言

一直想设计一个巨无霸单体应用,

  1. 什么功能都可以往里面塞,
  2. 功能都可以配置,
  3. 最好还可以定制,
  4. 新功能可插拔。
  5. 最好是单体的,
  6. 所有的功能都高度内聚,
  7. 流程都是可配置的。

为什么是单体的?

因为如果要同时满足功能可以配置,可以定制,可以插拔,那么必然会牵涉到自动代码生成。如果是微服务的,每次定制一个功能,要改动好多项目的代码,改动不好同步, 怕是会很痛苦。如果是单体应用,那么只需要敲一下命令行,所有需要修改的地方都自动修改好了。

说到这里,好像问题出来了。上面说的不像是一个单体应用,更像是一个单体应用模板,或者单体应用生成器. 维护这个生成器本身又会成为一个大的负担, 整个流程变长,系统变复杂了. 如果是一个一直在跑的成熟的单体应用,那会简单很多。

架构和微服务

先理解一下以下概念:

  1. 微服务架构
    1. 微服务是一种通过多个小型服务组合来构建单个应用的架构风格,这些服务围绕业务能力而非特定的技术标准来构建。各个服务可以采用不同的编程语言,不同的数据存储技术,运行在不同的进程之中。服务采取轻量级的通信机制和自动化的部署机制实现通信与运维。
  2. 单体架构
  3. HTTP/REST, RPC和消息总线.
    1. 微服务对外应该通过无状态的REST API提供服务。微服务不能主动回call.
    2. 消息总线因为双向通信的关系,增加了状态的复杂性,增加了耦合性。
  4. SOLID原则 + DIP(依赖倒置) + CARP(合成服用原则)
  5. DDD(Domain-Driven Design领域驱动设计), 有点类似MVVM, 多加了一层领域层(VM)层。
    1. 这种设计好像很少见,可能太重了。
    2. 领域模型跟技术毫无关系,而是为了更有结构化的拆解和表达业务逻辑
  6. 六边形架构. 这个词一点也不形象,容易给人误解。我个人理解如下:
    1. 端口和适配器架构 (又称六边形架构)
    2. 六边形只是一个代号,没有特殊含义。
    3. 接口和实现分离.
    4. API: 应用对UI层提供一套服务接口, API, 供UI层调用.
    5. 驱动适配器: 应用对数据库层和其它底层(基础设施)提供一套服务接口定义,供它们适配。基础设施通过适配器注入到应用中来供应用调用。
    6. 前后端分离的Rails App可以理解为是六边形架构的经典实现。
    7. Rails Console也可以理解为六边形里面的UI(访问)的一种形式。
    8. Rails Active Record可以理解为一个通配的数据库驱动适配器。各个数据库通过适配Active Record来把自己注入到系统中来,供系统调用。
  7. MVC
  8. MVVM

简单一点理解,上面的4及以后的概念都是在单体架构这个框架内讨论的。

微服务和单体架构是服务架构模式,不是代码架构模式。服务是代码之上的一种概念,是一种业务逻辑的抽象,描述和约定了输入什么,什么情况下会输出什么。 具体的功能细节还是由代码实现。

记住软件架构设计里面的一条万金油法则: 没有任何是不能通过多加一层抽象来解决的,如果有,那就再加一层。

K8S和Spring Cloud

  1. Spring Cloud是应用层的微服务治理框架。对Spring深度绑定,并且很多概念太重,不建议学。
  2. K8S是基础设施层的服务治理技术. 可以有效屏蔽具体的语言实现,通过容器和强大的私有网络技术解决微服务治理的问题,把服务治理彻底从应用层剔除掉.
  3. Spring Cloud终究会被淘汰, K8S才是王者。

表 1-1 传统 Spring Cloud 与 Kubernetes 提供的解决方案对比

Kubernetes Spring Cloud  
弹性伸缩 Autoscaling N/A
服务发现 KubeDNS / CoreDNS Spring Cloud Eureka
配置中心 ConfigMap / Secret Spring Cloud Config
服务网关 Ingress Controller Spring Cloud Zuul
负载均衡 Load Balancer Spring Cloud Ribbon
服务安全 RBAC API Spring Cloud Security
跟踪监控 Metrics API / Dashboard Spring Cloud Turbine
降级熔断 N/A Spring Cloud Hystrix

问题

当前软件开发领域面临的问题

  1. 社会分工越来越细, 软件需要集成的各种服务越来越多.这些第三方服务的继承往往都只需要通过修改配置,改极其少量的代码就可以完成。但是修改配置又是一件容易出错的事情。
  2. 软件需求越来越复杂。 社交都能玩出各种稀奇古怪的玩法, 电商的玩法也是千奇百怪,各种营销工具就更加不用说了。
  3. 软件技术层出不穷。每种软件技术都还有自己擅长的方面和不擅长的方面,没有哪种语言或者技术能一统天下. 这个开发者带来极大的学习成本。
  4. 轮子越来越多. 每个项目都把以前做过的功能重新做一遍,并且还质量不一定有以前做得好。严重浪费社会资源.

为什么会需要巨无霸应用?

因为现在重复的代码太多,轮子也太多。类似的功能反复做,反复造轮子, 浪费社会资源。现在非常流行的低代码,无代码就是非常好的一种避免反复造轮子的形式。

案例分析

挑选一些典型的应用来分析,方便从可扩展性, 可挂载性, 工作流引擎,自动代码生成, 项目模板几个方面来挑选项目分析.

  1. Redmine, 一个项目管理系统, 有插件扩展机制.
  2. Spree, 一种可挂载的完整的服务,还可以自定义扩展
  3. Apache/Airflow, Apache下面的一个开源工作流引擎。
    1. Apache isis tutorial, isis教程.
  4. Apache/isis, 一个自动生成UI和API的方案.
  5. Odoo, 一个开源ERP项目.
  6. Ofbiz, Apache开源ERP项目,是一个Java框架,包含一个ofbiz plugin.
  7. Azure, 研究Azure的整体架构,有助于理解怎么设计可扩展的系统。

附加项:

  1. Expo.

基础原则

必须有一些设计方面的基础原则,保证设计不会跑太偏。

  1. 限定范围。要明确哪些东西需要考虑,哪些不应该考虑.
  2. 选一个明确的架构方案, 保证设计沟通的时候有一个主线。
    1. 现在各种架构多如牛毛。如MVC, MVVM, DDD, 六边形.
    2. 网上有各种文章解释这些架构。非常方便不同的人理解学习学习这些思想。
    3. 这些架构属于能高效的传递设计思想,保证架构沟通的顺畅。
    4. 选用公开的架构有助于和第三方服务代码的集成。
  3. 要方便测试。
    1. 东西多了就难免会相互干扰。单元测试是代码质量和逻辑稳定性的第一堡垒。一定要方便测试,并且要有足够的测试覆盖。
    2. 代码重构也极度依赖于单元测试。
    3. 不方便测试的方案不能选用。
  4. 方便调试。
    1. 一旦系统上线,会有各种奇葩的问题出现。甚至会有很多乌龙出现。如果没有一种非常方便的调试机制,光处理各种线上问题都会把人搞死。
    2. 数据要好回放.
    3. 日志要清晰具体。还要方便检索定位.
    4. impersonate.
  5. 自我诊断
    1. 在线数据的自我诊断. 系统跑到一定程度,很多数据就慢慢开始不符合系统的规定了。可能是历史数据迁移的时候未迁移好。也可能是某些数据跑创建的时候抛异常,系统遗留了脏数据。还有可能是管理人员不太合规范的数据操作导致的。这些都应该能被识别出来,如果能自我修复,那是最好的。
    2. 数据有效性检查是最基础的。
  6. 要方便接入APM.
    1. APM可以高效诊断在线系统的性能。
    2. APM还能高效定位代码出错的位置。
  7. 方便的文档生成工具.
    1. API说明文档,swagger.

方案设计

  1. 巨无霸单体
  2. 微服务集合
  3. 低代码应用
  4. 项目模板/生成器

解藕

即便是单体应用,也要有很好的解藕性,保证在业务发展到一定程度以后可以扩展,拆分。

解藕的方法:

  1. 前后端分离. 前后端分离保证了业务的代码无关性。
    1. 前后端通过标准的HTTP请求来通信,只要都遵循HTTP标准, 前端可以随意替换技术方案,后端也可以随意替换技术方案。
    2. 并且,前端都可以整体替换,也都可以局部小范围替换。后端也是如此。彼此无感知。
    3. 可以方便整合第三方代码和服务。
  2. SSO/JWT. 通过SSO/JWT方案,可以打通不同的系统,可以做到服务级别的隔离,节藕程度更加高。
  3. 用K8S部署.
    1. K8S部署的好处是在方案替换的时候可以分流,新老方案共存,相互验证。保证平滑过渡。

参考

  1. Github - How To Build Monolithic System
  2. 清晰架构(01): 融合 DDD、洋葱架构、整洁架构、CQRS…(译)
    1. 英文原文, DDD, Hexagonal, Onion, Clean, CQRS, … How I put it all together
  3. 凤凰架构