ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CodeGuide 实战专栏:仿桌面微信 IM 系统的服务端架构设计——从架构目标到 DDD 四层模型落地

CodeGuide 实战专栏:仿桌面微信 IM 系统的服务端架构设计——从架构目标到 DDD 四层模型落地 文档教程后端【免费下载链接】CodeGuide:books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总旨在为大家提供一个清晰详细的学习教程侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助请给予支持(关注、点赞、分享)项目地址https://gitcode.com/gh_mirrors/code/CodeGuide点击查看免费下载本篇基于 《NettyJavaFx 实战仿桌面版微信聊天》专栏 中的服务端架构设计章节展开讲解一个即时通信IM控制中心服务端的架构设计全过程如何从业务目标出发提炼架构约束在 MVC 与 DDD 两种模型之间做取舍并把 DDD 四层结构interfaces / application / domain / infrastructure落地成真实工程骨架。读完本篇你可以掌握一套目标驱动的服务端架构设计方法以及 DDD 四层模型在 Netty 通信服务中的具体组织方式。一、架构设计的核心理念更适合才是更好的架构这个词听起来高大上但本质上并不神秘。哪怕是最初练习作业式的 CRUD本身也是一种建构模式。架构设计的关键不在于堆砌先进概念而在于找到与业务体量相匹配的模型一个只有几十人访问的小型工程没有必要非得上分布式也不是硬要在十万并发的场景下直连数据库。正如 服务端架构设计 一文开篇强调的只有适合你业务的才是更好的架构。同时一个架构模型的诞生远不止结构上的分层还包括多种技术及相应内部业务模块的融合。例如服务基础使用 Spring 还是 SpringBoot需要 RPC 时选择 Dubbo缓存使用 Redis数据库分库分表用 MyCat文件系统使用 ES以及自己开发的一些中间件。在 CodeGuide 仓库的 IM 实战专栏中这套技术融合最终收敛为 JavaFx Netty4.x SpringBoot Mysql 的组合并以偏向 DDD 领域驱动设计的方式组织工程结构。下文以该专栏中通信服务的控制中心服务端为具体对象拆解架构设计的目标与模型选择。二、架构目标设计之前先回答为什么这样设计如何设计适合当下需要的架构基本方法是先找到符合业务诉求的目标——每一个设计决策都要能回答我们之所以这样设计是为什么。针对 IM 通信服务端2.1 服务端架构设计 提出了四条明确的架构目标Web 管理面服务端要有 web 页面来管理通信用户以及对服务端本身进行控制和监控数据对象隔离性数据库的对象类不能被外部污染、要有隔离性。例如如果把数据库类暴露给外部当展示类使用当需要新增一个仅用于展示、数据库中并不存在的字段时数据库对象就已经被污染了通信协议抽离为独立 Jar 包由于服务端与客户端都使用 Java 语言实现 Netty 通信双方都要使用通信过程中的协议定义和解析因此必须抽离这一层对外提供 Jar 包分层职责清晰接口、业务处理、底层服务、通信交互要有明确的区分和实现避免造成混乱难以维护。这四条目标分别对应了后文架构模型中的具体分层目标 1 落在接口的 web 管理面上目标 2 落在领域层与基础设施层的隔离上目标 3 落成独立的通信协议包详见 2.2 通信协议包定义目标 4 则由整体分层结构保证。三、架构模型选型MVC 与 DDD 的取舍结合上述四条目标需要在两种熟悉的架构模型中做出选择一种是大多数 Java 开发者非常熟悉的MVC另一种是DDD 领域驱动设计。3.1 MVC 结构的局限贫血模型与腐化风险MVC 分层是一种典型的贫血模型设计它把状态PO/VO/Enum和行为Service 逻辑分离到不同包中domain 里写数据对象service 里写功能逻辑。这种结构前期交付速度非常快但缺少上下文约束长期迭代后会出现 CodeGuide 架构重构专题 中总结的腐化问题贫血对象被众多 Service 交叉使用Service 之间又相互调用对象、服务、组件的边界越来越模糊——一条裤子被加肥加大所有人都穿对应 IM 服务端的数据对象隔离目标架构目标 2MVC 结构没有天然的机制阻止数据库对象被上层直接引用隔离只能靠开发自觉。3.2 DDD 四层结构各司其职的工程模型从源码结构看IM 专栏最终选定的 DDD 四层模型其工程实现在 3.7 服务端控制台搭建 一文中给出了完整骨架itstack-naive-chat-server └── src ├── main │ ├── java │ │ └── org.itstack.naive.chat │ │ ├── application │ │ ├── domain │ │ ├── infrastructure │ │ ├── interfaces │ │ └── Application.java │ ├── resources │ │ ├── mybatis │ │ ├── spring │ │ └── application.yml │ └── webapp │ ├── chat │ ├── res │ ├── index.html │ └── res_layui.html └── test对照 MVC2DDD 架构重构 中讲解的 DDD 分层思想这四层的职责可以这样理解分层职责对应 IM 服务端架构目标interfaces 接口层提供接口实现、对外触发入口HTTP/RPC/MQ/JOB 等触发器是领域能力的触发器层架构目标 1web 管理面Layui 页面 接口与通信控制入口application 应用层领域编排对 domain 领域逻辑做封装组合处理小项目可省略以降低成本架构目标 4接口与业务处理之间的编排边界domain 领域层领域模型服务核心模块每个领域包内包含模型、仓储接口、领域服务三要素架构目标 2业务对象与持久化对象隔离充血模型承载行为infrastructure 基础设施层依赖 domain 定义的仓储接口做实现依赖倒置承载 MyBatis、Spring 配置、Netty 通信等底层能力架构目标 3/4通信交互与底层服务独立实现不污染领域层其中两个关键设计点值得展开依赖倒置infrastructure 层依赖 domain 层而不是反过来。domain 层定义仓储接口infrastructure 层的 DAO 去实现该接口。这样数据库对象PO只出现在基础设施层领域层和业务层引用的是领域模型对象架构目标 2 的数据对象隔离由此在结构上被强制保证domain 是最大的模块所有其他模块都围着 domain 转。领域内模型 服务 仓储自成闭环就像把炸药包里的火药、引线、包布封装到一起使用。3.3 与客户端架构的对称设计服务端选定的分层思路在客户端侧同样贯彻。从 2.3 客户端架构设计 可以看到客户端工程 itstack-naive-chat-ui 对应的业务工程采用了对称的分层UI 层使用 Maven 打包的 UI Jar 包通过内部接口和事件操作 UI 展现、发起行为强制 UI 与业务分离业务层负责窗体中用户信息维护好友、群组以及对话信息收发处理 UI 接口与事件协议包即服务端抽离出的通信协议 Jar中间穿插标识位区分登录、消息发送、添加好友等不同业务对象通信层Netty 框架下的 Socket 通信让开发聚焦业务运行环境JDK 1.8 桌面环境。服务端与客户端共享同一通信协议包正是架构目标 3 的直接落地。四、技术栈选型与配套设计在分层结构确定后IM 服务端的技术栈选型围绕通信 管理 持久化三条主线展开4.1 Netty通信层的基础Netty 是 JBOSS 提供的异步、事件驱动网络应用框架被 Dubbo、RocketMQ 等大量企业级项目作为基础通信组件使用能大幅简化 NIO 开发。IM 专栏在 2.2 通信协议包定义 中专门讨论了 Netty 的定位并通过一系列案例可对照 Netty 基础入门案例 阅读掌握了字符串收发、对象传输、自定义编解码器处理半包粘包等内容后才进入协议包设计。协议包的核心作用是在数据帧中间穿插一位标识帧用来区分传输的是不同业务对象登录、消息、好友等这与 RPC 框架如 Dubbo对外提供接口描述 Jar 包的思路一致。4.2 SpringBoot MyBatis管理面与持久化从工程骨架看resources/spring与resources/mybatis目录、application.yml配置表明服务端使用 SpringBoot 作为服务基础框架、MyBatis 作为 ORM 层落在 infrastructure 层实现。库表设计在 2.4 数据库表结构设计 中完成为体现核心功能库表尽量简单、只保留核心业务字段六个表分为三部分基础表用户和群组的维护关联表每个用户与好友、群组的关系行为表用户与好友/群组产生的对话及聊天记录。4.3 Layui服务端控制台页面为达成web 页面管理通信用户及服务端控制监控的架构目标 13.7 服务端控制台搭建 选用 Layui 作为后台页面框架简单、干净、整洁、集成方式多样页面结构放在webapp目录下index.html、res_layui.html 等用于查看 Netty 服务运行状态、用户在线列表和各维度通信信息。五、总结从目标到骨架的架构设计路径回看 IM 服务端架构设计的完整路径可以提炼出一条可复用的方法论先立目标从业务诉求提炼出可检验的架构目标管理面、对象隔离、协议抽离、职责清晰而不是先画分层图再做选型用目标去衡量 MVC 与 DDD——需要强制的数据对象隔离、需要清晰的接口/业务/底层/通信边界时DDD 四层模型的结构性约束优于 MVC 的约定性约束后落骨架把目标逐一对应到 interfaces / application / domain / infrastructure 的具体职责上用依赖倒置保证基础设施层不污染领域层用独立 Jar 包保证双端协议一致配套选型Netty 承载通信、SpringBoot MyBatis 承载管理与持久化、Layui 承载控制台页面每项技术都只服务于一个架构目标。这套目标驱动 分层落地的设计方式也正是 CodeGuide 仓库中多个实战项目IM、拼团、MCP 网关等共同遵循的架构思路。赞分享文档教程后端【免费下载链接】CodeGuide:books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总旨在为大家提供一个清晰详细的学习教程侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助请给予支持(关注、点赞、分享)项目地址https://gitcode.com/gh_mirrors/code/CodeGuide点击查看免费下载相关推荐用 Netty 实践分布式 IM 即时通信系统基于 JavaFx SpringBoot DDD 四层架构的仿微信桌面端全栈设计用 Netty 实践分布式 IM 即时通信系统基于 JavaFx SpringBoot DDD 四层架构的仿微信桌面端全栈设计 导读 本文以 Code文档教程后端CodeGuide DDD落地实战基于SpringBoot四层架构的领域驱动设计入门指南CodeGuide DDD落地实战基于SpringBoot四层架构的领域驱动设计入门指南 领域驱动设计DDD是一套把业务领域建模与软件架构设计相结合的指导文档教程后端终极指南CodeGuide架构设计中的DDD领域驱动设计落地实践终极指南CodeGuide架构设计中的DDD领域驱动设计落地实践 CodeGuide是GitHub加速计划中的重要项目由小傅哥多年一线互联网Java开发经验文档教程后端上一篇如何用Jazzy文档工具确保Swift代码示例的可运行性下一篇pydantic-monty 实战指南用 Monty 沙箱在 Python 宿主进程中安全执行不可信代码创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表