注册中心
Netflix公司

想必鱿鱼游戏,各位多少也看过,就是这家视频公司的节目。
1、Netflix是一家做视频的网站,可以这么说该网站上的美剧应该是最火的。
2、Netflix是一家没有CTO的公司,正是这样的组织架构能使产品与技术无缝的沟通,从而能快速迭代出更优秀的产品。在当时软件敏捷开发中,Netflix的更新速度不亚于当年的微信后台变更,虽然微信比Netflix迟发展,但是当年微信的灰度发布和敏捷开发应该算是业界最猛的。
3、Netflix由于做视频的原因,访问量非常的大,从而促使其技术快速的发展在背后支撑着,也正是如此,Netflix开始把整体的系统往微服务上迁移。
4、Netflix的微服务做的不是最早的,但是确是最大规模的在生产级别微服务的尝试。也正是这种大规模的生产级别尝试,在服务器运维上依托AWS云。当然AWS云同样受益于Netflix的大规模业务不断的壮大。
5、Netflix的微服务大规模的应用,在技术上毫无保留的把一整套微服务架构核心技术栈开源了出来,叫做Netflix OSS,也正是如此,在技术上依靠开源社区的力量不断的壮大。
6、Spring Cloud是构建微服务的核心,而Spring Cloud是基于Spring Boot来开发的。
7、Pivotal在Netflix开源的一整套核心技术产品线的同时,做了一系列的封装,就变成了Spring Cloud;虽然Spring Cloud到现在为止不只有Netflix提供的方案可以集成,还有很多方案,但Netflix是最成熟的。

