15 KiB
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):
<PackageReference Include="Icomm.ResourcePool.Abstractions" Version="x.x.x" />
Sau (SmartPool):
<PackageReference Include="Icomm.SmartPool.Proxy" Version="10.0.1" />
Step 2: Cập Nhật Configuration
Trước (ProxyPool):
{
"TokenPoolOptions": {
"Host": "10.9.3.70",
"Port": 31287,
"protocol": "Grpc"
}
}
Sau (SmartPool):
{
"SmartPool": {
"Protocol": "Grpc",
"Host": "10.9.3.70",
"Port": 5001,
"DefaultAccessToken": "your-access-token",
"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
DefaultAccessTokennếu muốn tự động inject vào requests
Step 3: Cập Nhật Service Registration
Trước (ProxyPool - gRPC):
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):
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;
options.DefaultAccessToken = "your-access-token";
});
Step 4: Cập Nhật Code Sử Dụng
📝 Code Migration Examples
Example 1: Basic Proxy Request
ProxyPool (gRPC)
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
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ềIWebProxysẵn sàng sử dụng - ✅ Field names:
access_tokenthay vìAccessToken
Example 2: Proxy Request với Filters
ProxyPool (HTTP REST API)
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
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,protocolthay vìType - ✅ Strategy names:
least_delaythay vìleast_delay(giống nhau) - ✅
GetProxyAsync()trả vềIWebProxysẵn sàng
Example 3: Get Raw Proxy Information
ProxyPool
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
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
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
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:
ProxyUsageLogRequestthay vìProxyLogRequest - ✅ Field names:
proxy_id,status_code,response_time_ms(snake_case) - ✅ Có thêm
target_domainfield (required) - ✅ Hỗ trợ fire-and-forget và batch logging
Example 5: Alternative Strategy (Find Similar Proxy)
ProxyPool
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
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:
alternativethay vìleast_used - ✅ Field:
referer_proxy.idthay 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.jsonvới SmartPool configuration - Thay thế service registration từ manual gRPC/HTTP setup sang
AddSmartPoolClient() - Cập nhật dependency injection: inject
ISmartPoolClientthay 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
Typefield →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_rankingstrategy (mới) - ✅
alternativestrategy với referer proxy - ✅ Client-side caching tự động
- ✅ Batch logging tự động
📚 Additional Resources
💡 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
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
// 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
{
"SmartPool": {
"EnableClientCache": true,
"ClientCacheDurationSeconds": 30
}
}
5. Use Batch Logging for High Throughput
{
"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:
- Kiểm tra SmartPool Documentation
- Kiểm tra Troubleshooting Guide
- Liên hệ team phát triển
Last Updated: 2026-01-23