SpringCloud——Eureka

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rubulai/article/details/84985478

一、是什么
  Eureka是Netflix的一个子模块,也是核心模块之一。Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册与发现对于微服务架构来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了。功能类似于dubbo的注册中心,比如Zookeeper。Netflix在设计Eureka时遵守AP原则。

二、原理
  Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现(请对比Zookeeper)。Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。SpringCloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。
  原理图:
在这里插入图片描述
  dubbo原理图:
在这里插入图片描述
 Eureka包含两个组件:Eureka Server和Eureka Client
  Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
  Eureka Client是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
 Eureka中的三大角色:
  Eureka Server:提供服务注册和发现
  Service Provider:服务提供方将自身服务注册到Eureka,从而使服务消费方能够找到
  Service Consumer:服务消费方从Eureka获取注册服务列表,从而能够消费服务

三、Eureka Server服务注册中心搭建
 1、在父工程下新建服务注册中心模块microservicecloud-eureka-7001
 2、添加依赖:spring-cloud-starter-eureka-server

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<parent>
		<groupId>com.atguigu.springcloud</groupId>
		<artifactId>microservicecloud</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>

	<artifactId>microservicecloud-eureka-7001</artifactId>

	<dependencies>
		<!--eureka-server服务端 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka-server</artifactId>
		</dependency>
		<!-- 修改后立即生效,热部署 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>springloaded</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
	</dependencies>
</project>

 3、配置Eureka:

server: 
  port: 7001
 
eureka:
  instance:
    hostname: localhost #eureka服务端的实例名称
  client:
    register-with-eureka: false #false表示不向注册中心注册自己
    fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址

 4、在主启动类上启用EurekaServer:使用@EnableEurekaServer注解,表名这是一个Eureka服务注册中心,若使用@EnableEurekaClient则表明示Eureka的服务提供方

@SpringBootApplication
@EnableEurekaServer // EurekaServer服务器端启动类,接受其它微服务注册进来
public class EurekaServer7001_App {
	public static void main(String[] args) {
		SpringApplication.run(EurekaServer7001_App.class, args);
	}
}

 5、测试:http://localhost:7001/
在这里插入图片描述
四、将服务提供者(microservicecloud-provider-dept-8001)注册至Eureka
 1、引入依赖:spring-cloud-starter-eureka(注意不是spring-cloud-starter-eureka-server,spring-cloud-starter-eureka-server是服务注册的服务端,spring-cloud-starter-eureka是服务注册的客户端)

<!-- 将微服务provider侧注册进eureka -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

 2、配置服务注册的地址:告知将服务注册至哪儿(Eureka的地址)

eureka:
  client: #客户端注册进eureka服务列表内
    service-url: 
      defaultZone: http://localhost:7001/eureka

 3、启用Eureka服务注册客户端:@EnableEurekaClient

@SpringBootApplication
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
public class DeptProvider8001_App {

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

 4、测试:先启动Eureka Server,再启动服务提供者端,访问服务注册的服务端localhost:7001会看到注册的应用,该应用的名字是在服务提供者端的yml文件中设置的,Eureka将其全部置为大写
在这里插入图片描述
五、配置完善
 1、主机映射名称修改
  ①修改前的主机映射名称:由Eureka生成(规则:计算机名:应用名:端口)
在这里插入图片描述
  ②修改客户端应用(microservicecloud-provider-dept-8001)的Eureka实例名称

eureka:
  instance:
    instance-id: microservicecloud-dept8001

  ③修改之后:
在这里插入图片描述
 2、主机ip信息提示:当我们将鼠标放在主机映射名称上的超链接上时,左下角展示服务所在的ip信息
  ①修改前:显示的是计算机名
在这里插入图片描述
  ②修改客户端应用(microservicecloud-provider-dept-8001)的Eureka实例的ip地址显示方式:默认显示计算机名

eureka:
  instance:
    prefer-ip-address: true     #访问路径显示IP地址,默认显示计算机名

  ③修改之后:
在这里插入图片描述
 3、注册的微服务的info信息完善:
  ①完善之前:我们在点击主机映射名称的超链接时会报404
在这里插入图片描述
  ②修改microservicecloud-provider-dept-8001(服务提供端,同时也是Eureka服务注册的客户端),增加actuator依赖:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

  ③修改microservicecloud-provider-dept-8001(服务提供端,同时也是服务注册的客户端),在主配置文件中增加info信息配置:这里使用maven插件来读取project.artifactId和project.version的值,因此需在父工程下配置maven插件,见第④步配置(如果不采用变量读取的方式,则没必要进行第④步配置)

info:
  app.name: atguigu-microservicecloud
  company.name: www.atguigu.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

  ④在父工程下配置maven插件,使maven工程的各模块中能读取到工程中的一些变量,比如③中的变量:表示在src/main/resources文件夹下的配置文件可以读取maven工程的一些变量(比如:project.version),这些配置文件中以$开头和结尾的配置项将作为变量被maven的工程变量填充

<build>
	<finalName>microservicecloud</finalName>
	<resources>
		<resource>
			<directory>src/main/resources</directory>
			<filtering>true</filtering>
		</resource>
	</resources>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-resources-plugin</artifactId>
			<configuration>
				<delimiters>
					<delimit>$</delimit>
				</delimiters>
			</configuration>
		</plugin>
	</plugins>
</build>