两家java重度用户的公司,也是龙头。
springcloud和netflix
Spring Cloud 和 Netflix 是两个相关的概念,它们在构建和部署分布式系统和微服务架构方面发挥了重要作用。
Spring Cloud 是由Spring Framework社区提供的一组开源工具和库,用于构建和部署分布式系统和微服务架构。它提供了各种功能,包括服务发现、负载均衡、断路器、配置管理和消息传递等。Spring Cloud 的目标是简化分布式系统的开发和管理,使开发人员能够更轻松地构建具有高可用性、弹性和可扩展性的应用程序。
Netflix 是一个知名的在线娱乐平台,拥有许多流行的视频服务,例如Netflix影片流媒体服务。Netflix 开发了许多用于构建高可用性和弹性分布式系统的开源工具和框架。这些工具和框架包括Eureka、Ribbon、Hystrix、Zuul等,它们被广泛应用于构建和管理微服务架构。这些 Netflix 的开源项目提供了服务注册与发现、负载均衡、故障容错和API网关等功能。
Spring Cloud 与 Netflix 的关系是,Spring Cloud 基于 Netflix 的开源项目构建了一系列的抽象和封装,使得开发者可以更方便地使用 Netflix 的工具和框架。例如,Spring Cloud 使用 Eureka 作为默认的服务发现组件,使用 Ribbon 进行负载均衡,使用 Hystrix 实现断路器模式等。通过使用 Spring Cloud,开发者可以利用 Netflix 的强大工具集,更容易地构建和管理微服务架构。
总结一下,Spring Cloud 是一个用于构建和部署分布式系统和微服务的开源框架,而 Netflix 则是提供了一系列用于构建高可用性和弹性分布式系统的开源工具和框架。Spring Cloud 基于 Netflix 的工具和框架,提供了更方便的使用方式,并简化了分布式系统的开发和管理过程。
框架版本
本课程基于SpringBoot 2.3.6.RELEASE 和Spring Cloud Hoxton.SR9 版本
Spring Boot 2.3.6.RELEASE 和 Spring Cloud Hoxton.SR9 是两个版本号,分别代表了 Spring Boot 和 Spring Cloud 的特定版本。
Spring Boot 是一个用于简化和加速 Spring 应用程序开发的框架。它提供了自动配置、约定优于配置和快速启动等特性,使开发人员能够更快地构建独立的、可扩展的 Spring 应用程序。Spring Boot 的版本号是以 x.y.z.RELEASE 的形式命名,其中 x、y、z 分别表示主版本号、次版本号和修订号。例如,2.3.6.RELEASE 表示 Spring Boot 的主版本号为2,次版本号为3,修订号为6,RELEASE 表示这是一个正式发布的稳定版本。
Spring Cloud 是构建分布式系统和微服务架构的框架集合,它提供了各种功能和工具,如服务发现、负载均衡、断路器、配置管理等。Spring Cloud 的版本号使用命名风格为 x.y.z.SRn,其中 x、y、z 与 Spring Boot 保持一致,SRn 表示 Spring Cloud 的服务版本号。例如,Hoxton.SR9 表示 Spring Cloud 的主版本号为Hoxton,服务版本号为9。
理解微服务架构
微服务组件如下
Zuul server
Zuul Server 是 Netflix 开源的一个基于 JVM 的边缘服务网关,它是 Netflix Zuul 的一部分,用于构建和管理微服务架构中的 API 网关。
API 网关是位于客户端和后端微服务之间的中间层,它充当了请求的入口和出口,提供了一系列功能,如路由、负载均衡、安全认证、监控、限流等。API 网关能够将客户端的请求转发到后端的微服务,并对请求进行处理和过滤。
Zuul Server 提供了以下主要功能:
- 路由和转发:Zuul Server 可以根据预定义的路由规则将请求转发到相应的后端微服务。
- 负载均衡:Zuul Server 支持负载均衡,可以将请求均衡地分发到多个实例或副本中。
- 过滤和拦截:Zuul Server 可以在请求到达后端服务之前或响应返回客户端之前对请求和响应进行过滤和拦截,进行各种处理操作。
- 安全认证:Zuul Server 可以集成安全认证机制,例如使用 OAuth2 进行身份验证和授权。
- 监控和日志:Zuul Server 提供了监控和日志记录功能,可以追踪请求的流程和性能,并收集关键指标。
Zuul Server 在 Spring Cloud 中被广泛使用,它是 Spring Cloud Netflix 的一部分,与其他组件如 Eureka(服务发现)、Ribbon(负载均衡)、Hystrix(断路器)等配合使用,构建起完整的微服务架构。
需要注意的是,Netflix 在 2020 年宣布停止对 Zuul 1.x 的维护,并推荐使用 Spring Cloud Gateway 作为替代方案。Spring Cloud Gateway 是 Spring Cloud 提供的另一个网关实现,它基于 Spring WebFlux 构建,具有更高的性能和更多的扩展性。因此,如果你要使用最新的技术栈,可以考虑使用 Spring Cloud Gateway 替代 Zuul Server。
Hystrix
Hystrix是Netflix开源的Java库,用于实现断路器模式(Circuit Breaker pattern)。它旨在提高分布式系统的弹性,通过隔离和控制系统依赖中的故障点。
Hystrix的核心概念是断路器,它是一种监控和控制对依赖的访问的机制。在一个分布式系统中,当某个依赖出现故障或延迟时,Hystrix能够阻止请求对该依赖的继续发送,而是快速失败或采取替代方案。这种机制可以防止故障在系统中蔓延,提高系统的稳定性和可用性。
Hystrix提供了以下主要功能:
- 断路器:Hystrix会根据一定的条件自动打开断路器,停止请求对失败的依赖进行发送,并快速失败。当故障情况改善时,断路器会逐渐关闭,重新允许请求。
- 资源隔离:Hystrix通过将每个依赖封装在独立的线程池中,使得依赖之间的调用可以独立运行,避免一个依赖的故障影响其他依赖的性能。
- 后备机制:Hystrix允许为每个依赖定义备选方案,当主要依赖出现故障时,可以快速切换到备选方案以提供基本的功能。
- 实时监控和指标收集:Hystrix提供了监控仪表板,可以实时查看断路器的状态、依赖的指标以及请求的成功和失败情况。
总体而言,Hystrix是一种用于构建弹性分布式系统的强大工具,可以帮助应对依赖故障和延迟,并提供故障恢复和保护机制。它已经在Netflix等许多大规模分布式系统中得到广泛应用。
eureka-server
Eureka Server是Netflix开源的一个服务注册和发现组件,它用于构建基于微服务架构的应用程序。Eureka Server的主要功能是充当服务注册中心,负责管理和维护服务实例的信息。
在一个微服务架构中,各个服务会以独立的方式运行,并通过网络进行通信。服务需要将自己的信息(如主机名、端口号、健康状态等)注册到Eureka Server中,使其他服务能够发现并与之通信。
Eureka Server的工作原理如下:
- 服务注册:服务在启动时向Eureka Server注册自己的信息。Eureka Server会记录这些信息,并维护一个服务实例的列表。
- 服务发现:其他服务需要与某个服务进行通信时,会向Eureka Server查询该服务的信息。Eureka Server会返回可用的服务实例列表,供请求方选择。
- 健康监测:Eureka Server会周期性地向注册的服务实例发送心跳请求,以检测服务的健康状态。如果某个服务实例停止发送心跳或被标记为不健康,Eureka Server将从注册列表中移除该实例。
- 高可用性:Eureka Server支持多节点部署,多个Eureka Server节点之间相互注册,形成一个集群。这样即使某个Eureka Server节点故障,其他节点仍然可以提供服务注册和发现的功能。
Eureka Server提供了简单而强大的服务注册和发现机制,使得微服务架构中的各个服务能够动态地发现和调用彼此。它是Netflix的开源项目之一,已经被广泛应用于构建具有高度可扩展性和弹性的分布式系统。
config-server
Config Server(配置服务器)是Spring Cloud中的一个组件,用于集中管理和提供应用程序的配置信息。它充当了一个集中式配置存储和分发的角色,使得应用程序能够动态地获取配置信息而无需硬编码在代码中。
Config Server的工作原理如下:
- 配置存储:Config Server将应用程序的配置信息存储在版本控制系统(如Git、SVN等)或其他外部存储中,如文件系统或数据库。
- 配置获取:应用程序启动时,通过配置中心客户端向Config Server发送请求,请求所需的配置信息。Config Server会根据应用程序的配置标识(如应用名称、环境等)返回相应的配置信息。
- 动态刷新:Config Server支持配置信息的动态刷新。当配置发生变化时,应用程序可以通过发送请求给Config Server来获取最新的配置,而无需重新启动应用程序。
- 安全性和权限控制:Config Server提供了安全性和权限控制机制,可以对配置信息进行保护和管理,确保只有授权的应用程序可以获取到相应的配置。
通过使用Config Server,开发人员可以将应用程序的配置信息集中管理,并且可以在运行时动态地修改和更新配置,而无需重新部署应用程序。这使得应用程序的配置管理更加灵活和便捷,同时也提高了系统的可维护性和可扩展性。
架构图

