Kubernetes和Spring Boot @Service负载平衡

时间:2019-10-21 21:39:29

标签: spring-boot kubernetes openfeign

我有在两个节点上运行的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的,而且由于我同时调试两个节点,所以我没有注意到这一点。

1 个答案:

答案 0 :(得分: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。

相关问题