【问题标题】:Load balancing (ribbon) and routing (zuul) Spring REST API (Spring Data JPA) requests to multiple copies of same service负载平衡 (ribbon) 和路由 (zuul) Spring REST API (Spring Data JPA) 请求到同一服务的多个副本
【发布时间】:2017-01-15 19:06:21
【问题描述】:

我似乎找不到以下场景的明确示例/解决方案;任何帮助/信息将不胜感激!

我有一个 Spring REST API 服务,它使用 Spring Data JPA 连接到后端数据库服务器。我在多台机器上运行这个完全相同的服务,并且我有一个反向代理,它将客户端请求(使用 Netflix Zuul)路由到这些 API 服务,以便访问数据库中的数据。但是,我想对请求进行负载平衡(通过反向代理和可能的 Netflix 功能区),以便每个请求仅发送到单个 API 服务器(以负载平衡的方式)。

Spring Data JPA 根据我定义的实体类和其余存储库自动配置端点。一种解决方案是在反向代理上为 API 服务上的每个端点生成一个等效端点,然后使用 Ribbon 客户端分别对每个端点进行负载平衡。但是,这似乎不是合适的解决方案。

我的问题是,Netflix Zuul 或 Ribbon 是否提供任何功能来处理这种情况?本质上,我希望能够设置一个 YAML 配置,它只是告诉 Zuul 使用功能区客户端并根据可用的 listOfServers 功能区配置自动将所有请求负载平衡到给定端点。

application.yml

例子:

DatabaseAPI:
  ribbon:
    eureka:
      enabled: false
  listOfServers: localhost:8080, localhost:8181, localhost:8282
  ServerListRefreshInterval: 15000

zuul:
  routes:
    data:
      path: /db/**
      ServiceId: DatabaseAPI

现在,例如,我希望 /db/** 的每个请求都以循环方式发送到服务器列表中的一个可用服务器。注意:使用此示例配置,每个请求都会同时发送到所有可用服务器。我只希望其中一个接收每个请求。

【问题讨论】:

  • 我也遇到了同样的难题,你找到解决办法了吗?
  • 除了我在上面的问题中建议的有点不合理的可能解决方案之外,不,我还没有找到一个好的解决方案!我暂时把它放在一边,但我希望能尽快找到解决方案。

标签: spring rest jpa spring-boot load-balancing


【解决方案1】:

默认情况下,Zuul 使用 Ribbon 来定位要通过发现转发到的实例(例如,在您的情况下是 Eureka)。因此,在网关应用程序 (Zuul) 中,您不需要在类路径中有 Ribbon。

如果您没有通过 Zuul 看到实例之间的负载平衡,请尝试增加请求(例如 > 200 个请求)

【讨论】:

    【解决方案2】:

    我发现这实际上是为你自动配置的,如果你在类路径上有 Zuul 和 Ribbon。基本上,我创建了三个这样的项目:

    尤里卡服务器

    bootstrap.properties

    spring.application.name=eureka-server
    

    application.properties

    server.port=8761
    eureka.client.register-with-eureka=false
    eureka.client.fetch-registry=false
    

    尤里卡服务器

    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaServer {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaServer.class, args);
        }
    
    }
    

    微服务项目

    bootstrap.properties

    spring.application.name=microservice
    

    application.properties

    server.port=8081
    

    MsApplication

    @SpringBootApplication
    @EnableDiscoveryClient
    public class MsApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MsApplication.class, args);
        }
    
    }
    
    @RestController
    class DummyController {
    
        @Value("${server.port}")
        private int serverPort;
    
        @GetMapping("/")
        public String home() {
            return "Microservice on port: " + serverPort;
        }
    
        @GetMapping("/test")
        public String someLogic() {
            return "Some hard stuff is done here";
        }
    
    }
    

    微服务网关

    bootstrap.properties

    spring.application.name=microservice-gateway
    

    application.properties

    server.port=9090
    

    MsGatewayApplication

    @EnableZuulProxy
    @EnableDiscoveryClient
    @SpringBootApplication
    public class MsGatewayApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MsGatewayApplication.class, args);
        }
    
    }
    

    注意在这个microservice-gateway 项目中,您的类路径必须具有 Ribbon 依赖项。

    要运行第二个微服务实例,请使用以下命令:

    java -jar -Dserver.port=8082 -Deureka.instance.metadataMap.instanceId=INSTANCE2 microservice-0.0.1-SNAPSHOT.jar

    当您点击此网址 http://localhost:9090/microservice/ 时,您将交替收到响应:端口上的微服务:8081,端口上的微服务:8082(这意味着 Ribbon 使用循环算法调用这两个实例)

    【讨论】:

    • 他的问题中没有任何内容表明他正在使用 Eureka;事实上,他明确禁用了它ribbon.eureka.enabled=false
    • 尽管他禁用了它,但 pegasus 仍试图解释循环行为。这就是问题所在。
    【解决方案3】:

    如果我没记错的话,“您希望其中一个接收每个请求”,您为什么不使用 Zuul 过滤器(预过滤器)来处理这个问题。对于上述答案,我还想澄清一件事

    Please check this link for detail

    【讨论】:

      猜你喜欢
      • 2012-06-01
      • 2016-04-17
      • 1970-01-01
      • 2019-11-23
      • 1970-01-01
      • 2022-11-04
      • 1970-01-01
      • 2020-10-25
      • 1970-01-01
      相关资源
      最近更新 更多