【Eureka】Eureka 介绍与实战

1. Eureka 简介

Eureka 是 Netflix 开发的一个服务注册和发现组件,主要用于微服务架构中。它的核心功能是帮助微服务之间进行通讯和管理,使得服务能够动态地发现彼此,实现灵活的服务调用和负载均衡。

1.1 核心概念

  • 服务注册中心(Eureka Server):这是一个中央注册中心,所有微服务实例都会将自己的信息注册到这个中心,并定期发送心跳来维持其租约。
  • 服务提供者(Service Provider):提供服务的应用,在启动时向 Eureka Server 注册自己,并定期续租。可以是 SpringBoot 应用或其他技术实现,只要对外提供的是Rest风格服务即可。
  • 服务消费者(Service Consumer):使用服务的应用,通过 Eureka Server 查找可用的服务实例。消费应用从注册中心获取服务列表,从而得知每个服务方的信息,知道去哪里调用服务方。

1.2 工作流程

  1. 服务注册:服务实例启动时,会向 Eureka Server 注册自己的信息,包括服务名、IP地址、端口号等。
  2. 服务续租:服务实例定期(默认30秒)向 Eureka Server 发送心跳,以续租其租约。
  3. 服务注销:服务实例关闭时,会向 Eureka Server 发送注销请求。Eureka Server将此实例从注册列表中移除。
  4. 获取服务列表:服务消费者会从 Eureka Server 获取服务列表,并根据负载均衡策略选择一个服务实例进行调用。

1.3 高可用

Eureka Server 支持集群部署,多个 Eureka Server 实例相互注册,形成高可用的服务注册中心。

1.4 主要特点

  • 开源:Eureka 是开源的,可以免费使用和修改。
  • 可靠性:具有内置的容错机制,能够在服务器崩溃时保持可用。
  • 动态性:服务实例可以动态地注册和注销,适应服务的动态变化。
  • 易于集成:可以轻松地与 Spring Cloud 等框架集成。
  • 基于 RESTful:使用 RESTful API,可以与其他基于 HTTP 的服务轻松集成。
    通过使用 Eureka,可以实现以下功能:
  • 服务注册:每个微服务实例在启动时会自动将自己的信息注册到 Eureka Server。
  • 服务发现:服务可以通过 Eureka Client 查询 Eureka Server 来获取可用服务的列表。
  • 负载均衡:Eureka Client 提供了简单的轮询负载均衡策略。
  • 故障转移:如果某个服务实例出现故障,Eureka Client 会自动检测并从服务列表中移除这个实例。

Eureka 是一个强大而可靠的服务注册与发现工具,适用于云原生应用和微服务架构,能够提高系统的可用性和可伸缩性。

2. Eureka 故障处理

处理服务实例故障通常涉及以下几个步骤:

  1. 健康检查
    • 服务端检查:服务实例应定期向服务注册中心(如Eureka Server)发送心跳,表明自己处于健康状态。如果服务实例无法在预定时间内发送心跳,注册中心可能会将其标记为不健康或已下线。
    • 客户端检查:客户端在调用服务之前,可以执行健康检查,以确认服务实例是否可用。
  2. 故障检测
    • 超时检测:客户端在尝试与服务实例通信时,如果发生超时,可以认为服务实例可能出现了故障。
    • 异常检测:服务实例在处理请求时,如果抛出异常,可以根据异常类型和频率来判断服务是否出现故障。
  3. 服务下线
    • 当服务实例被检测到故障时,应该从服务注册中心下线,以避免其他客户端继续尝试调用这个故障实例。
  4. 重试机制
    • 客户端在调用服务时,如果遇到故障,可以实施重试机制,尝试其他服务实例。
  5. 负载均衡
    • 当某个服务实例故障时,负载均衡器应该能够检测到这一点,并停止向这个实例发送请求,而是将请求分发到其他健康的实例。
  6. 熔断机制
    • 当服务实例持续故障,可以启用熔断机制,暂时停止对故障服务的调用,防止系统雪崩。
  7. 故障通知
    • 系统应具备故障通知机制,当服务实例出现故障时,及时通知运维人员。
  8. 自动恢复
    • 对于可以自动恢复的故障(如临时网络问题),系统应能在问题解决后自动重新注册服务实例。
  9. 日志记录和监控
    • 记录详细的日志信息,以便分析故障原因。
    • 通过监控系统实时监控服务状态,一旦发现异常立即采取措施。
  10. 人工干预
    • 对于无法自动恢复的故障,需要人工介入进行问题排查和修复。

在微服务架构中,服务注册与发现组件(如Eureka)通常会提供上述大部分功能,以帮助自动处理服务实例的故障。通过这些机制,可以大大提高系统的稳定性和可用性。

3. Eureka 三种负载均衡策略

3.1 默认负载均衡策略

