系列文章:Go 聊天室实战系列(1/6)项目地址:https://gitee.com/gaogaohang/go-land_-learning
技术栈:Go 1.23 + Gin + PostgreSQL + Redis + Vue3
一、为什么选择 Go?
在开始这个项目之前,我对比了几个技术选型:
最终选择 Go 的理由:
性能:聊天室需要处理大量并发连接
部署:单个二进制文件,无需 JVM
学习价值:补充多语言能力
二、项目架构设计
2.1 分层架构
采用经典的三层架构:
┌─────────────────────────────────────────┐
│ API Layer │
│ (internal/api/) │
│ - 路由定义 │
│ - 请求参数绑定 │
│ - 响应格式化 │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Service Layer │
│ (internal/service/) │
│ - 业务逻辑 │
│ - 事务管理 │
│ - 权限校验 │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Repository Layer │
│ (internal/repository/) │
│ - 数据库操作 │
│ - GORM 封装 │
│ - 缓存管理 │
└─────────────────────────────────────────┘2.2 目录结构
go-chat/
├── cmd/ # 命令入口
├── internal/ # 内部包(Go 私有包约定)
│ ├── api/ # API 层
│ │ ├── auth.go # 认证接口
│ │ ├── user.go # 用户接口
│ │ └── chat.go # 聊天接口
│ ├── service/ # 业务层
│ │ ├── auth_service.go
│ │ ├── user_service.go
│ │ └── chat_service.go
│ ├── repository/ # 数据层
│ │ ├── user_repo.go
│ │ └── message_repo.go
│ ├── model/ # 数据模型
│ │ ├── user.go
│ │ └── message.go
│ ├── middleware/ # 中间件
│ │ ├── jwt.go # JWT 认证
│ │ └── cors.go # CORS
│ └── config/ # 配置管理
├── pkg/ # 公共包
│ ├── response/ # 统一响应
│ ├── errors/ # 错误码定义
│ └── logger/ # 日志模块
├── web/ # 前端代码 (Vue3 + TS)
├── config.dev.yaml # 开发环境配置
├── config.test.yaml # 测试环境配置
├── config.prod.yaml # 生产环境配置
├── main.go # 入口文件
├── Makefile # 构建脚本
├── .air.toml # air 热重载配置
└── README.md # 项目文档设计原则:
internal/:Go 的私有包约定,外部无法 importpkg/:公共包,可被外部引用配置文件按环境分离
三、核心代码解析
3.1 入口文件 (main.go)
func main() {
// 1. 加载配置
config.LoadConfig()
// 2. 初始化日志
logger.Init()
// 3. 初始化数据库
database.InitPostgres()
database.InitRedis()
// 4. 注册路由
router := gin.Default()
api.RegisterRoutes(router)
// 5. 启动服务
port := config.GetServerPort()
router.Run(":" + port)
}启动流程:配置 → 日志 → 数据库 → 路由 → 服务
3.2 统一响应格式 (pkg/response/)
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
RequestID string `json:"request_id"`
}
func Success(data interface{}) Response {
return Response{
Code: 0,
Message: "success",
Data: data,
RequestID: generateRequestID(),
}
}
func Error(code int, message string) Response {
return Response{
Code: code,
Message: message,
Data: nil,
RequestID: generateRequestID(),
}
}设计思考:
所有接口返回统一格式
code=0表示成功,非 0 表示错误request_id用于日志追踪
3.3 错误码定义 (pkg/errors/)
// 系统级错误 (1000-1999)
const (
ErrSystemError = 1000 + iota
ErrDatabaseError
ErrCacheError
)
// 认证授权 (2000-2999)
const (
ErrAuthRequired = 2000 + iota
ErrTokenExpired
ErrTokenInvalid
)
// 用户模块 (3000-3999)
const (
ErrUserNotFound = 3000 + iota
ErrUserExists
)
// ... 好友、会话、消息、群组模块分类清晰,便于前端根据错误码处理。
四、配置管理
4.1 多环境配置
# config.dev.yaml
server:
port: 8080
mode: debug
database:
host: localhost
port: 5432
user: 111111
password: 111111
db_name: chatdb
redis:
host: localhost
port: 6379
log:
level: debug
output: stdout4.2 环境变量覆盖
export CHAT_ENV=prod
export CHAT_SERVER_PORT=9090
./bin/go-chat优先级:环境变量 > 配置文件 > 默认值
五、Makefile 自动化
.PHONY: build run test clean
# 构建
build:
go build -o bin/go-chat main.go
# 开发环境运行
run:
go run main.go -env=dev
# 生产环境运行
run-prod:
./bin/go-chat -env=prod
# 测试
test:
go test -v ./...
# 测试覆盖率
test-coverage:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
# Docker 构建
docker-build:
docker build -t go-chat:latest .
# Docker 运行
docker-run:
docker run -p 8080:8080 go-chat:latest
# 开发模式(热重载)
dev:
air使用体验:
make build # 构建
make run # 运行
make test # 测试
make dev # 热重载开发六、开发工具链
6.1 air 热重载
# .air.toml
root = "."
tmp_dir = "tmp"
[build]
cmd = "go build -o ./tmp/main main.go"
bin = "./tmp/main"
include_ext = ["go", "yaml", "json"]
exclude_dir = ["tmp", "web", "bin"]效果:修改代码后自动重启服务,无需手动操作。
6.2 项目统计
八、遇到的挑战
挑战 1:分层边界模糊
问题:Service 层和 Repository 层职责不清 解决:明确约定
Repository:只负责 CRUD,不包含业务逻辑
Service:处理业务规则、事务、权限
挑战 2:配置管理混乱
问题:多处读取配置,难以统一管理 解决:单例配置中心,启动时加载,全局访问
挑战 3:错误处理不一致
问题:有的返回 error,有的返回 Response 解决:统一使用 pkg/response 包装
九、下一步
在下一篇文章中,我们将深入讲解 JWT 认证与中间件设计,包括:
JWT 原理详解
登录接口实现
认证中间件编写
权限校验实践
十、项目信息
📦 项目地址:https://gitee.com/gaogaohang/go-land_-learning
📝 系列文章:Go 聊天室实战系列(1/6)
🏷️ 技术标签:#Go #Gin #PostgreSQL #Redis #Vue3
欢迎 Star & Fork!有任何问题欢迎在评论区交流! 🚀