Đây là một ngày làm việc đầy hiệu quả - làm đại lý

/imgposts/3mt6q3gs.jpg

Gần đây, tôi gặp một yêu cầu lưu trữ lượng lớn nhật ký từ các thiết bị trực tuyến. Nhật ký được tải lên qua MQTT, và phía máy chủ sử dụng golang để đăng ký các chủ đề MQTT nhằm thu thập thông tin này trước khi lưu vào MySQL. Ban đầu, vì lười biếng, tôi đã sử dụng InfluxDB 2 để lưu trữ dữ liệu thời gian liên quan đến hệ thống này. Tuy nhiên, sau khi hoàn thành một dự án, tôi nhận ra rằng việc sử dụng MySQL hiệu quả hơn nhiều so với InfluxDB 2.0. Cụ thể, cú pháp truy vấn của InfluxDB 2.0 thực sự không quen thuộc, cộng với việc tôi không có kinh nghiệm về vận hành, dẫn đến việc phải mất thêm thời gian tìm hiểu cách quản lý nó. Điều đó thật lãng phí! Vì vậy, tôi quyết định sử dụng công nghệ mà mình thạo nhất, đảm bảo tính ổn định và đáng tin cậy.

Theo đánh giá của tôi, nếu lưu trữ nhật ký theo tháng, mỗi bảng sẽ chứa ít hơn 10 triệu bản ghi. Do đó, không cần thiết phải phân chia dữ liệu theo ngày hoặc tuần.

Hôm nay, tôi đã giải quyết được vấn đề này một cách thành công, điều này thực sự là một bước đột phá trong việc lưu trữ nhật ký thiết bị.

  1. DeepSeek đã mô tả một giải pháp cho việc lưu trữ nhật ký theo tháng bằng Golang GORM. Tôi thấy rằng phương án này hoàn toàn khả thi.
  2. Tôi đã nhờ Github Copilot tạo ra phiên bản đầu tiên của mã nguồn. Kết quả rất đáng tin cậy. Hơn nữa, mã do Claude 3.7 phát triển dựa trên mã nguồn hiện tại của dự án còn hoàn thiện hơn nữa. Mặc dù vẫn còn một chút lỗi nhỏ, nhưng chúng dễ dàng sửa chữa.
  3. Sử dụng thư viện go cron để lập kế trang cá cược bóng đá hoạch tự động tạo các bảng MySQL cho vài tháng tới. Cần đảm bảo rằng các bảng đã tồn tại thì không bị xung đột.
  4. Thêm chức năng chọn tháng và ngày trên giao diện người báo bóng đá dùng Ant Design Pro để tiện lợi chuyển đổi giữa các bảng dữ liệu khác nhau theo tháng.

Mỗi ngày, tôi đều học được nhiều câu lệnh SQL mới mẻ và mạnh mẽ từ AI 😅

1CREATE TABLE IF NOT EXISTS log_202503 LIKE log;

Đây là lần đầu tiên tôi nhìn thấy câu lệnh SQL như vậy. CREATE TABLE IF NOT EXISTS %s LIKE log hoạt động rất tốt vì ban đầu tôi sử dụng bảng log đơn giản không phân bảng. Cách này giúp dễ dàng tạo ra các bảng mới dựa trên cấu trúc bảng gốc.

 1type Log struct {
 2  ID        uint      `gorm:"primaryKey"`
 3  CreatedAt time.Time
 4  UpdatedAt time.Time
 5}
 6
 7// TableName trả về tên bảng cho nhật ký hiện tại
 8// Định dạng sẽ là log_YYYYMM, ví dụ: log_202401
 9func (Log) TableName() string {
10  // Sử dụng thời gian hiện tại để xác định tên bảng
11  return GetLogTableName(time.Now())
12}
13
14// GetLogTableName trả về tên bảng nhật ký cho một thời điểm cụ thể
15func GetLogTableName(t time.Time) string {
16  return fmt.Sprintf("log_%d%02d", t.Year(), int(t.Month()))
17}
18
19// EnsureLogTableExists đảm bảo rằng bảng cho thời điểm cụ thể tồn tại
20func EnsureLogTableExists(t time.Time) error {
21  tableName := GetLogTableName(t)
22  // Kiểm tra xem bảng có tồn tại không
23  var count int64
24  DB.Raw("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = ?", tableName).Count(&count)
25  if count == 0 {
26    // Bảng không tồn tại, tạo nó bằng cách sao chép cấu trúc từ bảng log cơ sở
27    err := DB.Exec(fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s LIKE log", tableName)).Error
28    if err != nil {
29      return err
30    }
31  }
32  return nil
33}
34
35// EnsureCurrentMonthTableExists đảm bảo rằng bảng cho tháng hiện tại tồn tại
36func EnsureCurrentMonthTableExists() error {
37  return EnsureLogTableExists(time.Now())
38}

Chèn dữ liệu:

1// Lưu log vào cơ sở dữ liệu, cần lưu vào bảng log của tháng hiện tại
2DB.Table(GetLogTableName(time.Now())).Create(log)

Phía frontend khá đơn giản. Chỉ cần thêm một thành phần chọn năm-tháng, gửi yêu cầu lọc về phía backend là đủ.

Tôi đã hoàn thành việc phân bảng tự động, khóa thiết bị từ xa qua MQTT, cũng như tích hợp cả giao diện người dùng. Ngoài ra, tôi còn nghiên cứu cách truy vấn thông tin thiết bị trực tuyến từ EMQX. Đây là một ngày làm việc đầy hiệu quả! ✌️ Giờ thì tôi có thể nghỉ ngơi một chút rồi, cảm giác như não bộ đã ngừng hoạt động... 🥱

Tìm hiểu cách sử dụng API EMQX để kiểm tra trạng thái trực tuyến của thiết bị MQTT.