Spring Cloud 注册中心之Eureka

·  阅读 1938

一、简介

1. 服务注册与发现

image.png

  • Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心
  • 而系统中的其他微服务,使用 Eureka的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。
  • 在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息 比如 服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))
  • 简单来说,就是各个微服务的服务器到注册中心(比如Eureka)中注册,维护人员可以通过注册中心监控各个微服务是否正常运行;而各个微服务之间,可以通过注册中心获取到其他微服务的真实地址,然后进行RPC调用。

2. 服务治理

  • 在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册

3. Eureka

  • Eureka是常用的服务注册中心。但目前已经停止维护,替代产品包括ZK、consul、nacos等
  • Eureka包括两个角色Eureka Server、Eureka Client
    • Eureka Server:各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。(也就是真正的注册中心服务器)
    • EurekaClient:是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)(也就是去注册的微服务)

二、单机版Eureka

1. eureka server

1.1 导包

  • 最重要的就是,eureka-server这个包
    <dependencies>
        <!--eureka-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!--boot web actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--一般通用配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>
复制代码

1.2 yaml配置文件

server:
  port: 7001

eureka:
  instance:
    hostname: locahost #eureka服务端的实例名称
  client:
    register-with-eureka: false     #false表示不向注册中心注册自己。
    fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      defaultZone: http://127.0.0.1:7001/eureka/
复制代码

1.3 主启动类

@SpringBootApplication
@EnableEurekaServer  // 这是一个Eureke服务器
public class EurekaApplication7001 {
  public static void main(String[] args) {
    SpringApplication.run(EurekaApplication7001.class, args);
  }
}
复制代码

1.4 打开监控网页

http://localhost:7001/
复制代码

image.png

  • 至此,完成了Eureka服务器的配置。

2. eureka client

  • 无论是调用方还是被调用方,都需要在Eureka服务器上进行注册。操作如下:

2.1 导包

  • 最重要的就是,eureka-client
    <dependencies>
        <!--eureka-client-->
        <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--mysql-connector-java-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--jdbc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
复制代码

2.2 yaml 配置文件

server:
  port: 8001
spring:
  application:
    name: cloud-payment-service
eureka:
  instance:
  # 表示实例的名字,会显示在监控页面上
    instance-id: payment8001
    #访问路径可以在监控页面上显示IP地址
    prefer-ip-address: true
  client:
    #表示是否将自己注册进EurekaServer默认为true。
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetchRegistry: true
    service-url:
      # eureka服务器的地址
      defaultZone: http://127.0.0.1:7001/eureka
复制代码

2.3 主启动类

@SpringBootApplication
@EnableEurekaClient  // 表示这是一个eureka客户端
@EnableDiscoveryClient //服务发现
public class PaymentApplication8001 {
  public static void main(String[] args) {
    SpringApplication.run(PaymentApplication8001.class, args);
  }
}
复制代码

2.4 启动

  • 启动之后,看监控网页是否有新服务/实例的注册进来 image.png
  • 值得一提的是,上面Application的名字,就是在配置文件中写的spring.application.name 至此,完成了单机版的服务注册,至于如何服务调用,还需要其他组件,因此留在其他章节介绍。

三、集群版Eureka

  • 通常服务器都不可能单点运行,因为如果万一机器出故障了,那就整个服务没办法进行了,因此,对于Eureka的服务器和客户端,都需要使用集群。实现故障容错
  • 使用集群,还是实现负载均衡。

1. eureka server

1.1 构建多个服务

  • 根据上面单机版的服务,复制出多个服务,7001、7002、7003...

1.2 修改yaml配置文件

  • 重点是将defaultZone修改为其他剩余的Eureka服务器,声明其他的兄弟
server:
  port: 7001

eureka:
  instance:
    hostname: locahost #eureka服务端的实例名称
  client:
    register-with-eureka: false     #false表示不向注册中心注册自己。
    fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
    service-url:
      # 写下其他集群服务器的url
      defaultZone: http://127.0.0.1:7002/eureka/
复制代码

1.3 监控中心

  • 其他没有需要修改的了,可以直接在监控网页上看到其他兄弟了 image.png

2. eureka client

  • 操作也很简单,只需要修改一处就好了

1.1 修改配置文件

  • 重点就是修改了defaultZone,将集群中所有的eureka server地址写上去。其他没有变化
eureka:
  instance:
    instance-id: payment8001
    #访问路径可以显示IP地址
    prefer-ip-address: true
  client:
    #表示是否将自己注册进EurekaServer默认为true。
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetchRegistry: true
    service-url:
      #defaultZone: http://localhost:7001/eureka
      defaultZone: http://127.0.0.1:7001/eureka,http://127.0.0.1:7002/eureka  # 集群版
复制代码

1.2 监控中心

  • 目前有两台Client image.png

4、服务发现

  • 注册到注册中心的机器,可以看到注册中心中所有的服务及实例。这种操作,叫做服务发现。

1. 添加注解

  • 首先,需要在主启动类中,添加一个注解@EnableDiscoveryClient
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient //服务发现
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001.class,args);
    }
}
复制代码

2. 在容器中获取 DiscoveryClient

  • DiscoveryClient默认已在容器中,直接通过自动注入的方式获取。
@Autowired
private DiscoveryClient discoveryClient;
复制代码

3. 获取所有服务信息

  • 会返回所有服务的名字
  @GetMapping("/allService")
  public CommonResult<List<String>> allService() {
    List<String> services = discoveryClient.getServices();
    log.info("Eureka包含的服务包括:" + services.toString());
    return new CommonResult<>(CommonResult.SUCCESS, "获取所有服务成功!", services);
  }
复制代码

4. 获取某个服务的所有实例

  @GetMapping("/allInstances/{serviceName}")
  public CommonResult<List<ServiceInstance>> allInstances(@PathVariable("serviceName") String serviceName) {
    List<ServiceInstance> instances = discoveryClient.getInstances(serviceName);
    log.info("CLOUD-PAYMENT-SERVICE 包含的实例包括:" + instances.toString());
    return new CommonResult<>(CommonResult.SUCCESS, "获取所有实例成功!", instances);
  }
复制代码

五、Eureka的自我保护机制

  • Eureka默认拥有自我保护机制。也就是说,当某个服务实例在注册中心中掉线之后,注册中心并不会立刻把它删除,而是会保留。
  • 这样的操作,保证了AP(高可用、分区容错性),而丢弃了C(强一致性)。
  • 而对于自我保护机制,是可以关闭的
eureka.server.enable-self-preservation=false
复制代码
分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改