Files
ResourcePool.Docs/MIGRATION_GUIDE_PROXYPOOL_TO_SMARTPOOL.md
T

579 lines
15 KiB
Markdown

# Migration Guide: ProxyPool → SmartPool
Hướng dẫn chi tiết để migrate code client từ ProxyPool (legacy) sang SmartPool (new system).
---
## 📋 Tổng Quan
### ProxyPool (Legacy System)
- ❌ Không có SDK client, phải tự implement gRPC/HTTP client
- ❌ Field names: PascalCase (`AccessToken`, `Host`, `Port`)
- ❌ Strategies: `random`, `round_robin`, `least_used`, `least_delay`, `least_response_time`
- ❌ Không có client-side caching, batch logging, connection pooling tự động
- ✅ Đơn giản, phù hợp cho use cases cơ bản
### SmartPool (New System)
- ✅ SDK client với nhiều tính năng tối ưu
- ✅ Field names: snake_case (`access_token`, `host`, `port`)
- ✅ Strategies: `round_robin` (default), `random`, `least_delay`, `adaptive_ranking`, `alternative`
- ✅ Client-side caching, batch logging, connection pooling tự động
- ✅ Exception handling chi tiết với typed exceptions
- ✅ Performance cao hơn ~30-50%
---
## 🔄 Migration Steps
### Step 1: Cài Đặt NuGet Package
**Trước (ProxyPool):**
```xml
<PackageReference Include="Icomm.ResourcePool.Abstractions" Version="x.x.x" />
```
**Sau (SmartPool):**
```xml
<PackageReference Include="Icomm.SmartPool.Proxy" Version="10.0.1" />
```
### Step 2: Cập Nhật Configuration
**Trước (ProxyPool):**
```json
{
"TokenPoolOptions": {
"Host": "10.9.3.70",
"Port": 31287,
"protocol": "Grpc"
}
}
```
**Sau (SmartPool):**
```json
{
"SmartPool": {
"Protocol": "Grpc",
"Host": "10.9.3.70",
"Port": 5001,
"UseSecureConnection": false,
"TimeoutMs": 30000,
"EnableClientCache": true,
"ClientCacheDurationSeconds": 30,
"EnableBatchLogging": true,
"LogBatchSize": 50,
"EnableFireAndForgetLogging": true
}
}
```
**Lưu ý:**
- SmartPool sử dụng port khác (5001 cho gRPC, 5000 cho HTTP)
- Cần cấu hình `ConfigManager:AccessToken` nếu muốn tự động inject vào requests
### Step 3: Cập Nhật Service Registration
**Trước (ProxyPool - gRPC):**
```csharp
using Icomm.ResourcePool.Abstractions;
using MagicOnion.Client;
using Grpc.Net.Client;
// Manual gRPC client setup
var channel = GrpcChannel.ForAddress("http://10.9.3.70:31287");
var client = MagicOnionClient.Create<IProxyService>(channel);
```
**Sau (SmartPool):**
```csharp
using Icomm.SmartPool.Proxy.Extensions;
// In Startup.cs or Program.cs
services.AddSmartPoolClient(configuration);
// Or with explicit options
services.AddSmartPoolClient(configuration, options =>
{
options.Protocol = SmartPoolProtocol.Grpc;
options.Host = "10.9.3.70";
options.Port = 5001;
});
```
### Step 4: Cập Nhật Code Sử Dụng
---
## 📝 Code Migration Examples
### Example 1: Basic Proxy Request
#### ProxyPool (gRPC)
```csharp
using Icomm.ResourcePool.Abstractions;
using Icomm.ResourcePool.Abstractions.Requests;
using Icomm.ResourcePool.Abstractions.Responses;
using MagicOnion.Client;
using Grpc.Net.Client;
var channel = GrpcChannel.ForAddress("http://10.9.3.70:31287");
var client = MagicOnionClient.Create<IProxyService>(channel);
var request = new ProxyRequest
{
AccessToken = "your-access-token"
};
var response = await client.GetProxy(request);
var proxy = response.Proxy;
// Use proxy
var handler = new HttpClientHandler
{
Proxy = new WebProxy($"{proxy.Host}:{proxy.Port}")
{
Credentials = new NetworkCredential(proxy.AuthUsername, proxy.AuthPassword)
}
};
var httpClient = new HttpClient(handler);
```
#### SmartPool
```csharp
using Icomm.SmartPool.Proxy;
using Icomm.SmartPool.Abstractions.Requests;
using System.Net;
public class MyService
{
private readonly ISmartPoolClient _smartPoolClient;
public MyService(ISmartPoolClient smartPoolClient)
{
_smartPoolClient = smartPoolClient;
}
public async Task MakeRequestAsync()
{
// Get proxy as IWebProxy (ready to use)
var request = new GetProxyRequest
{
access_token = "your-access-token"
};
var proxy = await _smartPoolClient.GetProxyAsync(request);
if (proxy != null)
{
var handler = new HttpClientHandler { Proxy = proxy };
var httpClient = new HttpClient(handler);
// Use httpClient...
}
}
}
```
**Key Changes:**
- ✅ Không cần tự setup gRPC channel
- ✅ Method `GetProxyAsync()` trả về `IWebProxy` sẵn sàng sử dụng
- ✅ Field names: `access_token` thay vì `AccessToken`
---
### Example 2: Proxy Request với Filters
#### ProxyPool (HTTP REST API)
```csharp
using RestSharp;
using Icomm.ResourcePool.Abstractions.Requests;
using Icomm.ResourcePool.Abstractions.Responses;
var client = new RestClient("http://10.9.3.70:31249");
var request = new RestRequest("/api/resource-pool/v1/ProxyPool/get-v2", Method.Post);
request.AddJsonBody(new ProxyRequestByFeature
{
AccessToken = "your-access-token",
Type = "httpv6",
Strategy = "least_delay",
TargetDomain = "facebook.com",
Country = "VN"
});
var response = await client.ExecuteAsync<ProxyResponse>(request);
var proxy = response.Data.Proxy;
var proxyObj = new WebProxy($"{proxy.Host}:{proxy.Port}")
{
Credentials = new NetworkCredential(proxy.AuthUsername, proxy.AuthPassword)
};
```
#### SmartPool
```csharp
using Icomm.SmartPool.Proxy;
using Icomm.SmartPool.Abstractions.Requests;
var request = new GetProxyRequest
{
access_token = "your-access-token",
strategy = "least_delay",
target_domain = "facebook.com",
ip_version = "v6",
protocol = "http",
country = "VN"
};
var proxy = await _smartPoolClient.GetProxyAsync(request);
if (proxy != null)
{
var handler = new HttpClientHandler { Proxy = proxy };
var httpClient = new HttpClient(handler);
// Use httpClient...
}
```
**Key Changes:**
- ✅ Không cần HTTP client setup
- ✅ Field names: `ip_version`, `protocol` thay vì `Type`
- ✅ Strategy names: `least_delay` thay vì `least_delay` (giống nhau)
-`GetProxyAsync()` trả về `IWebProxy` sẵn sàng
---
### Example 3: Get Raw Proxy Information
#### ProxyPool
```csharp
var response = await client.GetProxyV2(new ProxyRequestByFeature
{
AccessToken = "your-access-token",
Type = "httpv6",
Strategy = "random",
Country = "US"
});
var proxy = response.Proxy;
Console.WriteLine($"Proxy: {proxy.Host}:{proxy.Port}");
Console.WriteLine($"Country: {proxy.Country}");
Console.WriteLine($"Auth: {proxy.AuthUsername}:{proxy.AuthPassword}");
```
#### SmartPool
```csharp
var request = new GetProxyRequest
{
access_token = "your-access-token",
strategy = "random",
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}");
Console.WriteLine($"Auth: {proxyServer.auth_username}:{proxyServer.auth_password}");
}
```
**Key Changes:**
- ✅ Method: `GetRawProxyAsync()` thay vì `GetProxyV2()`
- ✅ Field names: `host`, `port`, `country`, `auth_username`, `auth_password` (snake_case)
---
### Example 4: Log Proxy Usage
#### ProxyPool
```csharp
var logRequest = new ProxyLogRequest
{
AccessToken = "your-access-token",
ProxyId = proxy.Id,
StatusCode = 200,
ResponseTimeMs = 450
};
var logClient = new RestClient("http://10.9.3.70:31249");
var logRestRequest = new RestRequest("/api/resource-pool/v1/ProxyPool/used", Method.Post);
logRestRequest.AddJsonBody(logRequest);
await logClient.ExecuteAsync(logRestRequest);
```
#### SmartPool
```csharp
var logRequest = new ProxyUsageLogRequest
{
access_token = "your-access-token",
proxy_id = proxyServer.id,
target_domain = "facebook.com",
status_code = 200,
response_time_ms = 450
};
// Synchronous logging
await _smartPoolClient.LogProxyUsageAsync(logRequest);
// Or fire-and-forget (non-blocking)
_client.QueueLogProxyUsage(logRequest);
```
**Key Changes:**
- ✅ Request type: `ProxyUsageLogRequest` thay vì `ProxyLogRequest`
- ✅ Field names: `proxy_id`, `status_code`, `response_time_ms` (snake_case)
- ✅ Có thêm `target_domain` field (required)
- ✅ Hỗ trợ fire-and-forget và batch logging
---
### Example 5: Alternative Strategy (Find Similar Proxy)
#### ProxyPool
```csharp
var request = new ProxyRequestByFeature
{
AccessToken = "your-access-token",
Strategy = "least_used",
RefererProxy = new ProxyServer { Id = 123 },
Type = "httpv6",
Country = "VN"
};
var response = await client.GetProxyV2(request);
var alternativeProxy = response.Proxy;
```
#### SmartPool
```csharp
var request = new GetProxyRequest
{
access_token = "your-access-token",
strategy = "alternative",
referer_proxy = new SmartProxyServer { id = 123 },
ip_version = "v6",
protocol = "http",
country = "VN"
};
var alternativeProxy = await _smartPoolClient.GetRawProxyAsync(request);
```
**Key Changes:**
- ✅ Strategy: `alternative` thay vì `least_used`
- ✅ Field: `referer_proxy.id` thay vì `RefererProxy.Id`
---
## 🔀 Field Name Mapping
| ProxyPool (PascalCase) | SmartPool (snake_case) |
|------------------------|------------------------|
| `AccessToken` | `access_token` |
| `Host` | `host` |
| `Port` | `port` |
| `AuthUsername` | `auth_username` |
| `AuthPassword` | `auth_password` |
| `Type` | `protocol` (và `ip_version`) |
| `Country` | `country` |
| `TargetDomain` | `target_domain` |
| `Strategy` | `strategy` |
| `RefererProxy` | `referer_proxy` |
| `ProxyId` | `proxy_id` |
| `StatusCode` | `status_code` |
| `ResponseTimeMs` | `response_time_ms` |
---
## 🎯 Strategy Mapping
| ProxyPool Strategy | SmartPool Strategy | Notes |
|-------------------|-------------------|-------|
| `random` | `random` | Giống nhau |
| `round_robin` | `round_robin` | Giống nhau (default trong SmartPool) |
| `least_delay` | `least_delay` | Giống nhau |
| `least_used` | `alternative` | SmartPool dùng `alternative` với `referer_proxy` |
| `least_response_time` | `least_delay` | Tương đương |
| N/A | `adaptive_ranking` | Mới trong SmartPool |
---
## 🚨 Breaking Changes
### 1. Port Numbers
- **ProxyPool**: 31287 (gRPC), 31249 (HTTP)
- **SmartPool**: 5001 (gRPC), 5000 (HTTP)
### 2. API Endpoints
- **ProxyPool**: `/api/resource-pool/v1/ProxyPool/*`
- **SmartPool**: `/api/smart-pool/v1/SmartProxy/*`
### 3. Request/Response Types
- **ProxyPool**: `ProxyRequest`, `ProxyRequestByFeature`, `ProxyResponse`, `ProxyServer`
- **SmartPool**: `GetProxyRequest`, `SmartProxyResponse`, `SmartProxyServer`
### 4. Field Naming Convention
- **ProxyPool**: PascalCase
- **SmartPool**: snake_case
### 5. Protocol Field
- **ProxyPool**: `Type` = `"http"`, `"httpv6"`, `"socks"`
- **SmartPool**: `protocol` = `"http"`, `"socks5"` + `ip_version` = `"v4"`, `"v6"`
---
## ✅ Migration Checklist
- [ ] Cài đặt NuGet package `Icomm.SmartPool.Proxy`
- [ ] Cập nhật `appsettings.json` với SmartPool configuration
- [ ] Thay thế service registration từ manual gRPC/HTTP setup sang `AddSmartPoolClient()`
- [ ] Cập nhật dependency injection: inject `ISmartPoolClient` thay vì tự tạo client
- [ ] Thay thế tất cả `ProxyRequest``GetProxyRequest`
- [ ] Thay thế tất cả `ProxyRequestByFeature``GetProxyRequest`
- [ ] Cập nhật field names từ PascalCase sang snake_case
- [ ] Cập nhật strategy names (nếu có `least_used``alternative`)
- [ ] Cập nhật `Type` field → `protocol` + `ip_version`
- [ ] Thay thế `GetProxy()` / `GetProxyV2()``GetProxyAsync()` / `GetRawProxyAsync()`
- [ ] Cập nhật proxy usage logging: `ProxyLogRequest``ProxyUsageLogRequest`
- [ ] Cập nhật port numbers trong configuration
- [ ] Test tất cả proxy requests
- [ ] Test error handling với SmartPool exceptions
- [ ] Cập nhật unit tests
---
## 🎁 Benefits After Migration
### 1. Performance Improvements
- **Connection Pooling**: Giảm latency reconnect từ ~50-100ms xuống ~5ms
- **Client-side Caching**: Giảm network calls ~90% khi cache hit
- **Batch Logging**: Giảm N network calls → 1 call
- **Response Compression**: Giảm payload size ~30-50%
### 2. Better Developer Experience
- ✅ Typed exceptions với error codes
- ✅ Try methods (`TryGetProxyAsync()`) không throw exceptions
- ✅ Fire-and-forget logging (non-blocking)
- ✅ Health check method (`PingAsync()`)
### 3. Advanced Features
-`adaptive_ranking` strategy (mới)
-`alternative` strategy với referer proxy
- ✅ Client-side caching tự động
- ✅ Batch logging tự động
---
## 📚 Additional Resources
- [SmartPool SDK Documentation](./docs/src/Icomm.SmartPool.Proxy/README.md)
- [SmartPool API Documentation](./docs/src/Icomm.API.SmartPool/README.md)
- [SmartPool Quick Reference](./docs/src/Icomm.SmartPool.Proxy/QUICK_REFERENCE.md)
---
## 💡 Tips & Best Practices
### 1. Gradual Migration
- Có thể migrate từng phần, không cần migrate toàn bộ cùng lúc
- Có thể chạy song song ProxyPool và SmartPool trong giai đoạn transition
### 2. Error Handling
```csharp
using Icomm.SmartPool.Proxy.Exceptions;
try
{
var proxy = await _smartPoolClient.GetRawProxyAsync(request);
}
catch (AccessTokenRequiredException)
{
// Handle missing access token
}
catch (NoAvailableProxiesException ex)
{
// Handle no proxies available
// Retry with different token or wait
}
catch (NoMatchingProxiesException)
{
// Handle no matching proxies
// Relax filters or use different strategy
}
catch (SmartPoolException ex)
{
// Handle other SmartPool errors
_logger.LogError(ex, "SmartPool error: {ErrorCode}", ex.ErrorCode);
}
```
### 3. Use Try Methods for Silent Failures
```csharp
// Instead of try-catch, use Try methods
var proxy = await _smartPoolClient.TryGetRawProxyAsync(request);
if (proxy == null)
{
// Fallback logic
return;
}
// Use proxy...
```
### 4. Enable Client Caching for Better Performance
```json
{
"SmartPool": {
"EnableClientCache": true,
"ClientCacheDurationSeconds": 30
}
}
```
### 5. Use Batch Logging for High Throughput
```json
{
"SmartPool": {
"EnableBatchLogging": true,
"LogBatchSize": 50,
"LogBatchFlushIntervalMs": 5000,
"EnableFireAndForgetLogging": true
}
}
```
---
## ❓ FAQ
### Q: Có thể dùng cả ProxyPool và SmartPool cùng lúc không?
**A:** Có, nhưng không khuyến nghị. Nên migrate hoàn toàn sang SmartPool.
### Q: SmartPool có backward compatible với ProxyPool không?
**A:** Không, SmartPool là hệ thống mới hoàn toàn với API và data model khác.
### Q: Làm sao migrate nếu đang dùng HTTP REST API?
**A:** Có thể tiếp tục dùng HTTP REST API với SmartPool, nhưng khuyến nghị dùng SDK client để có nhiều tính năng tối ưu.
### Q: Có cần thay đổi access token không?
**A:** Không, nhưng cần đảm bảo access token có mapping trong SmartPool system.
### Q: Performance có cải thiện bao nhiêu?
**A:** Tùy use case, thường cải thiện 30-50% nhờ connection pooling, caching, và batch logging.
---
## 📞 Support
Nếu gặp vấn đề trong quá trình migration, vui lòng:
1. Kiểm tra [SmartPool Documentation](./docs/src/Icomm.SmartPool.Proxy/README.md)
2. Kiểm tra [Troubleshooting Guide](./docs/src/Icomm.API.SmartPool/README.md#troubleshooting)
3. Liên hệ team phát triển
---
**Last Updated**: 2026-01-23