简体   繁体   English

Node.js代理请求合并

[英]Nodejs proxy request coalescing

I'm running into an issue with my http-proxy-middleware stuff. 我的http-proxy-middleware资料出现问题。 I'm using it to proxy requests to another service which ie might resize images et al. 我用它来代理请求到另一个服务,即可能会调整图像大小等。

The problem is that multiple clients might call the method multiple times and thus create a stampede on the original service. 问题在于,多个客户端可能会多次调用该方法,从而在原始服务上创建踩踏事件。 I'm now looking into (what some services call request coalescing ie varnish) a solution that would call the service once, wait for the response and 'queue' the incoming requests with the same signature until the first is done, and return them all in a single go... This is different from 'caching' results due to the fact that I want to prevent calling the backend multiple times simultaneously and not necessarily cache the results. 我现在正在研究一种解决方案,该解决方案将调用该服务一次,等待响应并以相同的签名“排队”传入的请求,直到第一个完成,然后全部返回(该服务将某些服务称为request coalescing )一次即可...这与“缓存”结果不同,原因是我想防止同时调用后端多次,而不必缓存结果。

I'm trying to find if something like that might be called differently or am i missing something that others have already solved someway... but i can't find anything... 我正在尝试查找类似的名称是否可能被不同地称呼,或者我是否错过了其他人已经解决的某些东西……但我找不到任何东西……

As the use case seems pretty 'basic' for a reverse-proxy type setup, I would have expected alot of hits on my searches but since the problemspace is pretty generic i'm not getting anything... 由于用例对于反向代理类型设置来说似乎很“基本”,所以我原本希望在搜索中找到很多匹配项,但是由于问题空间非常通用,所以我什么也没得到...

Thanks! 谢谢!

A colleague of mine has helped my hack my own answer. 我的一位同事帮助我破解了自己的答案。 It's currently used as a (express) middleware for specific GET -endpoints and basically hashes the request into a map, starts a new separate request. 当前,它用作特定GET端点的(快速)中间件,并且基本上将请求散列到映射中,并启动一个新的单独请求。 Concurrent incoming requests are hashed and checked and walked on the separate request callback and thus reused. 并发的传入请求被散列,检查并遍历单独的请求回调,从而被重用。 This also means that if the first response is particularly slow, all coalesced requests are too 这也意味着,如果第一个响应特别慢,则所有合并的请求也是如此

This seemed easier than to hack it into the http-proxy-middleware, but oh well, this got the job done :) 这似乎比将其入侵到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;
  });
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM