0

我让 Kubernetes 在两个节点上运行,一个应用程序部署在两个节点上(两个 pod,每个节点一个)。

这是一个 Spring Boot 应用程序。它使用 OpenFeign 来实现服务可发现性。在应用程序中,我定义了一个 RestController,它有一些 API 和一个从 API 内部调用的 @Autowired @Service。

每当我对其中一个 API 发出请求时,Kubernetes 都会使用某种负载平衡将流量路由到其中一个 pod,然后调用应用程序 RestController。这很好,我希望这是负载平衡的。

一旦调用该 API 并调用 @Autowired @Service,就会出现问题。不知何故,这也得到了负载平衡,并且对 @Service 的调用可能最终在另一个节点上。

继承人和例子:

  • 我们有两个节点:node1,node2
  • 我们向 node1 的 IP 地址发出请求。
    • 这可能会负载平衡到 node2(这很好)
  • node1 获取请求并调用@Autowired @Service
  • 调用跳转到 node2(这是问题发生的地方)

在代码中:
控制器:

 @Autowired
 private lateinit var userService: UserService
 @PostMapping("/getUser")
   fun uploadNewPC(@RequestParam("userId") userId: String): User {
       println(System.getEnv("hostIP")) //123.45.67.01
       return userService.getUser(userId)
   }

服务:

@Service
class UserService {
  fun getUser(userId: String) : User {
   println(System.getEnv("hostIP")) //123.45.67.02
   ...
  }
}

我希望负载平衡仅发生在 REST 请求上,而不是应用程序对其 @Service 组件的内部调用。我将如何实现这一目标?Spring Boot 的 @service 组件在 Kubernetes 集群中的运行方式是否有任何配置?我可以改变这个吗?

提前致谢。

编辑:
经过一些调试,我发现负载平衡到另一个节点的不是服务,而是初始http请求。即使请求是专门发送到 node1 的 url ... 由于我同时调试两个节点,我没有注意到这一点。

4

1 回答 1

1

好吧,我没有使用过 openfeign,但据我了解,它确实只能对 REST 请求进行负载平衡。

如果我的问题是正确的,您会说当 REST 控制器调用服务组件(在这种情况下为 UserService)时,会发出网络调用,这是不可取的。

在这种情况下,我相信以下几点考虑将是有益的:

  1. Spring Boot 默认情况下与此级别的负载均衡无关,它应该以某种方式在 Spring Boot 应用程序中进行配置。

  2. 这也与此应用程序在 Kubernetes 环境中运行这一事实无关,同样它只是一个 Spring Boot 配置。

  3. 假设你有一个UserService明显没有任何负载均衡逻辑的接口,spring boot 必须将它包装到某种代理中来添加这些功能。所以尝试调试应用程序启动,在控制器方法中放置一个断点并检查用户服务的实际类型,再次它必须是某种代理

  4. 如果 3 中的假设是正确的,则必须在应用程序上下文中注册某种 bean 后处理器(可能在某些依赖项的 spring.factories 文件中)类。如果您将创建一些自定义方法来打印所有 bean(Bean Post Processor 也是一个 bean),您可能会看到可疑的 bean。

于 2019-10-22T14:58:31.347 回答