【Spring Cloud】Eureka注册中心从原理到实战图文详细教程




1. Eureka介绍

  • Eureka 是 Spring Cloud 中的一个组件,主要是作为注册中心。

1.1 Eureka能解决的问题

  • 服务注册
  • 服务发现:服务消费者如何获取服务提供者的地址信息?
  • 负载均衡:如果有多个服务提供者,消费者应该和选择?
  • 健康检测:消费者如何得知服务提供者的健康状态?
  • 以上都是 Eureka 能家具的问题。

image-20221123152002726


2. Eureka原理

  • Eureka 是 C/S 架构。自己本身是 Server 服务端,而微服务容器实例都是客户端。
  • 每一个微服务容器实例启动的那一刻,都会把自己的信息 (微服务名称、IP 、端口) 注册给 Eureka 。
  • 此时,如果有微服务想要远程调用其他微服务,就去找 Eureka 注册中心,Eureka 查询注册列表,如果有,就把对于的微服务信息发送给消费者。
  • 消费者拿到多个提供者实例列表,就要从中挑选一个实例作为提供者,这时会采用负载均衡策略来挑选。
  • 挑选出来一个提供者后,就向这个提供者发起远程调用。
  • 如何保证服务提供者是健康的呢?在 Eureka 注册的微服务实例,每隔 30 秒都会向 Eureka 发送一次心跳续约,来确认自己的健康状态。如果有一天,Eureka 没有收到某个微服务实例的心跳,就会把它从注册列表中剔除掉。这样,消费者向 Eureka 拉取注册列表时,就不会拉取到宕机的微服务信息了。

image-20221123152151104


3. 搭建Eureka Server


3.1 引入依赖

  • 创建新的微服务,这个微服务就是专门用来做 Eureka 的服务端。

    image-20221215113155241

  • 这个微服务命名为 eureka-server ,选择 Maven 工程。

    image-20221215131910881

  • 创建完成后,在 eureka-server 微服务的 pom.xml 文件中引入 spring-cloud-starter-netflix-eureka-server 的 Maven 坐标。

  • 这个依赖中,Spring 已经把 Eureka 自动装配,几乎可以做到零配置直接用。

<!-- Eureka注册中心服务端 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
  • 可以看到,导入 Eureka 的 Maven 坐标时,并没有指定其版本。这是在 Spring Boot 中学过的内容。这是因为在 eureka-server 微服务的父工程 (cloud-demo) 中,已经把所有依赖的版本都管理好了。我们可以打开父工程 cloud-demopom.xml 文件,可以看到在 <parent> 标签下有 spring-boot-starter-parent

    image-20221215133707381

    也可以在 <properties> 标签下看到 Spring Cloud 的版本:

    image-20221215133853458

    <denpendencies> 标签下,可以看到 Spring Cloud 的依赖:

    image-20221215134006052

    点进【<artifactId>spring-cloud-dependencies</artifactId>】,可以看到在 <properties> 标签下定义好了大量的 Spring Cloud 组件的版本信息。所以当我们导入 Spring Cloud 组件时,无需指定版本。

    image-20221215134238374


3.2 编写启动类

  • 打开 eureka-server 微服务的启动类 Main.java (把它重命名为 EurekaApplication.java ) 。添加 Spring Boot 注解 @SpringBootApplication

  • 添加 @EnableEurekaServer 注解来打开 Eureka 服务。

    @SpringBootApplication
    @EnableEurekaServer
    @Slf4j
    public class EurekaApplication {
          
          
    
        public static void main(String[] args) {
          
          
            SpringApplication.run(EurekaApplication.class, args);
            log.info("Eureka注册中心启动成功");
        }
    }
    

3.3 修改配置文件

  • src/main/resources 目录下创建配置文件 application.yml

  • 修改 application.yml 配置文件,加入下面的配置。

    server:
      port: 10086 # 服务端口
    
    spring:
      application:
        name: eurekaserver  # 微服务名称
    
    eureka:
      client:
        service-url:  # Eureka的地址信息
          defaultZone: http://localhost:10086/eureka
    

    其中,为什么要在 Eureka 的 client 客户端把 Eureka 微服务自己也配置进去呢?因为 Eureka 自己也是微服务,Eureka 启动时,也会把自己也注册进 Eureka 上。这是为了将来 Eureka 集群之间通信使用的。例如,我启动了 3 个 Eureka 服务,那么这 3 个 Eureka 服务就相互注册,这样他们就可以做数据交流了。只是因为现在只有一台 Eureka 服务,所以只配了自己。


3.4 启动Eureka微服务

  • 在 Eureka 微服务的启动类 EurekaApplication.java 中启动。

    image-20221215140120227

  • 可以在底栏 Services 中发现多了一个正在运行的微服务,那就是 Eureka 。

    image-20221215140319720

  • 此时我们可以在浏览器中输入 http://localhost:10086/ 来访问 Eureka 的主页。也可以在 IDEA 底栏的 Services 中,点击 EurekaApplication:10086/ 的端口号直接打开浏览器访问。

    image-20221215141134732

    如果你能看到这个页面,说明你的 Eureka 注册中心就搭建成功了。这个页面中,最重要的部分就是中间的 Instances currently registered with Eureka 。这里罗列了当前注册到 Eureka 的微服务实例信息。


