2

我正在尝试在网关后面的同一域上获取一堆单独的服务器。目前,可以通过多个名称从外部访问这些服务器中的每一个。我们的销售团队希望为客户提供一个唯一的 url,所以如果一个服务器为 10 个客户提供服务,我们有 10 条 CNAME 记录指向它。

如您所见,使用 5 或 6 台服务器,数量apiEndpoints非常多。最重要的是,可以在任何给定时间创建新的 CNAME,从而使硬编码变得apiEndpoints难以管理。

是否有可能有一个动态serviceEndpoint网址。我在想的是这样的:

apiEndpoints:
  legacy:
    host: '*.mydomain.com'
    paths: '/v1/*'
serviceEndpoints:
  legacyEndPoint:
    url: '${someVarWithValueofStar}.internal.com'
pipelines:
  default:
    apiEndpoints:
      - legacy:
    policies:
      - proxy:
          - action:
              serviceEndpoint: legacyEndPoint

基本上,我想要实现的是将所有内容重定向x.mydomain.com到可以是任何东西的x.internal.com地方。x

我可以在 url 字符串中使用变量吗?有没有办法获取与主机中的通配符匹配的字符串?还有其他选择来解决这个问题吗?

4

2 回答 2

2

我最终为了我的需要一起破解了一个代理插件。非常基础,需要更多的工作和测试,但这是我开始的:

代理插件(my-proxy)

const httpProxy = require("http-proxy");

/**
 * This is a very rudimentary proxy plugin for the express gateway framework.
 * Basically it will redirect requests xxx.external.com to xxx.internal.com
 * Where xxx can be any name and the destination comes from providing a 
 * service endpoint with a http://*.destination.com url
 * @param {*} params 
 * @param {*} config 
 */
module.exports = function (params, config) {
  const serviceEndpointKey = params.serviceEndpoint;
  const changeOrigin = params.changeOrigin;
  const endpoint = config.gatewayConfig.serviceEndpoints[serviceEndpointKey];
  const url = endpoint.url;
  const reg = /(\/\/\*\.)(\S+)/;
  const match = reg.exec(url);
  const domain = match[2];
  const proxy = httpProxy.createProxyServer({changeOrigin : changeOrigin});
  proxy.on("error", (err, req, res) => {
    console.error(err);
    if (!res.headersSent) {
      res.status(502).send('Bad gateway.');
    } else {
      res.end();
    }
  });
  return (req, res, next) => {
    const hostname = req.hostname;
    const regex = /^(.*?)\./
    const tokens = regex.exec(hostname)
    const serverName = tokens[1];
    const destination = req.protocol + "://" + serverName + "." + domain;

    proxy.web(req, res, {target : destination});
  };
};

网关.config.xml

http:
  port: 8080
apiEndpoints:
  legacy:
    host: '*.external.com'
    paths: '/v1/*'
serviceEndpoints:
  legacy_end_point:
    url: 'https://*.internal.com'
policies:
  - my-proxy
pipelines:
  default:
    apiEndpoints:
      - legacy
    policies:
      - my-proxy:
          - action:
              serviceEndpoint: legacy_end_point 
              changeOrigin: true

这一切都归结为正则表达式解析apiEndpointsserviceEndpoints主机和网址中的通配符,到目前为止没有什么特别的。我查看了内置代理插件的源代码,我认为我的幼稚方法不太适合,但它可以满足我的需要。

于 2018-05-22T23:22:57.097 回答
0

谢谢你的问题,我认为在接下来的几个月里会被很多人问到这个问题。

Express Gateway 支持环境变量;不幸的是,现在apiEndpoint只能是一个单一且定义明确的端点,没有任何替代功能。

这是我们可能会在不久的将来改变的东西——使用代理表 API,它可以让您插入一些更困难的模板。

如果这对您来说很紧迫,我会邀请您打开一个问题,以便团队中的每个人都知道这个功能,我们可以有效地优先考虑它。

与此同时,不幸的是,您将不得不处理大量的 ApiEndpoints

五。

于 2018-05-18T08:41:47.060 回答