Eureka注册中心

准备:微服务搭建

使用Eureka(尤里卡),前提是先有服务,如果服务没有搭建好,参考我上一篇文章 ,有服务就是用,客户端A调用服务端B形式的就行
微服务场景模拟

Eureka (服务发现框架)

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。
Eureka包含两个组件:Eureka ServerEureka Client
Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。
在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。

心跳,移除都可以配置,开发时,为了观察效果,可以适当降低,上线还原

Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。

我们采取先入门,再讲尤里卡原理

一、入门案例

1.1.编写EurekaServer

创建一个项目,启动一个EurekaServer:

依然使用spring提供的快速搭建工具:
Eureka注册中心_第1张图片

选择依赖:
Eureka注册中心_第2张图片
完整的Pom文件:下载jar包比较慢 本地仓库配成华为云镜像快一点


<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.0modelVersion>

	<groupId>com.czxy.demogroupId>
	<artifactId>eureka-demoartifactId>
	<version>0.0.1-SNAPSHOTversion>
	<packaging>jarpackaging>

	<name>eureka-demoname>
	<description>Demo project for Spring Bootdescription>

	<parent>
		<groupId>org.springframework.bootgroupId>
		<artifactId>spring-boot-starter-parentartifactId>
		<version>2.0.1.RELEASEversion>
		<relativePath/> 
	parent>

	<properties>
		<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
		<java.version>1.8java.version>
        
		<spring-cloud.version>Finchley.RC1spring-cloud.version>
	properties>

	<dependencies>
        
		<dependency>
			<groupId>org.springframework.cloudgroupId>
			<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
		dependency>
	dependencies>

	<dependencyManagement>
		<dependencies>
            
			<dependency>
				<groupId>org.springframework.cloudgroupId>
				<artifactId>spring-cloud-dependenciesartifactId>
				<version>${spring-cloud.version}version>
				<type>pomtype>
				<scope>importscope>
			dependency>
		dependencies>
	dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.bootgroupId>
				<artifactId>spring-boot-maven-pluginartifactId>
			plugin>
		plugins>
	build>

	<repositories>
		<repository>
			<id>spring-milestonesid>
			<name>Spring Milestonesname>
			<url>https://repo.spring.io/milestoneurl>
			<snapshots>
				<enabled>falseenabled>
			snapshots>
		repository>
	repositories>
project>

编写启动类:

@SpringBootApplication
@EnableEurekaServer // 声明这个应用是一个EurekaServer
public class EurekaDemoApplication {

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

编写配置application.yml:

server:
  port: 10086 # 端口
spring:
  application:
    name: eureka-server # 应用名称,会在Eureka中显示
eureka:
  client:
    register-with-eureka: false # 是否注册自己的信息到EurekaServer,默认是true
    fetch-registry: false # 是否拉取其它服务的信息,默认是true
    service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址。
      defaultZone: http://127.0.0.1:${server.port}/eureka

启动服务,并访问:http://127.0.0.1:10086
Eureka注册中心_第3张图片
没有服务注册到尤里卡,所以实例为空Eureka注册中心_第4张图片

1.2 将user-service注册到Eureka

注册服务,就是在服务上添加Eureka的客户端依赖,客户端代码会自动把服务注册到EurekaServer中。

我们在user-service-demo中添加Eureka客户端依赖:

先添加SpringCloud依赖:全部复制追加


<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-dependenciesartifactId>
            <version>Finchley.RC1version>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>

<repositories>
    <repository>
        <id>spring-milestonesid>
        <name>Spring Milestonesname>
        <url>https://repo.spring.io/milestoneurl>
        <snapshots>
            <enabled>falseenabled>
        snapshots>
    repository>
repositories>

然后是Eureka客户端:添加依赖中


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>

在启动类上开启Eureka客户端功能

通过添加@EnableDiscoveryClient来开启Eureka客户端功能

@SpringBootApplication
@EnableEurekaClient // 开启EurekaClient功能
public class UserServiceDemoApplication {
	public static void main(String[] args) {
		SpringApplication.run(UserServiceDemoApplication.class, args);
	}
}

编写配置

server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/crm?useUnicode=true&characterEncoding=utf8
    username: root
    password: 123
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: user-service # 应用名称
eureka:
  client:
    service-url: # EurekaServer地址
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true # 当调用getHostname获取实例的hostname时,返回ip而不是host名称
    ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找

注意:

  • 这里我们添加了spring.application.name属性来指定应用名称,将来会作为应用的id使用。
  • 不用指定register-with-eureka和fetch-registry,因为默认是true

重启项目,报错

Eureka注册中心_第5张图片
在这里插入图片描述
解决方案,设置如下:
Eureka注册中心_第6张图片
注意层级关系,yaml语法很注重

main:
    allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册

再次运行,OK
Eureka注册中心_第7张图片
我们发现user-service服务已经注册成功了

1.3 消费者从Eureka获取服务

接下来我们修改consumer-demo,尝试从EurekaServer获取服务。

方法与消费者类似,只需要在项目中添加EurekaClient依赖,就可以通过服务名称来获取信息了!

1)添加依赖:

