## 12.2 单体系统到系统拆分
如果你对上一节还有疑惑,在想为什么我不把所有系统放到一个工程里,打成一个war包,也就是我们所谓的单体系统呢?
单体系统确实是一种常见系统设计方式,这十几年年来最主要的设计方式。单体系统的所有功能都在一个工程里,打成一个war包,部署。这样有如下明显好处
* 单体系统开发方式简单,我们从刚开始学习编程,就是完成的单体系统,开发人员只要集中精力开发当前工程
* 容易修改,如果需要修改任何功能,都非常方便,只需要修改一个工程范围的代码
* 测试简单,单体系统测试不需要考虑别的系统,避免本书下册要提到的各种REST,MQ调用
* 部署也很容易:不需要考虑跟别的系统关系,直接打war包部署到Web服务器即可
* 性能容易扩展,可以通过Nginx,把一个应用部署到多个服务器上。
随着业务发展,重构,单体系统越来越多,在开发一个庞大的单体系统的时候,就会有如下弊病
* 单体系统庞大,越来越难理解单体系统,微小的改动牵涉面广泛导致开发小组小心谨慎,开发速度会越来越慢。另外,启动一个庞大的单体系统,可能需要3分钟,或者更多时间
* 多个功能在同一个单体系统上开发,导致测试越来越慢,比如,测试必须排期,串行测试
* 单体系统如果想对技术进行更新换代,那代价非常大,如果是个小系统构成,则可以选取一个小系统先做尝试。单体大系统是几乎不可能做技术升级的
* 单体系统的所有功能运行在同一个JVM里,功能会互相影响,比如一个统计上传word文档的页码的功能由于非常消耗CPU,因此,会因为调用统计功能,导致整个系统短暂都不可用,出现假死的现象
因此,越来越多的架构师在设计系统的时候,会考虑系统拆分成多个单体小系统甚至是微服务。对于传统企业应用,拆成小系统更合适,对互联网系统,使用微服务个更合适,这是因为
* 传统IT系统本质上还是会用一个数据库,而微服务提倡的是一个服务一个数据库
* 传统IT系统很少需要调用其他模块服务。传统IT系统通过工作流来串联其他子系统。而电商类的微服务则是通过RPC等方式进行交互,是一个轻量级协议。传统IT系统也可以通过SOA,JMS跟其他系统(非子系统)交互,采用重量级协议
* 微服务对系统的基础设施要求很高,比如微服务治理,弹性库等等,只要电商系统才有人力物力去做这种事情,而传统IT系统,及时财大气粗,也暂时不具备微服务那样的IT基础设置
因此,对于大多数传统IT应用来说,单体拆分小系统在技术上没有风险,是一个可以立即实施的架构。如下是一个单体系统拆分后的物理架构
![design](https://box.kancloud.cn/75653e93821a56a762392539607bdad4_1376x700.png)
对于用户来说,访问不同的菜单功能,讲定位到不同的子系统,提供服务。
> 关于如上物理架构实现,在本书的下册。plus系统即可以拆分成小系统,也可以作为一个单体系统来设计。这一章主要介绍plus系统的核心功能和开发方法
- 再版说明
- 1 前言
- 1.1 内容介绍
- 1.2 Java EE
- 1.2.1 Java EE 架构
- 1.5 如何阅读本书
- 1.6 本书第二版与第一版区别
- 1.7 本书例子
- 1.8 购买正版
- 2 Spring Boot 基础
- 2.1 检查Java环境
- 2.2 安装IDE
- 2.3.1 安装Eclipse
- 2.3.2 安装Idea
- 2.3.3 Idea和 Eclipse 区别
- 2.3 Maven安装和配置
- 2.3.1 Maven介绍
- 2.3.2 安装Maven
- 2.3.3 pom文件构成
- 2.3.4 设置Maven镜像
- 2.3.5 IDE设置Maven
- 2.4 Spring框架
- 2.4.1 Spring 历史
- 2.4.2 Spring 容器介绍
- 2.4.3 Spring 常用注解
- 2.5 Hello,Spring Boot
- 2.5.1 创建一个Maven工程
- 2.5.2 增加Web支持
- 2.5.3 hello world
- 2.5.4 使用热部署
- 2.5.5 添加Rest支持
- 2.5.6 配置HTTP监听端口
- 3 MVC框架
- 3.1 集成MVC框架
- 3.1.1 引入依赖
- 3.1.2 Web应用目录结构
- 3.1.3 Java 包名结构
- 3.2 使用Controller
- 3.3 URL 映射到方法
- 3.3.1 @RequestMapping
- 3.3.2 URL路径匹配
- 3.3.4 HTTP method匹配
- 3.3.5 consumes和 produces
- 3.3.6 params和header匹配
- 3.4 方法参数
- 3.4.1 PathVariable
- 3.4.2 Model&ModelAndView
- 3.4.3 JavaBean接收HTTP参数
- 3.4.4 @RequsestBody接收JSON
- 3.4.5 MultipartFile
- 3.4.6 @InitBinder
- 3.5 验证框架
- 3.5.1 JSR-303
- 3.5.2 MVC中使用@Validated
- 3.5.3 自定义校验
- 3.6 WebMvcConfigurer
- 3.6.1 拦截器
- 3.6.2 跨域访问
- 3.6.3 格式化
- 3.6.4 注册Controller
- 3.7 Redirect 和 Forward
- 3.8 通用错误处理
- 3.9 异步请求
- 3.10 处理静态资源
- 3.11 调用Service
- 3.11.1 申明一个Service类
- 3.11.2 事务管理
- 3.12 CURL 命令
- 4 视图技术
- 4.1 Json技术
- 4.1.1 SpringBoot中使用Jackson
- 4.1.2 配置Jackson
- 4.1.3 Jackson三种使用方式
- 4.1.4 Jackson 树遍历
- 4.1.5 对象绑定
- 4.1.6 流式操作
- 4.1.7 Jackson 注解
- 4.1.9 集合的反序列化
- 4.1.10 关于Jackson性能说明
- 4.2 Beetl模板引擎
- 4.2.1 安装Beetl
- 4.2.2 设置定界符号和占位符
- 4.2.3 自动检测模板变化
- 4.2.4 GroupTemplate
- 4.2.5 使用变量
- 4.2.6 表达式
- 4.2.7 控制语句
- 4.2.8 函数调用
- 4.2.9 格式化函数
- 4.2.10 直接调用Java
- 4.2.11 标签函数
- 4.2.12 HTML标签
- 4.2.13 安全输出
- 4.2.14 配置Beetl
- 4.2.15 布局
- 4.2.16 验证模板
- 4.2.17 脚本引擎
- 4.2.18 为什么选择Beetl
- 5 数据库访问
- 5.1 配置数据源
- 5.2 Hikari 配置选项
- 5.3 JDBC Template
- 5.3.1 查询
- 5.3.2 修改
- 5.3.3 JdbcTemplate 增强
- 5.3 Spring Data JPA 支持
- 5.3.1 创建Entity
- 5.3.2 简化Entity
- 5.3.3 Repository
- 5.3.4 CrudRepository
- 5.3.5 PagingAndSortingRepository
- 5.3.6 JpaRepository
- 5.3.7 持久化Entity
- 5.3.6 Sort
- 5.3.7 Pageable和 Page
- 5.3.8 基于方法名字查询
- 5.3.9 @Query 查询
- 5.3.10 使用JPA Query
- 5.3.11 Example 查询
- 5.3.12 一个使用JPA糟糕回忆
- 6 BeetlSQL
- 6.1 BeetlSQL 特点
- 6.2 配置BeetlSQL
- 6.3 一个例子
- 6.3.1 创建实体对象
- 6.3.2 创建Dao
- 6.3.3 编写Service
- 6.3.4 编写一个复杂的SQL
- 6.4 SQLManager
- 6.5 Mrakdown 文件
- 6.6 跨数据库
- 6.6 翻页查询
- 6.7 实体对象和多表结果集
- 6.8 直接使用SQL
- 6.9 Query 类
- 6.10 代码生成
- 6.11 BeetlSQL函数
- 6.11 一些重要注解
- 6.11.1 @Table
- 6.11.2 @Version
- 6.11.3 @SqlResource
- 6.11.4 @SqlProvider
- 6.11.5 自定义注解
- 6.12 重要配置事项
- 6.13 扩展BeetlSQL
- 6.14 主从支持
- 6.15 最佳实践
- 7 MyBatis
- 7.1 Spring Boot 集成
- 7.2 编写Mapper文件
- 7.2.1 查询
- 7.2.2 更新语句
- 7.2.4 SQL片段
- 7.3 动态SQL
- 7.4 MyBatis-Plus集成
- 8 Spring Boot 配置
- 8.1 SpringBoot 配置
- 8.1.1 服务器配置
- 8.1.2 使用其他Web服务器
- 8.1.3 配置启动信息
- 8.1.4 配置浏览器显示ico
- 8.2 日志配置
- 8.3应用配置读取
- 8.3.1 Environment
- 8.3.2 @Value
- 8.3.3 @ConfigurationProperties
- 8.4 SpringBoot 自动装配
- 8.4.1 @Configuration和@Bean
- 8.4.2 Bean条件装配
- 8.4.3 Class 条件装配
- 8.4.4 Environment装配
- 8.4.5 其他条件装配
- 8.4.6 联合多个条件
- 8.4.7 Condition接口
- 8.4.8 制作Stater
- 8.5 Application.properties
- 8.6 其他配置
- 8.6.1 静态文件配置
- 8.6.2 热启动配置
- 8.7 HikariCP配置
- 9 部署Spring Boot 应用
- 9.1 以Jar文件运行
- 9.2 以war方式部署
- 9.3 多环境部署
- 9.4 @Profile
- 9.5 Launcher
- 10 Testing 单元测试
- 10.1 JUnit 介绍
- 10.1.1 Junit相关概念
- 10.1.2 Junit 测试
- 10.1.3 Assert
- 10.1.4 Suite
- 10.2 Spring Boot 单元测试
- 10.2.1 测试范围依赖
- 10.2.2 SpringBoot 测试脚手架
- 10.2.3 测试Service
- 10.2.4 测试MVC
- 10.2.5 完成MVC请求模拟
- 10.2.6 比较 MVC返回结果
- 10.2.7 JSON 比较
- 10.3 Mockito
- 10.3.1 模拟对象
- 10.3.2 模拟方法参数
- 10.3.3 模拟方法返回值
- 10.4 @Sql
- 11 AOP和事务
- 11.1 AOP
- 11.2 事务和Spirng 事务管理
- 11.2.1 事务处理
- 11.2.2 隔离保护
- 11.2.3 Spring Boot 事务管理
- 11.2.4 分布式事物
- 12 Spring Boot Plus 安装
- 12.1 代码工程
- 12.2 单体系统到系统拆分
- 12.3 安装
- 12.4 核心模型
- 12.4.1 Function
- 12.4.2 Menu
- 12.4.3 Role
- 12.4.4 User表
- 12.4.5 数据字典表
- 12.4.6 审计表
- 12.5 代码生成
- 12.5.1 子系统生成
- 12.5.1 配置子系统
- 12.5.2 业务代码生成
- 12.6 权限系统原理
- 12.6.1 功能权限
- 12.6.2 数据权限
- 12.6.3 加密
- 12.7 Plus的配置类