4. 服务注册

  • 接下来,我们把用户微服务 user-service 注册到 EurekaServer 中。一共两步,与搭建 Eureka 的步骤非常相似。

4.1 导入依赖

  • 在用户微服务 user-servicepom.xml 文件中导入 spring-cloud-starter-netflix-eureka-client 的 Maven 坐标。注意这里是客户端 client

    <!-- Eureka注册中心客户端 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client </artifactId>
    </dependency>
    

4.2 修改配置文件

  • 打开用户微服务 user-service 的配置文件 application.yml ,加入以下内容。

    spring:
      application:
        name: userservice  # 微服务名称
    
    eureka:
      client:
        service-url:  # Eureka的地址信息
          defaultZone: http://localhost:10086/eureka/
    
  • 经过这两步,用户微服务 user-service 就成功注册到 Eureka 中了。同理,按照同样的步骤,把订单微服务 order-service 也注册到 Eureka 中。


4.3 重启微服务

  • 重启用户微服务 user-service 和订单微服务 order-service

    image-20221215143415635

  • 此时在浏览器中输入 http://localhost:10086/ 来访问 Eureka 的主页。

    image-20221215145033950

    可以看到用户微服务 user-service 和订单微服务 order-service 都成功注册到 Eureka 中了。


4.4 启动多个微服务实例

  • 在企业的实际开发中,一个微服务往往有多个实例,以达到高可用的目的。实际开发部署中,多个微服务实例是通过 Docker 将微服务构建成镜像,然后依照这个镜像创建多个 Docker 容器实例来实现的。鉴于有一部分同学还没接触过 Docker ,这里先使用 IDEA 的功能来本地运行多个用户微服务 user-service 实例。

  • 进入 IDEA 底栏的 Services ,找到 UserApplication ,右击,选择【Copy Configuration…】。

    image-20221215145645950

  • 然后随便起个名字,点击【Modify options】。

    image-20221215145923298

  • 添加虚拟机选项【Add VM options】。

    image-20221215150014805

  • 然后换个端口,否则端口会冲突。在【VM options】一栏输入 -Dserver.port=8082

    image-20221215150216390

  • 点击【OK】后,会发现多出来一个用户微服务 UserApplication2 ,启动它。

    image-20221215150355083

  • 然后回到 Eureka 主页,发现注册列表中,用户微服务USERSERVICE 的实例个数变成 2 了,且能看到 2 个 IP:端口。

    image-20221215150658144

    到此,使用 Eureka 实现服务注册就完成了。


5. 服务发现

  • 本节,我们将设定订单微服务 order-service 为消费者,用户微服务 user-service 为提供者,订单微服务远程调用用户微服务的查询服务。
  • 本节我们将使用订单微服务 order-service 拉取服务注册列表。
  • 服务拉取是基于服务名称获取服务列表,然后再对服务列表做负载均衡选取出一个微服务实例进行远程调用。

5.1 修改业务层代码

  • 修改订单微服务 order-service 的业务层代码 OrderService.java 。修改 RestTemplate 的访问 URL 路径,用要远程调用的微服务名代替原来的 IP 和端口。

【小贴士】

String url = "http://userservice/user/" + order.getUserId();
  • OrderService.java
@Service
public class OrderService {
    
    

    @Autowired
    private OrderMapper orderMapper;
    // 自动注入RestTemplate,用于发起HTTP请求远程调用
    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
    
    
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.使用RestTemplate发起HTTP请求,查询订单所属用户信息
        // 2.1 根据查询的订单order中的userId动态生成HTTP请求的url
        String url = "http://userservice/user/" + order.getUserId();
        // 2.2 发送HTTP请求,实现远程调用
        User user = restTemplate.getForObject(url, User.class);
        // 3.把远程调用获得的user封装进order对象中
        order.setUser(user);
        // 4.返回order订单信息
        return order;
    }
}

5.2 在RestTemplate上添加负载均衡注解

  • 在订单微服务 order-service 的启动类 OrderApplication.java 中的 RestTemplate 上添加 @LoadBalanced 负载均衡注解。

    image-20221215152019123

  • OrderApplication.java

// 注册RestTemplate,用来发起HTTP请求远程调用
@Bean
@LoadBalanced	// 负载均衡注解
public RestTemplate restTemplate() {
    
    
    return new RestTemplate();
}

5.3 重启OrderApplication

image-20221215153010466

  • 接下来,把两个 UserApplication 的日志清空,以便查看 OrderApplication 是如何来选取用户微服务 UserApplication 进行远程调用的。

  • 在 Postman 中,向发送 2 个请求 http://localhost:8080/order/101http://localhost:8080/order/102

    image-20221215153405576

    image-20221215153423586

  • 回到两个 UserApplication 的日志中,可以看到第一次调用了 8082 端口的用户微服务;

    image-20221215153559590

    而第二次则调用了 8081 端口的用户微服务。

    image-20221215153717689

    说明负载均衡成功实现。在使用 RestTemplate 发起 HTTP 远程调用时,我们不需要关心想要远程调用的 IP 地址和端口号,只需要把对于的微服务名写在 URL 上,Eureka 会自动帮我们在多个微服务实例中均衡地选取一个进行远程调用。

  • 以上,就称为服务发现和服务拉取。

猜你喜欢

转载自blog.csdn.net/Sihang_Xie/article/details/128331789