简介:

eureka称为注册中心,用于注册所有的微服务的,即就是使用SpringCloud做微服务开发,所有的服务都必须注册到eureka(注册中心),这样eureka(注册中心)就可以对所有的服务做统一管理了,最终是为了做服务发现(服务调用,只有注册在同一个注册中心中的所有服务之间才可以互相调用)。

CAP原则

  1. C(Consistency)强一致性: 指数据在多个副本之间能够保持一致的特性,严格的一致性;
  2. A(Availability)可用性: 指系统提供的服务必须一直处于可用的状态,每次请求都能获取到响应(但不保证获取的数据为最新数据);
  3. P(Partition tolerance)分区容错性(可靠性):分布式系统在遇到任何网络分区故障的时候,仍然能够对外提供可用性的服务,除非整个网络环境都发生了故障;

**C:**数据的一致性(注册中心A、B、C里面的数据是一致的)

Zookeeper注重数据的强一致性。

Eureka不是很注重数据的一致性。

A: 服务的可用性

在Zookeeper中,若主机挂了,则Zookeeper集群整体就不对外提供服务了,需要花费120秒左右选一个新的主机出来才能继续对外提供服务。

Eureka注重服务的可用性,Eureka集群只要有一台活着,它就能对外提供服务。

**P:**分区的容错性

由于各种网络原因,分区容错性是必须需要实现的。

Eureka和Zookeeper的区别(面试题)

Zookeeper注重数据的强一致性,选择的是CP原则。

Eureka注重服务的可用性,选择的是AP原则。

Eureka的使用

服务端的pom文件:
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
客户端的pom文件:
<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>
关于版本控制,推荐使用Hoxton.SR12版本的
版本控制:
<properties>
            <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
</properties>
选择器:
在使用ide创建项目时候,客户端必须选择web依赖,才可以正常注册到服务端eureka
代码:
服务端主启动类上添加注解:
@EnableEurekaServer客户端主启动类上添加注解:
@EnableEurekaClient
application.properties文件
#客户端:
# 应用名称
spring.application.name=eureka-client
#应用端口
server.port=8080
#注册客户端到服务端
eureka.client.service-url.defaultZone=http://localhost:8761/eureka#服务端:
# 应用名称
spring.application.name=eureka-server
#应用端口
server.port=8761
服务端其他配置:
#设置eureka服务端应用名称
spring.application.name=eureka-server-01
#设置eureka服务端(注册中心)端口--默认端口8761
server.port=8761

#注册中心定期剔除服务列表中未续约服务的时间周期--60000毫秒
eureka.server.eviction-interval-timer-in-ms=60000
#是否开启保护机制--避免因为网络等原因客户端未及时续约,而导致误剔除
eureka.server.enable-self-preservation=true
#未续约服务的阈值(百分比)--未续约的服务只要不超过这个百分比就不做剔除--体现了eureka的高可用性
eureka.server.renewal-percent-threshold=0.85

#是否注册当前服务(eureka服务端应用)到注册中心
eureka.client.register-with-eureka=false
客户端其他配置:
#设置我们的应用(服务)的名称
spring.application.name=my-server-01
#设置我们的应用(服务)的端口
server.port=8080


#是否将当前服务(我们的应用(服务))注册到注册中心
eureka.client.register-with-eureka=true
#将当前应用(服务)注册到注册中心--值为eureka服务端(注册中心)的url地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
#是否从注册中心拉取服务列表
eureka.client.fetch-registry=true
#从注册中心拉取服务列表的时间周期--每5秒钟拉取更新一次
eureka.client.registry-fetch-interval-seconds=5

#服务续约的时间周期--每10秒续约一次
eureka.instance.lease-renewal-interval-in-seconds=10
#服务续约的超时时间,超出该时间没有续约,注册中心则剔除该服务--20秒
eureka.instance.lease-expiration-duration-in-seconds=20

#服务在注册中心的注册信息的主机名称--localhost
eureka.instance.hostname=localhost
#服务在注册中心的注册信息的显示格式--主机名:应用名称:端口
eureka.instance.instance-id=${eureka.instance.hostname}:${spring.application.name}:${server.port}
#显示服务部署到的主机的IP
eureka.instance.prefer-ip-address=true

集群搭建

服务端集群搭建:

#properties文件修改