理解服务注册
在分布式系统中,服务注册是指将服务的网络位置和元数据信息注册到一个中心化的服务注册表或注册中心中,以便其他服务能够发现和使用该服务。
服务注册的目的是让各个服务能够动态地找到其他服务并建立通信连接,而无需硬编码依赖的具体网络地址和端口号。通过服务注册,服务之间可以实现解耦,提高系统的灵活性、可扩展性和可维护性。
下面是对服务注册的几个关键概念的解释:
- 服务:一个服务是指在分布式系统中独立运行的可编程实体,可以提供某种功能或服务。服务可以是微服务架构中的一个微服务,也可以是其他类型的服务。
- 服务注册表/注册中心:服务注册表是一个中心化的组件或服务,用于存储和管理所有服务的网络位置和元数据信息。它充当了服务发现的中心枢纽。
- 服务实例:一个服务的运行实例被称为服务实例。每个服务可以有多个实例运行在不同的主机或容器中。
- 注册:注册是指将服务实例的信息(如主机名、端口号、健康状态等)发送到服务注册表,并在注册表中进行记录和存储。
- 发现:发现是指其他服务从服务注册表中查询服务的信息,以便能够与之建立通信。发现可以通过服务注册表提供的API或其他机制进行。
通过服务注册和发现,系统中的服务能够动态地找到彼此,建立通信连接,并相互协作完成业务功能。服务注册提供了一种解耦的方式,使得服务可以独立进行扩展、部署和管理,同时也提高了系统的弹性和可靠性。
常见的服务注册和发现的实现包括Netflix Eureka、Apache ZooKeeper、Consul和etcd等。这些工具和框架提供了方便的机制来管理和发现服务,简化了分布式系统的开发和部署。
常见注册中心系统

Nacos、Etcd、Eureka和Consul都是常见的服务注册和发现的实现工具,它们在分布式系统中起着类似的作用,但具有不同的特点和功能。下面我将简要介绍这些工具:
- Nacos: Nacos是阿里巴巴开源的一款服务发现和配置管理工具。它提供了服务注册和发现、动态配置管理和服务元数据管理等功能。Nacos支持多种注册中心模式,包括基于Raft协议的集群模式和基于数据库的持久化模式。它还提供了丰富的特性,如健康检查、流量管理、动态路由等,适用于微服务架构的构建。
- Etcd: Etcd是CoreOS开源的一个高可用的键值存储系统,也被广泛应用于服务注册和发现。Etcd提供了一个分布式的一致性存储,用于存储服务的配置信息、元数据和发现信息。它使用Raft一致性算法来保证数据的一致性和高可用性。Etcd的特点包括简单的HTTP API、触发器和监视器以及强大的一致性保证。
- Eureka: Eureka是Netflix开源的一个服务注册和发现组件,用于构建基于微服务架构的应用程序。Eureka使用了基于REST的轻量级通信协议,并提供了自我保护机制来处理网络分区和故障情况。Eureka的设计目标是简单、高可用和可靠,已经在Netflix等许多大规模分布式系统中得到广泛应用。
- Consul: Consul是HashiCorp开源的一款服务网格和服务发现工具。它提供了服务注册和发现、健康检查、分布式一致性和故障转移等功能。Consul使用Raft协议来实现分布式一致性,并提供了HTTP和DNS接口供服务发现。Consul还支持多数据中心部署和多种服务发现模式。
这些工具都具有各自的特点和优势,可以根据具体的需求和架构选择合适的工具。它们都为分布式系统提供了服务注册和发现的基本功能,以实现服务之间的解耦和通信,提高系统的灵活性和可扩展性。
启动Eureka注册中心
https://docs.spring.io/spring-cloud-netflix/docs/3.0.3/reference/html/
启动Eureka需要创建一个Spring Boot项目的原因是Eureka本身是一个基于Spring框架的组件,它提供了与Spring Boot无缝集成的功能和特性。通过创建一个Spring Boot项目,您可以方便地配置和启动Eureka服务器。
以下是一些使用Spring Boot创建Eureka服务器的好处:
- 自动配置:Spring Boot提供了自动配置的功能,可以根据项目的依赖和配置信息来自动配置Eureka服务器。这样可以大大简化了配置过程,减少了手动配置的工作量。
- 简化的启动过程:通过Spring Boot,您可以使用一些简单的注解和命令来启动Eureka服务器,而不需要编写复杂的启动脚本或配置文件。Spring Boot提供了内嵌的Tomcat容器,使得启动和管理Eureka服务器变得更加方便。
- 统一的依赖管理:使用Spring Boot创建项目可以方便地管理项目的依赖关系。您只需在项目的配置文件中添加Eureka相关的依赖,Spring Boot将自动处理依赖冲突和版本兼容性等问题,确保项目的稳定性和一致性。
- 生态系统支持:Spring Boot拥有广泛的生态系统和活跃的社区支持,您可以轻松地找到各种与Eureka集成的插件、扩展和解决方案。这些资源可以帮助您更好地使用和管理Eureka服务器,以满足您的具体需求。
总之,通过创建一个Spring Boot项目来启动Eureka服务器,可以获得自动配置、简化的启动过程、依赖管理和生态系统支持等好处。这样可以节省时间和精力,并且提供了更好的开发体验和集成能力。

