Eureka_ 注册中心

Eureka:注册中心
:::info
专门用来管理各个微服务之间的通讯地址、调用、处理故障、通过服务名可以实现服务的调用,以及做服务监控
:::

1. EurekaServer & EurekaClient

这一部分可以类比着RocketMQ的原理看
:::info
EurekaServer(服务端)(注册中心):

  1. 注册中心也是一个需要启动的服务,他是依托于我们的服务进行启动的,也就意味着你需要准备一个SpringBoot项目整合EurekaServer,跑起来变成一个Eureka的服务端,此时注册中心就有了
    :::
    :::info
    EurekaClient(客户端)(其他服务):

  2. 在微服务中只要是一个服务都必须注册进入到Eureka中,所有注册进入到EurekaServer中的服务都被称为Eureka的客户端也就是EurekaClient
    :::

2. Eureka提供的四大功能

  1. **服务注册:**在服务启动的时候把自己的服务名称、IP、Port注册到注册中心,那么也就意味着服务中需要指定Eureka的注册地址
  2. **服务续约:**服务与注册中心之间保持一个30S的心跳机制,这是为了保证让注册中心知道自己还活着
  3. **服务发现:**每隔30S去注册中心中定时拉取所有的服务的注册地址清单保存到本地,这是为了各个服务能够知道其他服务的地址进行调用
  4. **服务下线:**注册中心检测到服务已经死了,并且满足剔除条件那么就会将服务的所有信息进行清除,Eureka有自我保护机制,防止网络波动导致的大范围下线,默认85%阈值

3. Eureka自我保护机制

当Eureka Server节点在短时间内丢失过多的客户端实例时:
Eureka会进入自我保护模式,以防止整个服务注册中心失效。
:::info
自我保护模式的工作原理如下:

  1. Eureka Server会定时统计每分钟内客户端实例的心跳信息,包括注册数量、续约数量等。
  2. 如果最近15分钟内的心跳失败率超过阈值(默认为85%),Eureka Server就会触发自我保护模式。
  3. 进入自我保护模式后,Eureka Server会暂停剔除失效实例的操作,同时将注册表中的实例保护起来,不会过期。
  4. 客户端继续发送心跳续约请求,尝试恢复正常状态。
  5. 当心跳失败率下降到阈值以下时,Eureka Server会自动退出自我保护模式,并恢复正常的实例剔除操作。
    :::

4. Eureka简单使用

4.1 创建springboot项目

这里使用Maven父子项目举例
项目结构:
image.png

4.2 项目相关依赖

:::info
这里我使用的是:
SpringCloud-H版本-SR3
SpringBoot:2.2.X
:::
需要注意对应SpringCloud和SpringBoot的版本

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.noting</groupId>
    <artifactId>SpringCloud-Netflix</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>eureka-server</module>
        <module>pojo</module>
        <module>server</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!-- springboot项目依赖,表明是springboot父项目-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>

    <!-- 父项目管理微服务的所有依赖,但是不引用,服务之间自己引用需要的依赖 
        统一管理依赖项版本
        简化子模块的配置
  			避免重复定义
  	-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

  	<!-- 项目需要的的公共依赖 -->
    <dependencies>
        <!--小辣椒lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

    </dependencies>

</project>

4.3 注册中心服务端

  1. 依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>SpringCloud-Netflix</artifactId>
        <groupId>com.noting</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-server</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!-- springweb依赖,-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

      <!-- 服务端依赖,-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>
  1. 服务端配置
server:
  port: 8761 # 标识当前Eureka服务端的端口号

eureka:
  instance:
    hostname: localhost # 当前Eurek的实例名称
  client:
    registerWithEureka: false # 在客户端依赖中默认为true,所以服务端需要关闭
    fetchRegistry: false # 在客户端依赖中默认为true,所以服务端需要关闭
    serviceUrl: # http://localhost:8761/eureka/
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  1. 启动类配置
package com.noting;

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

@SpringBootApplication
@EnableEurekaServer // 标识当前服务是一个Eureka的服务端
public class EurekaServerApp {

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

}
  1. 访问效果

image.png

4.4 跨服务使用类

:::info
将被使用的服务打包,再在使用者的pom.xml中导入依赖
注意!需要注意防止出现循环依赖
:::
image.png
image.png

        <!-- 导入的user-pojo的依赖 -->
        <dependency>
            <groupId>com.noting</groupId>
            <artifactId>user-pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

4.5 客户端

  1. 依赖
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>server</artifactId>
        <groupId>com.noting</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-server</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- 导入的user-pojo的依赖 -->
        <dependency>
            <groupId>com.noting</groupId>
            <artifactId>user-pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--springweb依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 表示注册到eureka客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

</project>
  1. 客户端配置
server:
  port: 10011

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/ # 表示注册中心的地址
  instance: # 打开IP注册
    instance-id: ${spring.application.name}:${server.port} # 设置实例名称
    prefer-ip-address: true # 开启IP注册

# 指定服务名称,此服务下的集群所有服务都叫此服务名
spring:
  application:
    name: user-server


  1. 启动类配置
package com.noting;

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

@SpringBootApplication
@EnableEurekaClient // 这个注解可以省略,因为导入了client依赖
public class userServerApp {

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

}
  1. 接口:可以浏览器访问
package com.noting.controller;

import com.noting.domain.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class userController {

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

    @GetMapping("/{id}")
    public User getUser(@PathVariable("id") Long id){
        User user = new User(id, "三无鸢", "学习微服务-----" + port);
        return user;
    }
}

4.6 客户端简单设置集群

  1. 启动客户端之后修改配置文件端口号
  2. image.png
  3. image.png
  4. 最后启动刚刚复制修改启动项

4.7 服务A调用另外的服务B(集群)的接口

注意调用方式和负载均衡
A接口

package com.noting.controller;

import com.noting.domain.User;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/order")
public class orderController {

    @Autowired
    // RestTemplate 用于发送 HTTP 请求的类,通过调用其 getForObject() 方法来发起 GET 请求。
    private RestTemplate restTemplate;


    @GetMapping("/{id}")
    public User getUser(@PathVariable("id") Long id){
        // 这里由于使用user使用了集群,并且restTemplate设置了负载均衡,这里调用的地址写为eureka的客户端的服务名
        User user = restTemplate.getForObject("http://user-server/user/" + id, User.class);
        return user;
    }
}

A启动类

package com.noting;

import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;


@SpringBootApplication
public class orderServerApp {

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

    // 此注解的意思是将方法中响应的对象交给spring容器管理,此注解必须在@Configuration注解的类中使用
    // 方法名称就是容器中Bean的名称
    @Bean
    // 复杂均衡的的注解,让RestTemplate具有负载均衡的能力
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }


    // 配置负载均衡为随机算法
    @Bean
    public RandomRule randomRule(){
        return new RandomRule();
    }


}

B接口

package com.noting.controller;

import com.noting.domain.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class userController {

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

    @GetMapping("/{id}")
    public User getUser(@PathVariable("id") Long id){
        User user = new User(id, "三无鸢", "学习微服务-----" + port);
        return user;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值