Spring Cloud 之注册中心 Eureka 精讲 您所在的位置:网站首页 springboot在项目中的作用 Spring Cloud 之注册中心 Eureka 精讲

Spring Cloud 之注册中心 Eureka 精讲

2023-06-28 18:49| 来源: 网络整理| 查看: 265

🍓 简介:java系列技术分享(👉持续更新中...🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢迎点赞 👍 收藏 ⭐留言 📝

Cloud2.jpg

一、Eureka简介

Spring Cloud官网:spring.io/projects/sp… Eureka官网:github.com/Netflix/eur…

Spring Cloud 是目前用于开发微服务的主流框架之一,我们都知道在微服务架构中最为基础、核心的模块,就是服务注册与发现。

Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现 服务注册和发现。Eureka Server 作为 服务注册中心,系统中的 其他微服务,使用 Eureka 的 客户端 连接到 Eureka Server,并通过 心跳连接 检测服务的 存活状态。

Eureka 包含两个组件:Eureka Server 和 Eureka Client

Eureka Server: 作为 服务注册中心,提供 服务注册和发现,提供服务注册服务,各个节点启动后,会在 EurekaServer 中进行注册,这样 EurekaServer 中的服务注册表中将会存储所有可用服务节点的信息。

Eureka Client: 所有注册到 服务中心 的服务。是一个 Java 客户端,用于简化 Eureka Server 的交互,客户端同时也具备一个内置的、使用轮询 (round-robin) 负载算法的负载均衡器。在应用启动后,将会向 Eureka Server 发送心跳 (默认周期为 30 秒)。

Service Provider: 把 自身的服务 注册到 Eureka Server,从而使 服务消费方 能够找到。 Service Consumer: 从 Eureka Server 获取 服务注册列表,从而能够 消费服务。 二、 Eureka 注册中心

在微服务架构中往往会有一个注册中心,每个微服务都会向注册中心去注册自己的地址及端口信息,注册中心维护着服务名称与服务实例的对应关系。首先我们注册中心服务端:eureka-server,这必须是一个独立的微服务。下面我们来搭建搭建 eureka-server。

原始http服务调用 -存在问题:

如果有多个服务提供者,消费者如何选择? 消费者如何获取服务提供者地址信息? 如何知晓服务提供者是否健康?

请看下图

(纯手工绘制有点瑕疵)Eureka的作用 图解:

Eureka的作用-图解

在这里插入图片描述

2.1 首先基于Spring Boot创建父工程

以Maven模块化项目方式创建,便于各个微服务的项目管理。 在这里插入图片描述

2.1.1 需要注意(重要)

来自Spring Cloud官方文档 :spring.io/projects/sp…

概述了Spring Cloud的版本与Spring Boot的版本对应关系,需要注意最新更新可查看官方文档

在这里插入图片描述

2.1.2 本项目引入主要配置

父项目Pom文件

可以看到下文中:Spring Boot的版本是2.7.1 因此根据上图Spring Cloud 的版本为:2021.0.1 在这里插入图片描述

第一种 (选择一种即可,区别不大) org.springframework.boot spring-boot-starter-parent 2.7.1 1.8 2021.0.1 5.8.2 org.springframework.boot spring-boot-starter-web cn.hutool hutool-all ${hutool.version} org.projectlombok lombok org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import 第二种

不引入parent也可以这样配置

1.8 2.7.1 2021.0.1 5.8.2 org.springframework.boot spring-boot-starter-web cn.hutool hutool-all ${hutool.version} org.projectlombok lombok org.springframework.boot spring-boot-dependencies ${spring-boot.version} pom import org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import

两种都可以

2.2 搭建Eureka-Server 在父工程基础上 创建eureka-server模块` 引入spring-cloud-starter-netflix-eureka-server依赖 org.springframework.cloud spring-cloud-starter-netflix-eureka-server 在启动类上添加@EnableEurekaServer注解 添加配置 server: port: 10086 spring: application: name: eureka-server main: allow-bean-definition-overriding: true eureka: client: serviceUrl: defaultZone: http://127.0.0.1:10086/eureka/ # register-with-eureka: false # 不注册自己 # fetch-registry: false #不拉取服务 启动服务 然后访问:http://localhost:10086/ 看到如下页面则成功 在这里插入图片描述 2.3 搭建Eureka-Client(服务注册)

将provider-service注册到Eureka-Server中步骤如下:

在父工程基础上 创建provider-service模块(服务提供者) 引入spring-cloud-starter-netflix-eureka-client依赖,注意后缀是client org.springframework.cloud spring-cloud-starter-netflix-eureka-client 添加配置 server: port: 20086 spring: application: name: provider-service main: allow-bean-definition-overriding: true eureka: client: serviceUrl: defaultZone: http://127.0.0.1:10086/eureka/

同理创建consumer-service模块(服务消费者)

最终项目结构如下图所示:

我这里创建了个common公共包,无要求,非必须 在这里插入图片描述

2.4 服务拉取准备工作 2.4.1 需求

需求:根据订单id查询订单的同时查询对应用户信息一起返回

消费者中提供订单信息 提供者提供用户信息 数据在各自对应数据库中

2.4.2 数据库表数据展示

order订单表 在这里插入图片描述 用户表 在这里插入图片描述

2.4.3 消费者端 controller @RestController @RequestMapping("/consumer") public class ConsumerController { /** * 消费者 */ @Autowired private ConsumerService consumerService; @GetMapping("{orderId}") public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) { // 根据id查询订单并返回 return consumerService.queryOrderById(orderId); } } service public interface ConsumerService { /** * 根据id查询订单并返回 */ Order queryOrderById(Long orderId); } impl @Service public class ConsumerServiceImpl implements ConsumerService { @Autowired private OrderMapper orderMapper; @Autowired private RestTemplate restTemplate; /** * 根据id查询订单并返回 */ @Override public Order queryOrderById(Long orderId) { // 1.查询订单 Order order = orderMapper.findById(orderId); //2远程查询用户信息 String url="http://localhost:20086/provider/"+order.getUserId(); //2. 发起调用 User user = restTemplate.getForObject(url, User.class); //3. 存入order order.setUser(user); // 4.返回 return order; } } mapper @Mapper public interface OrderMapper { @Select("select id, name, num, user_id userId, price from `order` where id = #{id}") Order findById(Long orderId); } 启动类,并配置RestTemplate @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } /** * 没有实例化RestTemplate时,初始化RestTemplate * @return */ @ConditionalOnMissingBean(RestTemplate.class) @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } } 2.4.4 提供者端 controller @RestController @RequestMapping("/provider") public class ProviderController { @Autowired private ProviderService providerService; /** * 根据id查询用户信息 */ @GetMapping("/{id}") public User queryById(@PathVariable("id") Long id) { return providerService.queryById(id); } } service public interface ProviderService { /** * 根据id查询用户信息 */ User queryById(Long id); } impl @Service public class ProviderServiceImpl implements ProviderService { @Autowired private UserInfoMapper userMapper; /** * 根据id查询用户信息 */ @Override public User queryById(Long id) { return userMapper.findById(id); } } mapper @Mapper public interface UserInfoMapper { @Select("select * from user where id = #{id}") User findById(@Param("id") Long id); } 启动类 @SpringBootApplication public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } } 2.4.5 注册成功

在这里插入图片描述

三、服务启动测试 3.1 原始http全路径调用 及 存在问题

查看上文代码消费者端是基于全路径http://localhost:20086/provider/1 调用

//2远程查询用户信息 String url="http://localhost:20086/provider/"+order.getUserId();

成功调用如下图 在这里插入图片描述

存在问题:

如果有多个服务提供者,消费者如何选择? 消费者如何获取服务提供者地址信息? 如何知晓提供者是否健康 ?

可参考上文------Eureka的作用 图解

3.2 使用Eureka注册中心的服务名调用

这是成功注册的服务

基于服务名称获取服务列表,然后对服务列表做负载均衡

在这里插入图片描述

服务名代替ip,端口

使用provider-service(自己配置的服务名)代替localhost:20086

//2远程查询用户信息 String url="http://provider-service/provider/"+order.getUserId();

在服务消费者的启动类的RestTemplate添加@LoadBalanced负载均衡注解

负载均衡详解后续文章中更新

/** * 没有实例化RestTemplate时,初始化RestTemplate * @return */ @ConditionalOnMissingBean(RestTemplate.class) @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); }

测试结果成功 在这里插入图片描述

四、总结 4.1 Eureka的作用 消费者该如何获取服务提供者具体信息? 服务提供者启动时向eureka注册自己的信息 eureka保存这些信息 消费猪根据服务名称向eureka拉取提供者信息 如果有多个服务提供者,消费者该如何选择? 服务消费者利用负载均衡算法,从服务列表中选择一个 消费者如何感知服务提供者健康状态? 服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态 eureka会更新记录服务列表信息,心跳不正常会被剔除 消费者就可以拉取到最新的信息 4.2 在Eureka架构中,微服务角色有两类: EurekaServer: 服务端,注册中心 记录服务信息 心跳监控 Eurekaclient:客户端 Provider: 服务提供者,例如案例中的provider-service 注册自己的信息到EurekaServer 每隔30秒向EurekaServer发送心跳 consumer:服务消费者,例如案例中的 consumer-service 根据服务名称从EurekaServer拉取服务列表 基于服务列表做负载均衡,选中一个微服务后发起远程调用

ds



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有