文章目录
- 引言
- 一、应用分层架构设计
-
- [1. 层次划分](#1. 层次划分)
- [2. 异常处理规范](#2. 异常处理规范)
- [3. 数据模型规范](#3. 数据模型规范)
- 二、二方库依赖管理
-
- [1. GAV(GroupId, ArtifactId, Version)规范](#1. GAV(GroupId, ArtifactId, Version)规范)
- [2. 二方库版本号命名规则](#2. 二方库版本号命名规则)
- [3. 统一版本管理](#3. 统一版本管理)
- [4. 避免枚举类型在API中的使用](#4. 避免枚举类型在API中的使用)
- 三、服务器配置与优化
-
- [1. 调整 TCP 协议的 time_wait 超时时间](#1. 调整 TCP 协议的 time_wait 超时时间)
- [2. 增加文件句柄数](#2. 增加文件句柄数)
- [3. 设置 JVM 参数以应对 OOM 问题](#3. 设置 JVM 参数以应对 OOM 问题)
- [4. 保持堆内存大小一致](#4. 保持堆内存大小一致)
- 小结
![](https://i-blog.csdnimg.cn/direct/028745c48d464ffa9e3e83f5d773b679.png)
引言
在软件开发中,系统架构的设计至关重要,尤其是在高并发、分布式以及复杂业务需求的场景下。为了保证系统的高效、稳定以及可维护性,采用合理的架构设计和规范是非常关键的。接下来,我们将深入探讨应用分层的架构设计、二方库依赖的管理策略、服务器配置与优化等多个方面。
一、应用分层架构设计
应用分层架构是一种常见的架构模式,通过将系统划分为不同的层次来进行解耦,确保每一层仅关注其自身的职责,并且依赖于更低层次的服务。以下是典型的应用分层架构设计:
1. 层次划分
-
开放接口层:
- 主要职责是将Service方法暴露成RPC接口或Web接口。它还承担了安全控制、流量控制等。
- 示例:
UserService
暴露一个RPC接口,用户通过接口访问其登录功能。
-
终端显示层:
- 负责将模板渲染并展示给用户。当前流行的渲染技术包括Velocity、JS渲染、JSP渲染等。
- 示例:前端界面通过Velocity渲染HTML页面并展示给用户。
-
Web 层:
- 主要处理访问控制、参数校验等基本的业务处理。这个层级有时负责简单的业务操作。
- 示例:Web层接受请求并进行用户验证,后续将请求转发到Service层。
-
Service 层:
- 执行具体的业务逻辑,是业务处理的核心。
- 示例:
OrderService
处理订单相关的业务逻辑。
-
Manager 层:
-
用于封装通用的业务处理逻辑,例如第三方平台的调用、缓存策略等。
-
示例:
PaymentManager
封装与支付网关的通信。通用业务处理层,它有如下特征:
1) 对第三方平台封装的层,预处理返回结果及转化异常信息。
2) 对 Service 层通用能力的下沉,如缓存方案、中间件通用处理。
3) 与 DAO 层交互,对多个 DAO 的组合复用。
-
-
DAO 层:
- 与数据库进行交互,执行数据的持久化操作。
- 示例:
UserDAO
执行数据库查询操作,获取用户信息。
-
外部接口或第三方平台:
- 与其他公司或服务进行交互,例如调用外部API等。
- 示例:
PaymentService
与第三方支付平台对接。
2. 异常处理规范
异常处理的规范化对于提升系统的稳定性至关重要。对于不同的层次,异常处理应该遵循不同的策略:
- 在DAO层 ,异常通过
DAOException
抛出,不需要打印日志,日志处理交给上层(Service层)。 - 在Service层,异常需要记录详细的日志,并尽可能包括请求参数,便于问题排查。
- Web层处理界面相关的异常时,应该避免将异常抛到上层,而是直接跳转到错误页面并显示用户友好的提示信息。
3. 数据模型规范
对于层与层之间的数据传输,采用不同的模型来进行封装和传递,常见的模型有:
- DO(Data Object):与数据库表结构一一对应的对象。
- DTO(Data Transfer Object):服务层与外部交互时传递的数据对象。
- BO(Business Object):封装了业务逻辑的对象。
- VO(View Object):用于展示层的数据传输对象。
这种数据模型的使用使得系统的各个层次之间解耦,同时确保数据的一致性和可维护性。
二、二方库依赖管理
阿里定义: 一方库:本工程中各模块依赖。
二方库:公司内部依赖库,依赖其他模块的库。
三方库:公司之外的库。
二方库依赖管理是大型系统架构中不可忽视的一部分,它直接关系到系统的稳定性和可扩展性。以下是一些关于二方库依赖的最佳实践:
1. GAV(GroupId, ArtifactId, Version)规范
- GroupId :规范为
com.{公司/BU}.{业务线}
,最多四级。 - ArtifactId:表示产品线和模块的名称,确保语义清晰。
- Version:按照主版本号、次版本号和修订号来定义,避免使用SNAPSHOT版本。
示例:
xml
<dependency>
<groupId>com.taobao.jstorm</groupId>
<artifactId>jstorm-tool</artifactId>
<version>1.2.0</version>
</dependency>
2. 二方库版本号命名规则
- 主版本号:产品方向发生变化,或者架构不兼容时进行升级。
- 次版本号:增加主要功能,但保持向后兼容。
- 修订号:主要用于修复bug或增加小功能。
3. 统一版本管理
为了避免在子项目中出现版本不一致的问题,建议在父项目中定义一个统一的版本变量,所有依赖的版本号都通过该变量来统一管理。
示例:
xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
4. 避免枚举类型在API中的使用
为了确保系统的可扩展性和跨系统的兼容性,建议不要在API的返回值中使用枚举类型,避免在不同的系统间产生不兼容的问题。
三、服务器配置与优化
为了保证高效的运行和快速响应,服务器的配置和优化是至关重要的。
如下是一些推荐的配置和优化策略:
1. 调整 TCP 协议的 time_wait 超时时间
在高并发环境下,服务器连接过多可能导致time_wait状态的连接无法及时释放,从而影响新连接的建立。可以通过调整TCP连接超时时间来解决这一问题:
bash
# 修改 /etc/sysctl.conf 文件
net.ipv4.tcp_fin_timeout = 30
2. 增加文件句柄数
在并发连接数较多的情况下,操作系统默认的文件句柄数可能不足,导致"open too many files"错误。可以通过修改操作系统的配置来增加文件句柄数:
bash
# 修改文件句柄数
ulimit -n 65535
3. 设置 JVM 参数以应对 OOM 问题
为了在发生内存溢出时能够及时获取堆内信息进行排查,可以在JVM启动时配置-XX:+HeapDumpOnOutOfMemoryError
:
bash
# 设置 JVM 参数
-XX:+HeapDumpOnOutOfMemoryError
4. 保持堆内存大小一致
为避免垃圾回收后堆内存大小的调整带来的性能波动,建议在线上生产环境中设置JVM的初始堆内存(Xms)和最大堆内存(Xmx)为相同的大小:
bash
# 设置 JVM 堆内存
-Xms2g -Xmx2g
小结
上述总结了在多层架构设计、二方库依赖管理以及服务器配置优化等方面的最佳实践和规范。遵循这些原则可以有效提高系统的可维护性、稳定性以及扩展性。尤其在高并发、大规模的分布式系统中,合理的架构和依赖管理不仅能降低开发和运维成本,还能提升系统的性能和可伸缩性 。
![](https://i-blog.csdnimg.cn/direct/867ed8514aaf43de82fe556f332af898.jpeg)