下一步,直接创建,不安装依赖,待会手工修改pom.xml
修改pom.xml
spring-cloud依赖包配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.yuchaoit</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka</name>
<description>eureka</description>
<properties>
<java.version>1.8</java.version>
<spring.cloud-version>Hoxton.SR9</spring.cloud-version>
</properties>
<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依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<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>
Mvn下载依赖
注意是阿里云的mvn源

确认模块下载好了

继续修改Eureka配置
刚才于超老师是下载了模块,想用,还得改改配置。
application.yml
server:
port: 8761
eureka:
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
register-with-eureka: false
fetch-registry: false
instance:
hostname: localhost
这个配置文件是用于配置一个使用Eureka作为服务注册中心的服务器。以下是每个配置属性的中文解释:
server.port: 8761:- 这个属性设置服务器运行的端口号为8761。当服务器启动时,它将监听并处理到达该端口的网络请求。
eureka.client.service-url.defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/:- 这个属性配置了Eureka客户端的服务URL。
${eureka.instance.hostname}将会被替换为实际的主机名,${server.port}将会被替换为配置文件中设置的端口号。因此,这个属性的值将是一个完整的Eureka服务注册中心的URL,形如http://localhost:8761/eureka/。
- 这个属性配置了Eureka客户端的服务URL。
eureka.client.register-with-eureka: false:- 这个属性设置Eureka客户端是否应该向Eureka服务注册中心注册自己。在这个配置中,设置为
false,表示该客户端不会注册自己到Eureka服务注册中心。
- 这个属性设置Eureka客户端是否应该向Eureka服务注册中心注册自己。在这个配置中,设置为
eureka.client.fetch-registry: false:- 这个属性设置Eureka客户端是否应该从Eureka服务注册中心获取注册表信息。在这个配置中,设置为
false,表示该客户端不会从Eureka服务注册中心获取注册表信息。
- 这个属性设置Eureka客户端是否应该从Eureka服务注册中心获取注册表信息。在这个配置中,设置为
eureka.instance.hostname: localhost:- 这个属性配置了Eureka客户端实例的主机名。在这个配置中,将客户端实例的主机名设置为
localhost。
- 这个属性配置了Eureka客户端实例的主机名。在这个配置中,将客户端实例的主机名设置为

EurekaApplication
这是一个Spring Boot应用程序的Java代码,用于启动一个Eureka服务器。下面是对每个注解和方法的解释:
@SpringBootApplication:这是一个Spring Boot应用程序的主要注解,表示这是一个可执行的Spring Boot应用程序。它包含了多个注解的组合,用于自动配置、扫描和启动应用程序。@EnableEurekaServer:这是一个Eureka服务器相关的注解,用于启用Eureka服务器功能。通过添加这个注解,应用程序将被配置为一个Eureka服务器,用于服务注册和发现。public static void main(String[] args):这是应用程序的入口方法。在这个方法中,使用SpringApplication.run()方法启动了Spring Boot应用程序。它接受两个参数,第一个参数是应用程序的主类,第二个参数是命令行参数。
通过以上的代码配置,该应用程序将以Eureka服务器的身份运行,并提供服务注册和发现的功能。
package cn.yuchaoit.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
启动Eureka注册中心
创建spring cloud项目三部曲:
- 引入依赖包
- 修改application.yml配置文件
- 启动类添加注解

访问8761

