JavaEE-2020-01-多层架构及其应用领域

多层架构及其应用领域

Web架构

HTTP和HTML

HTTP(HyperText Transfer Protocol)是web浏览器与web服务器的交流方式约定.

  • 超文本(HyperText)指不仅有文本, 还有指向其它文件的链接, 以及图像, 声音, 视频等其它媒体方式的资源.

  • 网页(web page)是在浏览器中解释执行的符合HTML(HyperText Markup Language)格式的纯文本文件.

  • 超链接(hyperlink)指向服务器(网站)上的资源(网页和其它文件). 超链接是网页(web page)之间的导航方式. 网页之间的超链接把各个服务器上的页面链接在一起, 构成了WWW(World Wide Web).

  • 网页的内容 - HTML

    • 网页的样式 - CSS
    • 网页与用户的交互 - JavaScript
    • 转到其它网页 - 超链接
      JavaEE-2020-01-多层架构及其应用领域

HTTP协议的交互过程

  • 浏览器向服务器发送访问资源的请求
    • GET/POST… URL代表的网站资源
  • 服务器向浏览器向浏览器发送响应
    • HTML格式的网页
    • 或者其它文本格式, 例如
      • json文件 - 近几年很流行
      • Base64编码的二进制文件 - 可以传输任何文件

静态网页和动态生成网页

最初的Web用户在通过超链接导航, 在静态网页之间浏览固定的内容. 网站的维护者通过修改静态网页, 为用户提供新的内容. 例如: 每天修改新闻网页. 在只有静态网页的条件下, 用户与网站的交互操作, 例如发布信息, 是难以完成的.

用户与网站之间的交互, 可以实现为: 根据用户的操作, 在服务器上动态生成网页返回给用户. 动态生成网页的技术包括: CGI, Java Servlet, JSP, PHP, ASP等众多服务器端技术.

Java Web架构

支持多线程和网络通信的Java语言提供了Java Servlet技术用于在服务器上动态生成网页. 进一步演进出生成动态网页的模板JSP(Java Server Page).

  • Java Servlet是Java程序生成HTML文件. 想象一下, 用print()函数输出一个字符串作为网页的工作量!
    • Java代码中嵌入网页
  • JSP是在HTML文件中嵌入Java程序. Java程序的结果(字符串), 替换网页中Java程序. 像在网页文件中调用了一个Java函数, 得到函数的结果.
    • 网页中嵌入Java代码

JSP(Java Server Page)在服务器端动态生成网页.
JavaEE-2020-01-多层架构及其应用领域

服务器端JSP执行过程

  • 服务器接收浏览器的请求信息
    • 接收到的URL对应的资源
    • 接收到的来自浏览器的参数
  • URL对应的资源的处理方式
    • 静态资源
      • 直接返回资源对应的文件
    • 资源是JSP
      • 根据资源的名称, 找到对应的JSP文件, 生成对应的Servlet. 然后由对应的Servlet处理.
      • 可以看出JSP是Servlet的一种方便开发的简化.
    • 资源是servlet
      • 读取浏览器的请求中附带的参数
      • 执行servlet中的业务逻辑
      • 返回生成的响应(HTML文件/JSON文件/Base64编码的二进制文件等)

浏览器执行网页的过程

接收服务器传来的文件, 解码出文件内容. 如果是HTML文件(网页), 则按照内容的顺序执行网页中的脚本, 展示渲染网页中的内容.

浏览器只与HTTP协议, 网页的URL有关. 与服务器生成网页的技术无关.

架构演进

业务架构的演进

