Eureka停更了,我该何去何从...

Posted 猿生日记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Eureka停更了,我该何去何从...相关的知识,希望对你有一定的参考价值。

一. 背景:

Eureka 2.0 (Discontinued)



The existing open source work on eureka 2.0 is discontinued. The code base and artifacts that were released as part of the existing repository of work on the 2.x branch is considered use at your own risk.
Eureka 1.x is a core part of Netflix's service discovery system and is still an active project.
    服务注册中心是SOA的重要组成部分,它负责服务的注册、发现和管理等功能,是维护SOA计算模式正常运行的基础,Eureka停更不停用,也不再维护,我们也需要 替换合适 的服务注册中心。
    可以采用的有比如Zookeeper/Consul/ ♥Nacos♥ 下面来谈一谈各个之间的差异
二. CAP原则:

    CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。


  • 一致性(C):在分布式系统中,如果服务器集群,每个节点在同时刻访问必须要保持数据的一致性.同一时间看到的数据是一致的.

  • 可用性(A):保证每个请求不管成功或者失败都有响应,所有的请求都会得到响应 .

  • 分区容错性(P):系统中任意信息的丢失或失败不会影响系统的继续运作.

三. Zookeeper代替Eureka:

    Zookeeper采用CP保证数据的一致性的问题当我们ZK领导者因为某种情况下部分节点出现了故障,会自动重新实现选举新的领导角色,整个选举的过程中为了保证数据一致性的问题, 客户端暂时无法使用我们的Zookeeper, 那么这意味着整个微服务无法实现通讯(本地有缓存除外)。

    原理采用(ZAB原子广播协议) ,ZAB协议有两种模式,它们分别是恢复模式和广播模式。当服务启动或者在领导者崩溃后,ZAB就进入了恢复模式,当领导者被选举出来,且大多数server的完成了和leader的状态同步以后,恢复模式就结束了。

    状态同步保证了leader和server具有相同的系统状态,一旦leader已经和多数的follower进行了状态同步后,他就可以开始广播消息了,即进入广播状态。这时候当一个server加入zookeeper服务中,它会在恢复模式下启动,发现leader,并和leader进行状态同步。待到同步结束,它也参与消息广播。

3.1 Zab协议如何保持数据的一致性
    所有写的请求统一交给我们的领导(leader)角色实现,领导角色写完数据之后,领导角色再将数据同步给每个节点,数据之间同步采用2pc两个阶段提交协议。

    选举过程:

    • 先去比较zxid,zxid谁最大谁就是为领导角色;

    • 如果zxid相等的情况下,myid谁最大谁就为领导角色;

    Eureka采用AP设计思想实现分布式注册中心, 完全去中心化、每个节点都是相等,采用你中有我、我中有你相互注册设计思想,只要最后有一台Eureka节点存在整个微服务就可以实现通讯。

中心化:必须围绕一个领导角色作为核心,选举领导和跟随者角色。
去中心化:每个角色都是均等。

3.2 zookeeper注册中心示例
代码参见:

https://github.com/xingchunjing/springcloud2020

猿生日记--jxc
pom文件添加依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
yml文件配置
spring:
  cloud:
    zookeeper:
      connect-string: 127.0.0.1:2181
主启动类
//该注解用于使用 consul 或者 zookeeper 作为注册中心时注册服务
@EnableDiscoveryClient
配置类
package com.jingxc.study.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
consumer-controller
package com.jingxc.study.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
public class ZookeeperConsumerController {

    @Value("${server.port}")
    private String serverPort;
    public static final String INVOKE_URL = "http://cloud-provider-gesoten";
    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/test/zk")
    public String consumerZk(){
        String result = restTemplate.getForObject(INVOKE_URL + "/test/zk",String.class);
        return result;
    }
}
provider-controller
package com.jingxc.study.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@RestController
public class GesotenProviderController {

    @Value("${server.port}")
    private String serverPort;

    @RequestMapping("/test/zk")
    public String providerZk(){
        return "springcloud with zookeeper" + serverPort + UUID.randomUUID().toString();
    }

}
zookeeper注册中心信息
[zk: localhost:2181(CONNECTED) 5] ls /services 
[cloud-consumer-zookeeper, cloud-provider-gesoten]
[zk: localhost:2181(CONNECTED) 6] ls /services/cloud-provider-gesoten 
[fa1acc10-597c-46d5-acb1-af4f02d97e1b]
[zk: localhost:2181(CONNECTED) 7]  get /services/cloud-provider-gesoten/fa1acc10-597c-46d5-acb1-af4f02d97e1b
{"name":"cloud-provider-gesoten","id":"fa1acc10-597c-46d5-acb1-af4f02d97e1b","address":"bogon","port":8001,"sslPort":null,"payload":{"@class":"org.springframework.cloud.zookeeper.discovery.ZookeeperInstance","id":"application-1","name":"cloud-provider-gesoten","metadata":{}},"registrationTimeUTC":1615441764462,"serviceType":"DYNAMIC","uriSpec":{"parts":[{"value":"scheme","variable":true},{"value":"://","variable":false},{"value":"address","variable":true},{"value":":","variable":false},{"value":"port","variable":true}]}}

zookeeper持久节点:该数据节点被创建后,就会一直存在于zookeeper服务器上,直到有删除操作来主动删除这个节点。

zookeeper临时节点:临时节点的生命周期和客户端会话绑定在一起,客户端会话失效,则这个节点就会被自动清除。

zookeeper注册中心的服务节点属于临时节点

四.Consul代替Eureka:

4.1 Consul 的主要特点有:

