【问题标题】:Multi-tenant ServiceStack API, same deployment to respond to requests on different hostnames?多租户 ServiceStack API,相同的部署来响应不同主机名上的请求?
【发布时间】:2013-10-24 21:58:10
【问题描述】:

我们正在使用 ServiceStack 创建多租户 API。我们想做基于 DNS 的负载平衡和路由,而不是通过反向代理(如 nginx 或 haproxy)拼接。

我们有具有租户参数的请求 DTO。 ServiceStack(及其 SwaggerFeature)允许我们定义自定义路由,并记录 DTO,以便我们可以从路径、查询、标题或正文中读取值。

我们如何(最好)连接事物,以便 DTO 属性也可以从主机名模式中读取值?那么,让 Route 从匹配的主机名和路径中获取值?

我们希望有类似的网址

  • https://{tenant}.{DNS zone for environment}/{rest of path with tokens}

此外 - 外 DNS 区域将根据我们所处的环境而有所不同 - 对于非生产我们使用(例如)testing-foobar.com,而生产我们使用 real-live.com。理想情况下,我们可以通过一个单一的路由声明来支持两者(我们更喜欢在运行时装饰 Request DTO 而不是命令式声明AppHost.Init)。

【问题讨论】:

  • 我的第一个倾向是使用request and response filters你考虑过吗?
  • 我会使用 Request 过滤器注入任何实现自定义 ITenant 接口的请求 DTO,该接口仅具有 Tenant 属性。另一种解决方案是使用 IHttpRequest.Tennant() 扩展方法,您可以在检查 AbsoluteUri 或 RawUrl 属性的所有服务中重复使用该方法。
  • @mythz - 有没有一个例子展示了如何在 ServiceStack 中实现这个?

标签: binding routing servicestack load-balancing


【解决方案1】:

我本周在一个现有的多租户系统上解决了这个问题,该系统使用 .NET 安全主体来处理用户权限和租户。我使用自定义 ServiceRunner 来选择租户并设置安全性。您的多租户方法有所不同,但使用 ServiceRunner 似乎仍然是一种有效的方法。

你最终会得到这样的东西:

public class MyServiceRunner<T> : ServiceRunner<T>
{
    public MyServiceRunner(IAppHost appHost, ActionContext actionContext)
        : base(appHost, actionContext)
    {}

    public override void BeforeEachRequest(IRequestContext requestContext, T request)
    {
        // Set backend authentication before the requests are processed.
        if(request instanceof ITenantRequest)
        {
            Uri uri = new Uri(requestContext.AbsoluteUri);
            string tenant = uri.Host; // Or whatever logic you need...
            ((ITenantRequest).Tenant = tenant;
        }
    }
}

public class MyAppHost : AppHostBase
{
    public MyAppHost() : base("My Web Services", typeof(MyService).Assembly) { }

    public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext)
    {
        return new MyServiceRunner<TRequest>(this, actionContext);
    }

    public override void Configure(Container container)
    {
        ...
    }
}

也许请求过滤方法更好,但这对我们有用。

【讨论】:

  • 我们已经有一个 IServiceRunner 来做我们的 UnitOfWork - 我不认为这些可以被链接
猜你喜欢
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 1970-01-01
  • 2018-09-24
  • 1970-01-01
  • 2020-05-15
相关资源
最近更新 更多