<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>架构设计 on Cooper&#39;s Blog</title>
    <link>https://www.wsqyouth.cn/tags/architecture/</link>
    <description>Recent content in 架构设计 on Cooper&#39;s Blog</description>
    <generator>Hugo</generator>
    <language>en</language>
    <managingEditor>Coopers</managingEditor>
    <atom:link href="https://www.wsqyouth.cn/tags/architecture/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>基于go标准分层架构项目设计实现</title>
      <link>https://www.wsqyouth.cn/2023/11/19/go-layered-architecture/</link>
      <pubDate>Sun, 19 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://www.wsqyouth.cn/2023/11/19/go-layered-architecture/</guid>
      <description>&lt;h3 id=&#34;缘起&#34;&gt;缘起&lt;/h3&gt;
&lt;p&gt;最近主要看了两方面知识，一方面是技术相关的，如何设计一个比较好的后端架构项目代码；一方面是非技术相关的，如何写一篇好的技术文章，能够让他人读懂并有收获。因此这篇文章我会借助于chatgpt尝试通过问题发起，然后思考、调研、设计、实战的方式输出一篇文章出来。&lt;/p&gt;
&lt;h3 id=&#34;一问题如何设计一个高性能的web服务框架&#34;&gt;一、问题：如何设计一个高性能的web服务框架？&lt;/h3&gt;
&lt;p&gt;依据笔者这么多年的开发经验，（没吃过猪肉肯定也见过猪走，笑），期望中的高性能web server应该是这样子的：前端通过golang gin实现，将get/post请求到网关，在网关的基本非业务功能处理后，转发到后端的server，server之间通过rpc请求进行转发处理，整个项目遵循golang 标准项目的模块架构，能够使得项目可扩展，便于开发。最好是采用类似DDD的依赖注入和插件化的思想。我把这些设计要点给chat gpt，然后让他帮助我进行设计，我在他的基础上进行综合整理下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;实现网关的基本功能&lt;/strong&gt;：网关是一个重要的组件，它可以处理所有进入你的系统的请求，提供路由，负载均衡，认证，限流等功能。&lt;/p&gt;
&lt;p&gt;IDL校验：使用Gin的绑定和验证功能来进行输入数据的校验。Gin支持将请求体绑定到一个结构体，并使用标签来进行数据验证。你也可以使用一些第三方的验证库，如go-playground/validator，来进行更复杂的验证。&lt;/p&gt;
&lt;p&gt;中间件：使用Gin的中间件来来处理一些通用的逻辑，如日志，错误处理，认证，限流等功能。你可以使用Gin提供的一些内置中间件，也可以编写自己的中间件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用Golang和Gin框架&lt;/strong&gt;：Golang是一种高性能的编程语言，适合构建高性能的web server。Gin是一个高性能的web框架，提供了很多有用的特性，如路由，中间件，参数绑定等，可以帮助你快速开发web server。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;前后端分离&lt;/strong&gt;：将前端和后端的逻辑分离，使得系统更易于扩展和维护。你可以使用Golang的http包或者更高级的http客户端库，如resty，来发送请求到后端的server。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用RPC框架&lt;/strong&gt;：这取决于你的具体需求。如果你的后端服务是在内网中，且需要高性能的请求，那么使用RPC，如gRPC，是一个很好的选择。如果你的后端服务是在公网中，或者需要更好的跨语言兼容性，那么使用HTTP/REST可能是更好的选择。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;数据库&lt;/strong&gt;：选择使用MySQL作为数据库。你可以使用Golang的database/sql包来操作数据库，也可以使用一些ORM库，如gorm，来简化数据库操作。你需要考虑数据库连接池的管理，以及如何处理数据库事务。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;测试&lt;/strong&gt;：你需要为你的代码编写测试，包括单元测试，集成测试，和端到端测试。你可以使用Golang的testing包来编写测试，也可以使用一些第三方的测试库，如testify，来提供更多的测试功能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;部署&lt;/strong&gt;：你需要考虑如何部署你的应用。你可以使用Docker来容器化你的应用，然后使用Kubernetes或者Docker Swarm来进行部署。你也需要考虑如何进行日志收集，性能监控，和错误报告。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;项目布局&lt;/strong&gt;：遵循golang-standards/project-layout的设计是一个很好的实践。这个布局将项目分为多个模块，如cmd，pkg，api，web，scripts等，每个模块都有其特定的职责，这样可以使得项目结构清晰，易于理解和维护。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;采用类似DDD的依赖注入&lt;/strong&gt;：这是一个很好的设计，可以使得你的代码更易于测试和重构。你可以使用一些依赖注入库，如google/wire，来帮助你实现这个设计。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;很好，能够描述清楚我想要的后端框架的样子，之后我让chatgpt给我找一些采用上述类似设计思想的框架供我参考学习，它给我如下的一些学习资源。（当然我又问了其他的一些问题，将得到的书籍、博客社区也补充进来）&lt;/p&gt;
&lt;p&gt;Q: 那有没有类似设计思想的文章或者github工程呢，我需要通过这个项目学习整个的组织架构，同时提高自己的架构能力。&lt;/p&gt;
&lt;p&gt;A: 可以帮助你提高你的架构能力。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;GitHub项目&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/golang-standards/project-layout&#34;&gt;Go项目布局模板&lt;/a&gt;：这个项目提供了一个标准的Go项目布局模板，你可以参考它来组织你的代码。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bxcodec/go-clean-arch&#34;&gt;Go Clean Architecture&lt;/a&gt;：这个项目是一个实现了Clean Architecture的Go项目，它使用了依赖注入和接口，可以帮助你理解如何设计和组织代码。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/eminetto/go-clean-architecture&#34;&gt;Go-Boilerplate&lt;/a&gt;：这个项目是一个Go的项目模板，它使用了Clean Architecture和DDD的设计思想，可以帮助你理解如何在实际项目中应用这些设计思想。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文章&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://ewanvalentine.io/microservices-in-golang-part-1/&#34;&gt;使用Go和DDD构建微服务&lt;/a&gt;：这是一个系列的文章，作者详细介绍了如何使用Go和DDD来构建微服务，包括如何设计领域模型，如何实现服务，如何进行测试等。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://medium.com/@eminetto/clean-architecture-using-golang-b63587aa5e3f&#34;&gt;Go中的Clean Architecture&lt;/a&gt;：这篇文章介绍了如何在Go中实现Clean Architecture，包括如何设计接口，如何使用依赖注入等&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;书籍&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164&#34;&gt;《架构整洁之道》&lt;/a&gt;：这本书由著名的软件工程师Robert C. Martin（又名Uncle Bob）撰写，详细介绍了如何设计和实现整洁的架构。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215&#34;&gt;《领域驱动设计：软件核心复杂性应对之道》&lt;/a&gt;：这本书由Eric Evans撰写，是领域驱动设计（DDD）的经典之作。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;博客和社区&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.golang.org/&#34;&gt;Go官方博客&lt;/a&gt;：这里有很多关于Go的深度文章，包括一些关于架构和设计的文章。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://golangweekly.com/&#34;&gt;Golang Weekly&lt;/a&gt;：这是一个每周更新的Go新闻和文章的邮件列表，你可以通过它来跟踪Go的最新动态。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://forum.golangbridge.org/&#34;&gt;Go论坛&lt;/a&gt;：这是一个Go的社区论坛，你可以在这里提问和讨论Go相关的问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;二常用的框架分层设计及选型&#34;&gt;二、常用的框架分层设计及选型&lt;/h3&gt;
&lt;p&gt;这里笔者按照时间维度搜集整理了几种常见的分层架构设计模型，整理记录下来。&lt;/p&gt;
&lt;h4 id=&#34;21-mvc模型&#34;&gt;2.1 MVC模型&lt;/h4&gt;
&lt;p&gt;MVC是由Model（模型）、View（视图）、Controller（控制器）三层组成，是一种将业务逻辑、数据、界面显示分离开来的软件设计模式。其中后端分层架构：Controller（服务调用）、Service（逻辑）、Dao（数据访问）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Model：功能的实现，数据库的管理，主要负责数据存取；&lt;/li&gt;
&lt;li&gt;View：用户能够看到的界面，主要负责数据展示；&lt;/li&gt;
&lt;li&gt;Controller：对请求进行处理，连接模型层和视图层。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种是比较经典的设计模型，耦合性、重用性、维护性还是可以的。笔者在php开发和c++开发业务代码时经常看到这种设计：
前端请求-&amp;gt; cgi服务模块 -&amp;gt; controller业务逻辑模块-&amp;gt; dao模块&lt;/p&gt;
&lt;h4 id=&#34;21-ddd微服务模块&#34;&gt;2.1 DDD微服务模块&lt;/h4&gt;
&lt;p&gt;DDD (Domain-Driven Design) 是一种软件架构设计方法，它旨在将业务逻辑和数据模型与技术实现分离开来，以便更好地满足复杂业务需求，避免“大泥球”式的代码（一图胜千言，怎奈我的博客还不支持图片，先纯文字描述吧）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户接口层：负责处理用户请求、渲染视图和返回响应。&lt;/li&gt;
&lt;li&gt;应用层：主要面向用例和流程相关的操作，无具体业务规则，负责将用户请求转换成领域行为，并将领域行为传递给领域层进行处理。应用层还负责协调领域层多个领域对象协作完成业务流程。应用层应该是很薄的一层，避免将业务规则实现到应用层中，否则庞大的应用层会使得领域模型失焦，最终演化成传统的三层架构。&lt;/li&gt;
&lt;li&gt;领域层：是DDD架构中最重要的层，负责表示业务逻辑和数据模型，用来表达业务概念、业务状态和业务规则。领域层通常包含各种领域对象、值对象、聚合根和实体等。领域层通常使用面向对象的设计和编程技术来实现。&lt;/li&gt;
&lt;li&gt;基础设施层：负责提供技术实现，例如数据库访问、网络通信、日志记录和缓存等。基础设施层并不属于被依赖的最底层，而是采用依赖倒置的方式封装基础资源服务，实现应用层、领域层与基础层的解耦，降低外部资源变化对应用的影响。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总体来说，这种设计是比较适应未来的趋势的，笔者将过去和未来两种模式放到这里，方便读者站在时间的窗口，来看后面的发展。不过本文实战部分并不会使用这两种模式，而是参考golang-standards/project-layout的设计，设计一个比较简单的系统处理，方便读者理解其中的思路。&lt;/p&gt;
&lt;h3 id=&#34;二基于golang-standardsproject-layout设计进行实战&#34;&gt;二、基于golang-standards/project-layout设计进行实战&lt;/h3&gt;
&lt;p&gt;首先去github上找下类似设计思想的工程代码，然后研究学习下，再回头找下这个项目：
&lt;a href=&#34;https://github.com/bxcodec/go-clean-arch&#34;&gt;Go Clean Architecture&lt;/a&gt;：这个项目是一个实现了Clean Architecture的Go项目，它使用了依赖注入和接口，可以帮助你理解如何设计和组织代码。&lt;/p&gt;
&lt;p&gt;代码链接：https://github.com/bxcodec/go-clean-arch/blob/master/app/main.go&lt;/p&gt;
&lt;p&gt;在看了整个项目代码后，主要实现并不是很优雅，我们也没必要照搬全抄，而是借鉴里面亮点的部分，这里我提取出这个项目工程中一些设计亮点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;参数可配置化，使用viper进行参数读取解析&lt;/li&gt;
&lt;li&gt;中间件，实现对请求的中间件处理&lt;/li&gt;
&lt;li&gt;使用Repo实现对数据库访问的依赖注入&lt;/li&gt;
&lt;li&gt;使用了DDD的一些思想，存储层、领域层啥的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我们在这个亮点的基础上从这个项目提取核心，通过围绕MysqlArticle表包含这些思想写一个完整的demo代码，用来回答我们文章开头的问题。&lt;/p&gt;
</description>
    </item>
  </channel>
</rss>
