Nodejs代理请求合并
我遇到了我的http-proxy-middleware问题。我正在使用它来代理对另一个服务的请求,即可能调整图像大小等。
问题是多个客户端可能多次调用该方法,从而在原始服务上创建一个踩踏事件。我现在正在研究(有些服务称为request coalescing
即varnish)一种解决方案,它会调用服务一次,等待响应并使用相同的签名“排队”传入的请求,直到第一次完成,并将它们全部返回单个go ...这与'缓存'结果不同,因为我想防止同时多次调用后端而不一定缓存结果。
我试图找到这样的东西可能被称为不同或者我错过了其他人已经解决过的东西......但我找不到任何东西......
由于用例对于反向代理类型设置看起来非常“基本”,我本来期望我的搜索有很多点击,但由于问题空间非常通用,我没有得到任何东西......
谢谢!
回答如下:我的一位同事帮我解决了自己的问题。它目前用作特定GET
端点的(快速)中间件,并且基本上将请求散列到地图中,启动新的单独请求。并发传入请求被散列并检查并在单独的请求回调上行走,从而重新使用。这也意味着如果第一个响应特别慢,那么所有合并的请求也是如此
这似乎比将它破解成http-proxy-middleware更容易,但是哦,这就完成了工作:)
const axios = require('axios');
const responses = {};
module.exports = (req, res) => {
const queryHash = `${req.path}/${JSON.stringify(req.query)}`;
if (responses[queryHash]) {
console.log('re-using request', queryHash);
responses[queryHash].push(res);
return;
}
console.log('new request', queryHash);
const axiosConfig = {
method: req.method,
url: `[the original backend url]${req.path}`,
params: req.query,
headers: {}
};
if (req.headers.cookie) {
axiosConfig.headers.Cookie = req.headers.cookie;
}
responses[queryHash] = [res];
axios.request(axiosConfig).then((axiosRes) => {
responses[queryHash].forEach((coalescingRequest) => {
coalescingRequest.json(axiosRes.data);
});
responses[queryHash] = undefined;
}).catch((err) => {
responses[queryHash].forEach((coalescingRequest) => {
coalescingRequest.status(500).json(false);
});
responses[queryHash] = undefined;
});
};
Nodejs代理请求合并
我遇到了我的http-proxy-middleware问题。我正在使用它来代理对另一个服务的请求,即可能调整图像大小等。
问题是多个客户端可能多次调用该方法,从而在原始服务上创建一个踩踏事件。我现在正在研究(有些服务称为request coalescing
即varnish)一种解决方案,它会调用服务一次,等待响应并使用相同的签名“排队”传入的请求,直到第一次完成,并将它们全部返回单个go ...这与'缓存'结果不同,因为我想防止同时多次调用后端而不一定缓存结果。
我试图找到这样的东西可能被称为不同或者我错过了其他人已经解决过的东西......但我找不到任何东西......
由于用例对于反向代理类型设置看起来非常“基本”,我本来期望我的搜索有很多点击,但由于问题空间非常通用,我没有得到任何东西......
谢谢!
回答如下:我的一位同事帮我解决了自己的问题。它目前用作特定GET
端点的(快速)中间件,并且基本上将请求散列到地图中,启动新的单独请求。并发传入请求被散列并检查并在单独的请求回调上行走,从而重新使用。这也意味着如果第一个响应特别慢,那么所有合并的请求也是如此
这似乎比将它破解成http-proxy-middleware更容易,但是哦,这就完成了工作:)
const axios = require('axios');
const responses = {};
module.exports = (req, res) => {
const queryHash = `${req.path}/${JSON.stringify(req.query)}`;
if (responses[queryHash]) {
console.log('re-using request', queryHash);
responses[queryHash].push(res);
return;
}
console.log('new request', queryHash);
const axiosConfig = {
method: req.method,
url: `[the original backend url]${req.path}`,
params: req.query,
headers: {}
};
if (req.headers.cookie) {
axiosConfig.headers.Cookie = req.headers.cookie;
}
responses[queryHash] = [res];
axios.request(axiosConfig).then((axiosRes) => {
responses[queryHash].forEach((coalescingRequest) => {
coalescingRequest.json(axiosRes.data);
});
responses[queryHash] = undefined;
}).catch((err) => {
responses[queryHash].forEach((coalescingRequest) => {
coalescingRequest.status(500).json(false);
});
responses[queryHash] = undefined;
});
};