  ⑤配置好之后测试:点击服务应用注册的超链接就可以看到配置的应用信息
在这里插入图片描述
  为便于查看浏览器中的json数据,可以在谷歌浏览器上安装一个插件JsonView,详情参考

六、自我保护机制
 在访问我们搭建的Eureka Server服务端时有时会出现如下的提示:这是Eureka的自我保护在起作用
在这里插入图片描述
  服务掉线:
在这里插入图片描述
  自我保护机制:某时刻某一个微服务不可用了,eureka不会立刻清理,依旧会对该微服务的信息进行保存。
  默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。但是当网络故障发生时,微服务与Eureka Server之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题——当Eureka Server节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。一旦进入该模式,Eureka Server就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式。
  在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。当它收到的心跳数重新恢复到阈值以上时,该Eureka Server节点就会自动退出自我保护模式。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。
  综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。
  在Spring Cloud中,可以禁用自我保护模式,在Eureka的服务端(microservicecloud-eureka-7001)的主配置文件中配置:

eureka.server.enable-self-preservation = false

七、Eureka服务发现
  对于注册到Eureka的微服务,可以在Eureka的客户端通过SpringCloud提供的服务发现接口DiscoveryClient来获取服务的注册信息(所有注册到该Eureka服务端的服务信息)
 1、在服务注册客户端使用DiscoveryClient科获取所有服务注册的信息:可以查阅到在Eureka中注册服务的所有应用的信息

@RestController
public class DeptController {

	@Autowired
	private DiscoveryClient client;

	@RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
	public Object discovery() {
		//获取所有的微服务
		List<String> services = client.getServices();
		System.out.println(">>>>" + services);
		//获取具体名称的微服务:相同名称的微服务可能有多个——即所谓的分布式集群
		List<ServiceInstance> instances = client.getInstances("MICROSERVICECLOUD-DEPT");
		for (ServiceInstance inst : instances) {
			System.out.println(
					inst.getServiceId() + "\t" + inst.getHost() + "\t" + inst.getPort() + "\t" + inst.getUri());
		}
		return this.client;
	}
}

 2、启用服务注册发现:主启动类加注解@EnableDiscoveryClient

@SpringBootApplication
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
@EnableDiscoveryClient //启用服务注册的发现
public class DeptProvider8001_App {

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

 3、可访问localhost:8001/dept/discovery接口进行测试
在这里插入图片描述
 4、在消费者端通过RestTemplate调用服务端接口

@RestController
public class DeptController_Consumer {
	private static final String REST_URL_PREFIX = "http://localhost:8001";

	@Autowired
	private RestTemplate restTemplate;
	
	@RequestMapping(value = "/consumer/dept/discovery")
	public Object discovery() {
		return restTemplate.getForObject(REST_URL_PREFIX + "/dept/discovery", Object.class);
	}
}

  问题目前为止消费端依然是采用RestTemplate的方式来调用的服务端接口,并没有调用Eureka中注册的服务,那服务注册有什么用呢?在Ribbon章节的[Ribbon配置初步]中会有讲解。
 5、访问消费者端
在这里插入图片描述
八、Eureka集群配置
 1、搭建集群环境:参照microservicecloud-eureka-7001搭建microservicecloud-eureka-7002和microservicecloud-eureka-7003,即搭建Eureka集群
 2、复制microservicecloud-eureka-7001的pom中的依赖至microservicecloud-eureka-7002和microservicecloud-eureka-7003
 3、复制microservicecloud-eureka-7001的主启动类至microservicecloud-eureka-7002和microservicecloud-eureka-7003,并修改主启动类的名字
 4、修改映射配置,找到hosts文件,添加以下配置:将三个域名映射到同一个地址

127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com

 5、修改集群中的三个项目的主配置文件,让集群中的各个机器之间手牵手:主要是修改hostname和defaultZone的值,hostname的值与hosts文件保持一致,defaultZone的值使各个Eureka机器手牵手
  microservicecloud-eureka-7001的application.yml:

server:
  port: 7001
  
eureka:
  instance:
    hostname: eureka7001.com #eureka服务端的实例名称
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

  microservicecloud-eureka-7002的application.yml:

server:
  port: 7002
  
eureka:
  instance:
    hostname: eureka7002.com #eureka服务端的实例名称
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/

  microservicecloud-eureka-7003的application.yml:

server:
  port: 7003
  
eureka:
  instance:
    hostname: eureka7003.com #eureka服务端的实例名称
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/

 6、想把微服务发布到上面的eureka集群中,需要修改eureka客户端(microservicecloud-provider-dept-8001)的eureka配置,主要是修改defaultZone的值:之前是单机版,只写一个值;现为集群,应写集群的每一个地址,以逗号隔开

eureka:
  instance:
    instance-id: microservicecloud-dept8001
    prefer-ip-address: true
  client:
    service-url:
      #defaultZone: http://localhost:7001/eureka #单机版
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ #集群

 7、测试:将集群中的三台机器(此处为三个项目)和eureka客户端启动,访问任意一个eureka服务,会看到以下画面
在这里插入图片描述
  SpringCloud中微服务向Eureka注册服务的时候是以应用为单位注册的,而dubbo中微服务向zookeeper注册服务的时候是以接口为单位的。

九、Eureka对比Zookeeper
 1、CAP原则:最多只能同时较好的满足其中的两个
  C:Consistency——强一致性
  A:Availability——可用性
  P:Partition tolerance——分区容错性
在这里插入图片描述
在这里插入图片描述
 2、Zookeeper保证的是CP,Eureka保证的是AP
  著名的CAP理论指出,一个分布式系统不可能同时满足C(强一致性)、A(可用性)、P(分区容错性),由于分区容错性P在分布式系统中是必须要保证的,因此我们只能在A和C之间进行权衡:Zookeeper保证的是CP,Eureka保证的是AP。
  ①Zookeeper保证CP:
在这里插入图片描述
  ②Eureka保证AP:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/rubulai/article/details/84985478