Eureka 与 Ribbon 结合使用时,Ribbon作为客户端负载均衡器,确实有一个默认的负载均衡策略。默认情况下,Ribbon 使用的是RoundRobinRule策略,这是一种简单的轮询策略,它会按照顺序逐一将请求分配到各个服务实例上。

这意味着如果你没有在配置文件中显式指定负载均衡策略,Ribbon 将默认使用RoundRobinRule。这种策略在大多数情况下都能提供基本的负载均衡功能,确保请求在各个服务实例之间均匀分布。

如果你想要查看或修改默认的负载均衡策略,可以在 Spring Cloud 应用的配置文件(application.propertiesapplication.yml)中进行设置。例如,下面是如何在application.yml中显式设置默认轮询策略的示例:

yaml 复制代码
ribbon:
  eureka:
    enabled: true
  NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

尽管这里显式设置了默认策略,实际上即使不设置,Ribbon 也会默认使用RoundRobinRule。如果你想要使用其他策略,只需要将NFLoadBalancerRuleClassName的值改为其他策略的实现类即可。

3.2 随机负载均衡策略

要设置 Ribbon 的随机负载均衡策略,你需要修改 Spring Cloud 应用的配置文件,指定使用RandomRule类作为负载均衡规则。以下是具体的步骤和示例:

  1. 添加Ribbon依赖

    确保你的 Spring Boot 项目已经包含了 Spring Cloud Ribbon 的依赖。在pom.xmlbuild.gradle文件中,你应该看到如下依赖:

    Maven示例:

    xml 复制代码
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
  2. 配置Ribbon

    在你的应用配置文件(通常是application.propertiesapplication.yml)中,设置NFLoadBalancerRuleClassName属性为com.netflix.loadbalancer.RandomRule

    application.yml配置示例:

    yaml 复制代码
    ribbon:
      eureka:
        enabled: true  # 确保Eureka用于服务发现
      NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  # 设置随机负载均衡策略

    如果你使用的是application.properties格式,配置将如下所示:

    properties 复制代码
    ribbon.eureka.enabled=true
    ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
  3. 重启应用

    修改配置后,你需要重启你的Spring Boot应用,以便新的配置生效。

使用RandomRule后,Ribbon 将随机选择服务实例来处理请求,而不是按照轮询或其他规则。这适用于当你想要在服务实例之间实现真正的随机分布请求时。

Warning: 如果你在使用 Spring Cloud Finchley 或更高版本,Ribbon 已经被重新设计为通过 Spring Cloud Commons 中的LoadBalancerClient接口工作,此时配置方式可能会有所不同。在这种情况下,你可能需要使用@LoadBalanced注解来创建一个RestTemplateWebClient,并使用相应的负载均衡策略。

3.3 自定义负载均衡策略

在 Spring Cloud 中,Eureka 通常与 Ribbon 结合使用来实现客户端的负载均衡。Ribbon 是一个客户端负载均衡器,它可以与 Eureka 配合工作,根据 Eureka 中注册的服务列表来选择调用的服务实例。以下是如何配置 Eureka 的负载均衡策略的基本步骤:

  1. 添加依赖

    在你的Spring Boot应用的pom.xmlbuild.gradle文件中,确保你已经添加了Spring Cloud Eureka和Spring Cloud Ribbon的依赖。

    Maven示例:

    xml 复制代码
    <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>
  2. 配置Ribbon

    在你的应用配置文件(如application.propertiesapplication.yml)中,你可以设置Ribbon的负载均衡策略。

    示例配置:

    yaml 复制代码
    # application.yml
    ribbon:
      eureka:
        enabled: true  # 启用Eureka来获取服务列表
      NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule  # 负载均衡策略

    这里NFLoadBalancerRuleClassName是配置负载均衡规则的关键。以下是一些常用的负载均衡规则:

    • com.netflix.loadbalancer.RoundRobinRule:轮询策略,默认策略。
    • com.netflix.loadbalancer.RandomRule:随机策略。
    • com.netflix.loadbalancer.AvailabilityFilteringRule:会过滤掉故障实例和那些高并发连接的实例。
    • com.netflix.loadbalancer.WeightResponseTimeRule:根据响应时间加权选择服务器。
    • com.netflix.loadbalancer.BestAvailableRule:选择并发请求最小的服务器。
  3. 自定义负载均衡策略

    如果你需要自定义负载均衡策略,可以创建一个类实现IRule接口,然后配置你的应用使用这个类。

    示例代码:

    java 复制代码
    public class MyCustomRule extends AbstractLoadBalancerRule {
        @Override
        public Server choose(Object key) {
            // 自定义选择逻辑
            return null;
        }
        @Override
        public void initWithNiwsConfig(IClientConfig clientConfig) {
            // 初始化配置
        }
    }

    然后在配置文件中指定你的自定义规则:

    yaml 复制代码
    ribbon:
      NFLoadBalancerRuleClassName: com.example.MyCustomRule