先添加SpringCloud依赖:和服务端一样,对尤里卡而言,服务端客户端都是客户端


<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-dependenciesartifactId>
            <version>Finchley.RC1version>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>

<repositories>
    <repository>
        <id>spring-milestonesid>
        <name>Spring Milestonesname>
        <url>https://repo.spring.io/milestoneurl>
        <snapshots>
            <enabled>falseenabled>
        snapshots>
    repository>
repositories>

然后是Eureka客户端:


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>

2)在启动类开启Eureka客户端

@SpringBootApplication
@EnableDiscoveryClient // 开启Eureka客户端
public class UserConsumerDemoApplication {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
    }
    public static void main(String[] args) {
        SpringApplication.run(UserConsumerDemoApplication.class, args);
    }
}

3)修改配置:

server:
  port: 8082
spring:
  application:
    name: consumer # 应用名称
eureka:
  client:
    service-url: # EurekaServer地址
      defaultZone: http://127.0.0.1:10086/eureka
  instance:
    prefer-ip-address: true # 当其它服务获取地址时提供ip而不是hostname
    ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的话会自己寻找

4)修改user-consumer-demo项目中的UserDao代码,用DiscoveryClient类的方法,根据服务名称,获取服务实例:

Eureka注册中心_第8张图片

 // 必须导入org.springframework.cloud.client.discovery.DiscoveryClient
    @Autowired
    private DiscoveryClient discoveryClient;


    public User queryUserById(Long id){
        //1、 根据user-service获取user-serivce 的集群的信息
        List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
        //2、由于我们没有集群,只有一个,所以直接取出第一个
        ServiceInstance instance = instances.get(0);
        //3、拼接URL
        String url = "http://"+instance.getHost()+":"+instance.getPort()+"/user/"+id;

        // 使用restTemplate发起请求
        ResponseEntity<User> entity = restTemplate.getForEntity(url, User.class);
        // 获取返回对象
        User user = entity.getBody();
        return user;
    }

5)运行Eureka注册中心结果
Eureka注册中心_第9张图片
Postman访问结果:
Eureka注册中心_第10张图片
感兴趣,可以Debug再运行一次: (可选,直接运行也可以)
在这里插入图片描述
Eureka注册中心_第11张图片
生成的URL: (可选,直接运行也可以)
Eureka注册中心_第12张图片

二、认识Eureka

引入:首先我们来解决第一问题,服务的管理。

问题分析

在刚才的案例中,user-service对外提供服务,需要对外暴露自己的地址。而user-consumer(调用者)需要记录服务提供者的地址。将来地址出现变更,还需要及时更新。这在服务较少的时候并不觉得有什么,但是在现在日益复杂的互联网环境,一个项目肯定会拆分出十几,甚至数十个微服务。此时如果还人为管理地址,不仅开发困难,将来测试、发布上线都会非常麻烦,这与DevOps的思想是背道而驰的。

网约车

这就好比是 网约车出现以前,人们出门叫车只能叫出租车。一些私家车想做出租却没有资格,被称为黑车。而很多人想要约车,但是无奈出租车太少,不方便。私家车很多却不敢拦,而且满大街的车,谁知道哪个才是愿意载人的。一个想要,一个愿意给,就是缺少引子,缺乏管理啊。

此时滴滴这样的网约车平台出现了,所有想载客的私家车全部到滴滴注册,记录你的车型(服务类型),身份信息(联系方式)。这样提供服务的私家车,在滴滴那里都能找到,一目了然。

此时要叫车的人,只需要打开APP,输入你的目的地,选择车型(服务类型),滴滴自动安排一个符合需求的车到你面前,为你服务,完美!

Eureka做什么?

Eureka就好比是滴滴,负责管理、记录服务提供者的信息。服务调用者无需自己寻找服务,而是把自己的需求告诉Eureka,然后Eureka会把符合你需求的服务告诉你。

同时,服务提供方与Eureka之间通过“心跳”机制进行监控,当某个服务提供方出现问题,Eureka自然会把它从服务列表中剔除。

这就实现了服务的自动注册、发现、状态监控。

2.1 原理图

基本架构:

Eureka注册中心_第13张图片

  • Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址
  • 提供者:启动后向Eureka注册自己信息(地址,提供什么服务)
  • 消费者:向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新
  • 心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态

2.2 Eureka详解

接下来我们详细讲解Eureka的原理及配置。

基础架构

Eureka架构中的三个核心角色:

  • 服务注册中心

    Eureka的服务端应用,提供服务注册和发现功能,就是刚刚我们建立的eureka-demo

  • 服务提供者

    提供服务的应用,可以是SpringBoot应用,也可以是其它任意技术实现,只要对外提供的是Rest风格服务即可。本例中就是我们实现的user-service-demo

  • 服务消费者

    消费应用从注册中心获取服务列表,从而得知每个服务方的信息,知道去哪里调用服务方。本例中就是我们实现的user-consumer-demo
    Eureka机制,宁可放过一千,不可错杀一个服务
    下篇文章,Eureka搭建集群

祝你幸福
送你一首歌《It Never Rains In Southern California [1972]》Albert hammond
附图:我的桌面

你可能感兴趣的:(微服务)