以银行为例展现架构的演变. [重要]

  • 最早期是一个人A0A_0负责全部存贷款活动, 相当于单层结构.

  • 随着业务的增加, 发现忙不过来了. 于是雇佣B0B_0负责记账. A0A_0负责接待客户和处理业务逻辑, B0B_0相当于数据库服务器.

    • 还有一个方案是加盟连锁, 雇佣A1A_1A0A_0自己做同样的业务. 但是客户的账户在A0A_0A1A_1之间同步需要时间和精力.
      • 随着业务的增加, 于是雇佣人数越来越多. A1,A2,...,AnA_1, A_2, ..., A_n做和A0A_0同样的负责接待客户和业务逻辑. nn可以任意大.
      • 账户同步的消耗越来越大. 完全同步是2n12^{n-1}, 通信量增长过快, 时间消耗过长.
        • 逐渐出现专门负责账户同步的MM. 形成P2P架构, 其关键是能够查询账户由哪个AiA_i负责.
        • 一个办法是不同步账户数据. 由每个AiA_i负责不同的客户, 采用专属客户经理制度.
          • 每个客户由其专属的客户经理AiA_i负责. 业务数据和业务处理局部化.
          • 客户之间的操作, 例如转账, 可能在需要多个客户经理参与. 形成分布式事务.
        • 还有是提升每个客户经理可以负责的客户数量, 进行业务活动过程分工, 与下面的情况相同.
  • 随着业务的继续增加, 可能发现A0A_0自己又忙不过来了. 于是雇佣了A1,A2,...,AnA_1, A_2, ..., A_n做和A0A_0同样的负责接待客户和业务逻辑. nn可以任意大.

    • B0B_0的工作量越来越大. 假设暂时还挺得住, 后面讨论记账的扩容问题.
  • 随着业务的继续增加, A0A_0觉得可以继续分工. 于是雇佣C0C_0负责处理业务逻辑. A0A_0A1,A2...,AnA_1,A_2...,A_n负责接待客户.

  • 随着业务的继续增加, C0C_0忙不过来了. 于是雇佣C1,C2,...,CmC_1, C_2, ..., C_m做和C0C_0同样的负责处理业务逻辑. mm可以任意大.

    • 客户来个由任意一个AiA_i接待, 交流好业务后, 到任意一个CjC_j处理业务逻辑, 到B0B_0记账.
  • 随着业务的继续增加, 终于B0B_0忙不过来了. 于是雇佣B1,B2,...,BpB_1, B_2, ..., B_pB0B_0同样负责记账.

    • 账户在B0...BpB_0...B_p之间同步, 需要话费时间和精力. - 分布式系统的延时造成数据一致性困难.
    • 多个客户对同一个客户的支付业务, 需要保持操作结果的正确性. - 需要操作的原子性, 数据一致性.
    • 其中B0...BoB_0...B_o负责记账, Bo+1...BpB_{o+1}...B_p负责查询余额开存款证明等查账服务. - 读写分离
  • 随着业务的增加, 账户同步的消耗越来越大. 于是考虑减少同步的需要.

    • 把客户的账户分区, 每个Bk{B0,...,Bp}B_k \in \{B_0,..., B_p\}只负责一部分账户. 每个账户只有特定的一个BkB_k负责. - 数据分区
      • 同步还是有的, 例如账户之间的转账. 可能两个账户在不同分区, 分布式事务出现了. 但毕竟一个BkB_k内的账户之间不用分布式事务.
    • 按照不同的业务把账户不同方面的信息, 由不同的BkB_k负责. 例如, 账户口令表, 账户余额表, 存款记录表, 取款记录, 贷款记录表等分给不同不同的BkB_k负责. - 数据库分表分库.
      • CjC_j处理一个业务时, 可能需要到几个不同的BkB_k. 增加了处理业务逻辑工作量.
      • 为了减少CjC_j的难度, 把业务逻辑按照账户的不同方面分开, 由不同的CjC_j负责. CjC_j需要处理的业务逻辑就简单一些了, 招人和培训变得容易, 功能也相对稳定.
      • 通过组合这些CjC_j就可能提供新业务, 例如, 组合出存款送鸡蛋活动, 贷款送大米等活动, 可以在原有的存款/贷款的基础上增加送鸡蛋, 送大米活动即可. 再招一批专门负责设计组织这些业务活动的D0...DqD_0...D_q. 称为市场经理.

