Spring Cloud Eureka:微服务世界的GPS,让服务无处可藏!

注册中心介绍 

String url = "http://127.0.0.1:9090/product/"+ orderInfo.getProductId(); 

当更换机器, 或者新增机器时, 这个URL就需要跟着变更, 就需要去通知所有的相关服务去修改. 随之⽽来的就是各个项⽬的配置⽂件反复更新, 各个项⽬的频繁部署. 这种没有具体意义, 但⼜不得不做的⼯作, 会让⼈⾮常痛苦.

同样的, 微服务开发时, 也可以采⽤类似的⽅案

服务启动/变更时, 向注册中⼼报道. 注册中⼼记录应⽤和IP的关系

调⽤⽅调⽤时, 先去注册中⼼获取服务⽅的IP, 再去服务⽅进⾏调⽤

什么是注册中⼼

在最初的架构体系中, 集群的概念还不那么流⾏, 且机器数量也⽐较少, 此时直接使⽤DNS+Nginx就可 以满⾜⼏乎所有服务的发现. 相关的注册信息直接配置在Nginx. 但是随着微服务的流⾏与流量的激增, 机器规模逐渐变⼤, 并且机器会有频繁的上下线⾏为, 这种时候需要运维⼿动地去维护这个配置信息是 ⼀个很⿇烦的操作. 所以开发者们开始希望有这么⼀个东西, 它能维护⼀个服务列表, 哪个机器上线了, 哪个机器宕机了, 这些信息都会⾃动更新到服务列表上, 客⼾端拿到这个列表, 直接进⾏服务调⽤即可. 这个就是注册中⼼.

注册中⼼主要有三种⻆⾊:

  • 服务提供者(Server):⼀次业务中, 被其它微服务调⽤的服务. 也就是提供接⼝给其它微服务
  • 服务消费者(Client):⼀次业务中, 调⽤其它微服务的服务. 也就是调⽤其它微服务提供的接⼝
  • 服务注册中⼼(Registry): ⽤于保存Server 的注册信息, 当Server 节点发⽣变更时, Registry 会同步 变更服务与注册中⼼使⽤⼀定机制通信, 如果注册中⼼与某服务⻓时间⽆法通信, 就会注销该实例

他们之间的关系以及⼯作内容, 可以通过两个概念来描述

  • 服务注册:服务提供者在启动时, 向 Registry 注册⾃⾝服务, 并向 Registry 定期发送⼼跳汇报存活状 态
  • 服务发现: 服务消费者从注册中⼼查询服务提供者的地址,并通过该地址调⽤服务提供者的接⼝. 服务 发现的⼀个重要作⽤就是提供给服务消费者⼀个可⽤的服务列表.

CAP理论

谈到注册中⼼, 就避不开CAP理论.

CAP 理论是分布式系统设计中最基础, 也是最为关键的理论

  • ⼀致性(Consistency) CAP理论中的⼀致性, 指的是强⼀致性. 所有节点在同⼀时间具有相同的数据 可⽤性(Availability) 保证每个请求都有响应(响应结果可能不对)
  • 可⽤性(Availability) 保证每个请求都有响应(响应结果可能不对)
  • 分区容错性(Partition Tolerance) 当出现⽹络分区后,系统仍然能够对外提供服务

⼀个部⻔全国各地都有岗位, 这时候, 总部下发了⼀个通知, 由于通知需要开会周知全员, 当有客⼾咨 询时

  1. 所有成员对客⼾的回应结果都是⼀致的(⼀致性)
  2. 客⼾咨询时, ⼀定有回应(可⽤性)
  3. 当其中⼀个成员休假时, 这个部⻔的其他成员也可以对客⼾提供咨询服务(分区容错性)

CAP 理论告诉我们: ⼀个分布式系统不可能同时满⾜数据⼀致性, 服务可⽤性和分区容错性这三个基本 需求, 最多只能同时满⾜其中的两个

在分布式系统中, 系统间的⽹络不能100%保证健康, 服务⼜必须对外保证服务. 因此Partition Tolerance不可避免. 那就只能在C和A中选择⼀个. 也就是CP或者AP架构

正常情况:

⽹络异常:

  • CP架构: 为了保证分布式系统对外的数据⼀致性, 于是选择不返回任何数据
  • AP架构: 为了保证分布式系统的可⽤性, 节点2返回V0版本的数据(即使这个数据不正确)

更多参考: https://cloud.tencent.com/developer/article/1860632

