Some checks failed
Deploy / deploy (push) Has been cancelled
Full-stack web application for Telegram management - Frontend: Vue 3 + Vben Admin - Backend: NestJS - Features: User management, group broadcast, statistics 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1038 lines
31 KiB
Markdown
1038 lines
31 KiB
Markdown
# 代理IP管理模块 - 完整设计方案
|
||
|
||
## 📋 项目概述
|
||
|
||
基于现有Telegram账号管理系统,设计并实现一个完整的代理IP管理模块,支持多平台对接、智能检测、类型管理和用户体验优化。
|
||
|
||
## 🎯 设计目标
|
||
|
||
### 主要功能目标
|
||
1. **多平台统一管理** - 支持主流代理IP平台统一配置和管理
|
||
2. **智能检测验证** - 实时检测代理IP可用性、延迟、匿名性
|
||
3. **类型分类管理** - 住宅/数据中心/移动代理的分类管理
|
||
4. **自动化运维** - 故障自动切换、负载均衡、健康检查
|
||
5. **用户友好界面** - 直观的配置界面和监控面板
|
||
|
||
### 技术目标
|
||
- 高可用性:99.9%服务可用性
|
||
- 低延迟:代理检测<2秒响应
|
||
- 高并发:支持1000+并发代理连接
|
||
- 易维护:模块化设计,便于扩展
|
||
|
||
## 🏗️ 系统架构设计
|
||
|
||
### 整体架构
|
||
```
|
||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||
│ 前端管理界面 │────│ 后端API服务 │────│ 代理平台API │
|
||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||
│ 配置管理模块 │ │ 检测服务模块 │ │ 第三方平台 │
|
||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||
│ 数据存储层 │ │ 缓存服务层 │ │ 监控告警系统 │
|
||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||
```
|
||
|
||
### 核心模块设计
|
||
|
||
#### 1. 代理平台适配器 (ProxyAdapter)
|
||
```javascript
|
||
// 统一的代理平台接口
|
||
class BaseProxyAdapter {
|
||
async authenticate() {} // 认证
|
||
async getProxyList() {} // 获取代理列表
|
||
async checkProxy() {} // 检测代理
|
||
async getBalance() {} // 获取余额
|
||
async getStatistics() {} // 获取统计
|
||
}
|
||
|
||
// Rola-IP平台适配器
|
||
class RolaIPAdapter extends BaseProxyAdapter {
|
||
constructor(config) {
|
||
this.apiUrl = 'https://admin.rola-ip.co/api'
|
||
this.username = config.username
|
||
this.password = config.password
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 2. 代理检测引擎 (ProxyDetector)
|
||
```javascript
|
||
class ProxyDetector {
|
||
async batchCheck(proxies) {
|
||
// 批量检测代理可用性
|
||
// 检测项目:连通性、延迟、匿名性、地理位置
|
||
}
|
||
|
||
async realTimeMonitor(proxy) {
|
||
// 实时监控代理状态
|
||
}
|
||
|
||
async performanceTest(proxy) {
|
||
// 性能测试:速度、稳定性
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 3. 智能路由器 (ProxyRouter)
|
||
```javascript
|
||
class ProxyRouter {
|
||
async selectBestProxy(criteria) {
|
||
// 根据条件选择最佳代理
|
||
// 考虑因素:延迟、成功率、负载、地理位置
|
||
}
|
||
|
||
async loadBalance(proxies) {
|
||
// 负载均衡算法
|
||
}
|
||
|
||
async failover(failedProxy) {
|
||
// 故障切换
|
||
}
|
||
}
|
||
```
|
||
|
||
## 📊 数据库设计
|
||
|
||
### 1. 代理平台表 (proxy_platforms) - 已存在,需扩展
|
||
```sql
|
||
ALTER TABLE proxy_platforms ADD COLUMN status VARCHAR(20) DEFAULT 'active';
|
||
ALTER TABLE proxy_platforms ADD COLUMN last_check_time TIMESTAMP;
|
||
ALTER TABLE proxy_platforms ADD COLUMN success_rate DECIMAL(5,2) DEFAULT 0.00;
|
||
ALTER TABLE proxy_platforms ADD COLUMN avg_response_time INT DEFAULT 0;
|
||
ALTER TABLE proxy_platforms ADD COLUMN daily_quota INT DEFAULT 0;
|
||
ALTER TABLE proxy_platforms ADD COLUMN used_quota INT DEFAULT 0;
|
||
ALTER TABLE proxy_platforms ADD COLUMN cost_per_request DECIMAL(10,4) DEFAULT 0.0000;
|
||
```
|
||
|
||
### 2. 代理IP池表 (proxy_pools) - 新建
|
||
```sql
|
||
CREATE TABLE proxy_pools (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
platform_id INT NOT NULL,
|
||
proxy_type ENUM('residential', 'datacenter', 'mobile', 'static_residential') NOT NULL,
|
||
ip_address VARCHAR(45) NOT NULL,
|
||
port INT NOT NULL,
|
||
country_code VARCHAR(3),
|
||
city VARCHAR(100),
|
||
username VARCHAR(255),
|
||
password VARCHAR(255),
|
||
protocol ENUM('http', 'https', 'socks5') NOT NULL,
|
||
status ENUM('active', 'inactive', 'testing', 'failed') DEFAULT 'active',
|
||
last_used_time TIMESTAMP,
|
||
success_count INT DEFAULT 0,
|
||
fail_count INT DEFAULT 0,
|
||
avg_response_time INT DEFAULT 0,
|
||
anonymity_level ENUM('transparent', 'anonymous', 'elite') DEFAULT 'anonymous',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
|
||
FOREIGN KEY (platform_id) REFERENCES proxy_platforms(id),
|
||
INDEX idx_platform_type (platform_id, proxy_type),
|
||
INDEX idx_status_country (status, country_code),
|
||
INDEX idx_response_time (avg_response_time)
|
||
);
|
||
```
|
||
|
||
### 3. 代理检测日志表 (proxy_check_logs) - 新建
|
||
```sql
|
||
CREATE TABLE proxy_check_logs (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
proxy_id INT NOT NULL,
|
||
check_type ENUM('connectivity', 'performance', 'anonymity', 'geolocation') NOT NULL,
|
||
status ENUM('success', 'failed', 'timeout') NOT NULL,
|
||
response_time INT,
|
||
error_message TEXT,
|
||
check_details JSON,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
FOREIGN KEY (proxy_id) REFERENCES proxy_pools(id),
|
||
INDEX idx_proxy_time (proxy_id, created_at),
|
||
INDEX idx_status_type (status, check_type)
|
||
);
|
||
```
|
||
|
||
### 4. 代理使用统计表 (proxy_usage_stats) - 新建
|
||
```sql
|
||
CREATE TABLE proxy_usage_stats (
|
||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||
proxy_id INT NOT NULL,
|
||
account_id INT,
|
||
usage_type ENUM('telegram_auth', 'data_collection', 'general') NOT NULL,
|
||
success_count INT DEFAULT 0,
|
||
fail_count INT DEFAULT 0,
|
||
total_bytes_transferred BIGINT DEFAULT 0,
|
||
avg_response_time INT DEFAULT 0,
|
||
date DATE NOT NULL,
|
||
hour TINYINT NOT NULL,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
FOREIGN KEY (proxy_id) REFERENCES proxy_pools(id),
|
||
INDEX idx_proxy_date (proxy_id, date),
|
||
INDEX idx_account_date (account_id, date),
|
||
UNIQUE KEY uk_proxy_date_hour (proxy_id, date, hour)
|
||
);
|
||
```
|
||
|
||
## 🔧 核心功能实现
|
||
|
||
### 1. Rola-IP平台对接
|
||
|
||
#### 后端适配器实现
|
||
```javascript
|
||
// /backend/src/adapters/RolaIPAdapter.js
|
||
class RolaIPAdapter extends BaseProxyAdapter {
|
||
constructor(config) {
|
||
super()
|
||
this.baseUrl = 'https://admin.rola-ip.co'
|
||
this.username = config.username
|
||
this.password = config.password
|
||
this.session = null
|
||
}
|
||
|
||
async authenticate() {
|
||
const response = await axios.post(`${this.baseUrl}/api/login`, {
|
||
username: this.username,
|
||
password: this.password
|
||
})
|
||
|
||
if (response.data.success) {
|
||
this.session = response.data.session
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
async getProxyList(type = 'residential') {
|
||
const response = await axios.get(`${this.baseUrl}/api/proxies`, {
|
||
headers: { Authorization: `Bearer ${this.session}` },
|
||
params: { type, limit: 1000 }
|
||
})
|
||
|
||
return response.data.proxies.map(proxy => ({
|
||
ip: proxy.ip,
|
||
port: proxy.port,
|
||
username: proxy.username,
|
||
password: proxy.password,
|
||
country: proxy.country,
|
||
type: proxy.type,
|
||
protocol: proxy.protocol
|
||
}))
|
||
}
|
||
|
||
async checkProxy(proxy) {
|
||
// 通过代理发送测试请求
|
||
const testUrl = 'http://httpbin.org/ip'
|
||
const proxyConfig = {
|
||
host: proxy.ip,
|
||
port: proxy.port,
|
||
username: proxy.username,
|
||
password: proxy.password
|
||
}
|
||
|
||
const startTime = Date.now()
|
||
try {
|
||
const response = await axios.get(testUrl, {
|
||
proxy: proxyConfig,
|
||
timeout: 10000
|
||
})
|
||
const responseTime = Date.now() - startTime
|
||
|
||
return {
|
||
success: true,
|
||
responseTime,
|
||
realIP: response.data.origin,
|
||
anonymity: this.detectAnonymity(response.data, proxy.ip)
|
||
}
|
||
} catch (error) {
|
||
return {
|
||
success: false,
|
||
error: error.message,
|
||
responseTime: Date.now() - startTime
|
||
}
|
||
}
|
||
}
|
||
|
||
detectAnonymity(responseData, proxyIP) {
|
||
const realIP = responseData.origin
|
||
if (realIP === proxyIP) return 'transparent'
|
||
if (responseData.headers && responseData.headers['X-Forwarded-For']) {
|
||
return 'anonymous'
|
||
}
|
||
return 'elite'
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 服务层实现
|
||
```javascript
|
||
// /backend/src/service/ProxyManagementService.js
|
||
class ProxyManagementService {
|
||
constructor() {
|
||
this.adapters = new Map()
|
||
this.detectionQueue = new Queue('proxy-detection')
|
||
this.monitoringInterval = null
|
||
}
|
||
|
||
registerAdapter(platform, adapter) {
|
||
this.adapters.set(platform, adapter)
|
||
}
|
||
|
||
async syncProxyPools() {
|
||
for (const [platform, adapter] of this.adapters) {
|
||
try {
|
||
await adapter.authenticate()
|
||
const proxies = await adapter.getProxyList()
|
||
await this.updateProxyPool(platform, proxies)
|
||
} catch (error) {
|
||
this.logger.error(`同步${platform}代理池失败:`, error)
|
||
}
|
||
}
|
||
}
|
||
|
||
async updateProxyPool(platform, proxies) {
|
||
const platformRecord = await MProxyPlatformService.getInstance()
|
||
.findByPlatform(platform)
|
||
|
||
for (const proxy of proxies) {
|
||
await MProxyPoolService.getInstance().upsert({
|
||
platform_id: platformRecord.id,
|
||
ip_address: proxy.ip,
|
||
port: proxy.port,
|
||
proxy_type: proxy.type,
|
||
country_code: proxy.country,
|
||
username: proxy.username,
|
||
password: proxy.password,
|
||
protocol: proxy.protocol,
|
||
status: 'active'
|
||
})
|
||
}
|
||
}
|
||
|
||
async batchCheckProxies(proxyIds) {
|
||
const proxies = await MProxyPoolService.getInstance()
|
||
.findByIds(proxyIds)
|
||
|
||
const checkPromises = proxies.map(proxy =>
|
||
this.checkSingleProxy(proxy)
|
||
)
|
||
|
||
const results = await Promise.allSettled(checkPromises)
|
||
return results.map((result, index) => ({
|
||
proxyId: proxies[index].id,
|
||
...result.value
|
||
}))
|
||
}
|
||
|
||
async checkSingleProxy(proxy) {
|
||
const platform = await MProxyPlatformService.getInstance()
|
||
.findById(proxy.platform_id)
|
||
const adapter = this.adapters.get(platform.platform)
|
||
|
||
if (!adapter) {
|
||
return { success: false, error: '未找到对应的平台适配器' }
|
||
}
|
||
|
||
const result = await adapter.checkProxy(proxy)
|
||
|
||
// 记录检测日志
|
||
await MProxyCheckLogService.getInstance().create({
|
||
proxy_id: proxy.id,
|
||
check_type: 'connectivity',
|
||
status: result.success ? 'success' : 'failed',
|
||
response_time: result.responseTime,
|
||
error_message: result.error,
|
||
check_details: JSON.stringify(result)
|
||
})
|
||
|
||
// 更新代理状态
|
||
await MProxyPoolService.getInstance().updateById(proxy.id, {
|
||
status: result.success ? 'active' : 'failed',
|
||
avg_response_time: result.responseTime,
|
||
success_count: result.success ? proxy.success_count + 1 : proxy.success_count,
|
||
fail_count: result.success ? proxy.fail_count : proxy.fail_count + 1,
|
||
last_used_time: new Date()
|
||
})
|
||
|
||
return result
|
||
}
|
||
|
||
startMonitoring() {
|
||
// 每5分钟检测一次活跃代理
|
||
this.monitoringInterval = setInterval(async () => {
|
||
const activeProxies = await MProxyPoolService.getInstance()
|
||
.findByParam({
|
||
where: { status: 'active' },
|
||
limit: 50,
|
||
order: [['last_used_time', 'ASC']]
|
||
})
|
||
|
||
if (activeProxies.length > 0) {
|
||
await this.batchCheckProxies(activeProxies.map(p => p.id))
|
||
}
|
||
}, 5 * 60 * 1000)
|
||
}
|
||
|
||
stopMonitoring() {
|
||
if (this.monitoringInterval) {
|
||
clearInterval(this.monitoringInterval)
|
||
this.monitoringInterval = null
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. 智能代理选择算法
|
||
|
||
```javascript
|
||
// /backend/src/service/ProxySelectionService.js
|
||
class ProxySelectionService {
|
||
async selectOptimalProxy(criteria = {}) {
|
||
const {
|
||
country = null,
|
||
proxyType = null,
|
||
maxResponseTime = 2000,
|
||
minSuccessRate = 0.8,
|
||
excludeIds = []
|
||
} = criteria
|
||
|
||
// 构建查询条件
|
||
const whereClause = {
|
||
status: 'active',
|
||
avg_response_time: { [Op.lte]: maxResponseTime }
|
||
}
|
||
|
||
if (country) whereClause.country_code = country
|
||
if (proxyType) whereClause.proxy_type = proxyType
|
||
if (excludeIds.length > 0) whereClause.id = { [Op.notIn]: excludeIds }
|
||
|
||
// 计算成功率并排序
|
||
const proxies = await MProxyPoolService.getInstance().findByParam({
|
||
where: whereClause,
|
||
order: [
|
||
[Sequelize.literal('(success_count / (success_count + fail_count))'), 'DESC'],
|
||
['avg_response_time', 'ASC'],
|
||
['last_used_time', 'ASC']
|
||
],
|
||
limit: 10
|
||
})
|
||
|
||
// 过滤成功率
|
||
const qualifiedProxies = proxies.filter(proxy => {
|
||
const totalRequests = proxy.success_count + proxy.fail_count
|
||
if (totalRequests === 0) return true // 新代理给一次机会
|
||
return (proxy.success_count / totalRequests) >= minSuccessRate
|
||
})
|
||
|
||
if (qualifiedProxies.length === 0) {
|
||
throw new Error('未找到符合条件的代理')
|
||
}
|
||
|
||
// 负载均衡:选择最少使用的代理
|
||
return qualifiedProxies.reduce((prev, current) =>
|
||
(prev.last_used_time || 0) < (current.last_used_time || 0) ? prev : current
|
||
)
|
||
}
|
||
|
||
async getProxyPoolStats() {
|
||
const stats = await MProxyPoolService.getInstance().getModel().findAll({
|
||
attributes: [
|
||
'proxy_type',
|
||
'country_code',
|
||
'status',
|
||
[Sequelize.fn('COUNT', Sequelize.col('id')), 'count'],
|
||
[Sequelize.fn('AVG', Sequelize.col('avg_response_time')), 'avg_response_time'],
|
||
[Sequelize.literal('AVG(success_count / (success_count + fail_count + 1))'), 'avg_success_rate']
|
||
],
|
||
group: ['proxy_type', 'country_code', 'status'],
|
||
raw: true
|
||
})
|
||
|
||
return stats
|
||
}
|
||
}
|
||
```
|
||
|
||
## 📱 前端界面设计
|
||
|
||
### 1. 代理平台管理界面增强
|
||
|
||
在现有的 `proxyPlatformConfig.vue` 基础上增加功能:
|
||
|
||
```vue
|
||
<!-- 新增功能组件 -->
|
||
<template>
|
||
<div class="proxy-management">
|
||
<!-- 现有配置表格 -->
|
||
<div class="platform-config">
|
||
<!-- 现有代码保留 -->
|
||
</div>
|
||
|
||
<!-- 新增:实时监控面板 -->
|
||
<div class="monitoring-panel" style="margin-top: 20px;">
|
||
<Card>
|
||
<template #title>
|
||
<Icon type="ios-pulse" />
|
||
实时监控面板
|
||
</template>
|
||
<Row :gutter="16">
|
||
<Col :span="6">
|
||
<Statistic title="活跃代理" :value="stats.activeProxies" />
|
||
</Col>
|
||
<Col :span="6">
|
||
<Statistic title="平均延迟" :value="stats.avgResponseTime" suffix="ms" />
|
||
</Col>
|
||
<Col :span="6">
|
||
<Statistic title="成功率" :value="stats.successRate" suffix="%" :precision="1" />
|
||
</Col>
|
||
<Col :span="6">
|
||
<Statistic title="今日使用" :value="stats.todayUsage" />
|
||
</Col>
|
||
</Row>
|
||
</Card>
|
||
</div>
|
||
|
||
<!-- 新增:批量检测功能 -->
|
||
<div class="batch-operations" style="margin-top: 20px;">
|
||
<Card>
|
||
<template #title>
|
||
<Icon type="ios-settings" />
|
||
批量操作
|
||
</template>
|
||
<Space>
|
||
<Button type="primary" @click="batchCheckProxies" :loading="batchChecking">
|
||
<Icon type="ios-checkmark-circle" />
|
||
批量检测
|
||
</Button>
|
||
<Button @click="syncProxyPools" :loading="syncing">
|
||
<Icon type="ios-sync" />
|
||
同步代理池
|
||
</Button>
|
||
<Button @click="startMonitoring" v-if="!isMonitoring">
|
||
<Icon type="ios-play" />
|
||
开始监控
|
||
</Button>
|
||
<Button @click="stopMonitoring" v-else type="warning">
|
||
<Icon type="ios-pause" />
|
||
停止监控
|
||
</Button>
|
||
</Space>
|
||
</Card>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
```
|
||
|
||
### 2. 新建代理池管理页面
|
||
|
||
```vue
|
||
<!-- /frontend/src/view/configManage/proxyPoolManage.vue -->
|
||
<template>
|
||
<div class="proxy-pool-manage">
|
||
<Card>
|
||
<template #title>
|
||
<Icon type="ios-globe" />
|
||
代理IP池管理
|
||
</template>
|
||
<template #extra>
|
||
<Space>
|
||
<Select v-model="filters.proxyType" placeholder="代理类型" style="width: 120px;">
|
||
<Option value="">全部</Option>
|
||
<Option value="residential">住宅代理</Option>
|
||
<Option value="datacenter">数据中心</Option>
|
||
<Option value="mobile">移动代理</Option>
|
||
<Option value="static_residential">静态住宅</Option>
|
||
</Select>
|
||
<Select v-model="filters.country" placeholder="国家" style="width: 100px;">
|
||
<Option value="">全部</Option>
|
||
<Option value="US">美国</Option>
|
||
<Option value="UK">英国</Option>
|
||
<Option value="DE">德国</Option>
|
||
<Option value="JP">日本</Option>
|
||
</Select>
|
||
<Select v-model="filters.status" placeholder="状态" style="width: 100px;">
|
||
<Option value="">全部</Option>
|
||
<Option value="active">活跃</Option>
|
||
<Option value="inactive">非活跃</Option>
|
||
<Option value="failed">失败</Option>
|
||
</Select>
|
||
<Button @click="refreshList">刷新</Button>
|
||
</Space>
|
||
</template>
|
||
|
||
<!-- 代理池统计卡片 -->
|
||
<Row :gutter="16" style="margin-bottom: 16px;">
|
||
<Col :span="6" v-for="stat in poolStats" :key="stat.type">
|
||
<Card :bordered="false">
|
||
<Statistic
|
||
:title="stat.title"
|
||
:value="stat.value"
|
||
:prefix="stat.prefix"
|
||
:suffix="stat.suffix"
|
||
/>
|
||
</Card>
|
||
</Col>
|
||
</Row>
|
||
|
||
<!-- 代理列表表格 -->
|
||
<Table
|
||
:columns="proxyColumns"
|
||
:data="proxyList"
|
||
:loading="tableLoading"
|
||
stripe
|
||
border
|
||
size="small"
|
||
>
|
||
<!-- 自定义状态列 -->
|
||
<template #status="{ row }">
|
||
<Tag :color="getStatusColor(row.status)">
|
||
{{ getStatusText(row.status) }}
|
||
</Tag>
|
||
</template>
|
||
|
||
<!-- 自定义检测操作列 -->
|
||
<template #action="{ row }">
|
||
<Space>
|
||
<Button size="small" @click="checkSingleProxy(row.id)" :loading="row.checking">
|
||
检测
|
||
</Button>
|
||
<Button size="small" @click="viewProxyDetail(row)">
|
||
详情
|
||
</Button>
|
||
</Space>
|
||
</template>
|
||
</Table>
|
||
|
||
<!-- 分页 -->
|
||
<div style="margin-top: 16px; text-align: right;">
|
||
<Page
|
||
:total="total"
|
||
:current="pagination.page"
|
||
:page-size="pagination.pageSize"
|
||
@on-change="handlePageChange"
|
||
@on-page-size-change="handlePageSizeChange"
|
||
show-sizer
|
||
show-elevator
|
||
show-total
|
||
/>
|
||
</div>
|
||
</Card>
|
||
|
||
<!-- 代理详情弹窗 -->
|
||
<Modal v-model="detailModal.visible" title="代理详情" width="800">
|
||
<div v-if="detailModal.proxy">
|
||
<Descriptions :column="2" border>
|
||
<DescriptionsItem label="IP地址">{{ detailModal.proxy.ip_address }}</DescriptionsItem>
|
||
<DescriptionsItem label="端口">{{ detailModal.proxy.port }}</DescriptionsItem>
|
||
<DescriptionsItem label="类型">{{ detailModal.proxy.proxy_type }}</DescriptionsItem>
|
||
<DescriptionsItem label="协议">{{ detailModal.proxy.protocol }}</DescriptionsItem>
|
||
<DescriptionsItem label="国家">{{ detailModal.proxy.country_code }}</DescriptionsItem>
|
||
<DescriptionsItem label="城市">{{ detailModal.proxy.city }}</DescriptionsItem>
|
||
<DescriptionsItem label="匿名级别">{{ detailModal.proxy.anonymity_level }}</DescriptionsItem>
|
||
<DescriptionsItem label="平均延迟">{{ detailModal.proxy.avg_response_time }}ms</DescriptionsItem>
|
||
<DescriptionsItem label="成功次数">{{ detailModal.proxy.success_count }}</DescriptionsItem>
|
||
<DescriptionsItem label="失败次数">{{ detailModal.proxy.fail_count }}</DescriptionsItem>
|
||
<DescriptionsItem label="成功率">
|
||
{{ ((detailModal.proxy.success_count / (detailModal.proxy.success_count + detailModal.proxy.fail_count + 1)) * 100).toFixed(1) }}%
|
||
</DescriptionsItem>
|
||
<DescriptionsItem label="最后使用">{{ formatTime(detailModal.proxy.last_used_time) }}</DescriptionsItem>
|
||
</Descriptions>
|
||
|
||
<!-- 检测历史图表 -->
|
||
<div style="margin-top: 20px;">
|
||
<h4>检测历史</h4>
|
||
<div ref="checkHistoryChart" style="height: 200px;"></div>
|
||
</div>
|
||
</div>
|
||
</Modal>
|
||
</div>
|
||
</template>
|
||
```
|
||
|
||
### 3. 代理检测报告页面
|
||
|
||
```vue
|
||
<!-- /frontend/src/view/configManage/proxyTestReport.vue -->
|
||
<template>
|
||
<div class="proxy-test-report">
|
||
<Row :gutter="16">
|
||
<!-- 左侧:检测配置 -->
|
||
<Col :span="8">
|
||
<Card title="检测配置">
|
||
<Form :model="testConfig" :label-width="100">
|
||
<FormItem label="检测类型">
|
||
<CheckboxGroup v-model="testConfig.checkTypes">
|
||
<Checkbox label="connectivity">连通性</Checkbox>
|
||
<Checkbox label="performance">性能</Checkbox>
|
||
<Checkbox label="anonymity">匿名性</Checkbox>
|
||
<Checkbox label="geolocation">地理位置</Checkbox>
|
||
</CheckboxGroup>
|
||
</FormItem>
|
||
<FormItem label="超时时间">
|
||
<InputNumber v-model="testConfig.timeout" :min="1000" :max="30000" />
|
||
<span style="margin-left: 8px;">毫秒</span>
|
||
</FormItem>
|
||
<FormItem label="并发数">
|
||
<InputNumber v-model="testConfig.concurrency" :min="1" :max="50" />
|
||
</FormItem>
|
||
<FormItem label="测试目标">
|
||
<Input v-model="testConfig.targetUrl" placeholder="http://httpbin.org/ip" />
|
||
</FormItem>
|
||
</Form>
|
||
<Button type="primary" @click="startBatchTest" :loading="testing" long>
|
||
开始批量检测
|
||
</Button>
|
||
</Card>
|
||
</Col>
|
||
|
||
<!-- 右侧:检测结果 -->
|
||
<Col :span="16">
|
||
<Card title="检测结果">
|
||
<!-- 进度条 -->
|
||
<Progress
|
||
v-if="testing"
|
||
:percent="testProgress"
|
||
:status="testProgress === 100 ? 'success' : 'active'"
|
||
show-info
|
||
/>
|
||
|
||
<!-- 结果统计 -->
|
||
<Row :gutter="16" style="margin: 16px 0;" v-if="testResults.length > 0">
|
||
<Col :span="6">
|
||
<Statistic title="检测总数" :value="testResults.length" />
|
||
</Col>
|
||
<Col :span="6">
|
||
<Statistic title="成功数量" :value="successCount" prefix-icon="ios-checkmark" />
|
||
</Col>
|
||
<Col :span="6">
|
||
<Statistic title="失败数量" :value="failCount" prefix-icon="ios-close" />
|
||
</Col>
|
||
<Col :span="6">
|
||
<Statistic title="成功率" :value="successRate" suffix="%" :precision="1" />
|
||
</Col>
|
||
</Row>
|
||
|
||
<!-- 结果表格 -->
|
||
<Table
|
||
:columns="resultColumns"
|
||
:data="testResults"
|
||
size="small"
|
||
:max-height="400"
|
||
/>
|
||
</Card>
|
||
</Col>
|
||
</Row>
|
||
</div>
|
||
</template>
|
||
```
|
||
|
||
## 🚀 用户体验优化
|
||
|
||
### 1. 工作流程优化
|
||
|
||
#### 一键式配置流程
|
||
```javascript
|
||
// 简化的配置向导
|
||
const configWizard = {
|
||
steps: [
|
||
{
|
||
title: '选择代理平台',
|
||
description: '从预设平台中选择或添加自定义平台',
|
||
component: 'PlatformSelector'
|
||
},
|
||
{
|
||
title: '配置认证信息',
|
||
description: '输入API密钥或用户名密码',
|
||
component: 'AuthConfig'
|
||
},
|
||
{
|
||
title: '测试连接',
|
||
description: '验证配置是否正确',
|
||
component: 'ConnectionTest'
|
||
},
|
||
{
|
||
title: '同步代理池',
|
||
description: '获取可用代理列表',
|
||
component: 'ProxySync'
|
||
},
|
||
{
|
||
title: '完成配置',
|
||
description: '开始使用代理服务',
|
||
component: 'ConfigComplete'
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
#### 智能推荐系统
|
||
```javascript
|
||
// 基于使用历史的智能推荐
|
||
class ProxyRecommendationService {
|
||
async getRecommendations(userId, usage = 'telegram') {
|
||
// 分析用户历史使用模式
|
||
const userHistory = await this.getUserHistory(userId)
|
||
|
||
// 根据使用场景推荐
|
||
const recommendations = {
|
||
telegram: {
|
||
preferredCountries: ['US', 'UK', 'DE'],
|
||
preferredTypes: ['residential', 'mobile'],
|
||
maxLatency: 1500
|
||
},
|
||
scraping: {
|
||
preferredCountries: ['US', 'CA', 'AU'],
|
||
preferredTypes: ['datacenter', 'residential'],
|
||
maxLatency: 3000
|
||
}
|
||
}
|
||
|
||
return this.selectProxies(recommendations[usage])
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. 监控告警系统
|
||
|
||
```javascript
|
||
// 实时告警系统
|
||
class ProxyAlertSystem {
|
||
constructor() {
|
||
this.alerts = new Map()
|
||
this.thresholds = {
|
||
responseTime: 3000, // 响应时间阈值
|
||
successRate: 0.8, // 成功率阈值
|
||
availability: 0.9 // 可用性阈值
|
||
}
|
||
}
|
||
|
||
async checkAlerts() {
|
||
const platforms = await MProxyPlatformService.getInstance().getEnabledPlatforms()
|
||
|
||
for (const platform of platforms) {
|
||
const stats = await this.getPlatformStats(platform.id)
|
||
|
||
// 检查各项指标
|
||
if (stats.avgResponseTime > this.thresholds.responseTime) {
|
||
this.triggerAlert('high_latency', platform, stats)
|
||
}
|
||
|
||
if (stats.successRate < this.thresholds.successRate) {
|
||
this.triggerAlert('low_success_rate', platform, stats)
|
||
}
|
||
|
||
if (stats.availability < this.thresholds.availability) {
|
||
this.triggerAlert('low_availability', platform, stats)
|
||
}
|
||
}
|
||
}
|
||
|
||
triggerAlert(type, platform, stats) {
|
||
const alert = {
|
||
type,
|
||
platform: platform.platform,
|
||
message: this.getAlertMessage(type, platform, stats),
|
||
timestamp: new Date(),
|
||
severity: this.getAlertSeverity(type, stats)
|
||
}
|
||
|
||
// 发送告警通知
|
||
this.sendNotification(alert)
|
||
|
||
// 记录告警日志
|
||
this.logAlert(alert)
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 性能优化措施
|
||
|
||
#### 缓存策略
|
||
```javascript
|
||
// 多层缓存系统
|
||
class ProxyCacheManager {
|
||
constructor() {
|
||
this.memoryCache = new Map()
|
||
this.redisCache = redis.createClient()
|
||
this.cacheTTL = {
|
||
proxyList: 300, // 5分钟
|
||
checkResult: 60, // 1分钟
|
||
platformConfig: 1800 // 30分钟
|
||
}
|
||
}
|
||
|
||
async get(key, type = 'proxyList') {
|
||
// 1. 先查内存缓存
|
||
if (this.memoryCache.has(key)) {
|
||
return this.memoryCache.get(key)
|
||
}
|
||
|
||
// 2. 查Redis缓存
|
||
const cached = await this.redisCache.get(key)
|
||
if (cached) {
|
||
const data = JSON.parse(cached)
|
||
this.memoryCache.set(key, data)
|
||
return data
|
||
}
|
||
|
||
return null
|
||
}
|
||
|
||
async set(key, data, type = 'proxyList') {
|
||
const ttl = this.cacheTTL[type]
|
||
|
||
// 设置内存缓存
|
||
this.memoryCache.set(key, data)
|
||
|
||
// 设置Redis缓存
|
||
await this.redisCache.setex(key, ttl, JSON.stringify(data))
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 连接池管理
|
||
```javascript
|
||
// 代理连接池
|
||
class ProxyConnectionPool {
|
||
constructor(maxSize = 100) {
|
||
this.maxSize = maxSize
|
||
this.pool = new Map()
|
||
this.stats = {
|
||
created: 0,
|
||
reused: 0,
|
||
destroyed: 0
|
||
}
|
||
}
|
||
|
||
async getConnection(proxy) {
|
||
const key = `${proxy.ip}:${proxy.port}`
|
||
|
||
if (this.pool.has(key)) {
|
||
this.stats.reused++
|
||
return this.pool.get(key)
|
||
}
|
||
|
||
if (this.pool.size >= this.maxSize) {
|
||
// 清理最久未使用的连接
|
||
this.cleanup()
|
||
}
|
||
|
||
const connection = await this.createConnection(proxy)
|
||
this.pool.set(key, {
|
||
connection,
|
||
lastUsed: Date.now(),
|
||
proxy
|
||
})
|
||
|
||
this.stats.created++
|
||
return connection
|
||
}
|
||
|
||
cleanup() {
|
||
const entries = Array.from(this.pool.entries())
|
||
entries.sort((a, b) => a[1].lastUsed - b[1].lastUsed)
|
||
|
||
// 清理最久未使用的25%连接
|
||
const toRemove = Math.floor(entries.length * 0.25)
|
||
for (let i = 0; i < toRemove; i++) {
|
||
const [key, { connection }] = entries[i]
|
||
connection.destroy()
|
||
this.pool.delete(key)
|
||
this.stats.destroyed++
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 📈 扩展功能规划
|
||
|
||
### 1. 地理位置智能路由
|
||
- 根据目标服务器地理位置选择最近的代理
|
||
- 支持GPS坐标和城市级别的精确定位
|
||
- 延迟优化算法
|
||
|
||
### 2. 代理质量评分系统
|
||
- 综合评分算法:速度(30%) + 稳定性(25%) + 匿名性(20%) + 成功率(25%)
|
||
- 机器学习模型预测代理性能
|
||
- 用户评价反馈系统
|
||
|
||
### 3. 成本优化建议
|
||
- 使用成本分析和预算控制
|
||
- 代理使用效率报告
|
||
- 成本优化建议算法
|
||
|
||
### 4. API限流和配额管理
|
||
- 基于令牌桶算法的限流
|
||
- 代理平台配额监控
|
||
- 智能配额分配
|
||
|
||
## 🔒 安全考虑
|
||
|
||
### 1. 敏感信息保护
|
||
- API密钥和密码加密存储
|
||
- 传输过程TLS加密
|
||
- 访问权限控制
|
||
|
||
### 2. 代理安全检测
|
||
- 恶意代理识别
|
||
- 数据泄漏检测
|
||
- 流量分析监控
|
||
|
||
### 3. 合规性检查
|
||
- 代理使用合规性验证
|
||
- 地区法律法规遵循
|
||
- 用户协议条款检查
|
||
|
||
## 📋 实施计划
|
||
|
||
### 第一阶段:基础功能实现 (1-2周)
|
||
1. ✅ 分析现有代理平台功能
|
||
2. 🔄 实现Rola-IP平台适配器
|
||
3. 📊 扩展数据库表结构
|
||
4. 🎯 基础检测功能实现
|
||
|
||
### 第二阶段:高级功能开发 (2-3周)
|
||
1. 🤖 智能代理选择算法
|
||
2. 📱 前端界面增强
|
||
3. ⚡ 性能优化和缓存
|
||
4. 📈 监控告警系统
|
||
|
||
### 第三阶段:用户体验优化 (1-2周)
|
||
1. 🎨 界面美化和交互优化
|
||
2. 📋 配置向导实现
|
||
3. 🔍 智能推荐系统
|
||
4. 📊 数据可视化增强
|
||
|
||
### 第四阶段:测试和部署 (1周)
|
||
1. 🧪 全面功能测试
|
||
2. ⚡ 性能压力测试
|
||
3. 🔒 安全性测试
|
||
4. 🚀 生产环境部署
|
||
|
||
## 🎯 成功指标
|
||
|
||
### 功能指标
|
||
- [ ] 支持10+主流代理平台
|
||
- [ ] 代理检测准确率>95%
|
||
- [ ] 平均响应时间<2秒
|
||
- [ ] 系统可用性>99.9%
|
||
|
||
### 用户体验指标
|
||
- [ ] 配置时间<5分钟
|
||
- [ ] 界面响应时间<500ms
|
||
- [ ] 用户满意度>4.5/5
|
||
- [ ] 故障自动恢复率>90%
|
||
|
||
### 性能指标
|
||
- [ ] 支持1000+并发连接
|
||
- [ ] 内存使用<500MB
|
||
- [ ] CPU使用率<30%
|
||
- [ ] 数据库查询时间<100ms
|
||
|
||
---
|
||
|
||
*本设计方案将分阶段实施,优先实现核心功能,逐步完善高级特性和用户体验优化。* |