微服务注册与发现

目录

  • 简介
  • 实现服务注册组件
    • 设计服务注册表数据结构
    • 搭建应用程序框架
    • 定义服务注册表接口
    • 使用 ZooKeeper 实现服务注册
    • 服务注册模式
  • 实现服务发现组件
    • 搭建应用程序框架
    • 实现服务发现
    • 服务发现优化方案
    • 服务发现模式
  • 参考

简介

先来回顾下整体的微服务架构

在发布微服务时,可连接 ZooKeeper 来注册微服务,实现“服务注册”。当浏览器发送请求后,可使用 Node.js 充当 service gateway,处理浏览器的请求,连接 ZooKeeper,发现服务配置,实现服务发现。

实现服务注册组件

Service Registry(服务注册表),内部拥有一个数据结构,用于存储已发布服务的配置信息。本节会使用 Spring Boot 与 Zookeeper 开发一款轻量级服务注册组件。开发之前,先要做一个简单的设计。

设计服务注册表数据结构

首先在 Znode 树状模型下定义一个 根节点,而且这个节点是持久的。

在根节点下再添加若干子节点,并使用服务名称作为这些子节点的名称,并称之为 服务节点。为了确保服务的高可用性,我们可能会发布多个相同功能的服务,但由于 zookeeper 不允许存在同名的服务,因此需要再服务节点下再添加一层节点。因此服务节点则是持久的。

服务节点下的这些子节点称为 地址节点 。每个地址节点都对应于一个特定的服务,我们将服务配置存放在该节点中。服务配置中可存放服务的 IP 和端口。一旦某个服务成功注册到 Zookeeper 中, Zookeeper 服务器就会与服务所在的客户端进行心跳检测,如果某个服务出现了故障,心跳检测就会失效,客户端将自动断开与服务端的会话,对应的地址节点也需要从 Znode 树状模型中移除。因此 地址节点必须是临时而且有顺序的

根据上面的分析,服务注册表数据结构模型图如下所示

真实的服务注册实例如下:

由上图可见,只有地址节点才有数据,这些数据就是每个服务的配置信息,即 IP 与端口,而且地址节点是临时且顺序的,根节点与服务节点都是持久的。

下面会根据这个设计思路,实现服务注册表的相关细节。但是在开发具体细节之前,我们先搭建一个代码框架。手续爱你我们需要创建两个项目,分别是:

  • msa-sample-api 用于存放服务 API 代码,包含服务定义相关细节。
  • msa-framework 存放框架性代码,包含服务注册表细节

定义好项目后,就需要再 msa-sample-api 项目中编写服务的业务细节,在 msa-framework 项目中完成服务注册表的具体实现。

搭建应用程序框架

msa-sample-api 项目中搭建 Spring Boot 应用程序框架,创建一个名为 HelloApplication 的类,该类包含一个 hello() 方法,用于处理 GET:/hello 请求。

package demo.msa.sample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

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

    @RequestMapping (method= RequestMethod.GET, path = "/hello")
    public String hello() {
        return "hello";
    }
}

随后,在 application.properties 文件中添加如下配置项

server.port=8080
spring.application.name=msa-sample-api
registry.zk.servers=127.0.0.1:2181

之所以设置 spring.application.name 配置项,是因为我们正好将其作为服务名称来使用。registry.zk.servers 配置项表示服务注册表的 IP 与端口,实际上就是 Zookeeper 的连接字符串。如果连接到 Zookeeper 集群环境,就可以使用逗号来分隔多个 IP 与端口,例如: ip1:port,ip2:port,ip3:port

最后配置 maven 依赖:

<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>

    <groupId>demo.msa</groupId>
    <artifactId>msa-sample-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>msa-sample</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.6.RELEASE</version>
    </parent>

    <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    <dependency>
        <groupId>demo.msa</groupId>
        <artifactId>msa-framework</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

定义服务注册表接口

服务注册表接口用于注册相关服务信息,包括

  • 服务名称
  • 服务地址包括
    • 服务所在机器的 IP
    • 服务所在机器的端口

msa-framework 项目中创建一个名为 ServiceRegistry 的 Java 接口类,代码如下:

package demo.msa.framework.registry;

public interface ServiceRegistry {

    /**
     * 注册服务信息
     * @param serviceName 服务名称
     * @param serviceAddress 服务地址
     */
    void register(String serviceName, String serviceAddress);

}

