负载平衡(功能区)和路由(zuul)Spring REST API(Spring Data JPA)请求同一服务的多个副本

cor*_*ase 3 rest spring jpa load-balancing spring-boot

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

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

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

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

application.yml

例:

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

zuul:
  routes:
    data:
      path: /db/**
      ServiceId: DatabaseAPI
Run Code Online (Sandbox Code Playgroud)

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

小智 6

默认情况下,Zuul使用功能区来定位要通过发现转发的实例(例如,在您的情况下为Eureka).因此,在Gateway应用程序(Zuul)中,您不需要在类路径中使用Ribbon.

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


peg*_*sus 5

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

尤里卡服务器

bootstrap.properties

spring.application.name=eureka-server
Run Code Online (Sandbox Code Playgroud)

application.properties

server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
Run Code Online (Sandbox Code Playgroud)

尤里卡服务器

@EnableEurekaServer
@SpringBootApplication
public class EurekaServer {

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

}
Run Code Online (Sandbox Code Playgroud)

微服务项目

bootstrap.properties

spring.application.name=microservice
Run Code Online (Sandbox Code Playgroud)

application.properties

server.port=8081
Run Code Online (Sandbox Code Playgroud)

应用程序

@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";
    }

}
Run Code Online (Sandbox Code Playgroud)

微服务网关

bootstrap.properties

spring.application.name=microservice-gateway
Run Code Online (Sandbox Code Playgroud)

application.properties

server.port=9090
Run Code Online (Sandbox Code Playgroud)

MsGatewayApplication

@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class MsGatewayApplication {

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

}
Run Code Online (Sandbox Code Playgroud)

注意,在此微服务网关项目中,您必须对类路径具有Ribbon依赖项。

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

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

当您访问此URL http:// localhost:9090 / microservice /时,您将交替获得响应:端口:8081上的微服务,端口:8082上的微服务(这意味着Ribbon使用循环算法调用两个实例)