后台的微服务启动后,会注册自己到这里Instances
添加认证依赖
修改pom.xml

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
务必,maven reload,加载新依赖。
修改application.yml
这个配置文件是用于配置一个使用Eureka作为服务注册中心的服务器,并包含了一些安全相关的配置。以下是每个配置属性的解释:
server.port: 8761:- 这个属性设置服务器运行的端口号为8761。当服务器启动时,它将监听并处理到达该端口的网络请求。
eureka.client.service-url.defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:${server.port}/eureka/:- 这个属性配置了Eureka客户端的服务URL。
${spring.security.user.name}和${spring.security.user.password}将会被替换为实际的用户名和密码。${eureka.instance.hostname}将会被替换为实际的主机名,${server.port}将会被替换为配置文件中设置的端口号。因此,这个属性的值将是一个完整的Eureka服务注册中心的URL,形如http://admin:admin@localhost:8761/eureka/。这里使用了用户名和密码来对服务进行基本身份验证。
- 这个属性配置了Eureka客户端的服务URL。
eureka.client.register-with-eureka: false:- 这个属性设置Eureka客户端是否应该向Eureka服务注册中心注册自己。在这个配置中,设置为
false,表示该客户端不会注册自己到Eureka服务注册中心。
- 这个属性设置Eureka客户端是否应该向Eureka服务注册中心注册自己。在这个配置中,设置为
eureka.client.fetch-registry: false:- 这个属性设置Eureka客户端是否应该从Eureka服务注册中心获取注册表信息。在这个配置中,设置为
false,表示该客户端不会从Eureka服务注册中心获取注册表信息。
- 这个属性设置Eureka客户端是否应该从Eureka服务注册中心获取注册表信息。在这个配置中,设置为
eureka.instance.hostname: localhost:- 这个属性配置了Eureka客户端实例的主机名。在这个配置中,将客户端实例的主机名设置为
localhost。
- 这个属性配置了Eureka客户端实例的主机名。在这个配置中,将客户端实例的主机名设置为
spring.security.user.name: ${EUREKA_USER:admin}:- 这个属性配置了Spring Security的用户名。它使用了一个占位符
${EUREKA_USER:admin},表示如果环境变量EUREKA_USER存在,则使用环境变量的值作为用户名,否则使用默认值admin。
- 这个属性配置了Spring Security的用户名。它使用了一个占位符
spring.security.user.password: ${EUREKA_PASS:admin}:- 这个属性配置了Spring Security的密码。它使用了一个占位符
${EUREKA_PASS:admin},表示如果环境变量EUREKA_PASS存在,则使用环境变量的值作为密码,否则使用默认值admin。
- 这个属性配置了Spring Security的密码。它使用了一个占位符
spring.application.name: eureka:- 这个属性配置了Spring Boot应用程序的名称。在这个配置中,将应用程序的名称设置为
eureka。
- 这个属性配置了Spring Boot应用程序的名称。在这个配置中,将应用程序的名称设置为
通过以上的配置,该应用程序将以Eureka服务器的身份运行,使用基本身份验证保护服务,并且具有自定义的用户名、密码和应用程序名称。
server:
port: 8761
eureka:
client:
service-url:
defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:${server.port}/eureka/
register-with-eureka: false
fetch-registry: false
instance:
hostname: localhost
spring:
security:
user:
name: ${EUREKA_USER:admin}
password: ${EUREKA_PASS:admin}
application:
name: eureka
重启Eureka
此时就需要登录使用,加强安全性。

开发User-service服务
新建项目,user-service(选择Spring Cloud依赖和SpringBoot Web依赖),用来提供用户查询功能。

修改pom.xml
三部曲:
- pom.xml,并添加依赖
- 创建application.yml配置文件
- 创建Springboot启动类,并配置注解


注意reload
..
修改application.yml
写入Eureka服务端链接信息,以及账号密码。
以及instance-id必须唯一。
通过以上的配置,该用户服务将以Eureka客户端的身份运行,并连接到Eureka服务注册中心。它使用基本身份验证保护服务,并且具有自定义的用户名、密码、主机名、端口号和应用程序名称。
server:
port: 7000
eureka:
client:
serviceUrl:
defaultZone: http://${EUREKA_USER:admin}:${EUREKA_PASS:admin}@localhost:8761/eureka/
instance:
instance-id: ${eureka.instance.hostname}:${server.port}
prefer-ip-address: true
hostname: user-service
spring:
application:
name: user-service
修改启动类
package cn.yuchaoit.userservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
//注意这里也可使用@EnableEurekaClient
//但由于springcloud是灵活的,注册中心支持eureka、consul、zookeeper等
//若写了具体的注册中心注解,则当替换成其他注册中心时,又需要替换成对应的注解了。
//所以 直接使用@EnableDiscoveryClient 启动发现。
//这样在替换注册中心时,只需要替换相关依赖即可。
@EnableDiscoveryClient
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
启动服务,查看是否注册成功
有报错
Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://admin:admin@localhost:8761/eureka/}, exception=com.fasterxml.jackson.databind.exc.MismatchedInputException: Root name 'timestamp' does not match expected ('instance') for type [simple type, class com.netflix.appinfo.InstanceInfo]
修复Eureka服务端

新建java类
package cn.yuchaoit.eureka;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
@Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable(); //关闭csrf
http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); //开启认证
}
}
重启服务
服务注册成功