下面来实现 ServiceRegistry 接口,它会通过 ZooKeeper 客户端创建响应的 ZNode 节点,从而实现服务注册。

使用 ZooKeeper 实现服务注册

msa-framework 中创建一个 ServiceRegistry 的实现类 ServiceRegistryImpl 。同时还需要实现 ZooKeeper 的 Watch 接口,便于监控 SyncConnected事件,以连接 ZooKeeper 客户端。

package demo.msa.framework.registry;

import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ServiceRegistryImpl implements ServiceRegistry, Watcher {

    private static final String REGISTRY_PATH = "/registry";

    private static final int SESSION_TIMEOUT = 5000;

    private static final Logger logger = LoggerFactory.getLogger(ServiceRegistryImpl.class);

    private static CountDownLatch latch = new CountDownLatch(1);

    private ZooKeeper zk;

    public ServiceRegistryImpl() {
        // TODO Auto-generated constructor stub
    }

    public ServiceRegistryImpl(String zkServers) {
        try {
            // 创建 zookeeper
            zk = new ZooKeeper(zkServers, SESSION_TIMEOUT, this);
            latch.await();
            logger.debug("connect to zookeeper");
        } catch (Exception ex) {
            logger.error("create zk client fail", ex);
        }
    }

    @Override
    public void register(String serviceName, String serviceAddress) {
        try {
            // 创建根节点(持久节点)
            if (zk.exists(REGISTRY_PATH, false) == null) {
                zk.create(REGISTRY_PATH, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
                logger.debug("create registry node: {}", REGISTRY_PATH);
            }

            // 创建服务节点 (持久节点)
            String servicePath = REGISTRY_PATH + "/" + serviceName;
            if (zk.exists(servicePath, false) == null) {
                zk.create(servicePath, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

                logger.debug("create registry node: {}", REGISTRY_PATH);
            }

            // 创建地址节点  (临时有序节点)
            String addresspath = servicePath + "/address-";
            String addressNode = zk.create(addresspath, serviceAddress.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
            logger.debug("create address node: {} => {}", addressNode, serviceAddress);
            if (zk.exists(REGISTRY_PATH, false) == null) {
                zk.create(REGISTRY_PATH, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
                logger.debug("create registry node: {}", REGISTRY_PATH);
            }

            String servicePath = REGISTRY_PATH + "/" + serviceName;
            if (zk.exists(servicePath, false) == null) {
                zk.create(servicePath, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

                logger.debug("create registry node: {}", REGISTRY_PATH);
            }

            String addresspath = servicePath + "/address-";
            String addressNode = zk.create(addresspath, serviceAddress.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
            logger.debug("create address node: {} => {}", addressNode, serviceAddress);
        } catch(Exception ex) {
            logger.error("create node fail", ex);
        }

    }

    @Override
    public void process(WatchedEvent event) {
        if (event.getState() == Event.KeeperState.SyncConnected) {
            latch.countDown();
        }
    }
}

使用 ZooKeeper 的客户端 API, 很容易创建 ZNode 节点,只是在调用节点之前有必要调用 exists() 方法,判断将要创建的的节点是否已经存在。需要注意, 根节点和服务节点都是持久节点 ,只有地址节点是临时有序节点。并且有必要在创建节点完成后输出一些调试信息,来获知节点是否创建成功了。

我们的期望是,当 HelloApplication 程序启动时,框架会将其服务器 IP 与端口注册到服务注册表中。实际上,在 ZooKeeper 的 ZNode 树状模型上将创建 /registry/msa-sample-api/address-0000000000 节点,该节点所包含的数据为 127.0.0.1:8080msa-framework 项目则封装了这些服务注册行为,这些行为对应用端完全透明,对 ServiceRegistry 接口而言,则需要在框架中调用 register()方法,并传入 serviceName 参数(/registry/msa-sample-api/address-0000000000)与 serviceAddress 参数(127.0.0.1:8080)。

接下来要做的就是通过编写 Spring 的 @configuration 配置类来创建 ServiceRegistry 对象,并调用 register() 方法。具体代码如下:

package demo.msa.sample.config;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import demo.msa.framework.registry.ServiceRegistry;
import demo.msa.framework.registry.ServiceRegistryImpl;

@Configuration
public class RegistryConfig {
    @Value("${registry.zk.servers}")
    private String servers;

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

    @Value("${spring.application.name}")
    private String serviceName;

    @Bean
    public ServiceRegistry serviceRegistry() {
        ServiceRegistry serverRegistry = new ServiceRegistryImpl(servers);
        String serviceAdress = getServiceAddress();
        serverRegistry.register(serviceName, serviceAdress);
        return serverRegistry;
    }

    private String getServiceAddress() {
        InetAddress localHost = null;
        try {
          localHost = Inet4Address.getLocalHost();
        } catch (UnknownHostException e) {
        }
        String ip = localHost.getHostAddress();

        return ip + ":" + serverPort;
    }

}

其中,getServiceAddress 方法用来获取服务运行的本机地址和端口。

此时,服务注册组件已经基本开发完毕,此时可启动 msa-sample-api 应用程序,并通过命令客户端来观察 ZooKeeper 的 ZNode 节点信息。通过下面命令连接到 ZooKeeper 服务器,并观察注册表中的数据结构:

$ bin/zkCli.sh

服务注册表数据结构如下所示:

[zk: localhost:2181(CONNECTED) 4] ls /registry/msa-sample-api
[address-0000000001]
[zk: localhost:2181(CONNECTED) 5] get /registry/msa-sample-api/address-0000000001
127.0.0.1:8080
cZxid = 0x79
ctime = Sun Jan 06 18:22:18 CST 2019
mZxid = 0x79
mtime = Sun Jan 06 18:22:18 CST 2019
pZxid = 0x79
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x16817f3391b002c
dataLength = 16
numChildren = 0

服务注册模式

服务注册 (Service Registry) 是一种微服务架构的核心模式,我们可以在微服务网站上了解它的详细内容。

Service Registry 模式: https://microservices.io/patterns/service-registry.html

有两种服务注册模式

除了 ZooKeeper,还有一些其他的开源服务注册组件,比如 Eureka, Etcd, Consul 等。

实现服务发现组件

服务发现组件在微服务架构中由 Service Gateway(服务网关)提供支持,前端发送的 HTTP 请求首先会进入服务网关,此时服务网关将从服务注册表中获取当前可用服务对应的服务配置,随后将通过 反向代理技术 调用具体的服务。像这样获取可用服务配置的过程称为 服务发现。服务发现是整个微服务架构中的 核心组件,该组件不仅需要 高性能,还要支持 高并发,还需具备 高可用

当我们启动多个 msa-sample-api 服务(调整为不同的端口)时,会在服务注册表中注册如下信息:

/registry/msa-sample-api/address-0000000000 => 127.0.0.1:8080
/registry/msa-sample-api/address-0000000001 => 127.0.0.1:8081
/registry/msa-sample-api/address-0000000002 => 127.0.0.1:8082

以上结构表示同一个 msa-sample-api 服务节点包含 3 个地址节点,每个地址节点都包含一组服务配置(IP 和端口)。我们的目标是,通过服务节点的名称来获取其中某个地址节点所对应的服务配置。最简单的做法是随机获取一个地址节点,当然可以根据 轮询 或者 哈希 算法来获取地址节点。

因此,要实现以上过程,我们必须得知服务节点的名称是什么,也就是服务名称是什么,可以通过服务名称来获取服务配置,那么,如何获取服务名称呢?

当服务网关接收 HTTP 请求时,我们能够很轻松的获取请求的相关信息,最容易获取服务名称的地方就是请求头,我们不妨 添加一个名为 Service-Name 的自定义请求头,用它来定义服务名称,随后可在服务网关中获取该服务名称,并在服务注册表中根据服务名称来获取对应的服务配置。

搭建应用程序框架

我们再创建一个项目,名为 msa-service-gateway ,它相当于整个微服务架构中的前端部分,其中包括一个服务发现框架。至于测试请求,可以使用 firefox 插件 RESTClient 来完成。

项目msa-service-gateway 包含两个文件

  • app.js :服务网关应用程序,通过 Node.js 来实现
  • package.json 用于存放 Node.js 的基本信息,以及所依赖的 NPM 模块。

首先在 package.json 文件中添加代码

{
  "name": "msa-service-gateway",
  "version": "1.0.0",
  "dependencies": {
  }
}

实现服务发现

实现服务发现,需要安装 3 个模块,分别是

  • express : web Server 应用框架
  • node-zookeeper-client: node.js zooKeeper 客户端
  • http-proxy : 代理模块

使用下面命令来依次安装它们

npm install express -save
npm install node-zookeeper-client -save
npm install http-proxy -save

app.js 的代码如下所示

var express = require('express')
var zookeeper = require('node-zookeeper-client')
var httpProxy = require('http-proxy')

var REGISTRY_ROOT = '/registry';

var CONNECTION_STRING = '127.0.0.1:2181';
var PORT = 1234;

// 连接 zookeeper
var zk = zookeeper.createClient(CONNECTION_STRING);
zk.connect();

// 创建代理服务器对象并监听错误事件
var proxy = httpProxy.createProxyServer()
proxy.on('error', function(err, req, res) {
  res.end();
})

var app = express();
// 拦截所有请求
app.all('*', function (req, res) {
  // 处理图标请求
  if (req.path == '/favicon.ico') {
    res.end();
    return;
  }

  // 获取服务名称
  var serviceName = req.get('Service-Name');
  console.log('serviceName: %s', serviceName);
  if (!serviceName) {
    console.log('Service-Name request header is not exist');
    res.end();
    return
  }

  // 获取服务路径
  var servicePath = REGISTRY_ROOT + '/' + serviceName;
  console.log('serviceName: %s', servicePath)

  // 获取服务路径下的地址节点
  zk.getChildren(servicePath, function (error, addressNodes) {
    if (error) {
      console.log(error.stack);
      res.end();
      return;
    }

    var size = addressNodes.length;
    if (size == 0) {
      console.log('address node is not exist');
      res.end();
      return;
    }

    // 生成地址路径
    var addressPath = servicePath + '/';
    if (size === 1) {
      // 如果只有一个地址,则获取该地址
      addressPath += addressNodes[0];
    } else {
      // 若存在多个地址,则随机获取一个地址
      addressPath += addressNodes[parseInt(Math.random()*size)]
    }

    console.log('addressPath: %s', addressPath)

    zk.getData(addressPath, function(error, serviceAddress) {
      if (error) {
        console.log(error.stack);
        res.end();
        return;
      }

      console.log('serviceAddress: %s', serviceAddress)

      if (!serviceAddress) {
        console.log('service address is not exist')
        res.end()
        return
      }

      proxy.web(req, res, {
        target: 'http://' + serviceAddress
      });
    })
})
});

app.listen(PORT, function() {
  console.log('server is running at %d', PORT)
})

使用下面命令启动 web server:

$ node app.js

此时,使用 firefox 插件 RESTClient 向地址 http://localhost:1234/hello 发送请求,记得要配置 HTTP 头字段 Service-Name=msa-sample-api 。可以获取到结果 hello

在 Node.js 控制台可以看到如下输出结果。

$ node app.js
server is running at 1234
serviceName: msa-sample-api
serviceName: /registry/msa-sample-api
addressPath: /registry/msa-sample-api/address-0000000001
serviceAddress: 127.0.0.1:8080

服务发现优化方案

服务发现组件虽然基本可用,但实际上代码中还存在着大量的不足,需要我们不断优化(这部分内容后续完善)。

  1. 连接 ZooKeeper 集群环境
  2. 对服务发现的目标地址进行缓存
  3. 使服务网关具备高可用性

服务发现模式

服务发现 servicer discovery 是一种微服务架构的核心模式,它一般与服务注册模式共同使用。

服务发现模式分为两种:

  • 客户端发现 client side discovery

    • 是指服务发现机制在客户端中实现
  • 服务端发现 server side discovery
    • 服务发现机制通过一个路由中间件来实现
    • 当前实现的就是服务端发现模式

Ribbon 是一款基于 Java 的 HTTP 客户端附件,它可以查询 Eureka,将 HTTP请求路由到可用的服务接口上。

参考

  • 《架构探险—轻量级微服务架构》

原文地址:https://www.cnblogs.com/reycg-blog/p/10229945.html

时间: 2024-09-30 09:32:52

微服务注册与发现的相关文章

微服务-注册与发现-zookeeper bydasn

目录 一.微服务注册的概述 二.zookeeper2.1 zookeeper基本操作2.2 zookeeper集群搭建 一.微服务注册概述 在微服务中,有这么一个东西叫服务注册表,服务注册表是整个微服务的核心,功能有两个,服务注册以及服务发现.   那么这张表有什么要求?   a.服务注册以及服务发现:首先服务启动后,要往表上面写配置信息,注册服务,然后客户端要能发现服务,反向代理去拿这些东西.   b.心跳检测:如果发现某个服务没办法访问量,马上就得移除掉,要求高性能以及高可用. 二.zook

SpringCloud(二)服务注册与发现

离上一篇微服务的基本概念已经过去了几个月,在写那篇博客之前,自己还并未真正的使用微服务架构,很多理解还存在概念上.后面换了公司,新公司既用了SpringCloud也用了Dubbo+Zookeeper,就像上一篇文章说的,当一个服务是面向外部或者是直接提供给前端调用的,那么就使用SpringCloud,而一些内部公用的,比如一些特定服务(如发送短信),就使用Dubbo+Zookeeper,因为他在内部调用更像调用接一个接口,效率也会比较高,而一些模块型的功能,我们则使用SpringCloud. 在

Spring Cloud构建微服务架构(一)——服务注册与发现

Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策竞选.分布式会话和集群状态管理等操作提供了一种简单的开发方式. Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config.Spring Cloud Netflix.Spring Cloud CloudFoundry.Spr

初见微服务之服务注册与发现

什么是服务注册与发现 微服务将传统的"巨石"应用拆分成一个一个的组件应用,每个组件应用提供特定的服务,可以是一个,也可以是多个,并且组件所含服务应该是可以动态扩展的,随着时间推移.系统进化,可任意拆分.合并. 组件化应用和颗粒化的服务,遍布在系统的各个角落,由不同的项目成员进行维护,微服务的核心是化整为零.各司其职,这就要求开发人员不得操作其业务或服务范围以外的数据模型等资源,只能通过接口的访问,使用某一服务. 由于服务的跨度很大(公司很大的情况下).数量很多(数以百计甚至更多),为保

微服务~Eureka实现的服务注册与发现及服务之间的调用

微服务里一个重要的概念就是服务注册与发现技术,当你有一个新的服务运行后,我们的服务中心可以感知你,然后把加添加到服务列表里,然后当你死掉后,会从服务中心把你移除,而你作为一个服务,对其它服务公开的只是服务名称,而不是最终的服务地址URL,这对于云平台,容器化架构来说是非常重要的! 安装单独的Eureka服务(server) 服务注册-aspnetcore建立Eureka客户端(client) 服务发现-实现服务与服务的调用 一 安装单独的Eureka服务 安装tomcat,到apache官网ht

Spring Cloud构建微服务架构(一)服务注册与发现

原文来源:http://blog.didispace.com/springcloud1/ Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策竞选.分布式会话和集群状态管理等操作提供了一种简单的开发方式. Spring Cloud包含了多个子项目(针对分布式系统中涉及的多个不同开源产品),比如:Spring Cloud Config.Sprin

微服务-服务注册与发现

1.服务注册与发现基础架构 注册中心: 接受服务提供者的注册.存储服务提供者的服务信息 ,比如ip 端口号 服务名这些信息: 并且与微服务保持心跳,如果心跳不能保持则注销该实例. 所以注册中心主要提供服务提供者信息的存储,另外与服务提供者保持心跳以监控服务提供者的存活. 服务提供者: 向注册中心提供服务信息,以及一些健康状态. 服务消费者: 定期向注册中心发送查询请求,以获取服务提供者的信息,获取信息之后就向服务提供者发起服务调用. 当服务提供者向注册中心 ,注册或者注销时,它可以接收到来自注册

聊聊微服务的服务注册与发现

摘要: 一个好的服务注册发现中间件,应该是能完整地满足服务开发和治理的基础功能,然后才是性能和高可用.如果没有想清楚前面的功能,再高的可用性和性能都是浮云.最后,安全也同样重要.下面将从 服务注册.服务发现.容灾和高可用三个大方面来回答这些问题的主流做法. 引言 聊起微服务的服务注册与发现,很多人立马就会脱口而出 zk.etcd.consul.eureka 这些组件,进而聊到 CAP 如何取舍,性能如何,高可用和容灾是怎么实现的. 在这之前,站在组件使用者的角度,我想先问这么几个问题: 注册的

springcloud微服务系列之服务注册与发现组件Eureka

一.Eurake的简介二.使用Eureka进行服务的注册消费1.创建一个服务注册中心2.创建服务的提供者3.创建服务的消费者总结 一.Eurake的简介 今天我们来介绍下springcloud的核心组件Eureka,Eurake是负责微服务架构中服务治理的功能,负责各个服务实例的注册与发现. Eureka包含了服务器端和客户端组件.服务器端,也被称作是服务注册中心,用于提供服务的注册与发现. 客户端组件包含服务消费者与服务生产者.在应用程序运行时,服务生产者向注册中心注册自己的服务实例,当消费者