一、应用分层
1.为什么要分层?
拿餐饮举例,当你只是一个摊位的时候可以一个人制作所有流程,当客户多的时候揽客、点餐、制作等等就有顾不上忙不过来的地方了, 这时候必然要分工了,点菜、收银、厨师、送餐等。对应到软件系统工程中就是为了可扩展性和可维护性。
总结软件项目分层目的:
- 隐藏下层业务逻辑的复杂性
- 提高系统的组件化和可维护性
2.推荐业务分层
分层模型图
解释:
- 开放 API 层:可直接封装 Service 接口暴露成 RPC 接口;通过 Web 封装成 http 接口,网关控制层等。
- 终端显示层:各个端的模板渲染并执行显示的层。当前主要是 velocity 渲染,JS 渲染,JSP 渲染,移动端展示等。
- 请求处理Web 层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
- Service 层:相对具体的业务逻辑服务层。
- Manager层:通用业务处理层
- 对第三方平台封装的层,预处理返回结果及转化异常信息,适配上层接口(防腐层的概念)。
- 对Service层通用能力的下沉,如缓存方案、中间件通用 处理。
- 与DAO层交互,对多个DAO的组合复用。
- DAO 层:数据访问层,与底层 MySQL、Oracle、Hbase、SQLSERVER 等进行数据交互。
- 第三方服务:包括其它部门 RPC 服务接口,基础平台,其它公司的 HTTP 接口,如微信开放平台、支付宝付款等
- 外部数据接口:外部(应用)数据存储服务提供的接口,多见于数据迁移场景中
领域模型解释
- DO(Data Object):此对象与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
- DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。
- BO(Business Object):业务对象,可以由 Service 层输出的封装业务逻辑的对象。
- Query:数据查询对象,各层接收上层的查询请求。超过 2 个参数的查询封装,禁止使用 Map 类来传输。
- VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。BO对象也可以接受修改数据
分层异常处理
- DAO层:异常类型很多,不需要打印日志
- Manager/Service层:必须记录出错日志到磁盘,尽可能带上参数信息,保护案发现场
- Web层:绝不能往上抛异常,应跳转到友好错误页面,友好错误提示信息
- 开放接口层:将异常处理成错误码和错误信息方式返回
二、java构建
目前java构建工具主要有
- Apache Ant:早期工具,具有编译、测试、部署等功能,逐渐淘汰,不推荐使用
- Maven:目前java后端主流构建工具
- Gradle:比较新的工具,主要在android开发上使用,使用Groovy替代了maven的xml配置
Maven主要功能
- 依赖管理
- 规范目录结构
- 完整的项目构建阶段
- 支持多种插件
maven项目依赖的几个原则
- 按照DependencyManager版本声明进行仲裁
- 如果没有仲裁声明则按照依赖最短路径确定版本(例如项目引用了A包,A包又依赖了B包,那么项目对AB包的依赖路径为2)
- 若相同路径,则按照第一声明优先原则
排除依赖
<dependency>
<groupId>org.xxx</groupId>
<artifactId>xxxx</artifactId>
<!-- 排除的jar包列表 -->
<exclusions>
<!-- 排除的jar包 -->
<exclusion>
<groupId>组织名</groupId>
<artifactId>模块名称</artifactId>
</exclusion>
</exclusions>
</dependency>
几个排除依赖工具
- idea企业版的依赖图 show dependencies(热键 ctrl+alt+shift+u)
- idea社区版的依赖表
- maven命令
mvn:dependency:tree
三、二方库
名词解释:
-
一方库:工程内部
-
二方库:公司内部不同团队开发的依赖库
-
三方库:公司之外的开源库
-
工程坐标GAV: groupid、artifactid、version
声明规范
- groupID规范
格式:com.{公司/BU }.业务线 [.子业务线],最多4 级。 - Artifactid规范
格式:产品线名-模块名。语义不重复不遗漏 - 版本号
- 主版本号:产品方向改变,或者大规模API不兼容
- 次版本号:保持相对兼容,增加主要功能特性,影响范围极小
- 修订号:保持完全兼容,修复bug或新增次要功能特性。
工程坐标GAV: groupid、artifactid、version
- 线上应用不要依赖 SNAPSHOT 版本
- 正式发布的类库必须去中央仓库查证,使 RELEASE 版本号有延续性,
- 正式发布的类库版本号不允许覆盖升级。
- 二方库的新增或升级,保持除功能点之外的其它 jar 包仲裁结果不变。
- 二方库里定义的枚举类型,参数中可以使用返回值不允许使用
- 依赖于一个二方库群时,必须定义一个统一的版本变量,避免版本号不一致
- 禁止在依赖中出现相同的 GroupId,相同的 ArtifactId,但是不同的 Version。
二方库引用规约
- 线上应用不要依赖 SNAPSHOT 版本
- 正式发布的类库必须去中央仓库查证,使 RELEASE 版本号有延续性,
- 正式发布的类库版本号不允许覆盖升级。
- 二方库的新增或升级,保持除功能点之外的其它 jar 包仲裁结果不变。
- 二方库里定义的枚举类型,参数中可以使用返回值不允许使用
- 依赖于一个二方库群时,必须定义一个统一的版本变量,避免版本号不一致
- 禁止在依赖中出现相同的 GroupId,相同的 ArtifactId,但是不同的 Version。
二方库引用建议
- 底层基础技术框架、核心数据管理平台、或近硬件端系统谨慎引入第三方实现。
- 所有版本仲裁使用 语句块
- 二方库不要有配置项
- 不要使用不稳定的工具包或者 Utils 类
二方库发布原则
- 精简可控原则
a. 移除不必要的API和依赖
b. 只包含ServiceAPI、以及必要的工具类
c. 如果依赖其他 二方库,尽量provided引入
d. 无具体log实现,只依赖日志框架 (比如slf4j) - 稳定可追溯原则
a. 记录每个版本的变化
b. 标记二方库维护者
c. 源码位置
d. 公共二方库的行为不变
四、服务器相关
- 调小服务器TCP协议time_wait超时时间
- 调大服务器索支持的最大文件句柄数fd(File Descriptor)
默认值为1024,建议根据内存调整到数倍大小。 - JVM环境参数设置
a. XX:+HeapDumpOnOutOfMemoryError 参数 JVM 碰到 OOM场景时输出 dump 信息
b. JVM的Xms和Xmx设置一样大小的内存容量,避免在GC后调整堆大小带来的压力