Go 语言即时通讯系统开发日志-日志day2-5:架构设计与日志封装

Go语言即时通讯系统开发日志day2

计划:学习go中MySQL,Redis的使用,使用MySQL和Redis完成一个单聊demo。

总结:现在每天下午用来开发这个项目,如果有课的话可能学习时间只有3-4个小时,再加上今天的学习效率不高;今天只做了一些开发规划,并了解了go语言如何使用MySQLRedis,下了两篇博客,Go 语言 sqlx 库使用:对 MySQL 增删改查、Go 语言 Redis 使用 :安装、配置与操作,并把第一天的欠下的net/http库学习了解了一下,Go 语言 net/http 包使用:HTTP 服务器、客户端与中间件。打算先参照GitHub上的go-chat这个IM进行参考学习,后续有能力了再对项目的模块进行优化和重构。

项目实现顺序分析

大概分析了一下,后续开发的顺序,实际随情况而变,主要是为了防止每天开始学习时,不知从而下手的处境。

  • 基础架构搭建
    • 搭建项目结构
    • 日志系统封装
    • 配置系统
  • WebSocket基础服务
    • 实现WebSocket
    • 连接管理
  • 单聊核心功能
    • 数据库表设计
    • 数据模型
    • 消息流转
  • 前端实现(AI实现)
  • 其他功能
    • 消息状态
    • 通知系统
    • 用户认证

Go语言即时通讯系统开发日志day3

计划:了解Gin,Gorm框架的使用,构建项目结构,了解Go项目的开发流程。

总结:通过【最新Go Web开发教程】基于gin框架和gorm的web开发实战 (七米出品)学习了Go语言的Gin框架,Gorm框架。

Gin

Go语言 Gin框架 使用指南

Gin 是一个用 Go 编写的高性能 Web 框架,以轻量级和快速路由著称,适合构建 RESTful API 和微服务。它提供了中间件支持、JSON 解析、错误处理等常用功能,代码简洁且易于上手,是 Go 生态中最流行的 Web 框架之一。

Gorm

Go语言 GORM框架 使用指南

Gorm 是 Go 的 ORM(对象关系映射)库,支持 MySQL、PostgreSQL 等数据库,通过结构体模型操作数据,简化了数据库交互。它提供链式调用、事务管理、关联查询等功能,兼顾灵活性和易用性,适合快速开发数据驱动的应用。

两者常结合使用(Gin 处理 HTTP,Gorm 操作数据库)。可以看我写了的两篇博客了解其快速入门并使用。

Go语言即时通讯系统开发日志day4

计划:搭建项目基本结构,学习了解项目开发(架构、规范、开发了流程)等内容。

总结:写了两篇相关博客,Go语言 Gin框架 使用指南,Go语言 GORM框架 使用指南,快速浏览了一下 Go 语言项目开发实战(付费课程)。

项目架构

简单了解一下各种项目架构:

1. 分层架构(Layered Architecture)

  • 核心思想:将系统分为若干层(如表现层、业务层、数据层),每层仅依赖下层。
  • 优点:结构简单,易于分工和维护。
  • 缺点:层间可能冗余,性能瓶颈(如数据库访问集中)。
  • 场景:传统企业应用(如ERP、CRM)、教学示例。

2. MVC架构(Model-View-Controller)

  • 核心思想:分离数据(Model)、界面(View)和逻辑(Controller)。
  • 优点:开发快速,适合UI交互多的应用。
  • 缺点:Controller易臃肿,不适合复杂业务逻辑。
  • 场景:Web应用(如博客、内容管理系统)。

3. 微服务架构(Microservices)

  • 核心思想:将单体应用拆分为独立的小服务,通过API通信。
  • 优点:高扩展性、技术栈灵活、故障隔离。
  • 缺点:分布式复杂性(如事务、网络延迟)、运维成本高。
  • 场景:大型复杂系统(如电商平台、Uber)。

4. 事件驱动架构(Event-Driven Architecture, EDA)

  • 核心思想:通过事件(消息)异步触发组件行为,松耦合。
  • 优点:高实时性,易于扩展。
  • 缺点:事件顺序难保证,调试复杂。
  • 场景:实时系统(如金融交易、IoT)、最终一致性需求(如库存管理)。