Service Discovery : 服务注册与发现,Consul 的客户端可以做为一个服务注册到 Consul,也可以通过 Consul 来查找特定的服务提供者,并且根据提供的信息进行调用。

Health Checking: Consul 客户端会定期发送一些健康检查数据和服务端进行通讯,判断客户端的状态、内存使用情况是否正常,用来监控整个集群的状态,防止服务转发到故障的服务上面。

KV Store: Consul 还提供了一个容易使用的键值存储。这可以用来保持动态配置,协助服务协调、建立 Leader 选举,以及开发者想构造的其它一些事务。

Secure Service Communication: Consul 可以为服务生成分布式的 TLS 证书,以建立相互的 TLS 连接。可以使用 intentions 定义允许哪些服务进行通信。可以使用 intentions 轻松管理服务隔离,而不是使用复杂的网络拓扑和静态防火墙规则。

Multi Datacenter: Consul 支持开箱即用的多数据中心,这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域。

Consul 角色

Server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其它数据中心通讯。每个数据中心的 Server 数量推荐为 3 个或是 5 个。

Client: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群。

4.2 Consul 和 eureka的对比

我们先来通过一个表格做简单对比

Feature Euerka Consul
服务健康检查 可配支持 服务状态,内存,硬盘等
多数据中心 支持
kv 存储服务 支持
一致性 raft
CAP AP CP
使用接口(多语言能力) http(sidecar) 支持 http 和 dns
watch 支持 支持 long polling/大部分增量 全量/支持long polling
自身监控 metrics metrics
安全 acl /https
编程语言 JAVA GO

4.3 Consul注册中心示例
代码参见:

https://github.com/xingchunjing/springcloud2020

猿生日记--jxc
pom文件添加依赖
<!--   引入consul客户端     -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
yml文件配置
server:
  port: 80
spring:
  application:
    name: cloud-consumer-consul
  cloud:
    consul:
      host: 127.0.0.1
      port: 8500
      discovery:
        service-name: ${spring.application.name}
主启动类
//该注解用于使用 consul 或者 zookeeper 作为注册中心时注册服务
@EnableDiscoveryClient
配置类
package com.jingxc.study.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
consumer-controller
package com.jingxc.study.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
public class ZookeeperConsumerController {

    @Value("${server.port}")
    private String serverPort;
    public static final String INVOKE_URL = "http://cloud-provider-gesoten";
    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/test/co")
    public String consumerCO(){
        String result = restTemplate.getForObject(INVOKE_URL + "/test/zk",String.class);
        return result;
    }
}
provider-controller
package com.jingxc.study.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@RestController
public class GesotenProviderController {

    @Value("${server.port}")
    private String serverPort;

    @RequestMapping("/test/co")
    public String providerCo(){
        return "springcloud with consul" + serverPort + UUID.randomUUID().toString();
    }

}
consul控制台信息

Eureka停更了,我该何去何从...

遇到的问题
由于自己是在docker安装的consul,用的是mac本,所以在consul做健康检查时,遇到下面问题

Eureka停更了,我该何去何从...

访问http://localhost:8500/v1/agent/checks查看服务状态
{
    "service:cloud-consumer-consul-80":{
        "Node":"1",
        "CheckID":"service:cloud-consumer-consul-80",
        "Name":"Service 'cloud-consumer-consul' check",
        "Status":"passing",
        "Notes":"",
        "Output":"HTTP GET http://192.168.10.113:80/actuator/health: 200 OK Output: {"status":"UP"}",
        "ServiceID":"cloud-consumer-consul-80",
        "ServiceName":"cloud-consumer-consul",
        "ServiceTags":[
            "secure=false"
        ],
        "Type":"http",
        "Definition":{

        },
        "CreateIndex":0,
        "ModifyIndex":0
    },
    "service:cloud-provider-gesoten-8001":{
        "Node":"1",
        "CheckID":"service:cloud-provider-gesoten-8001",
        "Name":"Service 'cloud-provider-gesoten' check",
        "Status":"critical",
        "Notes":"",
        "Output":"Get "http://bogon:8001/actuator/health": dial tcp: lookup bogon on 192.168.65.1:53: no such host",
        "ServiceID":"cloud-provider-gesoten-8001",
        "ServiceName":"cloud-provider-gesoten",
        "ServiceTags":[
            "secure=false"
        ],
        "Type":"http",
        "Definition":{

        },
        "CreateIndex":0,
        "ModifyIndex":0
    }
}
可以看到
"Output":"Get "http://bogon:8001/actuator/health": dial tcp: lookup bogon on 192.168.65.1:53: no such host",
    在用docker和本机相连是总是出现这个问题,网上各种解决办法,我自己想了一个最简单的,哈哈Eureka停更了,我该何去何从...,不就是想访问本机嘛,修改成127.0.0.1不就行了,编辑host文件,哈哈,加一个127.0.0.1 bogon,解决问题

Eureka停更了,我该何去何从...

五.最后:
         Zookeeper/Consul作为注册中心,就先介绍到这,最大的一头Nacos,后面会有专门讲解Nacos=Eureka+Config+Bus
    Eureka停用了,立马就有技术顶上,自己不学习了,立马就有其他人顶上,头发掉一根少一根,技术学一点多一点

以上是关于Eureka停更了,我该何去何从...的主要内容,如果未能解决你的问题,请参考以下文章

Eureka停更了?试试Zookpper和Consul

SpringCloud Eureka 注册中心

解释下最近为啥停更了

SpringCloud H版 EureKa使用及集群讲解

SpringCloud Hoxton——Zookeeper服务注册与发现

SpringCloud Hoxton——Zookeeper服务注册与发现