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

一、Eureka简介
Spring Cloud
官网:https://spring.io/projects/spring-cloud
Eureka
官网:https://github.com/Netflix/eureka
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官方文档 :https://spring.io/projects/spring-cloud
概述了Spring Cloud的版本与Spring Boot的版本对应关系,需要注意
最新更新可查看官方文档

2.1.2 本项目引入主要配置
父项目Pom文件
可以看到下文中:
Spring Boot
的版本是
2.7.1
因此根据上图
Spring Cloud
的版本为:
2021.0.1

第一种 (选择一种即可,区别不大)
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.1</version><relativePath/></parent><properties><java.version>1.8</java.version><spring-cloud.version>2021.0.1</spring-cloud.version><hutool.version>5.8.2</hutool.version></properties><dependencies><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><dependencyManagement><!-- springCloud --><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
第二种
不引入parent也可以这样配置
<properties><java.version>1.8</java.version><spring-boot.version>2.7.1</spring-boot.version><spring-cloud.version>2021.0.1</spring-cloud.version><hutool.version>5.8.2</hutool.version></properties><dependencies><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencyManagement>
两种都可以
2.2 搭建Eureka-Server
- 在父工程基础上 创建eureka-server模块`
- 引入
spring-cloud-starter-netflix-eureka-server依赖
<!--eureka 服务端 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>
- 在启动类上添加
@EnableEurekaServer注解 - 添加配置
server:port:10086spring:application:name: eureka-server
main:allow-bean-definition-overriding:trueeureka: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
<!--eureka 客户端 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
- 添加配置
server:port:20086spring:application:name: provider-service
main:allow-bean-definition-overriding:trueeureka: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")publicclassConsumerController{/**
* 消费者
*/@AutowiredprivateConsumerService consumerService;@GetMapping("{orderId}")publicOrderqueryOrderByUserId(@PathVariable("orderId")Long orderId){// 根据id查询订单并返回return consumerService.queryOrderById(orderId);}}
- service
publicinterfaceConsumerService{/**
* 根据id查询订单并返回
*/OrderqueryOrderById(Long orderId);}
- impl
@ServicepublicclassConsumerServiceImplimplementsConsumerService{@AutowiredprivateOrderMapper orderMapper;@AutowiredprivateRestTemplate restTemplate;/**
* 根据id查询订单并返回
*/@OverridepublicOrderqueryOrderById(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
@MapperpublicinterfaceOrderMapper{@Select("select id, name, num, user_id userId, price from `order` where id = #{id}")OrderfindById(Long orderId);}
- 启动类,并配置RestTemplate
@SpringBootApplicationpublicclassConsumerApplication{publicstaticvoidmain(String[] args){SpringApplication.run(ConsumerApplication.class, args);}/**
* 没有实例化RestTemplate时,初始化RestTemplate
* @return
*/@ConditionalOnMissingBean(RestTemplate.class)@BeanpublicRestTemplaterestTemplate(){returnnewRestTemplate();}}
2.4.4
提供者端
- controller
@RestController@RequestMapping("/provider")publicclassProviderController{@AutowiredprivateProviderService providerService;/**
* 根据id查询用户信息
*/@GetMapping("/{id}")publicUserqueryById(@PathVariable("id")Long id){return providerService.queryById(id);}}
- service
publicinterfaceProviderService{/**
* 根据id查询用户信息
*/UserqueryById(Long id);}
- impl
@ServicepublicclassProviderServiceImplimplementsProviderService{@AutowiredprivateUserInfoMapper userMapper;/**
* 根据id查询用户信息
*/@OverridepublicUserqueryById(Long id){return userMapper.findById(id);}}
- mapper
@MapperpublicinterfaceUserInfoMapper{@Select("select * from user where id = #{id}")UserfindById(@Param("id")Long id);}
- 启动类
@SpringBootApplicationpublicclassProviderApplication{publicstaticvoidmain(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();
成功调用如下图
存在问题:
- 如果有多个服务提供者,消费者如何选择?
- 消费者如何获取服务提供者地址信息?
- 如何知晓提供者是否健康 ?
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@LoadBalancedpublicRestTemplaterestTemplate(){returnnewRestTemplate();}
测试结果
成功

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

版权归原作者 Dream_sky分享 所有, 如有侵权,请联系我们删除。