常⻅的注册中⼼

  1. Zookeeper Zookeeper的官⽅并没有说它是⼀个注册中⼼, 但是国内Java体系, ⼤部分的集群环境都是依赖 Zookeeper来完成注册中⼼的功能
  2. Eureka Eureka是Netflix开发的基于REST的服务发现框架, 主要⽤于服务注册, 管理,负载均衡和服务故障 转移. 官⽅声明在Eureka2.0版本停⽌维护, 不建议使⽤. 但是Eureka是SpringCloud服务注册/发现的默认 实现, 所以⽬前还是有很多公司在使⽤.
  3. Nacos Nacos是Spring Cloud Alibaba架构中重要的组件, 除了服务注册, 服务发现功能之外, Nacos还⽀持 配置管理, 流量管理, DNS, 动态DNS等多种特性

CAP理论对⽐

ZookeeperEurekaNacos
CAP理论 CCPAPCP或AP 默认AP

Eureka介绍

Eureka是Netflix OSS套件中关于服务注册和发现的解决⽅案. Spring Cloud对Eureka进⾏了集成, 并 作为优先推荐⽅案进⾏宣传, 虽然⽬前Eureka 2.0已经停⽌维护, 新的微服务架构设计中, 也不再建议使 ⽤, 但是⽬前依然有⼤量公司的微服务系统使⽤Eureka作为注册中⼼

官⽅⽂档: https://github.com/Netflix/eureka/wiki

Eureka主要分为两个部分:

  • Eureka Server: 作为注册中⼼Server端, 向微服务应⽤程序提供服务注册, 发现, 健康检查等能⼒
  • Eureka Client: 服务提供者, 服务启动时, 会向Eureka Server 注册⾃⼰的信息(IP,端⼝,服务信息 等),Eureka Server 会存储这些信息

关于Eureka的学习, 主要包含以下三个部分:

  1. 搭建Eureka Server
  2. 将order-service, product-service 都注册到Eureka
  3. order-service远程调⽤时, 从Eureka中获取product-service的服务列表, 然后进⾏交互

搭建Eureka Server

Eureka-server 是⼀个独⽴的微服务

创建Eureka-server ⼦模块

  • 复制原文件,修改pom文件中的组织名称

  • 同时将子项目的pom文件修改

搭建注册中心

创建项目

pom加入Eureka依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

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

配置文件,增加Eureka相关的配置

# Eureka相关配置
# Eureka 服务
server:
  port: 10010
spring:
  application:
    name: eureka-server
eureka:
  instance:
    hostname: localhost
  client:
    fetch-registry: false # 表示是否从Eureka Server获取注册信息,默认为true.因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,这里设置为false
    register-with-eureka: false # 表示是否将自己注册到Eureka Server,默认为true.由于当前应用就是Eureka Server,故而设置为false.
    service-url:
      # 设置与Eureka Server的地址,查询服务和注册服务都需要依赖这个地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

启动类,开启Eureka的功能

package Eureka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

测试

启动服务, 访问注册中⼼: http://127.0.0.1:10010/

服务注册

加入Eureka的依赖

<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
//在子项目中引入依赖,也就是服务提供方

修改配置信息

#Eureka Client
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10010/eureka/

spring:
  application:
    name: product-service

启动,测试程序

服务发现

加入Eureka的依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

修改配置信息

#Eureka Client
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10010/eureka/  

spring:
  application:
    name: order-service

修改远程调用代码

package order.service;

import lombok.extern.slf4j.Slf4j;
import order.mapper.OrderMapper;
import order.model.OrderInfo;
import order.model.ProductInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@Slf4j
@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    public OrderInfo selectOrderById(Integer orderId){
        OrderInfo orderInfo = orderMapper.selectOrderById(orderId);
        // String url = "http://127.0.0.1:9090/product/"+orderInfo.getProductId();
        //从Eureka中获取服务列表
        List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
        String uri = instances.get(0).getUri().toString();
        log.info("远程调用"+uri);
        String url=uri+"/product/"+orderInfo.getProductId();
        ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);
        orderInfo.setProductInfo(productInfo);
        return orderInfo;
    }
}

启动,测试程序

也可以通过order-service的代码

Eureka 和Zookeeper区别

Eureka和Zookeeper都是⽤于服务注册和发现的⼯具,区别如下

  1. Eureka是Netflix开源的项⽬, ⽽Zookeeper是Apache开源的项⽬
  2. Eureka 基于AP原则, 保证⾼可⽤, Zookeeper基于CP原则, 保证数据⼀致性
  3. Eureka 每个节点 都是均等的, Zookeeper的节点区分Leader 和Follower 或 Observer, 也正因为这 个原因, 如果Zookeeper的Leader发⽣故障时, 需要重新选举, 选举过程集群会有短暂时间的不可⽤.
  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值