5. 六边形架构(Hexagonal Architecture)

  • 核心思想:核心业务与外部依赖(如DB、UI)解耦,通过“端口-适配器”交互。
  • 优点:技术无关性,测试友好。
  • 缺点:设计成本高,可能过度工程化。
  • 场景:领域驱动设计(DDD)、长期演化的核心系统(如银行核心业务)。

6. CQRS(Command Query Responsibility Segregation)

  • 核心思想:读写分离,命令(写操作)和查询(读操作)使用不同模型。
  • 优点:独立优化读写性能,适合高并发查询。
  • 缺点:数据同步延迟,实现复杂。
  • 场景:社交平台、数据分析看板。

7. 无服务器架构(Serverless)

  • 核心思想:开发者无需管理服务器,按需运行函数(如AWS Lambda)。
  • 优点:零运维成本,自动扩缩容。
  • 缺点:冷启动延迟,不适合长任务。
  • 场景:低频任务(如定时作业、Webhook)、轻量API。

8. 空间基架构(Space-Based Architecture)

  • 核心思想:通过分布式内存网格(如Redis)共享数据,避免数据库瓶颈。
  • 优点:超高并发、低延迟。
  • 缺点:数据一致性难保证,成本高。
  • 场景:金融交易系统、实时游戏服务器。

9. 插件化架构(Plugin Architecture)

  • 核心思想:核心系统提供扩展点,功能通过插件动态加载。
  • 优点:灵活扩展,主系统轻量。
  • 缺点:插件管理复杂,接口需严格设计。
  • 场景:IDE(如VS Code)、可定制化软件(如WordPress)。

10. 前后端分离架构(Frontend-Backend Separation)

  • 核心思想:前端(React/Vue)与后端(API服务)独立开发,通过REST/GraphQL交互。
  • 优点:团队解耦,多端适配(Web/移动)。
  • 缺点:API设计需严谨,SEO需额外处理。
  • 场景:现代Web应用(如社交平台、管理后台)。

11. IAM架构(Identity and Access Management)

  • 核心思想:集中管理身份认证(Authentication)和权限授权(Authorization)。
  • 优点:统一安全管控,最小权限原则。
  • 缺点:集成复杂,可能成为单点故障。
  • 场景:企业级系统(如OA、云平台)、合规性要求高的领域(金融)。

12. 单体架构(Monolithic Architecture)

  • 核心思想:所有功能集中在一个代码库中,统一部署。
  • 优点:开发简单,适合小型项目。
  • 缺点:难以扩展,维护成本随规模增长。
  • 场景:初创项目、内部工具。

如何选择?

需求推荐架构
快速开发简单应用单体架构、MVC
高并发、大规模系统微服务、空间基架构
实时数据处理事件驱动架构
灵活扩展功能插件化架构
低成本、无运维无服务器架构
严格权限控制IAM架构
读写性能分离CQRS
长期演化的核心业务六边形架构

规范设计

开源规范

开源项目应遵循明确的许可证(如MIT、Apache-2.0),并在README中说明项目目标、使用方式及贡献指南。代码需保持模块化、可复用,并提供清晰的API文档,方便他人理解和使用。

文档规范

项目文档应包括README(快速入门)、API文档(如Swagger)、设计文档(架构图)和贡献指南(PR流程)。文档需结构化、定期更新,并采用Markdown等通用格式,确保易读性和可维护性。

版本规范

推荐使用语义化版本(SemVer):主版本号.次版本号.修订号(如v1.2.3),分别对应不兼容改动、新增功能、Bug修复。版本变更需在CHANGELOG中记录,明确影响范围,便于用户升级。

commit规范

类型类别说明
featProduction新增功能
fixProductionBug修复
perfProduction提高代码性能的变更
styleDevelopment代码格式类的变更,比如用gofmt 格式化代码、删除空行等
refactorProduction其他代码类的变更,这些变更不属于feat、fix、perf 和 style,例 如简化代码、重命名变量、删除冗余代码等
testDevelopment新增测试用例或是更新现有测试用例
ciDevelopment持续集成和部署相关的改动,比如修改Jenkins、GitLab CI等CI 配置文件或者更新systemdunit文件
docsDevelopment文档类的更新,包括修改用户文档或者开发文档等
choreDevelopment其他类型,比如构建流程、依赖管理或者辅助工具的变动等

