2.8 KiB
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
- Connection leak: Mỗi lần gọi
_clickHouseContext.proxy_logstạo một connection mới mà không đóng đúng cách - Không có connection pooling: Connections không được reuse
- 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
usingstatement - Connection string được cache trong constructor
2. Cập nhật ProxyRepository.UsedProxy()
Thay đổi:
- Sử dụng
CreateConnection()thay vì propertyproxy_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
- ✅ Connections được đóng đúng cách sau mỗi query
- ✅ Giảm số lượng connections đồng thời
- ✅ Lỗi ClickHouse không làm crash service
- ✅ 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_queriestrong ClickHouse config - Implement batch insert thay vì insert từng record
- Sử dụng queue + background worker để buffer logs
- Tăng
Tối ưu thêm (nếu cần)
Nếu vẫn gặp vấn đề, có thể implement:
- Batch Insert: Gom nhiều logs lại insert một lần
- Background Queue: Sử dụng Channel/BlockingCollection để buffer logs
- Circuit Breaker: Tạm dừng logging khi ClickHouse quá tải