Files
ResourcePool.Docs/CLICKHOUSE_FIX.md
T

85 lines
2.8 KiB
Markdown

# 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:**
```csharp
public IDbConnection proxy_logs =>
new ClickHouseConnection(_configuration.GetConnectionString(nameof(proxy_logs)));
```
**Sau:**
```csharp
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:**
```csharp
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