Files

2.8 KiB

ClickHouse Connection Fix

Vấn đề

Lỗi TOO_MANY_SIMULTANEOUS_QUERIES (Error Code 202) xảy ra khi có quá nhiều queries đồng thời đến ClickHouse (vượt quá limit 500).

Nguyên nhân

  1. Connection leak: Mỗi lần gọi _clickHouseContext.proxy_logs tạo một connection mới mà không đóng đúng cách
  2. Không có connection pooling: Connections không được reuse
  3. Không có error handling: Lỗi ClickHouse làm crash toàn bộ request

Giải pháp đã áp dụng

1. Sửa ClickHouseContext (ClickHouseContext.cs)

Trước:

public IDbConnection proxy_logs =>
    new ClickHouseConnection(_configuration.GetConnectionString(nameof(proxy_logs)));

Sau:

public IDbConnection CreateConnection()
{
    return new ClickHouseConnection(_connectionString);
}

Lợi ích:

  • Connection được tạo explicitly và có thể dispose đúng cách với using statement
  • Connection string được cache trong constructor

2. Cập nhật ProxyRepository.UsedProxy()

Thay đổi:

  • Sử dụng CreateConnection() thay vì property proxy_logs
  • Thêm try-catch để handle lỗi ClickHouse
  • Catch riêng error code 202 (TOO_MANY_SIMULTANEOUS_QUERIES)
  • Thêm command timeout (5 seconds)
  • Log warning thay vì throw exception để không ảnh hưởng main flow

Code:

try
{
    using var db = _clickHouseContext.CreateConnection();
    
    var res = await db.ExecuteAsync(
        @"INSERT INTO requested_logs ...",
        log,
        commandTimeout: 5
    );
    return res > 0;
}
catch (ClickHouseServerException ex) when (ex.ErrorCode == 202)
{
    Log.Warning("ClickHouse too many simultaneous queries. Skipping log.");
    return false;
}
catch (Exception ex)
{
    Log.Error(ex, "Failed to log proxy usage to ClickHouse");
    return false;
}

Kết quả mong đợi

  1. Connections được đóng đúng cách sau mỗi query
  2. Giảm số lượng connections đồng thời
  3. Lỗi ClickHouse không làm crash service
  4. Logs được ghi lại để monitoring

Monitoring

Sau khi deploy, cần theo dõi:

  • Số lượng warnings "ClickHouse too many simultaneous queries" trong logs
  • Số lượng errors "Failed to log proxy usage to ClickHouse"
  • Nếu vẫn còn nhiều warnings, cần xem xét:
    • Tăng max_concurrent_queries trong ClickHouse config
    • Implement batch insert thay vì insert từng record
    • Sử dụng queue + background worker để buffer logs

Tối ưu thêm (nếu cần)

Nếu vẫn gặp vấn đề, có thể implement:

  1. Batch Insert: Gom nhiều logs lại insert một lần
  2. Background Queue: Sử dụng Channel/BlockingCollection để buffer logs
  3. Circuit Breaker: Tạm dừng logging khi ClickHouse quá tải