Bảng giá

Bắt đầu nhanh

Tệp nguồn liên quan

Trang này được tạo dựa trên các tệp nguồn sau:

Dự án gochat là một hệ thống chat phân tán được viết bằng Go, hỗ trợ WebSocket và TCP. Hệ thống sử dụng kiến trúc microservice với các thành phần tách biệt: logic layer, connect layer, task service và API server.

Yêu cầu môi trường và phụ thuộc

Phiên bản Go và thư viện

Dự án yêu cầu Go phiên bản 1.18 trở lên, được định nghĩa trong go.mod:1-22. Các thư viện phụ thuộc chính bao gồm:

Thư việnMục đích
github.com/gin-gonic/gin v1.7.7HTTP web framework cho API server
github.com/gorilla/websocket v1.5.0Xử lý WebSocket connections
github.com/go-redis/redis v6.15.9Redis client cho caching
github.com/jinzhu/gorm v1.9.16ORM cho database operations
github.com/smallnest/rpcx v1.7.4RPC framework cho microservice communication
github.com/spf13/viper v1.11.0Configuration management

Công cụ cần thiết

Theo docker/Dockerfile:1-16, các công cụ sau được cài đặt trong môi trường container:

  • etcd v3.4.3: Service discovery và configuration center
  • Redis 5.0.9: In-memory data store
  • SQLite3: Database mặc định cho môi trường development
  • Supervisor: Process manager cho các service

Xây dựng Docker image

Build image với Makefile

Dự án cung cấp Makefile để xây dựng Docker image tùy chỉnh. Lệnh build cho phép chỉ định tag phiên bản:

bash
1make build TAG=1.18
2# hoặc
3make build TAG=latest

Theo Makefile:1-4, lệnh này sẽ thực hiện build image từ thư mục docker/ với tag lockgit/gochat:${TAG}.

Cấu hình Dockerfile

Dockerfile:1-29 định nghĩa image base là golang:1.18 và cài đặt các dependencies:

dockerfile
1FROM golang:1.18
2WORKDIR /go/src/gochat
3# Cài đặt gcc, supervisor, etcd, redis, sqlite3
4ENV RUN_MODE dev

Image mặc định sử dụng RUN_MODE=dev. Biến môi trường này có thể được override khi chạy container.

Khởi chạy ứng dụng

Lệnh khởi động nhanh (Khuyến nghị)

Cách nhanh nhất để khởi chạy gochat là sử dụng script run.sh với Docker:

bash
1# Môi trường development
2sh run.sh dev 127.0.0.1
3
4# Môi trường production
5sh run.sh prod x.x.x.x

Theo run.sh:1-95, script này thực hiện các bước:

  1. Kiểm tra tham số môi trường (dev hoặc prod)
  2. Validate địa chỉ IP
  3. Khởi chạy Docker container với image lockgit/gochat:1.18
  4. Mount các file cấu hình và source code
  5. Expose các port dịch vụ
  6. Thực thi script reload.sh để build và restart services

Cấu hình môi trường

Script run.sh chấp nhận hai tham số:

Tham sốGiá trị hợp lệMô tả
CONFIG_ENVdev, prodMôi trường chạy
IPADDRĐịa chỉ IP hợp lệIP của máy host

Theo run.sh:24-37, nếu tham số không hợp lệ, script sẽ thoát với mã lỗi 1 và hiển thị hướng dẫn sử dụng.

Port mapping

Container expose các port sau theo run.sh:66-72:

PortDịch vụMô tả
8080Web UIGiao diện web chat
7070APIHTTP API server
7000WebSocketWebSocket connection endpoint
7001TCPTCP connection endpoint
7002TCPTCP connection endpoint (additional)

Quy trình khởi động

正在加载图表渲染器...

Cấu trúc module và khởi động dịch vụ

Entry point chính

main.go:1-48 định nghĩa entry point của ứng dụng. Hệ thống sử dụng flag -module để xác định module cần chạy:

go
1flag.StringVar(&module, "module", "", "assign run module")

Các module khả dụng

Theo main.go:26-42, các module sau có thể được khởi động:

ModuleMô tảHàm khởi động
logicBusiness logic layerlogic.New().Run()
connect_websocketWebSocket connection handlerconnect.New().Run()
connect_tcpTCP connection handlerconnect.New().RunTcp()
taskBackground task servicetask.New().Run()
apiHTTP API serverapi.New().Run()
siteStatic web serversite.New().Run()

Khởi động API server

api/chat.go:1-67 minh họa cách API server được khởi động với Gin framework:

go
1func (c *Chat) Run() {
2    rpc.InitLogicRpcClient()
3    r := router.Register()
4    gin.SetMode(runMode)
5    srv := &http.Server{
6        Addr:    fmt.Sprintf(":%d", port),
7        Handler: r,
8    }
9    // Graceful shutdown handling
10}

