使用 Node.js 学习和实现网关
我正在学习网关并使用 Node.js 来实现它们。我关注的一个具体功能是速率限制,我打算自己实现。该速率限制器利用 IP 地址来跟踪请求数量。
为了确保功能正确实现,我需要进行彻底的测试。特别是,我正在寻找一种方法来使
multiple requests with different IP addresses
在本地测试速率限制。
考虑一个简单的(与我打算实现的不准确)速率限制器。
const cash = {};
const limit = 50;
const rateLimiter = async (req, res, next) => {
if (!cash[req.ip]) cash[req.ip] = { count: 0, time: [] };
if (cash[req.ip].count >= limit) {
if (Date.now() - cash[req.ip].time[0] < 60000) {
return res.send("Limit reached");
} else {
for (const t of cash[req.ip].time) {
if (Date.now() - t > 60000) break;
cash[req.ip].time.shift(); // Remove the oldest entry
cash[req.ip].count--;
}
}
}
cash[req.ip].count++;
cash[req.ip].time.push(Date.now());
next();
};
在 Axios 或 Node-Fetch 中操作 IP 地址以实现自定义请求
我想运行一个脚本,需要使用 Axios 或 Node-Fetch 向服务器发出自定义请求。我想进行一些实验,需要操作请求对象中发送的 IP 地址。
这是我当前使用 Axios 的代码的简化版本:
const axios = require("axios");
const http = require("http");
function getRandomPrivateIP() {
const octet3 = Math.floor(Math.random() * 256);
const octet4 = Math.floor(Math.random() * 256);
return `192.168.${octet3}.${octet4}`;
}
function createAxiosInstanceWithIP(ipAddress) {
const agent = new http.Agent({
localAddress: ipAddress,
});
return axios.create({ httpAgent: agent, httpsAgent: agent });
}
const url = "http://localhost:8080/gateway";
const numberOfRequests = 1000;
for (let i = 0; i < numberOfRequests; i++) {
const customIPAddress = getRandomPrivateIP(); // Invoke the function
const axiosInstance = createAxiosInstanceWithIP(customIPAddress);
axiosInstance
.get(url)
.then((response) => {
// Handle the response
console.log(`Request ${i + 1} successful`);
})
.catch((error) => {
// Handle errors
console.error(`Request ${i + 1} failed: ${error.message}`);
});
}
上面的代码抛出错误:
请求1000失败:绑定EINVAL 192.168.72.253
有没有办法操纵请求对象中的 IP 地址,以便更好地控制我尝试执行的实验?我已经探索了 Apache 服务器和其他专用 VPS 进行基准测试,但我想在脚本中为我的请求自定义 IP 地址。
此外,如果在某些情况下我可能会犯错误或需要以不同的心态来处理情况,请告诉我。
我找到了解决办法,如下
localAddress
中的http.Agent
选项用于将套接字绑定到本地接口的IP地址,但它不影响HTTP请求中的传出IP地址。为了实现我想要的,我们需要使用自定义 DNS 解析器将主机解析为特定的 IP。
这是代码的更新版本:
function createAxiosInstance(ipAddress) {
const agent = new http.Agent({
localAddress: ipAddress,
lookup: (hostname, options, callback) => {
callback(null, ipAddress, 4);
},
});
return axios.create({ httpAgent: agent, httpsAgent: agent });
}
此代码在
lookup
的 http.Agent
选项中包含自定义 DNS 解析器功能,可将主机名解析为指定的 IP 地址。