服务中心自我保护模式
当注册中心后面维护的服务实例出现故障后,注册中心会存在时间差来感知到服务故障。
- 停止user-service,但是注册中心仍然记录服务实例信息,这就是错误调用了。
- 默认情况下,如果
Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。 - 调整服务检测为5秒
Eureka服务端
resources/application.yml
server:
port: 8761
eureka:
client:
service-url:
defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@${eureka.instance.hostname}:${server.port}/eureka/
register-with-eureka: false
fetch-registry: false
instance:
hostname: localhost
server:
# 间隔5秒执行一次检测任务
eviction-interval-timer-in-ms: 5000
spring:
security:
user:
name: ${EUREKA_USER:admin}
password: ${EUREKA_PASS:admin}
application:
name: eureka
user-service客户端
resources/application.yml
server:
port: 7000
eureka:
client:
serviceUrl:
defaultZone: http://${EUREKA_USER:admin}:${EUREKA_PASS:admin}@localhost:8761/eureka/
instance:
instance-id: ${eureka.instance.hostname}:${server.port}
prefer-ip-address: true
hostname: user-service
#eureka客户端需要多长时间发送心跳给eureka服务器,表明他仍然或者,默认30秒
lease-renewal-interval-in-seconds: 2
#eureka服务器在接受到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除
lease-expiration-duration-in-seconds: 2
spring:
application:
name: user-service
服务注册、剔除正常
最长等待时间9秒,完成实例剔除。
- 关闭user-service服务
- 查看Eureka

Eureka集群高可用
Eureka集群高可用是指通过在多个Eureka服务器之间建立集群,实现Eureka服务注册中心的高可用性。它旨在确保即使其中一个Eureka服务器发生故障或不可用,系统仍然能够继续正常工作。
以下是Eureka集群高可用的主要原理和理解:
- 服务器冗余:搭建Eureka集群时,需要在多个物理或虚拟服务器上安装和运行Eureka服务器实例。这样,如果其中一个服务器发生故障,其他服务器仍然可用,提供服务注册和发现功能。
- 互相注册:在Eureka集群中的每个服务器上,都需要将其他服务器的地址添加为自己的服务注册中心。这样,每个服务器都知道其他服务器的存在,并能够通过相互注册来实现故障切换和负载均衡。
- 客户端配置:客户端应用程序需要配置多个Eureka服务器的地址,以便在一个服务器不可用时能够连接到其他可用的服务器。客户端还可以通过负载均衡策略选择最合适的服务器进行服务注册和发现。
- 心跳和故障检测:在Eureka集群中,每个Eureka服务器会定期发送心跳信号来表明自己的存活状态。其他服务器会监测这些心跳信号,并根据情况判断服务器是否正常工作。如果某个服务器停止发送心跳信号或被其他服务器检测到不可用,它将从集群中被移除,以保证集群的稳定性。
通过以上机制,Eureka集群高可用实现了对服务器故障的容错能力和自动故障恢复能力。即使其中一个服务器不可用,其他服务器仍然能够提供可靠的服务注册和发现功能,确保应用程序能够继续正常运行。这提高了系统的可用性和可靠性,对于构建分布式和高可用的微服务架构非常重要。
注意点
- 多实例的话eureka.instance.instance-id需要保持不一样,否则会当成同一个
- eureka.instance.hostname要与defaultZone里的地址保持一致
各个eureka的spring.application.name相同
eureka.instance.instance-id:在Eureka集群中,每个Eureka实例都应该具有唯一的instance-id。这个属性用于标识每个实例,并区分它们。如果多个实例具有相同的instance-id,Eureka将会将它们视为相同的实例,从而可能导致不正确的行为。因此,确保每个实例的instance-id是唯一的是非常重要的。eureka.instance.hostname:hostname属性应该与defaultZone配置中的地址保持一致。defaultZone是Eureka实例用于注册和发现其他实例的URL。如果hostname与defaultZone中的地址不匹配,Eureka将无法正确地发现和注册其他实例。spring.application.name:在Eureka集群中,各个Eureka实例的spring.application.name应该保持一致。这个属性表示应用程序的名称,用于在Eureka中唯一标识应用程序。确保所有实例具有相同的spring.application.name可以确保它们在Eureka注册表中被正确识别和管理。
通过遵守上述注意事项,可以确保多个Eureka实例能够正确地在集群中工作,相互发现和注册,并提供可靠的服务注册和发现功能。这对于构建高可用和可靠的微服务架构非常重要。
k8s部署Eureka集群
在Kubernetes(k8s)中部署Eureka集群意味着利用Kubernetes的功能和特性,在容器化环境中运行多个Eureka服务器实例,并建立一个可靠和可伸缩的Eureka服务注册中心。
以下是关于在Kubernetes上部署Eureka集群的一些理解和步骤:
- 容器化Eureka服务器:首先,将Eureka服务器进行容器化,可以使用Docker将Eureka服务器打包成镜像,并将镜像上传到Kubernetes的容器镜像仓库。这个镜像可以作为Eureka服务器实例的基础。
- 创建Kubernetes Deployment:使用Kubernetes的Deployment资源来定义Eureka服务器的部署。在Deployment中,指定要运行的Eureka服务器容器镜像、副本数量以及其他相关配置。Deployment将负责管理和维护指定数量的Eureka服务器实例。
- 服务发现和负载均衡:在Kubernetes中,使用Service资源来提供服务发现和负载均衡。创建一个Eureka服务的Service资源,并将其指向部署的Eureka服务器实例。这样,其他应用程序和服务可以通过Service名称来访问Eureka服务器,而不需要直接连接到特定的实例。
- 高可用和自动伸缩:Kubernetes提供了高可用性和自动伸缩的功能。通过适当配置Deployment和Service资源,可以实现Eureka集群的高可用性。Kubernetes会监视Eureka服务器实例的健康状态,并在实例故障或不可用时进行自动恢复。此外,根据负载情况,可以自动扩展或缩减Eureka服务器实例的数量,以满足流量需求。
- 配置管理:Kubernetes的配置管理机制可以用于管理Eureka服务器的配置信息。通过ConfigMap或Secret资源,可以将Eureka服务器所需的配置信息(例如端口、数据库连接等)集中管理,并在部署过程中将其注入到Eureka服务器容器中。
通过在Kubernetes上部署Eureka集群,可以利用Kubernetes提供的强大功能,如高可用性、自动伸缩、服务发现和负载均衡,实现可靠的服务注册和发现机制。这使得Eureka集群能够适应动态变化的容器环境,并提供可靠的服务治理能力,为微服务架构提供基础设施支持。
注意点
高可用互相注册,但是需要知道对方节点的地址。k8s中pod ip是不固定的,如何将高可用的eureka服务使用k8s交付?
statefulset+service
- 创建StatefulSet:定义一个StatefulSet资源,指定要运行的Eureka服务器容器镜像、副本数量以及其他相关配置。在配置文件中,设置
serviceName属性为Eureka服务的Service名称,这将用于为Eureka服务器提供稳定的DNS名称。 - 创建Headless Service:创建一个Headless Service来为StatefulSet中的每个Pod实例提供唯一的稳定DNS名称。设置Service的
clusterIP属性为"None",这将使Service成为一个虚拟的服务,不提供负载均衡功能,而是直接暴露Pod的DNS名称。 - 互相注册:在Eureka服务器的配置中,使用StatefulSet的DNS名称作为其他服务器的
defaultZone配置。由于StatefulSet的Pod名称是稳定的,这将确保每个Eureka服务器能够正确地互相发现和注册。
通过使用StatefulSet管理Eureka集群,每个Eureka服务器实例都具有稳定的标识符和DNS名称,即使Pod重新启动或迁移,也不会改变。这样可以确保Eureka服务器之间的互相注册和发现是可靠的,即使Pod的IP地址是不固定的。

