Sync README files from source repository [skip ci]
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user