SpringCloud开发实战(三):集成Eureka注册中心

目录
SpringCloud开发实战(一):搭建SpringCloud框架
SpringCloud开发实战(二):通过RestTemplate实现远程调用

Eureka简介

Eureka 是一个基于 Java 的开源技术,最广为人知的是作为 Netflix 开发的云原生架构的一部分,它主要用于构建微服务架构中的服务发现。在微服务架构中,应用程序被拆分成一组小的服务,每个服务运行在自己的进程中,并通过轻量级通信(通常是HTTP或消息队列)互相通信。随着服务数量的增长,手动管理服务间的交互变得越来越复杂,这就需要服务发现机制来动态地找到并连接到正确的服务实例。

Eureka 提供了一个RESTful服务端和客户端API,服务端作为注册中心,负责维护服务实例列表,包括它们的状态;客户端则用于服务实例的注册与发现。当服务启动后,它们会向 Eureka 注册中心注册自己,然后定时发送心跳以表明它们还"活着"。其他服务可以利用 Eureka 发现这些服务并通过解析得到的信息与之通信。

Eureka 的设计原则是优先考虑可用性,即使在出现分区的情况下,Eureka 仍然能够正常运行,只是牺牲了一部分准确性和健壮性。这是 CAP 定理在网络分区情况下选择 AP(可用性和分区容忍性)的结果。

一、为什么要引入Eureka

我们想想,假如我们的user-service部署了多个实例,如图:

我们大家来思考这几个问题:

order-service在发起远程调用的时候,该如何得知user-service实例的ip地址和端口?

有多个user-service实例地址,order-service调用时该如何选择?

order-service如何得知某个user-service实例是否依然健康,是不是已经宕机?

这些问题都需要利用SpringCloud中的注册中心来解决,其中最广为人知的注册中心就是Eureka,其结构如下:

回答之前的各个问题。

问题1:order-service如何得知user-service实例地址?

获取地址信息的流程如下:

  • user-service服务实例启动后,将自己的信息注册到eureka-server(Eureka服务端)。这个叫服务注册
  • eureka-server保存服务名称到服务实例地址列表的映射关系
  • order-service根据服务名称,拉取实例地址列表。这个叫服务发现或服务拉取

问题2:order-service如何从多个user-service实例中选择具体的实例?

  • order-service从实例列表中利用负载均衡算法选中一个实例地址
  • 向该实例地址发起远程调用

问题3:order-service如何得知某个user-service实例是否依然健康,是不是已经宕机?

  • user-service会每隔一段时间(默认30秒)向eureka-server发起请求,报告自己状态,称为心跳
  • 当超过一定时间没有发送心跳时,eureka-server会认为微服务实例故障,将该实例从服务列表中剔除
  • order-service拉取服务时,就能将故障实例排除了

二、搭建eureka-server

我们新建一个模块作为注册中心服务端:eureka-server,这必须是一个独立的微服务

2.1 引入eureka依赖

我们创建一个模块(过程略,没看过可以翻看之前文章),然后修改Pom文件,引入SpringCloud为eureka提供的starter依赖:

java 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

2.2 修改启动类

接着我们在启动类上添加一个@EnableEurekaServer注解,开启eureka的注册中心功能:

java 复制代码
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);
    }
}

2.3 修改application.yml配置文件

我们将其他内容都去掉,只保留下面内容

java 复制代码
server:
  port: 10086
spring:
  application:
    name: eureka-server
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

2.4 项目结构

项目结构如下

2.5 启动服务

我们运行EurekaApplication,然后在浏览器访问:http://127.0.0.1:10086

看到下面结果应该是成功了:

三、服务注册

下面,我们将user-service注册到eureka-server中去。

3.1 引入依赖

我们在user-service的pom文件中,引入下面的eureka-client依赖:

java 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

3.2 配置文件

在user-service中,修改application.yml文件,添加服务名称、eureka地址,增加Mybatis的日志信息:

java 复制代码
spring:
  application:
    name: userService
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

3.3 启动多个user-service实例

为了演示一个服务有多个实例的场景,我们添加一个SpringBoot的启动配置,再启动一个user-service。

首先,复制原来的user-service启动配置:

我们在弹出的窗口,填写信息,其中虚拟机选项输入

java 复制代码
-Dserver.port=8083

如果这个菜单被隐藏了,我们可以点修改选项,然后选择Java里面的添加虚拟机选项。或者使用快捷键ALT+V

现在,服务窗口会出现两个user-service启动配置:

不过,第一个是8082端口,第二个是8083端口。启动两个user-service实例,然后查看eureka-server管理页面:

四、服务发现

下面,我们将order-service的逻辑修改:向eureka-server拉取user-service的信息,实现服务发现。

4.1 引入依赖

之前说过,服务发现、服务注册统一都封装在eureka-client依赖,因此这一步与服务注册时一致。在order-service的pom文件中,引入下面的eureka-client依赖:

java 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

4.2 修改application.yml

服务发现也需要知道eureka地址,因此第二步与服务注册一致,都是配置eureka信息:

在order-service中,修改application.yml文件,添加服务名称(服务名称别忘记加了)、eureka地址:

java 复制代码
spring:
  application:
    name: orderService
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

4.3 服务拉取和负载均衡

最后,我们要去eureka-server中拉取user-service服务的实例列表,并且实现负载均衡。

但是负载均衡的操作不用我们去做,只需要添加一些注解即可。

在order-service的OrderApplication中,给RestTemplate这个Bean添加一个**@LoadBalanced**注解:

java 复制代码
import org.mybatis.spring.annotation.MapperScan;
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;

@MapperScan("org.demo.mapper")
@SpringBootApplication
public class OrderApplication {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

然后我们要修改order-service服务中的OrderService,将类中的queryOrderById方法中访问的url路径,用服务名代替ip、端口:

spring会自动帮助我们从eureka-server端,根据userService这个服务名称,获取实例列表,而后完成负载均衡。

五、测试

我们清空两个UserApplication的日志,然后调用http://localhost:8081/order/101五次,查看日志信息如下

我们能看到UserApplication调用了三次,UserApplication(1)调用了两次。

至此,我们成功集成Eureka注册中心,如果文章有任何错误,还请大家指出。不胜感激!!!

相关推荐
程序员 沐阳11 分钟前
Docker 命令完全指南:从入门到实战
docker·容器·eureka
小红的布丁17 分钟前
Redis 内存淘汰与过期策略
java·spring·mybatis
huihuihuanhuan.xin18 分钟前
spring循环依赖以及补充相关知识
java·后端·spring
繁星星繁19 分钟前
Docker(一)
java·c语言·数据结构·c++·docker·容器·eureka
shark222222241 分钟前
springboot中配置logback-spring.xml
spring boot·spring·logback
云烟成雨TD1 小时前
Spring AI 1.x 系列【22】深度拆解 ToolCallbackProvider 生命周期与调用链路
java·人工智能·spring
黎明丶之前2 小时前
Spring Cloud Gateway 升级与 Bucket4j 限流实践
java·spring cloud
StackNoOverflow2 小时前
Spring Data Redis 详解
java·redis·spring
splage3 小时前
maven导入spring框架
数据库·spring·maven