Eureka服务端application.yml
待会用k8s传入EUREKA_SERVER环境变量就行。
server:
port: ${EUREKA_PORT:8761}
eureka:
client:
service-url:
defaultZone: ${EUREKA_SERVER:http://${spring.security.user.name}:${spring.security.user.password}@localhost:8761/eureka/}
fetch-registry: true
register-with-eureka: true
instance:
instance-id: ${eureka.instance.hostname}:${server.port}
hostname: ${EUREKA_INSTANCE_HOSTNAME:localhost}
prefer-ip-address: true
server:
# 间隔5秒执行一次检测任务
eviction-interval-timer-in-ms: 5000
spring:
security:
user:
name: ${EUREKA_USER:admin}
password: ${EUREKA_PASS:admin}
application:
name: eureka-cluster
创建gitlab仓库

pom.xml修改
# 指定jar包的名字
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

制作Dockerfile
FROM openjdk:8-jdk-alpine
ADD target/eureka.jar app.jar
ENV JAVA_OPTS=""
CMD [ "sh", "-c", "java $JAVA_OPTS -jar /app.jar" ]

提交代码
git init
git remote add origin http://gitlab.yuchaoit.cn/spring-cloud/eureka-server.git
git add .
git commit -m "Initial commit"
git push -u origin master

镜像制作
# 先mvn构建生成jar包
# 获取一个mvn构建环境就行
[root@docker01 ~/springboot/eureka-server]#docker pull 10.0.0.66:5000/devops/tools:v1
v1: Pulling from devops/tools
ca3cd42a7c95: Pull complete
f38094e824b4: Pull complete
d54fc1e4015f: Pull complete
0fc4d94c01a4: Pull complete
d732a0f33906: Pull complete
16b829c5871c: Pull complete
f9c889308fb0: Pull complete
Digest: sha256:04b73d12db3f12349c3c58729ff4e0e6c804afbe8802f9f7ed7fe87bf9c51d24
Status: Downloaded newer image for 10.0.0.66:5000/devops/tools:v1
10.0.0.66:5000/devops/tools:v1
[root@docker01 ~/springboot/eureka-server]#
bash-5.1# git clone http://gitlab.yuchaoit.cn/spring-cloud/eureka-server.git
Cloning into 'eureka-server'...
Username for 'http://gitlab.yuchaoit.cn': root
Password for 'http://root@gitlab.yuchaoit.cn':
remote: Enumerating objects: 27, done.
remote: Counting objects: 100% (27/27), done.
remote: Compressing objects: 100% (18/18), done.
remote: Total 27 (delta 1), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (27/27), 60.81 KiB | 60.81 MiB/s, done.
Resolving deltas: 100% (1/1), done.
bash-5.1# cd eureka-server/
bash-5.1# mvn clean package
# 最终会得到jar包,再去docker build镜像就行
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:45 min
[INFO] Finished at: 2023-05-16T10:14:22Z
[INFO] ------------------------------------------------------------------------
bash-5.1# ls
Dockerfile mvnw mvnw.cmd pom.xml src target
bash-5.1# ls target/
classes eureka.jar.original generated-test-sources maven-status test-classes
eureka.jar generated-sources maven-archiver surefire-reports
bash-5.1#
# 构建,提交到私有仓库
bash-5.1# docker build . -t 10.0.0.66:5000/spring-cloud/eureka-cluster:v1
Sending build context to Docker daemon 52.67MB
Step 1/4 : FROM openjdk:8-jdk-alpine
8-jdk-alpine: Pulling from library/openjdk
e7c96db7181b: Pull complete
f910a506b6cb: Pull complete
c2274a1a0e27: Downloading [============> ] 17.85MB/70.73MB
# 推送
bash-5.1# docker login 10.0.0.66:5000
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
bash-5.1#
bash-5.1# docker push 10.0.0.66:5000/spring-cloud/eureka-cluster:v1
The push refers to repository [10.0.0.66:5000/spring-cloud/eureka-cluster]
77256fa4366b: Pushed
ceaf9e1ebef5: Pushed
9b9b7f3d56a0: Pushed
f1b5933fe4b5: Pushed
v1: digest: sha256:d25b55bb92be90eef84a0f0ff38c5caffa3c94ec334e551f8b1a35420654a616 size: 1159
bash-5.1#
statefulSet.yml
# eureka-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: eureka-cluster
namespace: yuchao
spec:
serviceName: "eureka"
replicas: 3
selector:
matchLabels:
app: eureka-cluster
template:
metadata:
labels:
app: eureka-cluster
spec:
imagePullSecrets:
- name: registry-10.0.0.66
containers:
- name: eureka
image: 10.0.0.66:5000/spring-cloud/eureka-cluster:v1
ports:
- containerPort: 8761
resources:
requests:
memory: 400Mi
cpu: 50m
limits:
memory: 2Gi
cpu: 2000m
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: EUREKA_SERVER
value: "http://admin:admin@eureka-cluster-0.eureka:8761/eureka/,http://admin:admin@eureka-cluster-1.eureka:8761/eureka/,http://admin:admin@eureka-cluster-2.eureka:8761/eureka/"
- name: EUREKA_INSTANCE_HOSTNAME
value: ${MY_POD_NAME}.eureka
- name: EUREKA_PORT
value: "8761"
无头service.yml
apiVersion: v1
kind: Service
metadata:
name: eureka
namespace: yuchao
labels:
app: eureka
spec:
ports:
- port: 8761
name: eureka
clusterIP: None
selector:
app: eureka-cluster
Ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: eureka-cluster
namespace: yuchao
spec:
ingressClassName: nginx
rules:
- host: eureka-cluster.yuchaoit.cn
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: eureka
port:
number: 8761
创建、查看Eureka
[root@k8s-master ~/spring-boot]#kubectl -n yuchao get po
NAME READY STATUS RESTARTS AGE
eladmin-api-7496b69c-dr9jk 1/1 Running 11 (26h ago) 5d2h
eladmin-web-7458474b64-mgrwp 1/1 Running 10 (5h1m ago) 26d
eureka-cluster-0 1/1 Running 0 32s
eureka-cluster-1 1/1 Running 0 29s
eureka-cluster-2 1/1 Running 0 26s
mysql-559d5fcc8b-vnpzf 1/1 Running 1 (5h1m ago) 2d
redis-7957d49f44-5mctq 1/1 Running 2 (5h1m ago) 2d
yuchao-ngx 1/1 Running 14 (5h1m ago) 39d
[root@k8s-master ~/spring-boot]#
修改hosts访问
基于k8s的,Eureka注册中心高可用就搭建好了
Eureka配置
server:
port: ${EUREKA_PORT:8761}
eureka:
client:
service-url:
defaultZone: ${EUREKA_SERVER:http://${spring.security.user.name}:${spring.security.user.password}@localhost:8761/eureka/}
fetch-registry: true
register-with-eureka: true # 同时注册自己
instance:
instance-id: ${eureka.instance.hostname}:${server.port}
hostname: ${EUREKA_INSTANCE_HOSTNAME:localhost}
prefer-ip-address: true
server:
# 间隔5秒执行一次检测任务
eviction-interval-timer-in-ms: 5000
spring:
security:
user:
name: ${EUREKA_USER:admin}
password: ${EUREKA_PASS:admin}
application:
name: eureka-cluster
