计划:学习go中MySQL,Redis的使用,使用MySQL和Redis完成一个单聊demo。
总结:现在每天下午用来开发这个项目,如果有课的话可能学习时间只有3-4个小时,再加上今天的学习效率不高;今天只做了一些开发规划,并了解了go语言如何使用MySQL,Redis,下了两篇博客,Go 语言 sqlx 库使用:对 MySQL 增删改查、Go 语言 Redis 使用 :安装、配置与操作,并把第一天的欠下的net/http库学习了解了一下,Go 语言 net/http 包使用:HTTP 服务器、客户端与中间件。打算先参照GitHub上的go-chat这个IM进行参考学习,后续有能力了再对项目的模块进行优化和重构。
大概分析了一下,后续开发的顺序,实际随情况而变,主要是为了防止每天开始学习时,不知从而下手的处境。
计划:了解Gin,Gorm框架的使用,构建项目结构,了解Go项目的开发流程。
总结:通过【最新Go Web开发教程】基于gin框架和gorm的web开发实战 (七米出品)学习了Go语言的Gin框架,Gorm框架。
Go语言 Gin框架 使用指南
Gin 是一个用 Go 编写的高性能 Web 框架,以轻量级和快速路由著称,适合构建 RESTful API 和微服务。它提供了中间件支持、JSON 解析、错误处理等常用功能,代码简洁且易于上手,是 Go 生态中最流行的 Web 框架之一。
Go语言 GORM框架 使用指南
Gorm 是 Go 的 ORM(对象关系映射)库,支持 MySQL、PostgreSQL 等数据库,通过结构体模型操作数据,简化了数据库交互。它提供链式调用、事务管理、关联查询等功能,兼顾灵活性和易用性,适合快速开发数据驱动的应用。
两者常结合使用(Gin 处理 HTTP,Gorm 操作数据库)。可以看我写了的两篇博客了解其快速入门并使用。
计划:搭建项目基本结构,学习了解项目开发(架构、规范、开发了流程)等内容。
总结:写了两篇相关博客,Go语言 Gin框架 使用指南,Go语言 GORM框架 使用指南,快速浏览了一下 Go 语言项目开发实战(付费课程)。
简单了解一下各种项目架构:
1. 分层架构(Layered Architecture)
2. MVC架构(Model-View-Controller)
3. 微服务架构(Microservices)
4. 事件驱动架构(Event-Driven Architecture, EDA)
5. 六边形架构(Hexagonal Architecture)
6. CQRS(Command Query Responsibility Segregation)
7. 无服务器架构(Serverless)
8. 空间基架构(Space-Based Architecture)
9. 插件化架构(Plugin Architecture)
10. 前后端分离架构(Frontend-Backend Separation)
11. IAM架构(Identity and Access Management)
12. 单体架构(Monolithic Architecture)
如何选择?
需求 | 推荐架构 |
---|---|
快速开发简单应用 | 单体架构、MVC |
高并发、大规模系统 | 微服务、空间基架构 |
实时数据处理 | 事件驱动架构 |
灵活扩展功能 | 插件化架构 |
低成本、无运维 | 无服务器架构 |
严格权限控制 | IAM架构 |
读写性能分离 | CQRS |
长期演化的核心业务 | 六边形架构 |
开源规范
开源项目应遵循明确的许可证(如MIT、Apache-2.0),并在README中说明项目目标、使用方式及贡献指南。代码需保持模块化、可复用,并提供清晰的API文档,方便他人理解和使用。
文档规范
项目文档应包括README(快速入门)、API文档(如Swagger)、设计文档(架构图)和贡献指南(PR流程)。文档需结构化、定期更新,并采用Markdown等通用格式,确保易读性和可维护性。
版本规范
推荐使用语义化版本(SemVer):主版本号.次版本号.修订号(如v1.2.3
),分别对应不兼容改动、新增功能、Bug修复。版本变更需在CHANGELOG中记录,明确影响范围,便于用户升级。
commit规范
类型 | 类别 | 说明 |
---|---|---|
feat | Production | 新增功能 |
fix | Production | Bug修复 |
perf | Production | 提高代码性能的变更 |
style | Development | 代码格式类的变更,比如用gofmt 格式化代码、删除空行等 |
refactor | Production | 其他代码类的变更,这些变更不属于feat、fix、perf 和 style,例 如简化代码、重命名变量、删除冗余代码等 |
test | Development | 新增测试用例或是更新现有测试用例 |
ci | Development | 持续集成和部署相关的改动,比如修改Jenkins、GitLab CI等CI 配置文件或者更新systemdunit文件 |
docs | Development | 文档类的更新,包括修改用户文档或者开发文档等 |
chore | Development | 其他类型,比如构建流程、依赖管理或者辅助工具的变动等 |
参考资料: Go 语言项目开发实战 - 规范设计(付费课程)
计划:选择项目架构,搭建项目结构,构建表结构。
总结:完成了项目构建,了解了MVC三层架构,了解了zap并对其完成了简单封装,使其可以向
log
库一样使用。
构建项目结构
.
├── api
├── cmd
├── configs
├── docs
├── pkg
├── test
├── go.mod
├── go.sum
├── internal
│ ├── config
│ ├── dao
│ ├── dto
│ ├── model
│ └── service
└── web
├── public
└── src
api/
:存放 API 协议定义文件,用于描述接口规范,不包含具体实现。
cmd/
:存放 可执行程序的入口文件(每个子目录对应一个独立的二进制程序)。
configs/
:存放 配置文件模板或默认配置(如开发/生产环境配置)。
pkg/
:存放 可复用的公共库代码(允许被其他项目导入)。
test/
:存放 集成测试/端到端测试代码(单元测试应直接放在各包内)。
internal/
:存放 私有业务逻辑(禁止被外部项目导入),是项目核心
onfig/
:定义配置结构体及加载逻辑。
dao/
(Data Access Object):数据库操作层(直接与 MySQL/Redis 等交互)。
dto/
(Data Transfer Object):定义 API 请求/响应的数据结构。
**model/
**定义数据库表对应的结构体(ORM 模型)。
service/
:实现核心业务逻辑(如消息发送、用户鉴权)。
web/
:存放 前端代码和静态资源。
public/
:编译后的静态文件(可直接通过 HTTP 访问)。
src/
:前端源码(如 React/Vue 项目)。】
用户发送消息流程:
参考资料:第 25 章 - Golang 项目结构
Model 层(数据 + 业务核心)
对应目录:
internal/model/
:定义数据结构(如 User
、Message
)internal/dao/
:数据库操作(CRUD)internal/service/
:业务逻辑(如发送消息的校验、权限控制)View 层(数据展示)
对应目录:web/
实时更新:通过 pkg/websocket
监听服务端推送。
Controller 层(请求协调)
对应目录:
api/
:定义接口协议(如 REST 路由、gRPC 方法)internal/dto/
:请求/响应的数据结构internal/service/
:实际控制层(处理参数校验、调用 Model 层)参考资料:MVC 三层架构案例详细讲解
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)
// 创建带轮转功能的 logger
std = NewWithRotate(InfoLevel, NewProductionRotateConfig(logPath))
initDone = true
}
func Default() *Logger {
once.Do(initLogger) // 线程安全的单次初始化
return std
}
sync.Once
确保线程安全的单次初始化TOML配置文件(
internal/config/config.go
):package config import ( "github.com/BurntSushi/toml" ) type LogConfig struct { LogPath string `toml:"logPath"` } type Config struct { LogConfig `toml:"logConfig"` } var cfg *Config func 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.Writer
if cfg.MaxSize > 0 {
writer = NewRotateBySize(cfg)
} else {
writer = NewRotateByTime(cfg)
}
// 创建 zap core
al := zap.NewAtomicLevelAt(level)
encoderCfg := zap.NewProductionEncoderConfig()
encoderCfg.EncodeTime = zapcore.RFC3339TimeEncoder
core := zapcore.NewCore(
zapcore.NewJSONEncoder(encoderCfg),
zapcore.AddSync(writer),
al,
)
return &Logger{
l: zap.New(core, opts...),
al: &al,
}
}
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...) }
// ...其他全局方法
代码地址:IM-Go/pkg/zap
参考资料:Go 第三方 log 库之 zap 使用、如何基于 zap 封装一个更好用的日志库、github-log