Golang中的多租户

3
我目前正在使用Go编写一个服务,需要处理多个租户。我已经确定使用一个数据库、共享表格的方法,并使用“tenant_id”来区分租户。
该服务的结构如下:
gRPC server -> gRPC Handlers -
                              \_ Managers (SQL)
                              /
HTTP/JSON server -> Handlers -

有两个服务器,一个是gRPC服务器(管理)和一个HTTP/JSON服务器(公共API),每个服务器都在自己的go-routine中运行,并具有各自的处理程序,可以利用不同管理器的功能。管理器(我们称之为"inventory-manager"),都位于不同的根级包中。据我所知,这些是我的领域实体。

在这方面,我有一些问题:

  1. 我找不到任何支持多租户的Go ORM。在sqlx包上编写自己的ORM是否是一个有效的选择?

  2. 未来的其他服务也需要支持多租户,所以我想我必须创建一些库/包。

  3. 今天,我通过为公共API服务器使用ResolveTenantBySubdomain中间件来解析租户。然后,我将解析后的租户ID放入与调用管理器一起发送的上下文值中。在管理器的不同方法中,我从上下文值中获取租户ID。然后,在每个SQL查询/exec调用中使用它,如果缺少或无效租户ID,则返回错误。我应该使用上下文来实现这个目的吗?

  4. 对于gRPC服务器上的租户解析,我认为我必须使用UnaryInterceptor函数进行中间件处理。由于gRPC API接口只能被其他后端服务访问,因此我认为在子域上解析是不必要的。但是,我应该如何嵌入租户ID?在头部吗?

真的希望我的问题是正确的。 谢谢,Karl。


1
  1. 当然,为什么不呢?
  2. 这不是一个问题。
  3. 上下文非常适合取消操作,但对于数据处理来说则很糟糕。
  4. 标头、参数,无论你想怎样做都可以。这是你的设计决策。
- Adrian
我发现 sqlx 很适合我的项目。只需注意设计决策,即从查询返回的未映射字段被视为“未使用的变量”,并将引发错误。请参见此处的二级文档,标题为“扫描目标安全性”http://jmoiron.github.io/sqlx/ - RayfenWindspear
1个回答

8
我找不到任何支持多租户的Go ORM。在sqlx包上编写自己的ORM是一个有效的选择吗?
在Go中,ORM是一个有争议的话题!一些Go用户喜欢它们,而其他人则讨厌它们并更喜欢手动编写SQL。这是个人偏好的问题。在这里询问特定库的建议是不相关的,而且无论如何,我不知道任何多租户ORM库 - 但没有什么阻止您使用sqlx的包装器(我每天都在一个这样做的系统上工作)。
将来的其他服务也需要多租户支持,所以我想我必须创建一些库/包。
从编程和接口模式的角度出发,将此行为抽象化是有意义的,但这里没有进一步的细节来回答更具体的问题。
今天,我通过使用ResolveTenantBySubdomain中间件来解决公共API服务器的租户问题。然后,我将已解析的租户ID放置在上下文值中,并随调用经理发送。在管理器的不同方法中,我从上下文值中获取租户ID。然后,该ID将用于每个SQL查询/ exec调用,如果缺少或无效租户ID,则返回错误。我是否应该为此目的使用context?
context.Context主要用于取消,而不是请求传播。虽然根据WithValue函数的文档,您的用法是可以接受的,但当前实现方式下使用context包传递值被广泛 认为 是一种糟糕的代码味道。与其使用缺乏类型安全和许多其他属性的隐式行为,为什么不在下游数据层的函数签名中显式传递租户ID呢?
解决gRPC服务器上的租户问题,我认为我需要使用UnaryInterceptor函数来处理中间件。由于gRPC API接口只会被其他后端服务访问,所以在这里解决子域名是不必要的。但是我应该如何嵌入租户ID?在头部吗?gRPC库对设计选择没有意见。您可以使用标头值(将租户ID作为“环境”参数传递给请求),或者显式地将租户ID参数添加到每个需要它的远程方法调用中。请注意,在此方式下在您的服务之间传递租户ID会创建外部信任-如果服务A向服务B发出请求并注释了租户ID,则假设服务A已执行必要的访问控制检查以验证该租户的用户确实正在发出请求。这种简单模型中没有任何东西可以防止流氓服务C请求服务B提供有关某个任意租户ID的信息。另一种实现方式是实现更复杂的不信任任何人策略,每个服务都提供足够的访问控制信息,以便根据其自己的策略决定是否应满足特定租户范围内的特定请求。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接