使用 Netflix Eureka 和 Ribbon 客户端负载均衡器进行服务发现

x33g5p2x  于2022-09-29 转载在 其他  
字(9.7k)|赞(0)|评价(0)|浏览(227)

Spring Cloud Netflix 通过自动配置和绑定到 Spring 环境为 Spring Boot 应用程序提供简单的云集成。

通过添加一些简单的注释,您可以快速利用和配置应用程序中的常见模式,并使用 Netflix 组件构建大型分布式系统。在本教程中,我们将介绍服务发现 (Eureka) 和客户端负载平衡 (Ribbon)。

使用 Netflix Eureka 进行服务发现

通过使用 Netflix Eureka,您可以在云环境中注册多个服务。这些服务的注册实例充当服务器并将其状态复制到连接的对等客户端。 Netflix Eureka 使用负载平衡算法管理对服务实例的请求。客户端检索服务注册表的所有连接实例的列表,并使用负载平衡算法将负载分配给这些实例,例如客户端负载平衡 (Ribbon)。

让我们首先实现服务器端服务注册表(Eureka Server)。打开终端(或使用 Spring Initializr)并创建一个具有以下依赖项的项目:

spring init -n eureka-server -dcloud-eureka-server

将添加以下依赖项:

<properties>     <java.version>1.8</java.version>     <spring-cloud.version>Greenwich.SR2</spring-cloud.version>   </properties>    <dependencies>     <dependency>       <groupId>org.springframework.cloud</groupId>       <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>     </dependency>      <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-test</artifactId>       <scope>test</scope>     </dependency>   </dependencies>    <dependencyManagement>     <dependencies>       <dependency>         <groupId>org.springframework.cloud</groupId>         <artifactId>spring-cloud-dependencies</artifactId>         <version>${spring-cloud.version}</version>         <type>pom</type>         <scope>import</scope>       </dependency>     </dependencies>   </dependencyManagement>

现在通过在主 Spring Boot 应用程序类中使用 @EnableEurekaServer 注释来启用 Eureka 服务器,该类也使用 @SpringBootApplication 注释进行注释。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

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

这就是配置 Eureka Server 所需的全部内容。在配置方面,在 application.yml 中定义以下属性:

eureka:   client:     registerWithEureka: false     fetchRegistry: false server:   port: 8761
  • registerWithEureka:如果我们将此属性设置为 true,那么在服务器启动时,内置客户端将尝试向 Eureka 服务器注册自己。
  • fetchRegistry:如果我们将此属性配置为 true,内置客户端将尝试获取 Eureka 注册表。
Replica node URL:  http://localhost:8761/eureka/  Changing status to UP Started Eureka Server Tomcat started on port(s): 8761 (http) with context path '' Updating port to 8761

我们可以将浏览器指向 http://localhost:8761 以查看 Eureka 仪表板,如下所示:

实施服务发现——Eureka 客户端

现在我们已经启动了 Eureka,我们将添加一个 Eureka Client。 为此,创建一个具有以下依赖项的项目:

spring init -n eureka-client -dcloud-eureka,web

将添加以下依赖项:

<properties>     <java.version>1.8</java.version>     <spring-cloud.version>Greenwich.SR2</spring-cloud.version>   </properties>    <dependencies>     <dependency>       <groupId>org.springframework.cloud</groupId>       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>     </dependency>      <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-web</artifactId>     </dependency>     <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-test</artifactId>       <scope>test</scope>     </dependency>   </dependencies>    <dependencyManagement>     <dependencies>       <dependency>         <groupId>org.springframework.cloud</groupId>         <artifactId>spring-cloud-dependencies</artifactId>         <version>${spring-cloud.version}</version>         <type>pom</type>         <scope>import</scope>       </dependency>     </dependencies>   </dependencyManagement>

向 Eureka 注册客户端意味着客户端提供自己的元信息(主机名、端口、健康指标 URL 和主页)。每个服务实例都会向 Eureka 服务器发送心跳消息;如果 Eureka 在可配置的时间表内没有收到心跳,则从注册表中删除该实例。

现在让我们通过添加注释 @EnableEurekaClient 使 Application 类成为 Eureka 客户端:

package com.example.eurekaclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

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

然后我们将创建一个向客户端注册的 REST 服务:

package com.example.eurekaclient;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
  @GetMapping("/hello")
  public String sayHello() {
    return "Hello World from EurekaClient!";
  }
}

现在让我们为这个客户端应用程序添加 application.yml 配置文件,如下所示:

