Sync README files from source repository [skip ci]

This commit is contained in:
Gitea Actions
2026-01-23 10:42:45 +00:00
commit f558a9c713
6 changed files with 1542 additions and 0 deletions
+790
View File
@@ -0,0 +1,790 @@
# Icomm.SmartPool.Proxy
Client SDK for SmartPool proxy management system. Supports both gRPC and HTTP protocols.
> 📖 **Xem tài liệu chi tiết**: [SDK_DOCUMENTATION.md](./SDK_DOCUMENTATION.md)
## ✨ Features
-**Dual Protocol**: gRPC (MagicOnion) và HTTP REST API
-**5 Chiến lược**: Random, Round Robin, Least Delay, Adaptive Ranking, Alternative
-**Tối ưu hiệu suất**: Keep-alive, Connection pooling, Client caching, Compression
-**Batch Logging**: Ghi log hiệu quả với batch processing
-**Fire-and-Forget**: Non-blocking logging
-**Compact Response**: Giảm payload size ~50-60%
## Installation
### Prerequisites
Đảm bảo bạn đã cấu hình NuGet source `ic` trong project:
```bash
# Thêm NuGet source (nếu chưa có)
dotnet nuget add source <nuget-feed-url> --name ic
```
### Install via NuGet Package
Cài đặt package từ NuGet repository:
```bash
dotnet add package --source ic --version 10.0.1 Icomm.SmartPool.Proxy
```
Hoặc thêm vào `.csproj` file:
```xml
<ItemGroup>
<PackageReference Include="Icomm.SmartPool.Proxy" Version="10.0.1" />
</ItemGroup>
```
Và cấu hình NuGet source trong `nuget.config`:
```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="ic" value="<nuget-feed-url>" />
</packageSources>
</configuration>
```
## Quick Start
### Configuration
Add to `appsettings.json`:
```json
{
"SmartPool": {
"Protocol": "Grpc",
"Host": "localhost",
"Port": 5001,
"UseSecureConnection": false,
"DefaultAccessToken": "your-access-token",
"TimeoutMs": 30000
}
}
```
### Register in DI Container
```csharp
using Icomm.SmartPool.Proxy.Extensions;
// In Startup.cs or Program.cs
services.AddSmartPoolClient(configuration);
```
### Use in Your Code
```csharp
public class MyService
{
private readonly ISmartPoolClient _smartPoolClient;
public MyService(ISmartPoolClient smartPoolClient)
{
_smartPoolClient = smartPoolClient;
}
public async Task MakeRequestAsync()
{
// Get proxy as IWebProxy (ready for HttpClient)
var proxy = await _smartPoolClient.GetProxyAsync(
strategy: "least_delay",
targetDomain: "facebook.com",
ipVersion: "v6"
);
if (proxy != null)
{
var handler = new HttpClientHandler { Proxy = proxy };
var httpClient = new HttpClient(handler);
var response = await httpClient.GetAsync("https://facebook.com");
// Log usage
await _smartPoolClient.LogProxyUsageAsync(
accessToken: "your-token",
proxyId: 123,
targetDomain: "facebook.com",
statusCode: (int)response.StatusCode,
responseTimeMs: 450
);
}
}
}
```
## Advanced Usage
### Get Raw Proxy Information
```csharp
var request = new GetProxyRequest
{
access_token = "your-token",
strategy = "adaptive_ranking",
target_domain = "facebook.com",
ip_version = "v6",
protocol = "http",
country = "US"
};
var proxyServer = await _smartPoolClient.GetRawProxyAsync(request);
if (proxyServer != null)
{
Console.WriteLine($"Proxy: {proxyServer.host}:{proxyServer.port}");
Console.WriteLine($"Country: {proxyServer.country}");
}
```
### Alternative Proxy Strategy
```csharp
var request = new GetProxyRequest
{
access_token = "your-token",
strategy = "alternative",
referer_proxy = new SmartProxyServer { id = 123 } // Current proxy that failed
};
var alternativeProxy = await _smartPoolClient.GetRawProxyAsync(request);
```
## Strategies
- **random**: Random selection
- **round_robin**: Balanced distribution
- **least_delay**: Fastest proxy (requires targetDomain)
- **adaptive_ranking**: Highest success rate (requires targetDomain)
- **alternative**: Similar proxy replacement (requires refererProxy)
## Protocol Selection
### gRPC (Recommended)
```csharp
services.AddSmartPoolClient(options =>
{
options.Protocol = SmartPoolProtocol.Grpc;
options.Host = "api.example.com";
options.Port = 5001;
});
```
**Pros**: High performance, binary protocol, streaming support
### HTTP
```csharp
services.AddSmartPoolClient(options =>
{
options.Protocol = SmartPoolProtocol.Http;
options.Host = "api.example.com";
options.Port = 5000;
});
```
**Pros**: Standard REST API, easier debugging, firewall-friendly
## Error Handling
SDK cung cấp exception handling chi tiết với các exception types tương ứng với error codes từ server:
### Exception Types
```csharp
using Icomm.SmartPool.Proxy.Exceptions;
try
{
var proxy = await _smartPoolClient.GetRawProxyAsync(request);
// Use proxy...
}
catch (AccessTokenRequiredException)
{
// Access token không được cung cấp
Console.WriteLine("Access token is required");
}
catch (AccessTokenInvalidException ex)
{
// Access token không hợp lệ hoặc không được phân quyền
Console.WriteLine($"Invalid access token: {ex.AccessToken}");
}
catch (NoAvailableProxiesException ex)
{
// Không có proxy available cho access token này
Console.WriteLine($"No proxies available for token: {ex.AccessToken}");
}
catch (NoMatchingProxiesException)
{
// Không có proxy match với filters (ip_version, protocol, country, etc.)
Console.WriteLine("No proxies match the specified filters");
}
catch (StrategyNotFoundException ex)
{
// Strategy không tồn tại
Console.WriteLine($"Strategy not found: {ex.StrategyName}");
}
catch (RefererProxyRequiredException)
{
// Alternative strategy cần referer_proxy
Console.WriteLine("Referer proxy is required for alternative strategy");
}
catch (SmartPoolException ex)
{
// Các lỗi khác từ SmartPool
Console.WriteLine($"SmartPool error ({ex.ErrorCode}): {ex.Message}");
}
catch (Exception ex)
{
// Network errors, timeout, etc.
Console.WriteLine($"Network error: {ex.Message}");
}
```
### Try Methods (Không Throw Exception)
SDK cung cấp các method `Try*` để bỏ qua exceptions và trả về `null` nếu lỗi:
```csharp
// TryGetRawProxyAsync - không throw exception
var proxy = await _smartPoolClient.TryGetRawProxyAsync(request);
if (proxy != null)
{
// Sử dụng proxy
Console.WriteLine($"Proxy: {proxy.host}:{proxy.port}");
}
else
{
// Xử lý khi không lấy được proxy (silent failure)
Console.WriteLine("Failed to get proxy");
}
// TryGetProxyAsync - không throw exception
var webProxy = await _smartPoolClient.TryGetProxyAsync(request);
if (webProxy != null)
{
var handler = new HttpClientHandler { Proxy = webProxy };
var httpClient = new HttpClient(handler);
// Use httpClient...
}
```
**Khi nào dùng Try methods:**
- Khi bạn muốn xử lý lỗi một cách silent (không cần biết chi tiết lỗi)
- Trong retry logic, khi bạn chỉ cần biết success/failure
- Khi performance quan trọng hơn error details
## Health Check
```csharp
var isHealthy = await _smartPoolClient.PingAsync();
if (!isHealthy)
{
Console.WriteLine("SmartPool API is not responding");
}
```
## Performance Optimizations
SDK đã được tối ưu với các tính năng:
- **Connection Pooling & Keep-Alive**: Giảm latency reconnect từ ~50-100ms xuống ~5ms
- **Client-side Caching**: Giảm network calls ~90% khi cache hit
- **Response Compression**: Giảm payload size ~30-50%
- **Batch Logging**: Giảm N network calls → 1 call
- **Fire-and-Forget**: Non-blocking logging, không block main flow
Xem chi tiết trong [SDK_DOCUMENTATION.md](./SDK_DOCUMENTATION.md#tối-ưu-hiệu-suất).
## Chi Tiết Các Modes và Cách Hoạt Động
### 1. Protocol Modes
#### gRPC Mode (Khuyến nghị)
**Cách hoạt động:**
- Sử dụng HTTP/2 với binary protocol (MessagePack)
- Connection pooling tự động với keep-alive
- Compression tự động (gzip/deflate)
- Streaming support cho batch operations
**Cấu hình:**
```json
{
"SmartPool": {
"Protocol": "Grpc",
"Host": "api.example.com",
"Port": 5001,
"UseSecureConnection": true,
"EnableCompression": true,
"CompressionAlgorithm": "gzip"
}
}
```
**Khi nào dùng:**
- ✅ High-performance scenarios (scraping, batch processing)
- ✅ Internal services (microservices communication)
- ✅ Khi cần throughput cao
- ✅ Khi có control over network (không bị firewall block HTTP/2)
**Ưu điểm:**
- Performance cao hơn HTTP ~30-50%
- Binary protocol → payload nhỏ hơn
- Connection pooling tự động
- Keep-alive giảm latency
**Nhược điểm:**
- Cần HTTP/2 support
- Khó debug hơn (binary format)
- Có thể bị firewall block
#### HTTP Mode
**Cách hoạt động:**
- Standard HTTP/1.1 REST API
- JSON serialization
- Standard HttpClient với connection pooling
- Dễ debug với browser DevTools
**Cấu hình:**
```json
{
"SmartPool": {
"Protocol": "Http",
"Host": "api.example.com",
"Port": 5000,
"UseSecureConnection": true
}
}
```
**Khi nào dùng:**
- ✅ External clients (web browsers, mobile apps)
- ✅ Khi cần debug dễ dàng
- ✅ Khi firewall chỉ cho phép HTTP
- ✅ Development/testing environments
**Ưu điểm:**
- Dễ debug (JSON, có thể test với Postman/curl)
- Universal support (mọi client đều hỗ trợ HTTP)
- Firewall-friendly
- Standard REST API
**Nhược điểm:**
- Performance thấp hơn gRPC
- Payload lớn hơn (JSON vs binary)
- Không có streaming support
### 2. Client-Side Caching Mode
**Cách hoạt động:**
- Cache proxy results trong memory (MemoryCache)
- Cache key dựa trên: access_token, strategy, filters (ip_version, protocol, country, target_domain)
- TTL: `ClientCacheDurationSeconds` (default: 30s)
- Sliding expiration: 50% của TTL
- Max entries: `ClientCacheMaxEntries` (default: 100)
**Flow:**
```
1. Request proxy với filters
2. Check cache → Cache hit? Return cached proxy
3. Cache miss? Call API → Cache result → Return proxy
4. Next request với same filters → Return từ cache (không call API)
```
**Cấu hình:**
```json
{
"SmartPool": {
"EnableClientCache": true,
"ClientCacheDurationSeconds": 30,
"ClientCacheMaxEntries": 100
}
}
```
**Khi nào dùng:**
- ✅ Khi request cùng filters nhiều lần
- ✅ Random/Round-robin strategies (không phụ thuộc vào real-time data)
- ✅ Giảm load cho API server
- ✅ Giảm latency cho client
**Khi KHÔNG nên dùng:**
- ❌ Least Delay strategy (cần real-time data)
- ❌ Adaptive Ranking strategy (cần real-time data)
- ❌ Khi cần proxy mới mỗi lần request
**Ví dụ:**
```csharp
// Request 1: Call API, cache result
var proxy1 = await _client.GetProxyAsync(new GetProxyRequest
{
strategy = "random",
ip_version = "v6"
});
// Request 2: Return từ cache (không call API)
var proxy2 = await _client.GetProxyAsync(new GetProxyRequest
{
strategy = "random",
ip_version = "v6"
});
// proxy1 và proxy2 giống nhau (cùng từ cache)
// Request 3: Khác filters → Call API mới
var proxy3 = await _client.GetProxyAsync(new GetProxyRequest
{
strategy = "random",
ip_version = "v4" // Khác filter
});
```
### 3. Logging Modes
#### Fire-and-Forget Mode
**Cách hoạt động:**
- Logging chạy trong background task (không block main thread)
- Nếu có batch logging → Queue vào channel
- Nếu không có batch → Fire task riêng
- Không đợi response từ server
**Cấu hình:**
```json
{
"SmartPool": {
"EnableFireAndForgetLogging": true
}
}
```
**Khi nào dùng:**
- ✅ High-throughput scenarios
- ✅ Khi logging không critical (best-effort)
- ✅ Khi không muốn block main flow
- ✅ Background processing
**Ví dụ:**
```csharp
// Non-blocking - không đợi response
await _client.LogProxyUsageAsync(new ProxyUsageLogRequest
{
proxy_id = 123,
status_code = 200,
response_time_ms = 450
});
// Code tiếp tục chạy ngay, không đợi log complete
```
#### Batch Logging Mode
**Cách hoạt động:**
- Queue log requests vào bounded channel
- Background task collect logs theo batch
- Flush khi đạt `LogBatchSize` hoặc `LogBatchFlushIntervalMs`
- Gửi batch đến server
**Flow:**
```
1. LogProxyUsageAsync() → Queue vào channel
2. Background task collect logs
3. Khi đủ LogBatchSize (50) hoặc timeout (5s) → Flush batch
4. Gửi batch đến server
```
**Cấu hình:**
```json
{
"SmartPool": {
"EnableBatchLogging": true,
"LogBatchSize": 50,
"LogBatchFlushIntervalMs": 5000
}
}
```
**Khi nào dùng:**
- ✅ High-throughput scenarios (1000+ requests/second)
- ✅ Khi muốn giảm network calls
- ✅ Khi có nhiều logs cần gửi
**Ví dụ:**
```csharp
// Queue 1000 logs
for (int i = 0; i < 1000; i++)
{
_client.QueueLogProxyUsage(new ProxyUsageLogRequest
{
proxy_id = i,
status_code = 200,
response_time_ms = 450
});
}
// Chỉ gửi ~20 batches (50 logs/batch) thay vì 1000 requests
```
**Kết hợp Fire-and-Forget + Batch:**
```json
{
"SmartPool": {
"EnableFireAndForgetLogging": true,
"EnableBatchLogging": true,
"LogBatchSize": 50,
"LogBatchFlushIntervalMs": 5000
}
}
```
→ Logging hoàn toàn non-blocking và batch processing
#### Synchronous Logging Mode
**Cách hoạt động:**
- Đợi response từ server
- Block cho đến khi log complete
- Throw exception nếu lỗi
**Cấu hình:**
```json
{
"SmartPool": {
"EnableFireAndForgetLogging": false,
"EnableBatchLogging": false
}
}
```
**Khi nào dùng:**
- ✅ Khi logging là critical (cần đảm bảo log được gửi)
- ✅ Low-throughput scenarios
- ✅ Debug/testing
**Ví dụ:**
```csharp
// Blocking - đợi response
var success = await _client.LogProxyUsageAsync(new ProxyUsageLogRequest
{
proxy_id = 123,
status_code = 200
});
if (!success)
{
// Handle failure
}
```
### 4. Connection Pooling & Keep-Alive Mode
**Cách hoạt động:**
**gRPC:**
- HTTP/2 connection pooling tự động
- Keep-alive ping mỗi `KeepAlivePingDelaySeconds` (60s)
- Ping timeout: `KeepAlivePingTimeoutSeconds` (30s)
- Connection idle timeout: `PooledConnectionIdleTimeoutMinutes` (5min)
- Connection lifetime: `PooledConnectionLifetimeMinutes` (10min)
**HTTP:**
- HttpClient connection pooling
- Connection idle timeout: `PooledConnectionIdleTimeoutMinutes` (5min)
- Connection lifetime: `PooledConnectionLifetimeMinutes` (10min)
**Cấu hình:**
```json
{
"SmartPool": {
"KeepAlivePingDelaySeconds": 60,
"KeepAlivePingTimeoutSeconds": 30,
"PooledConnectionIdleTimeoutMinutes": 5,
"PooledConnectionLifetimeMinutes": 10,
"EnableMultipleHttp2Connections": true,
"ConnectTimeoutSeconds": 5
}
}
```
**Lợi ích:**
- Giảm latency: Reuse connection thay vì tạo mới (~50-100ms → ~5ms)
- Giảm overhead: Không cần handshake mỗi request
- Better throughput: Multiple connections cho parallel requests
**Ví dụ:**
```csharp
// Request 1: Tạo connection mới (~50ms)
var proxy1 = await _client.GetProxyAsync();
// Request 2-100: Reuse connection (~5ms mỗi request)
for (int i = 0; i < 100; i++)
{
var proxy = await _client.GetProxyAsync();
}
// Total time: ~50ms + (99 * 5ms) = ~545ms
// Without pooling: ~100 * 50ms = ~5000ms
```
### 5. Compression Mode
**Cách hoạt động:**
- gRPC: Compression tự động với gzip/deflate
- HTTP: Accept-Encoding header
- Server compress response nếu client support
**Cấu hình:**
```json
{
"SmartPool": {
"EnableCompression": true,
"CompressionAlgorithm": "gzip"
}
}
```
**Lợi ích:**
- Giảm payload size ~30-50%
- Giảm bandwidth usage
- Faster transfer trên slow networks
**Khi nào dùng:**
- ✅ Khi bandwidth là bottleneck
- ✅ Mobile networks
- ✅ High-latency networks
- ✅ Khi response size lớn
**Trade-off:**
- CPU overhead cho compression/decompression
- Thường không đáng kể với modern CPUs
## Best Practices
### 1. Protocol Selection
```csharp
// High-performance internal service → gRPC
services.AddSmartPoolClient(options =>
{
options.Protocol = SmartPoolProtocol.Grpc;
});
// External client → HTTP
services.AddSmartPoolClient(options =>
{
options.Protocol = SmartPoolProtocol.Http;
});
```
### 2. Caching Strategy
```csharp
// Random/Round-robin → Enable cache
services.AddSmartPoolClient(options =>
{
options.EnableClientCache = true;
options.ClientCacheDurationSeconds = 30;
});
// Least Delay/Adaptive Ranking → Disable cache
services.AddSmartPoolClient(options =>
{
options.EnableClientCache = false; // Cần real-time data
});
```
### 3. Logging Strategy
```csharp
// High-throughput → Fire-and-forget + Batch
services.AddSmartPoolClient(options =>
{
options.EnableFireAndForgetLogging = true;
options.EnableBatchLogging = true;
options.LogBatchSize = 50;
});
// Critical logging → Synchronous
services.AddSmartPoolClient(options =>
{
options.EnableFireAndForgetLogging = false;
options.EnableBatchLogging = false;
});
```
### 4. Error Handling Pattern
```csharp
// Detailed error handling
try
{
var proxy = await _client.GetRawProxyAsync(request);
}
catch (NoAvailableProxiesException)
{
// Retry với different token hoặc wait
}
catch (NoMatchingProxiesException)
{
// Relax filters hoặc use different strategy
}
catch (SmartPoolException ex)
{
_logger.LogError(ex, "SmartPool error: {ErrorCode}", ex.ErrorCode);
}
// Silent failure
var proxy = await _client.TryGetRawProxyAsync(request);
if (proxy == null)
{
// Fallback logic
}
```
### 5. Retry Pattern với Alternative Strategy
```csharp
SmartProxyServer? currentProxy = null;
for (int retry = 0; retry < 3; retry++)
{
try
{
var request = retry == 0
? new GetProxyRequest { strategy = "least_delay", target_domain = "facebook.com" }
: new GetProxyRequest
{
strategy = "alternative",
referer_proxy = currentProxy
};
currentProxy = await _client.GetRawProxyAsync(request);
// Use proxy...
break; // Success
}
catch (NoMatchingProxiesException)
{
if (retry == 2) throw; // Last retry failed
// Continue to next retry
}
}
```
## Dependencies
- .NET 10.0
- MagicOnion.Client 6.1.7
- Microsoft.Extensions.* 10.0.2
## Documentation
- 📖 **[SDK Documentation](./SDK_DOCUMENTATION.md)** - Tài liệu chi tiết đầy đủ
- 📖 **[System README](../../SMARTPOOL_README.md)** - Tổng quan hệ thống
## License
Internal use only.