背景: 合作商的接口只能在内网访问,需要做一下接口转发将数据转发到我们自己的服务器。
方案:Node服务轻量级实现,因为部署服务的这台服务器要做复杂算法操作,需要尽可能的节省空间,所以这里只用HTTPS + 调度器库实现,占用内存5-6MB。
- 使用定时器定时从内网拉取接口A,转发到我们的接口B
- 加上错误重试和内存检测。
mkdir my-server
cd my-server
npm init -y
npm i node-schedule
const https = require('https');d
const schedule = require('node-schedule');
console.log('start');
const fetchDataInterval = 1000; // 间隔时间,单位为毫秒 (这里是每5秒执行一次)
let maxRetryAttempts = 3; // 最大重试次数
const maxMemoryUsageMB = 50; // 设置内存使用的阈值(以MB为单位)
function fetchDataAndForward() {
console.log('fetchDataAndForward');
// 从内网接口A获取数据
const requestA = https.request('https://mock.apifox.cn/m1/926576-0-default/pet/1', { method: 'GET' }, (responseA) => {
console.log('responseA.statusCode', responseA.statusCode)
if ((requestA.statusCode <= 200) || (requestA.statusCode >= 300)) {
console.error(`Error fetching data from internal API A. Status code: ${responseA.statusCode}`);
return; // 终止请求
}
let data = '';
responseA.on('data', (chunk) => {
data += chunk;
console.log('data', data);
});
responseA.on('end', () => {
console.log('end', data);
// 转发数据到外网接口B
const optionsB = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};
const requestB = https.request('https://mock.apifox.cn/m1/926576-0-default/pet', optionsB, (responseB) => {
if ((responseB.statusCode <= 200) || (responseB.statusCode >= 300)) {
console.error(`Error forwarding data to external API B. Status code: ${responseB.statusCode}`);
return; // 终止请求
}
responseB.on('data', (chunk) => {
console.log('Data forwarded successfully:', chunk.toString());
});
});
requestB.write(data);
requestB.end();
});
});
requestA.end();
requestA.on('error', (error) => {
console.error('Error fetching data from internal API A:', error);
// 添加重试逻辑
if (maxRetryAttempts > 0) {
console.log(`Retrying in ${interval / 1000} seconds...`);
setTimeout(() => {
console.log('Retrying...');
fetchDataAndForward(); // 重新执行请求
maxRetryAttempts--; // 减少重试次数
}, fetchDataInterval);
} else {
console.log('Max retry attempts reached. Stopping retries.');
}
});
}
const controlMemoryUsage = (task) => {
const memoryUsage = process.memoryUsage(); // 获取内存使用情况
console.log(`Memory usage: ${Math.round(memoryUsage.heapUsed / 1024 / 1024)} MB`);
if (memoryUsage.heapUsed / (1024 * 1024) > maxMemoryUsageMB) {
console.log('Memory usage exceeded the threshold. Taking corrective action...');
// 在内存使用超出阈值时,可以采取适当的措施
return;
}
task(); // 执行数据拉取
};
const job = () => {
controlMemoryUsage(fetchDataAndForward);
};
// 创建上午、中午和下午的任务
const morningJob = schedule.scheduleJob('00 08 * * *', job); // 每天上午 8:00
const noonJob = schedule.scheduleJob('00 12 * * *', job); // 每天中午 12:00
const afternoonJob = schedule.scheduleJob('00 16 * * *', job); // 每天下午 16:00