spring:   application:     name: spring-cloud-eureka-client  server:   port: 8180  eureka:   client:     service-url:       default-zone: ${EUREKA_URI:http://localhost:8761/eureka}   instance:     prefer-ip-address: true

启动应用程序。您应该在 Eureka 服务器控制台上看到该服务已注册:

2019-09-02 19:54:43.424  INFO 32676 --- [nio-8761-exec-2] c.n.e.registry.AbstractInstanceRegistry  : Registered instance SPRING-CLOUD-EUREKA-CLIENT/fedora.station:spring-cloud-eureka-client:8180 with status UP (replication=false) 2019-09-02 19:54:44.063  INFO 32676 --- [nio-8761-exec-3] c.n.e.registry.AbstractInstanceRegistry  : Registered instance SPRING-CLOUD-EUREKA-CLIENT/fedora.station:spring-cloud-eureka-client:8180 with status UP (replication=true) 2019-09-02 19:54:50.596  INFO 32676 --- [a-EvictionTimer] c.n.e.registry.AbstractInstanceRegistry  : Running the evict task with compensationTime 0ms

相反,在客户端控制台上:

[nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SPRING-CLOUD-EUREKA-CLIENT/fedora.station:spring-cloud-eureka-client:8180 - registration status: 204 2019-09-02 19:55:13.258  INFO 576 --- [freshExecutor-0] com.netflix.discovery.DiscoveryClient    : Disable delta property : false

如果您浏览到 http://localhost:8761 以查看 Eureka 仪表板,您应该会看到已发现的客户端:

使用 Netflix Ribbon 的客户端负载平衡

客户端负载平衡用于平衡对微服务的请求。实施客户端负载平衡提供了一种跨多个实例分配负载的方法。发现服务器返回这些多个实例的位置。这些实例仅用于弹性和负载共享,但客户端只需要选择一个服务实例。 Ribbon 是一个客户端负载均衡器,可让您对 HTTP 和 TCP 客户端的行为进行大量控制。

我们可以按如下方式引导功能区云应用程序:

spring init -n client-ribbon -dthymeleaf,web,cloud-ribbon,cloud-eureka

将添加以下依赖项:

<properties>     <java.version>1.8</java.version>     <spring-cloud.version>Greenwich.SR2</spring-cloud.version>   </properties>    <dependencies>     <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-thymeleaf</artifactId>     </dependency>     <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-web</artifactId>     </dependency>     <dependency>       <groupId>org.springframework.cloud</groupId>       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>     </dependency>     <dependency>       <groupId>org.springframework.cloud</groupId>       <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>     </dependency>      <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-test</artifactId>       <scope>test</scope>     </dependency>   </dependencies>    <dependencyManagement>     <dependencies>       <dependency>         <groupId>org.springframework.cloud</groupId>         <artifactId>spring-cloud-dependencies</artifactId>         <version>${spring-cloud.version}</version>         <type>pom</type>         <scope>import</scope>       </dependency>     </dependencies>   </dependencyManagement>

我们的应用程序将包含 @EnableEurekaClient 以及 @LoadBalanced,,它被放置在一个返回 RestTemplate 实例的方法上:

package com.example.ribbonclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

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

  @Bean
  @LoadBalanced
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }
}

RestTemplate 自动装配在以下 Service 类中,它将请求绑定到我们刚刚注册的 Eureka Client:

package com.example.ribbonclient.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class HelloServiceClient {
  @Autowired @LoadBalanced RestTemplate restTemplate;

  public String sayHello() {
    return restTemplate.getForObject("http://SPRING-CLOUD-EUREKA-CLIENT/hello", String.class);
  }
}

最后,我们包含一个简单的控制器,它使 Ribbon 客户端平衡器在“/hello”映射中可用:

package com.example.ribbonclient.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.ribbonclient.service.HelloServiceClient;

@Controller
public class HelloController {
  @Autowired HelloServiceClient helloServiceClient;

  @GetMapping("/hello")
  String sayHello(ModelMap model) {
    model.put("message", helloServiceClient.sayHello());
    return "hello";
  }
}

我们还将包含一个静态的 hello.html,它将消息文本显示为 thymeleaf 标记:

<html xmlns:th="http://www.thymeleaf.org">
         
    <body>
                 
        <h2 th:text="${message}"></h2>
             
    </body>
     
</html>

最后一条信息是 Ribbon 客户端的 application.yml 文件:

spring:   application:     name: spring-cloud-ribbon-client  server:   port: 8181  eureka:   client:     service-url:       default-zone: ${EUREKA_URI:http://localhost:8761/eureka}   instance:     prefer-ip-address: true

现在运行这个客户端应用程序并在 http://localhost:8761/ 打开浏览器:

如您所见,在 Eureka Dashboard 上,有两个服务注册为 SPRING-CLOUD-EUREKA-CLIENT 和 SPRING-CLOUD-RIBBON-CLIENT。

运行此示例后,我们将打开浏览器并转到 http://localhost:8181/hello,它应该显示如下内容:

恭喜!您刚刚设法使用 LoadBalancer Ribbon Client 运行了您的 Eureka Client-Server 应用程序。在下一个教程中,我们将展示如何使用 Feign 客户端来简化 Netflix 客户端的创建:NetFlix Feign 客户端入门本文的源代码位于:https://github.com/fmarchioni/masterspringboot/tree/master/cloud/eureka

相关文章