【问题标题】:Spring Boot - Zuul - Microservice - optimise API calls made to gateway to fetch user detailsSpring Boot - Zuul - 微服务 - 优化对网关的 API 调用以获取用户详细信息
【发布时间】:2021-02-22 13:44:45
【问题描述】:

我正在 Spring-Boot 中实现一个以 Zuul 作为网关的微服务架构。我有一个具有身份验证和授权逻辑的 zuul 网关服务。此外,它还公开了 API,响应用户详细信息,如用户 ID-用户名映射、当前登录用户等。因此,我的其他服务对网关进行 API 调用以获取任何用户信息。我已标记 zuul.sensitiveHeaders=Cookie,Set-Cookie 以允许将承载令牌传递给非网关微服务。

问题陈述 - 在我的其他服务中,我只是在需要的地方存储用户 ID。然后,在将数据返回到前端时,我对网关服务进行 API 调用以获取用户 ID 的用户名。当我修改单个数据时,这很好用。

但是,当我必须返回批量数据(比如 1000 条记录)时,我会进行 1000 次 API 调用以根据每条记录的用户 ID 获取用户名。这会影响速度。

示例 -

为了在 UI 上显示上述数据,我对网关进行了 8 次 API 调用,以获取每个用户 ID(created_by)的用户名。

有人可以帮我设计在这种情况下应该使用的架构吗?我想到的一些解决方案如下。但是我不太确定这些是否是最好的一个

  1. 登录后获取用户ID-用户名映射的哈希映射并存储在会话缓存中。但这会减慢登录调用速度
  2. 添加 OncePerPrequestFilter 以便在每次 API 调用时,都会获取用户 ID-用户名映射的哈希映射并将其传递给控制器​​。这是可行的,但在不需要此映射的 API 中,仍然会进行 API 调用,这将导致过载。

欢迎任何其他建议。

【问题讨论】:

    标签: spring spring-boot spring-mvc spring-security netflix-zuul


    【解决方案1】:

    不清楚您要做什么 - 问题标题似乎与描述没有太大关系。尽管如此,您似乎对这个问题有两个不同的方面:

    1. 在您的后端,您需要通过服务中使用的令牌(通过您的网关)传递用户信息。
    2. 在您的前端,您需要该信息的一些(最少?)子集用于显示目的(我说的是显示,但通常此信息将用于其他一些过程 - 例如“发送 用户电子邮件”)。

    此外,你提到:

    但是,当我必须返回批量数据(比如 1000 条记录)时,我会进行 1000 次 API 调用以根据每条记录的用户 ID 获取用户名。这会影响速度。

    您希望如何处理这种情况取决于您想要做什么以及您希望如何表示您的请求和结果。

    简而言之,您需要向我们提供此特定请求背后的实际用例背后的更多详细信息,以及系统中将发生的请求的性质。例如,您真的需要每个单独的用户吗?您是否可能需要系统中所有活动/非活动/用户的列表?在后一种情况下,查询读取优化模型就足够了,该模型在创建新用户时更新。在这种情况下,响应不仅会很快,而且您可以轻松添加分页和排序等不错的功能,因为您可能已经为基于集合的响应提供了此类功能。

    您的后端服务仍然可以仅根据令牌信息填充安全上下文:用户在系统中的角色是什么,提供的范围等。为了更改系统的状态,您仍然会(在某些时候进程)进行检查以检查当前系统状态,例如数据库调用。

    如果您只需要显示当前登录用户的一小部分详细信息(很少更改),并且此数据不是高度机密的,您可以考虑将其作为自定义 Claim 添加到您的不记名令牌中.例如,如果您使用 JWT 作为您的不记名令牌,您可以轻松地解码令牌并读取信息。

    所以,这取决于你到底想做什么。您真的需要为 1 个字段同时查询 >1,000 个个人用户吗?也许我误解了这个问题,但在我看来,您需要有关系统中大量实体(在本例中为用户)的非常具体的信息子集,以及读取优化的模型(甚至是数据库)由具有足够权限的用户直接查询的视图)可以完成这项工作。

    附带说明,Spring Cloud ZuulGreenwich 发布系列以来一直处于维护模式,截至 2019 年 1 月 22 日。您应该考虑升级到 Spring Cloud Gateway,它会取代它并提供(其中许多其他改进)非阻塞请求模型(与Zuul 阻塞模型相反)。

    【讨论】:

    • 谢谢。你理解的问题是正确的。我需要系统中所有活动/非活动/用户的列表。但是此数据与网关服务有关。所以基本上我需要的是 - 我的微服务应该在需要时提供这些数据。它不应该向网关发出 API 调用请求。
    • 那么问题是:如果您在各种服务中需要数据,为什么您的网关服务会包含这些数据?它是例如内存中的缓存吗?所有已撤销授权的用户?
    • 我只是想将身份验证和授权作为单独的微服务(网关),以便我可以插入任何其他微服务并且服务具有松散耦合。这就是数据与网关的原因。
    • 我不明白为什么您不能简单地创建一个允许在给定created_by ID 列表的情况下批量查询用户名的请求。但这不仅仅意味着批量请求与单个请求的性能:您实际上是加倍到达您的网关(客户端->网关->服务->网关->服务的这种性质的每个请求-> 网关 -> 客户端),从而将最大吞吐量减半。
    猜你喜欢
    • 2020-07-17
    • 2018-02-01
    • 2018-10-04
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    相关资源
    最近更新 更多