SpringCloud——Eureka从0到1入门实战

Eureka

Eureka 简介

Eureka 是 Netflix 开发的服务发现框架,本身是一个基于 REST 的服务,主要用于定 位运行在 AWS 域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。 SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务发现 功能。
Eureka 包含两个组件:Eureka Server 和 Eureka Client。

Eureka Server

Eureka Server 提供服务注册服务,各个节点启动后,会在 Eureka Server 中进行注册, 这样 EurekaServer 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。 Eureka Server 本身也是一个服务,默认情况下会自动注册到 Eureka 注册中心。 如果搭建单机版的 Eureka Server 注册中心,则需要配置取消 Eureka Server 的自动注 册逻辑。毕竟当前服务注册到当前服务代表的注册中心中是一个说不通的逻辑。 Eureka Server 通过 Register、Get、Renew 等接口提供服务的注册、发现和心跳检测等 服务。

Eureka Client

Eureka Client 是一个 java 客户端,用于简化与 Eureka Server 的交互,客户端同时也具 备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向 Eureka Server 发送心跳,默认周期为 30 秒,如果 Eureka Server 在多个心跳周期内没有接收到某个节点的心跳,Eureka Server 将会从服务注册表中把这个服务节点移除(默认 90 秒)。 Eureka Client 分 为 两 个 角 色 , 分 别 是 : Application Service(Service Provider) 和 Application Client(Service Consumer)

Application Service

服务提供方,是注册到 Eureka Server 中的服务

Application Client

服务消费方,通过 Eureka Server 发现服务,并消费。

注意:在这里,Application Service 和 Application Client 不是绝对上的定义,因为 Provider 在提供服务的同时,也可以消费其他 Provider 提供的服务;Consumer 在消费服 务的同时,也可以提供对外服务。

Eureka 的CAP定理

CAP 定理

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

  • 数据一致性:
    系统在执行某项操作后仍然处于一致的状态。在分布式系统 中,更新操作执行成功后所有的用户都应该读到最新的值, 这样的系统被认为是具有强一致性的。等同于所有节点访问 同一份最新的数据副本。
    • 优点:数据一致,没有数据错误可能
    • 缺点:相对效率降低
  • 服务可用性:
    每一个操作总是能够在一定的时间内返回结果,这里需 要注意的是"一定时间内"和"返回结果"。一定时间内指的是, 在可以容忍的范围内返回结果,结果可以是成功或者是失败
  • 分区容错性
    在网络分区的情况下,被分隔的节点仍能正常对外提供服务(分布式集群,数据被分布存储在不同的服务器上,无论 什么情况,服务器都能正常被访问)

定律:任何分布式系统只可同时满足二点,没法三者兼顾

Eureka满足AP

Eureka 分布集群是平等模型(无主模型), 所有的节点都是平等的,客户端访问任意节 点都可以提供实时的服务响应。如果某节点发送宕机等故障,接收到的请求会转交给其他的节点。无主模型,每个节点的数据可能不实时一致,节点需要通过网络通讯从其他节点获取数据,并实现数据的一 致。可能有网络延迟或 网络故障或通讯频率问 题。

搭建 Eureka 注册中心

Eureka Server 既是一个注册中心,同时也是一个服务。那么搭建 Eureka Server 的方式 和以往搭建 Dubbo 注册中心 ZooKeeper 的方式必然不同,那么首先搭建一个单机版的 Eureka Server 注册中心。

  • pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.lanh</groupId>
    <artifactId>eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>
  • application.yml
server:
# 设置 Eureka Server WEB 控制台端口、服务注册发现端口。Eureka Server 服务注册 发现端口默认为 8761。
    port: 8761
spring:
    application:
    # 设置 spring 应用命名,默认为 null。同命名的应用会注册到同一个服务集群中。
        name: cloud-eureka
eureka:
    client:
        # 是否将自己注册到 Eureka-Server 中,默认的为 true
        register-with-eureka: false
        # 是否从 Eureka-Server 中获取服务注册信息,默认为 true
        fetch-registry: false
        service-url:
            defaultZone: http://localhost:8761/eureka/
  • 启动类
package com.lanh.eureka;

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

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {

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

}

管理页面解读

在浏览器输入:http://localhost:8761/
管理页面如下:
在这里插入图片描述

  • System Status 系统状态展示
  • DS Replicas 注册中心集群列表
  • Instances currently registered with Eureka 已在注册中心中注册的服务列表
  • General Info 当前注册中心相关信息展示
  • Instance Info 当前注册中心实例信息展示

集群原理

Eureka Server 注册中心的集群和 Dubbo 的 ZooKeeper 注册中心集群在结构上有很大的 不同。Eureka Server 注册中心集群中每个节点都是平等的,集群中的所有节点同时对外提供 服务的发现和注册等功能。同时集群中每个 Eureka Server 节点又是一个微服务,也就是说,每个节点都可以在集群中的其他节点上注册当前服务。又因为每个节点都是注册中心,所 以节点之间又可以相互注册当前节点中已注册的服务,并发现其他节点中已注册的服务。
在这里插入图片描述

将服务注册到Eureka

创建服务提供者

  • pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.lanh</groupId>
    <artifactId>provider-user</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>provider-user</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <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</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>

  • application.yml
server:
# 设置 Eureka Server WEB 控制台端口、服务注册发现端口。Eureka Server 服务注册 发现端口默认为 8761。
    port: 8081
spring:
    application:
    # 设置 spring 应用命名,默认为 null。同命名的应用会注册到同一个服务集群中。
        name: provider-user
eureka:
    client:
        service-url:
            defaultZone: http://localhost:8761/eureka/
    instance:
        prefer-ip-address: true
  • 提供服务
package com.lanh.provideruser.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author Lanh
 **/

@RestController
public class Controller {
    @GetMapping("/show")
    public String show(){
        return "Hello";
    }
}
  • 启动类
package com.lanh.provideruser;

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

@SpringBootApplication
@EnableEurekaClient
public class ProviderUserApplication {

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

服务消费者

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.lanh</groupId>
    <artifactId>consumer-movie</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>consumer-movie</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <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</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>

  • application.yml
server:
# 设置 Eureka Server WEB 控制台端口、服务注册发现端口。Eureka Server 服务注册 发现端口默认为 8761。
    port: 8082
spring:
    application:
    # 设置 spring 应用命名,默认为 null。同命名的应用会注册到同一个服务集群中。
        name: consumer
eureka:
    client:
        # 是否将自己注册到 Eureka-Server 中,默认的为 true
        register-with-eureka: false
        service-url:
            defaultZone: http://localhost:8761/eureka/
    instance:
        prefer-ip-address: true
  • 调用服务
package com.lanh.consumermovie.controller;

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

/**
 * @Author Lanh
 **/
@RestController
public class Controller {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/show/{name}")
    public String show(@PathVariable String name){
        return this.restTemplate.getForObject("http://localhost:8081/show",String.class)+" "+name;
    }
}


  • 启动类
package com.lanh.consumermovie;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;


@SpringBootApplication
@EnableEurekaClient
public class ConsumerMovieApplication {

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

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

测试:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绿豆蛙给生活加点甜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值