API server hỗ trợ graceful shutdown khi nhận signal SIGHUP, SIGINT, SIGTERM, hoặc SIGQUIT theo api/chat.go:55-66.

Database initialization

db/db.go:21-42 khởi tạo kết nối SQLite database:

go
1func initDB(dbName string) {
2    configFilePath := realPath + "/db/gochat.sqlite3"
3    dbMap[dbName], e = gorm.Open("sqlite3", configFilePath)
4    dbMap[dbName].DB().SetMaxIdleConns(4)
5    dbMap[dbName].DB().SetMaxOpenConns(20)
6}

Lưu ý: Theo db/db.go:27, môi trường production nên chuyển sang MySQL driver.

Kiểm tra và truy cập

Truy cập Web Interface

Sau khi khởi động thành công, theo reload.sh:12-18, hệ thống sẽ hiển thị thông báo:

Beautiful ! Now, You can visit http://127.0.0.1:8080 , start the world.

Script reload.sh

reload.sh:1-18 thực hiện các tác vụ sau khi container khởi động:

  1. Thay thế địa chỉ IP trong static files dựa trên biến môi trường HOST_IP
  2. Build binary gochat.bin từ main.go
  3. Restart tất cả services thông qua supervisorctl
bash
1# Build command
2CGO_CFLAGS="-g -O2 -Wno-return-local-addr" go build -o /go/src/gochat/bin/gochat.bin /go/src/gochat/main.go

Xác minh dịch vụ đang chạy

Để kiểm tra các dịch vụ trong container đang hoạt động:

bash
1# Kiểm tra container đang chạy
2docker ps | grep gochat
3
4# Kiểm tra logs
5docker logs gochat-dev
6
7# Truy cập vào container
8docker exec -it gochat-dev /bin/bash

Sự khác biệt giữa các môi trường

Khía cạnhDevelopmentProduction
Docker imagelockgit/gochat:1.18lockgit/gochat:1.18
RUN_MODEdevprod
Config directorydocker/dev/docker/prod/
DatabaseSQLite3 (khuyến nghị MySQL cho prod theo db/db.go:27)Cần cấu hình MySQL

Các vấn đề thường gặp và cách khắc phục

1. Lỗi địa chỉ IP không hợp lệ

Triệu chứng: Script thoát với thông báo:

ip address error !!! please check 'x.x.x.x' is ip address?

Nguyên nhân: Theo run.sh:34-37, địa chỉ IP không đúng định dạng.

Giải pháp: Sử dụng địa chỉ IP hợp lệ theo định dạng xxx.xxx.xxx.xxx:

bash
1sh run.sh dev 192.168.1.100

2. Lỗi môi trường không được hỗ trợ

Triệu chứng: Script thoát với thông báo:

Sorry, error! Please execute For example:
    sh run.sh dev 127.0.0.1
    sh run.sh prod x.x.x.x

Nguyên nhân: Theo run.sh:24-32, tham số môi trường không phải dev hoặc prod.

Giải pháp: Chỉ sử dụng dev hoặc prod làm tham số đầu tiên.

3. Container đã tồn tại

Triệu chứng: Docker báo lỗi container với tên gochat-dev hoặc gochat-prod đã tồn tại.

Giải pháp: Xóa container cũ trước khi chạy lại:

bash
1docker rm -f gochat-dev
2# hoặc
3docker rm -f gochat-prod

4. Port đã được sử dụng

Triệu chứng: Docker không thể bind các port 8080, 7070, 7000-7002.

Giải pháp:

  • Kiểm tra port đang được sử dụng: netstat -tlnp | grep -E '8080|7070|7000|7001|7002'
  • Dừng dịch vụ đang sử dụng port hoặc sửa port mapping trong run.sh:66-72

5. Module không hợp lệ

Triệu chứng: Khi chạy binary trực tiếp, hiển thị:

exiting,module param error!

Nguyên nhân: Theo main.go:39-41, module không thuộc danh sách hợp lệ.

Giải pháp: Sử dụng một trong các module: logic, connect_websocket, connect_tcp, task, api, site.

Các bước tiếp theo

Sau khi khởi động thành công, có thể tham khảo các chủ đề sau:

  1. Cấu hình chi tiết: Xem các file cấu hình trong docker/dev/ hoặc docker/prod/
  2. Tùy biến database: Chuyển từ SQLite sang MySQL theo hướng dẫn tại db/db.go:27
  3. RPC communication: Tìm hiểu về service discovery với etcd tại task/rpc.go:82-106
  4. API endpoints: Khám phá các API routes trong module api
  5. WebSocket integration: Tìm hiểu về kết nối real-time trong module connect