image.png

参考资料: Go 语言项目开发实战 - 规范设计(付费课程)

Go语言即时通讯系统开发日志day5

计划:选择项目架构,搭建项目结构,构建表结构。

总结:完成了项目构建,了解了MVC三层架构,了解了zap并对其完成了简单封装,使其可以向log库一样使用。

项目结构

构建项目结构

.
├── api
├── cmd
├── configs
├── docs
├── pkg
├── test
├── go.mod
├── go.sum
├── internal
│   ├── config
│   ├── dao
│   ├── dto
│   ├── model
│   └── service
└── web├── public└── src
  1. api/:存放 API 协议定义文件,用于描述接口规范,不包含具体实现。

  2. cmd/:存放 可执行程序的入口文件(每个子目录对应一个独立的二进制程序)。

  3. configs/:存放 配置文件模板或默认配置(如开发/生产环境配置)。​

  4. pkg/:存放 可复用的公共库代码(允许被其他项目导入)。

  5. test/:存放 集成测试/端到端测试代码(单元测试应直接放在各包内)。

  6. internal/:存放 私有业务逻辑(禁止被外部项目导入),是项目核心

    • onfig/:定义配置结构体及加载逻辑。

    • dao/ (Data Access Object):数据库操作层(直接与 MySQL/Redis 等交互)。

    • dto/ (Data Transfer Object):定义 API 请求/响应的数据结构。

    • **model/**定义数据库表对应的结构体(ORM 模型)。

    • service/:实现核心业务逻辑(如消息发送、用户鉴权)。

  7. web/:存放 前端代码和静态资源

    • public/:编译后的静态文件(可直接通过 HTTP 访问)。

    • src/:前端源码(如 React/Vue 项目)。】

用户发送消息流程

image.png

参考资料:第 25 章 - Golang 项目结构

MVC 三层架构

image.png

Model 层(数据 + 业务核心)

对应目录:

  • internal/model/:定义数据结构(如 UserMessage
  • internal/dao/:数据库操作(CRUD)
  • internal/service/业务逻辑(如发送消息的校验、权限控制)

View 层(数据展示)

对应目录:web/

  • 前端代码(Vue/React)通过 API 或 WebSocket 获取数据并渲染。

实时更新:通过 pkg/websocket 监听服务端推送。

Controller 层(请求协调)

对应目录:

  • api/:定义接口协议(如 REST 路由、gRPC 方法)
  • internal/dto/:请求/响应的数据结构
  • internal/service/实际控制层(处理参数校验、调用 Model 层)

image.png

参考资料:MVC 三层架构案例详细讲解

日志封装 zap

核心结构

type Logger struct {l  *zap.Logger       // 实际的 zap logger 实例al *zap.AtomicLevel  // 支持动态调整日志级别
}
  • 封装了 zap.Logger 并添加了原子级别的日志级别控制

初始化机制

var (once     sync.Once   // 确保只初始化一次std      *Logger     // 默认 logger 实例logPath  string      // 日志路径initDone bool        // 初始化标志
)func initLogger() {// 从配置获取日志路径conf := config.GetConfig()logPath = filepath.Join(conf.LogConfig.LogPath, "app.log")// 创建日志目录os.MkdirAll(filepath.Dir(logPath), 0755)// 创建带轮转功能的 loggerstd = NewWithRotate(InfoLevel, NewProductionRotateConfig(logPath))initDone = true
}func Default() *Logger {once.Do(initLogger)  // 线程安全的单次初始化return std
}
  • 使用 sync.Once 确保线程安全的单次初始化
  • 自动从配置系统获取日志路径
  • 自动创建所需目录结构

TOML配置文件(internal/config/config.go):

package configimport ("github.com/BurntSushi/toml"
)type LogConfig struct {LogPath string `toml:"logPath"`
}type Config struct {LogConfig `toml:"logConfig"`
}var cfg *Configfunc GetConfig() *Config {if cfg == nil {cfg = &Config{}if _, err := toml.DecodeFile("config.toml", cfg); err != nil {panic(err)}}return cfg
}

对应的TOML文件 (configs/config.toml) :

[logConfig]
logPath = "logs/"

日志轮转实现

func NewWithRotate(level Level, cfg *RotateConfig, opts ...zap.Option) *Logger {// 选择轮转策略var writer io.Writerif cfg.MaxSize > 0 {writer = NewRotateBySize(cfg)} else {writer = NewRotateByTime(cfg)}// 创建 zap coreal := zap.NewAtomicLevelAt(level)encoderCfg := zap.NewProductionEncoderConfig()encoderCfg.EncodeTime = zapcore.RFC3339TimeEncodercore := zapcore.NewCore(zapcore.NewJSONEncoder(encoderCfg),zapcore.AddSync(writer),al,)return &Logger{l:  zap.New(core, opts...),al: &al,}
}
  • 根据配置自动选择轮转策略
  • 使用 JSON 格式编码日志
  • 支持动态日志级别调整

日志级别控制

func (l *Logger) SetLevel(level Level) {if l.al != nil {l.al.SetLevel(level)  // 原子操作修改日志级别}
}
  • 支持运行时动态调整日志级别

日志方法

// 各级别日志方法
func (l *Logger) Debug(msg string, fields ...Field)
func (l *Logger) Info(msg string, fields ...Field)
// ...其他级别方法// 全局快捷方法
func Debug(msg string, fields ...Field) { Default().Debug(msg, fields...) }
// ...其他全局方法
  • 提供从 Debug 到 Fatal 的全级别日志支持
  • 支持结构化日志字段
  • 提供全局快捷访问方法

代码地址:IM-Go/pkg/zap

参考资料:Go 第三方 log 库之 zap 使用、如何基于 zap 封装一个更好用的日志库、github-log

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/906248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对盒模型的理解

对CSS盒模型的深入理解 CSS盒模型是网页布局的基础概念,它描述了HTML元素在页面中所占的空间以及如何计算这些空间。以下是关于盒模型的全面解析: 1. 盒模型的基本组成 每个HTML元素都被视为一个矩形的盒子,这个盒子由内到外由四部分组成&…

RV1126多线程获取SMARTP的GOP模式数据和普通GOP模式数据

通过代码的方式同时获取SMARTP模式的VENC码流数据和普通GOP模式的VENC码流数据,并进行对比画质。 一.RV1126 VI采集摄像头数据并同时编码SMARTP模式和普通GOP模式的编码码流流程 RV1126利用多线程同时获取普通GOP的VENC码流数据和SMARTP的码流数据一般如上图&#…

在Ubuntu使用 Ansible 配置 Azure 资源的动态清单

使用 Ansible 配置 Azure 资源的动态清单 简介1.安装pipx2.通过 pipx 安装 Ansible3.安装azure.azcollection4.安装集合所需的依赖项5.生成动态库存 简介 在主机变化不定的云环境中,Ansible 的动态清单功能可以消除维护静态清单文件的负担 本教程将带你使用 Azure…

车载诊断架构 ---车载总线对于功能寻址的处理策略

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…

Github 2025-05-16 Java开源项目日报 Top9

根据Github Trendings的统计,今日(2025-05-16统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目9Netty:异步事件驱动的网络应用程序框架 创建周期:5043 天开发语言:Java协议类型:Apache License 2.0Star数量:33219 个Fork数量:…

大语言模型(LLM)如何通过“思考时间”(即推理时的计算资源)提升推理能力

大语言模型(LLM)如何通过“思考时间”(即推理时的计算资源)提升推理能力 核心围绕人类思维机制、模型架构改进、训练方法优化等展开 一、人类思维的启发:快思考与慢思考 类比心理学: 人类思维分两种模式: 快思考(系统1):直觉驱动,快速但易出错(如估算简单问题)。…

【ubuntu24.04】pycharm 死机结束进程

windows 远程pycharm到ubuntu执行程序 pycharm 在调试过程中,内存耗尽,然后死机了 pycharm 进程 (base) rootk8s-master-pfsrv:/home/zhangbin/下载# ps -ef | grep pycharm root 121245 3230568 0 5月14 pts/8 00:00:00 /bin/bash --rcfile …

从虚拟仿真到行业实训再到具身智能--华清远见嵌入式物联网人工智能全链路教学方案

2025年5月23-25日,第63届中国高等教育博览会(高博会)将在长春中铁东北亚国际博览中心举办。作为国内高等教育领域规模大、影响力广的综合性展会,高博会始终聚焦教育科技前沿,吸引全国高校管理者、一线教师、教育科技企…

本地部署dify+ragflow+deepseek ,结合小模型实现故障预测,并结合本地知识库和大模型给出维修建议

1.准备工作 使用ollama 拉取deepseek-r1:7b 官网下载ollama ollama run deepseek-r1:7b ollama list Ragflow专注于构建基于检索增强生成(RAG)的工作流,强调模块化和轻量化,适合处理复杂文档格式和需要高精度检索的场景。Dify…

https://api.ipify.org/?format=json 不好使

https://api.ipify.org/?formatjson 打不开,用下面新地址 https://api64.ipify.org/?formatjson

Linux基础开发工具三(git,gdb/cgdb)

不知道你⼯作或学习时,有没有遇到这样的情况:我们在编写各种⽂档时,为了防⽌⽂档丢失,更改 失误,失误后能恢复到原来的版本,不得不复制出⼀个副本,⽐如: “报告-v1” “报告-v2” …

如何优化 Elasticsearch 磁盘空间和使用情况

作者:来自 Elastic Kofi Bartlett 解释如何防止和处理磁盘过满(过度使用)以及磁盘容量未被充分利用的情况。 想获得 Elastic 认证?了解下一次 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有许多新功能&am…

itop-3568开发板驱动开发指南-实验程序的编写

本实验对应的网盘路径为:iTOP-RK3568 开发板【底板 V1.7 版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux 驱动配套资料\04_Linux 驱动例程\02。 本章实验将编写 Linux 下的驱动传参实例代码,通过“insmod”命令进行参数的传递,并将相应的…

lesson03-简单回归案例(理论+代码)

一、梯度下降 二、 线性方程怎么样? 三、有噪音吗? 四、让我们看一个列子 五、如何优化 启发式搜索 学习进度 六、线性回归、逻辑回归、分类 总结、 简单线性回归是一种统计方法,用于确定两个变量之间的关系。具体来说,它试图…

【C语言】易错题 经典题型

出错原因&#xff1a;之前运行起来的可执行程序没有关闭 关闭即可 平均数&#xff08;average&#xff09; 输入3个整数&#xff0c;输出它们的平均值&#xff0c;保留3位小数。 #include <stdio.h> int main() {int a, b, c;scanf("%d %d %d", &a, &…

修改样式还能影响功能?是的!

最常见的几种样式导致按钮点击无效的情况&#xff1a; 1. pointer-events: none; &#x1f449; 点击被彻底屏蔽 症状&#xff1a;按钮完全不能点击&#xff0c;事件不会触发。 可能原因&#xff1a;这个样式让元素“无法响应鼠标事件”。 button {pointer-events: none; }…

ai决策平台:AnKo如何推动引领智能化未来?

ai决策平台&#xff1a;AnKo如何推动引领智能化未来&#xff1f; ai决策平台正在改变企业运营模式&#xff0c;AnKo作为ai决策平台的代表&#xff0c;为智能管理提供新方向。借助ai决策平台&#xff0c;组织在效率与准确性上实现飞跃。ai决策平台的力量正被广泛认可。 ai决策…

开疆智能Profient转ModbusTCP网关连接ABB机器人MODBUS TCP通讯案例

本案例是通过开疆智能Profinet转ModbusTCP网关将西门子PLC与ABB机器人进行通讯 因西门子PLC采用Profinet协议&#xff0c;而ABB机器人采用的是ModbusTCP通讯。故采取此种方案。 配置过程&#xff1a; 1.MODBUS/TCP基于以太网&#xff0c;故ABB机器人在使用时需要有616-1PCIN…

2089. 找出数组排序后的目标下标——O(n)做法!

本题要求在一个已排序的数组 nums 中&#xff0c;找出所有等于目标值 target 的元素下标。若不存在这样的元素&#xff0c;则返回 {-1, -1}。解决该问题有两种主要方法&#xff1a;二分查找法和统计计数法。 二分查找法&#xff1a;首先对数组进行排序&#xff0c;然后通过二分…

pyspark测试样例

from pyspark.sql import SparkSession from pyspark.sql.functions import col, lit, concat 创建 SparkSession spark SparkSession.builder.appName(“SparkSQLExample”).getOrCreate() 创建 DataFrame&#xff08;可以是从 CSV、JSON 等文件读取&#xff09; data […