总结一下:

  • A0...AnA_0...A_n负责客户交流, 然后领着客户到D0...DqD_0...D_q参加活动.
    • 活动的数量可能小于qq. 可以根据不同的客户分配给不同的市场经理.
  • D0...DqD_0...D_qC0...CmC_0...C_m的基本业务为基础模块, 设计业务活动流程.
    • 基本业务的数量可能小于mm. 可以根据不同的用户分配给不同的业务基础模块副本.
  • C0...CmC_0...C_m处理特定的业务逻辑, 并要求对应的B0...BpB_0...B_p负责记账.
  • 可能业务基础模块与记账模块(数据库)一一对应. 也可能几个模块公用一个数据库. 也可能一个基础业务模块需要使用多个数据库

这样的架构在可以业务分工, 用户分区两个维度进行业务容量的扩展. 当然也可以在雇员能力(单机性能)上左垂直扩展. 这些D0...DqD_0...D_qC0...CmC_0...C_m称为微服务.

软件架构模式的演进

从单机程序, 到C/S架构, B/S架构, 多层B/S架构, 多层架构, 微服务架构的演化过程如下.

应用场景 架构 效果
功能简单, 数据量小 单机架构 简单, 容易掌握
多用户 C/S架构 多用户并发执行业务
客户端程序部署速度慢, 升级工作量大, 用户数量大 B/S架构 用户有浏览器就可以工作
业务逻辑复杂 多层B/S架构 业务逻辑规范, 开发分工明确
多种客户端, 特别是移动客户端 多层架构 移动端和网页端功能一致
业务功能多, 业务流程变化大, 新业务上线时间短 微服务架构 开发新业务速度快, 版本更新快

多层架构

  • 展示层负责与用户进行交互, 或者与其他系统集成时, 负责与其他系统交互.

  • 服务层负责处理业务活动. 可以继续分为业务流程和业务领域对象.

    • 业务流程通过组织业务领域对象完成业务活动.
    • 领域对象包括具体业务的数据和业务执行规则.
  • 持久层负责记录业务数据.

微服务架构

微服务架构(microservice architecture)以具有单一职责/业务功能的可独立部署的模块(微服务), 通过独立于语言的API相互通信合作完成任务, 组成完整的应用程序(application). [^Wikipedia2019, martinfowler2019]. 通常采用HTTP作为微服务之间的通信协议.

应用领域

  • 多层架构主要应用于企业级软件开发和互联网软件开发.
  • 微服务架构主要用于互联网软件和互联网企业软件开发.

目前传统企业的业务系统主要用多层架构方式开发.

企业和客户交互的主要途径由接待人员向软件转移, 例如微信小程序点餐, 进而促进企业内部流程的信息化, 形成企业的软件化趋势.

Spring框架

Java开发Web应用的过程中, 积累了大量实现特定需求的组件, 技术和实践经验. 为集成这些组件和技术, 开发了用于集成各种组件的模板 - Spring框架. Spring提供了对多层架构, 云原生, 微服务开发的支持.

Spring的用途[^https://spring.io/]

Spring makes programming Java quicker, easier, and safer for everybody. Spring’s focus on speed, simplicity, and productivity has made it the world’s most popular Java framework.

What can Spring do?

  • Microservices.

    Quickly deliver production‑grade features with independently evolvable microservices.

  • Reactive.

    Spring’s asynchronous, nonblocking architecture means you can get more from your computing resources.

  • Cloud.

    Your code, any cloud—we’ve got you covered. Connect and scale your services, whatever your platform.

  • Web apps

    Frameworks for fast, secure, and responsive web applications connected to any data store.

  • Serverless

    The ultimate flexibility. Scale up on demand and scale to zero when there’s no demand.

  • Event Driven

    Integrate with your enterprise. React to business events. Act on your streaming data in realtime.

  • Batch

    Automated tasks. Offline processing of data at a time to suit you.