#设置当前eureka服务端应用名称 -- 统一为eureka-server
spring.application.name=eureka-server
#设置当前eureka服务端(注册中心)端口 -- 第一个为8761
server.port=8761
#设置当前eureka服务端的主机名 -- 第一个为peer1
eureka.instance.hostname=host1
#将当前eureka服务端应用注册到主机名host2端口8762和主机名host3端口8763的eureka服务端
#(注册中心)
eureka.client.service-url.defaultZone=http://host2:8762/eureka,http://host3:8763/eureka,http://host1:8761/eureka
#当前eureka服务端应用在注册中心的注册信息的显示格式--主机名:应用名称:端口
eureka.instance.instance-id=${eureka.instance.hostname}:${spring.application.name}:${server.port}
#显示当前eureka服务端应用部署到的主机的IP
eureka.instance.prefer-ip-address=true
重点:
需要搭建eureka集群的服务端的模块的应用名称应该统一
每个服务端的端口不一样
注册到其他服务端的时候,同时将自己也注册
客户端集群搭建:
# 应用名称
spring.application.name=demo_client
# 应用服务 WEB 访问端口
server.port=8083
#注册到eureka服务端
eureka.client.service-url.defaultZone=http://localhost:8761/eureka


重点:

只需要将各个客户端的应用名称统一,并且将每个客户端的访问端口设为不同

概念理解

服务的注册

当项目(eureka的客户端)启动时,就会使用post请求向注册中心(eureka的服务端)发送自己的元数据(ip,端口,健康的状态监控等),eureka的服务端会在自己内部以Map保存这些元数据(服务列表)。

Map<String, Map<String, Lease<InstanceInfo>>>

整个Map的键是应用名称(spring.application.name) (全大写),整个Map的值也是个Map;值Map的键是应

用集群的实例id(eureka.instance.instance-id),值Map的值是应用集群的实例的具体信息(InstanceInfo)。

服务的续约

项目启动成功,向注册中心注册自己成功后,还会定时的向注册中心汇报自己,表示自己还活着 — 心跳机制。

服务的下线(主动下线)

当项目关闭时,会给注册中心报告,说明自己要下机了。

服务的剔除(被动下线)

当项目超过了指定时间没有向注册中心汇报自己,那么注册中心就会认为此服务死掉了,会把它剔除掉,不会再放流量和请求到此服务了。

服务发现

简介

服务发现是指,一个服务(集群下就是服务的一个实例)通过从注册中心拉取的服务列表,根据服务(应用)名称,发现并找到另一个服务(集群下就是服务的一个实例)。{一个客户端访问另一个客户端}

代码

@RestController
public class FindController {

    /**
     * 注入RestTemplate对象
     * 使用其可以发送rest风格的请求
     * 实现发送http请求到eureka中别的服务
     */
    @Autowired
    private RestTemplate restTemplate;

    /**
     * 注入DiscoveryClient对象
     * 使用该对象可实现发现服务
     * 借助该对象可获得eureka中的某个服务的集群信息
     */
    @Autowired
    private DiscoveryClient discoveryClient;

    /*
      处理/find的请求并传参serverName -- 值给服务(应用)my-server-03的名称;
      然后响应字符串文本给客户端;
     */
    @RequestMapping("/find")
    public String find(String serverName){

        //拿到参数名称的服务(应用)的所有实例(非集群下是单个实例,集群下就是多个实例)
        List<ServiceInstance> instances = discoveryClient.getInstances(serverName);
        //拿到0角标的服务(应用)的实例(目前是非集群,服务只有一个实例)
        ServiceInstance instance = instances.get(0);
        //拿到服务实例的IP和端口
        String ip = instance.getHost();
        int port = instance.getPort();
        //拼接出请求url -- my-server-03服务(应用)的/info请求的url
        String url = "http://"+ip+":"+port+"/info";
        //发出请求,并接收my-server-03服务(应用)的/info请求响应的字符串文本
        String result = restTemplate.getForObject(url, String.class);
        //将接收的my-server-03服务(应用)的/info请求响应的字符串文本再响应给客户端
        return result;
    }
}//RestTemplate在初始化时候,是没有被自动注入IOC容器的,所以需要手动注入到IOC容器中
//配置RestTemplate的bean对象添加到容器,其可以发送rest风格的请求
@Bean
public RestTemplate restTemplate(){
    return new RestTemplate();
}

服务发现重点:

#必须在配置类中手动注入ioc后才可以使用 @Autowired private RestTemplate restTemplate; #发现的核心类 @Autowired private DiscoveryClient discoveryClient;

Eureka重点!!!

!!!

@EnableEurekaClient 和 @EnableEurekaServer 不能忘