通过以上步骤,你可以配置和自定义 Eureka 客户端的负载均衡策略,以适应特定需求。

4. Eureka 实践

下面将展示如何使用Eureka搭建一个简单的服务注册与发现环境。

1. 创建 Eureka Server

使用 Spring Initializr 创建一个 Spring Boot 项目,并添加 Eureka Server 依赖。

xml 复制代码
<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

在主类上添加@EnableEurekaServer注解。

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

配置文件中设置 Eureka Server 的端口和其他属性。

yaml 复制代码
# application.yml
server:
  port: 8761
eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
2. 创建服务提供者

创建另一个 Spring Boot 项目,并添加 Eureka Client 依赖。

xml 复制代码
<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

在主类上添加@EnableDiscoveryClient注解。

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceProviderApplication.class, args);
    }
}

配置文件中指定 Eureka Server 的地址。

yaml 复制代码
# application.yml
spring:
  application:
    name: service-provider
server:
  port: 8080
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
3. 创建服务消费者

创建另一个 Spring Boot 项目,添加 Eureka Client 和 Web依赖。

xml 复制代码
<!-- pom.xml -->
<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>

在主类上添加@EnableDiscoveryClient注解,并创建一个 REST 控制器。

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceConsumerApplication.class, args);
    }
}
@RestController
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/greeting")
    public String getGreeting() {
        // 假设服务提供者有一个/greeting的端点
        return restTemplate.getForObject("http://service-provider/greeting", String.class);
    }
}

配置文件中指定 Eureka Server 的地址。

yaml 复制代码
# application.yml
spring:
  application:
    name: service-consumer
server:
  port: 8081
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

确保在ConsumerController中注入了RestTemplate,并在其上添加了@LoadBalanced注解,以启用负载均衡功能。

java 复制代码
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}
4. 启动服务

按照以下顺序启动服务:

  1. 启动Eureka Server :运行EurekaServerApplication的主类。
  2. 启动服务提供者 :运行ServiceProviderApplication的主类,并确保它成功注册到 Eureka Server。
  3. 启动服务消费者 :运行ServiceConsumerApplication的主类。
5. 测试服务发现和调用

一旦所有服务都启动并运行,你可以测试服务消费者是否能够发现服务提供者并调用其 API。

  1. 打开浏览器,访问 Eureka Server 的仪表板:http://localhost:8761/。你应该能看到注册的服务列表,包括SERVICE-PROVIDERSERVICE-CONSUMER
  2. 访问服务消费者的端点:http://localhost:8081/greeting。如果一切配置正确,你应该会看到服务提供者返回的响应。
6. 注意事项
  • 心跳续租 :服务提供者必须定期发送心跳来续租其在 Eureka Server 上的租约。如果 Eureka Server 在90秒内没有接收到服务提供者的心跳,它会将该实例从其注册列表中移除。
  • 自我保护模式:在特定情况下,Eureka Server 可能会进入自我保护模式,这会阻止它注销那些没有发送心跳的服务实例。这是为了在网络分区或服务中断期间保持系统的稳定性。
  • 实例元数据:服务实例可以在注册时提供额外的元数据,这些元数据可以在服务发现时被消费者使用。

通过上述步骤,我们进行了 Eureka 的基本使用,并了解了它在微服务架构中的作用。Eureka 使得服务之间的发现和调用变得更加灵活和可靠,是构建分布式系统的重要组件之一。

相关推荐
Linux运维老纪3 小时前
DNS缓存详解(DNS Cache Detailed Explanation)
计算机网络·缓存·云原生·容器·kubernetes·云计算·运维开发
Elastic 中国社区官方博客17 小时前
使用 Ollama 和 Kibana 在本地为 RAG 测试 DeepSeek R1
大数据·数据库·人工智能·elasticsearch·ai·云原生·全文检索
Linux运维老纪1 天前
windows部署deepseek之方法(The Method of Deploying DeepSeek on Windows)
linux·人工智能·分布式·云原生·运维开发·devops
Elastic 中国社区官方博客1 天前
Elastic Cloud Serverless 获得主要合规认证
大数据·数据库·elasticsearch·搜索引擎·云原生·serverless·全文检索
超级阿飞2 天前
在K8s中部署动态nfs存储provisioner
云原生·容器·kubernetes·nfs
赵渝强老师2 天前
【赵渝强老师】K8s中Pod探针的TCPSocketAction
云原生·容器·kubernetes
努力的小T2 天前
Linux二进制部署K8s集群的平滑升级教程
linux·运维·服务器·云原生·容器·kubernetes·云计算
2的n次方_2 天前
Eureka 服务注册和服务发现的使用
spring boot·spring cloud·云原生·eureka·服务发现
赵渝强老师3 天前
【赵渝强老师】K8s中Pod探针的ExecAction
云原生·容器·kubernetes
vibag3 天前
Kubernetes(一)
java·云原生·容器·kubernetes