Go語言即時通訊系統開發日志day2
計劃:學習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進行參考學習,后續有能力了再對項目的模塊進行優化和重構。
項目實現順序分析
大概分析了一下,后續開發的順序,實際隨情況而變,主要是為了防止每天開始學習時,不知從而下手的處境。
- 基礎架構搭建
- 搭建項目結構
- 日志系統封裝
- 配置系統
- 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規范
類型 | 類別 | 說明 |
---|---|---|
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 語言項目開發實戰 - 規范設計(付費課程)
Go語言即時通訊系統開發日志day5
計劃:選擇項目架構,搭建項目結構,構建表結構。
總結:完成了項目構建,了解了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 項目結構
MVC 三層架構
Model 層(數據 + 業務核心)
對應目錄:
internal/model/
:定義數據結構(如User
、Message
)internal/dao/
:數據庫操作(CRUD)internal/service/
:業務邏輯(如發送消息的校驗、權限控制)
View 層(數據展示)
對應目錄:web/
- 前端代碼(Vue/React)通過 API 或 WebSocket 獲取數據并渲染。
實時更新:通過 pkg/websocket
監聽服務端推送。
Controller 層(請求協調)
對應目錄:
api/
:定義接口協議(如 REST 路由、gRPC 方法)internal/dto/
:請求/響應的數據結構internal/service/
:實際控制層(處理參數校驗、調用 Model 層)
參考資料: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