【SpringCloud】Eureka 案例上手稍微带点原理

news/2025/1/15 21:45:53/

文章目录

  • 1. 前置工作
    • 1.1 搭建 user-server
      • 1.1.1 pom
      • 1.1.2 po,mapper,controller
      • 1.1.3 yml
      • 1.1.4 启动类
      • 1.1.5 启动并访问
    • 1.2 搭建 order-server
      • 1.2.1 pom
      • 1.2.2 po mapper controller
      • 1.2.3 yml
      • 1.2.4 启动类
      • 1.2.5 启动并访问
    • 1.3 两个服务通信
  • 2. Eureka
    • 2.1 Eureka 概述
    • 2.2 搭建 Eureka
      • 2.2.1 pom
      • 2.2.2 yml
      • 2.2.3 启动类
      • 2.2.4 启动访问
    • 2.3 将服务注册进 Eureka
    • 2.4 通过Eureka调用服务
  • 3. Eureka 原理
  • 4. 注意



在这里插入图片描述


1. 前置工作

先准备两个能独立跑起来的微服务(user-server 和 order-server)

将 所需 SQL 导入

/*Navicat Premium Data TransferSource Server         : CentOS7Source Server Type    : MySQLSource Schema         : cloudTarget Server Type    : MySQLDate: 28/05/2023 10:19:17
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for tb_order
-- ----------------------------
DROP TABLE IF EXISTS `tb_order`;
CREATE TABLE `tb_order`  (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单id',`user_id` bigint(20) NOT NULL COMMENT '用户id',`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '商品名称',`price` bigint(20) NOT NULL COMMENT '商品价格',`num` int(10) DEFAULT 0 COMMENT '商品数量',PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `username`(`name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;-- ----------------------------
-- Records of tb_order
-- ----------------------------
INSERT INTO `tb_order` VALUES (101, 1, 'Apple 苹果 iPhone 12 ', 699900, 1);
INSERT INTO `tb_order` VALUES (102, 2, '雅迪 yadea 新国标电动车', 209900, 1);
INSERT INTO `tb_order` VALUES (103, 3, '骆驼(CAMEL)休闲运动鞋女', 43900, 1);
INSERT INTO `tb_order` VALUES (104, 4, '小米10 双模5G 骁龙865', 359900, 1);
INSERT INTO `tb_order` VALUES (105, 5, 'OPPO Reno3 Pro 双模5G 视频双防抖', 299900, 1);
INSERT INTO `tb_order` VALUES (106, 6, '美的(Midea) 新能效 冷静星II ', 544900, 1);
INSERT INTO `tb_order` VALUES (107, 2, '西昊/SIHOO 人体工学电脑椅子', 79900, 1);
INSERT INTO `tb_order` VALUES (108, 3, '梵班(FAMDBANN)休闲男鞋', 31900, 1);-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user`  (`id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '收件人',`address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '地址',PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 109 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES (1, '宋祖儿', '北京市朝阳区');
INSERT INTO `tb_user` VALUES (2, '景甜', '陕西省西安市');
INSERT INTO `tb_user` VALUES (3, '李现', '湖北省十堰市');
INSERT INTO `tb_user` VALUES (4, '郭德纲', '天津市');
INSERT INTO `tb_user` VALUES (5, '王思聪', '辽宁省沈阳市');
INSERT INTO `tb_user` VALUES (6, '刘亦菲', '湖北省武汉市');SET FOREIGN_KEY_CHECKS = 1;

1.1 搭建 user-server


在这里插入图片描述

1.1.1 pom

<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.9.RELEASE</version><relativePath/></parent><groupId>com.snow</groupId><artifactId>cloud_user</artifactId><version>1.0-SNAPSHOT</version><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><servlet.version>3.1.0</servlet.version><druid.version>1.1.20</druid.version><mybatisplus.version>3.4.1</mybatisplus.version><mysql.version>5.1.6</mysql.version><commons.lang.version>3.7</commons.lang.version><commons.codec.version>1.10</commons.codec.version><fastjson.version>1.2.45</fastjson.version><lombok.version>1.18.4</lombok.version><!-- SpringCloud版本号 --><spring-cloud.version>Hoxton.SR10</spring-cloud.version></properties><!-- 版本锁定: 并不是jar包导入 --><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><!-- 打包方式为pom: 说明我们导入的是一个父工程 --><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency><!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatisplus.version}</version><exclusions><exclusion><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId></exclusion></exclusions></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><!-- 阿里JSON解析器 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.16</version></dependency></dependencies></project>

1.1.2 po,mapper,controller

@Data
@TableName("tb_user")
public class User {@TableId(type = IdType.AUTO)private Long id;private String username;private String address;
}
@Mapper
public interface UserMapper extends BaseMapper<User> {}
@RestController
@RequestMapping("/user")
public class UserController {@Resourceprivate UserMapper userMapper;@GetMapping("/get/{id}")public User get(@PathVariable("id") Long id){return userMapper.selectById(id);}
}

1.1.3 yml

server:port: 8081
spring:datasource:url: jdbc:mysql://192.168.0.108:3306/cloud?useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.jdbc.Driver

1.1.4 启动类

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

1.1.5 启动并访问

效果如下


在这里插入图片描述


1.2 搭建 order-server

1.2.1 pom

<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.9.RELEASE</version><relativePath/></parent><groupId>com.snow</groupId><artifactId>cloud_order</artifactId><version>1.0-SNAPSHOT</version><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><servlet.version>3.1.0</servlet.version><druid.version>1.1.20</druid.version><mybatisplus.version>3.4.1</mybatisplus.version><mysql.version>5.1.6</mysql.version><commons.lang.version>3.7</commons.lang.version><commons.codec.version>1.10</commons.codec.version><fastjson.version>1.2.45</fastjson.version><lombok.version>1.18.4</lombok.version><!-- SpringCloud版本号 --><spring-cloud.version>Hoxton.SR10</spring-cloud.version></properties><!-- 版本锁定: 并不是jar包导入 --><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><!-- 打包方式为pom: 说明我们导入的是一个父工程 --><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><!-- druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.version}</version></dependency><!-- mybatis-plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatisplus.version}</version><exclusions><exclusion><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId></exclusion></exclusions></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency><!-- 阿里JSON解析器 --><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.16</version></dependency></dependencies></project>

1.2.2 po mapper controller

@Data
@TableName("tb_order")
public class Order {@TableId(type = IdType.AUTO)private Long id;private Long price;private String name;private Integer num;private Long userId;@TableField(exist = false)private User user;
}
@Data
public class User {private Long id;private String username;private String address;
}
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}
@RestController
@RequestMapping("/order")
public class OrderController {@Resourceprivate OrderMapper orderMapper;@GetMapping("/get/{id}")public Order get(@PathVariable("id") Long id){Order order = orderMapper.selectById(id);return order;}
}

1.2.3 yml

server:port: 9091
spring:datasource:url: jdbc:mysql://192.168.0.108:3306/cloud?useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.jdbc.Driver

1.2.4 启动类

@SpringBootApplication
public class OrderServerApplication {public static void main(String[] args) {SpringApplication.run(OrderServerApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}}

1.2.5 启动并访问

效果如下


在这里插入图片描述


至此 两个独立的微服务就顺利的跑起来了。

1.3 两个服务通信

上面的两个独立服务已经跑起来了,因为上来看呢, 可以看到我们的 order服务是需要调用 user 服务的。如下图


在这里插入图片描述
可以看到我们的 order信息里的 user 是为null,因为我们还没有去调用 user 服务。
下来我们在 order服务里调用 user 服务。

改造 order 服务的 OrderController:

@RestController
@RequestMapping("/order")
public class OrderController {@Resourceprivate OrderMapper orderMapper;@Resourceprivate RestTemplate restTemplate;@GetMapping("/get/{id}")public Order get(@PathVariable("id") Long id){String url = "http://localhost:8081/user/get/";Order order = orderMapper.selectById(id);User user = restTemplate.getForObject(url + order.getUserId(), User.class);order.setUser(user);return order;}
}

启动,访问


在这里插入图片描述

可以看到 order 里有 user 的数据了 !OK!


2. Eureka


2.1 Eureka 概述


Eureka 是 Netflix 提供的基于 REST 的服务发现组件,用于帮助开发者管理微服务架构中的服务实例。它提供了一个可伸缩的注册中心,可以让每个微服务都能够找到其他微服务的位置和元数据信息,并对其进行负载均衡、自动故障转移等操作。

通过将 Eureka Server 部署在中心服务器上,然后将各个微服务节点(即Eureka Client)注册到该中心服务器上,便可以实现微服务间的快速查找和调用。

在这里插入图片描述

使用Eureka能够方便地扩展和部署大规模微服务应用程序,并让你更容易地维护和监控整个系统。

同时,由于Eureka本身是基于REST接口设计的,因此它能够与多种编程语言和框架无缝集成,可以让开发者像使用本地服务一样轻松地编写分布式应用程序。

2.2 搭建 Eureka

2.2.1 pom

<?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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.9.RELEASE</version></parent><artifactId>eureka-service</artifactId><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><!-- SpringCloud版本号 --><spring-cloud.version>Hoxton.SR10</spring-cloud.version></properties><!-- 版本锁定: 并不是jar包导入 --><dependencyManagement><dependencies><!-- todo:2.导入springCloud父工程 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><!-- 打包方式为pom: 说明我们导入的是一个父工程 --><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies><build><finalName>app</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

2.2.2 yml

server:port: 10086
spring:application:name: eureka-server
eureka:# 给内置的客户端设置服务端地址client:service-url:defaultZone: http://127.0.0.1:10086/eurekaregister-with-eureka: false # 不注册自己fetch-registry: false #不拉取服务本eureka服务中的服务信息

2.2.3 启动类

@SpringBootApplication
// 开启Eureka服务端支持
@EnableEurekaServer
public class EurekaApplication {public static void main(String[] args) {SpringApplication.run(EurekaApplication.class, args);}}

2.2.4 启动访问

在这里插入图片描述


2.3 将服务注册进 Eureka

给user服务和order服务分别引入依赖:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

修改 user 和 order 的 yml 文件

server:port: 8081spring:datasource:url: jdbc:mysql://192.168.0.108:3306/cloud?useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.jdbc.Driverapplication:name: USER-SERVEReureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance: # 在Eureka中显示服务的ip地址ip-address: 127.0.0.1 # 配置服务器ip地址prefer-ip-address: true # 更倾向于使用ip,而不是host名instance-id: ${eureka.instance.ip-address}:${server.port} # 自定义实例的id
server:port: 9091
spring:datasource:url: jdbc:mysql://192.168.0.108:3306/cloud?useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.jdbc.Driverapplication:name: ORDER-SERVEReureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka

重启服务。


在这里插入图片描述

服务就已注册进来了。


2.4 通过Eureka调用服务

回看我们之前 order 调用 user 时候的方式是直接通过 RestTemplate 调用的,这样耦合是有些大的,比如我们的 user 服务换了部署地址,就得去动 order 的源代码。实在不妥。
在这里插入图片描述

下来我们通过 Eureka 提供的注册发现服务去调用。

改造OrderController

 @GetMapping("/get/{id}")public Order get(@PathVariable("id") Long id){String user_server_name = "USER-SERVER";String url = "http://" + user_server_name + "/user/get/";Order order = orderMapper.selectById(id);User user = restTemplate.getForObject(url + order.getUserId(), User.class);order.setUser(user);return order;}

启动访问:


在这里插入图片描述


3. Eureka 原理


Eureka 采用了客户端-服务端的设计架构,分为 Eureka Server 和 Eureka Client 两部分。

在这里插入图片描述

Eureka Server 是一个基于 RESTful 的服务,用于管理和维护客户端节点的信息。每个 Eureka Client 向 Eureka Server 注册自己提供的服务,并定时通过心跳机制告知 Eureka Server 自己仍然存活。同时,Eureka Server 也会定期对注册在自己那里的每个 Eureka Client 进行监控,以确保它们正常运行。

Eureka Client 则是一个轻量级的 Java 客户端,用于将自己注册到 Eureka Server 并获取所依赖服务的信息。他们使用轮询来访问 Eureka Server 来达到负载均衡的目的。 另外,它还会缓存 Eureka Server 中的服务列表信息,当服务端不能访问时可以快速切换到本地缓存服务列表模式,尽可能降低系统的开销。
在这里插入图片描述

具体流程如下

Eureka Client 启动后,会向 Eureka Server 发送一个注册请求,包含了该客户端所提供的服务实例、IP 地址、端口号等元数据。
Eureka Server 接收到注册请求后,会将该客户端所提供的服务实例信息记录到自身的内存中,同时将变更信息广播给其他的 Eureka Server 节点,以实现服务注册中心的高可用和服务同步。

Eureka Client 通过 “心跳” 机制定期向 Eureka Server 发送请求,以更新服务健康状态、刷新缓存等操作。如果在一定时间内 Eureka Server 没有接收到“心跳”消息,则会将该客户端实例从注册列表中摘除。
Eureka Client 还可以通过发送 RESTful API 请求来查询可用的服务节点信息,以实现负载均衡等功能。

Eureka 的核心对象是服务实例,每个服务实例都可以作为提供者向 Eureka Server 注册自己,同时也可以作为消费者从 Eureka Server 中获取所需服务的信息,从而实现服务发现和调用。


4. 注意


Eurek 已经停止维护 2.x 版本!



在这里插入图片描述


http://www.ppmy.cn/news/462594.html

相关文章

c# 从零到精通 dataGridView控件插入数据

c# 从零到精通 dataGridView控件插入数据 using System; using System.Data; using System.Text; using System.Windows.Forms; using System.Windows; using System.Drawing; namespace Test05 { public partial class Form1 : Form { public Form1() { InitializeComponent()…

断触问题分析思路

在使用手机的时候&#xff0c;有时候会出现触碰中断的异常问题&#xff0c;比如点击无效&#xff0c;已经存在的触碰事件突然消失&#xff0c;这种问题很直观&#xff0c;用户体验很差。 如果能够复现问题&#xff0c;抓到实时log&#xff0c;分析起来会清楚很多。可以打开开发…

小米游戏本8代 风扇噪音大解决办法

来源于&#xff1a;https://tieba.baidu.com/p/6772997477 之前困扰了很久&#xff0c;清过灰&#xff0c;换过硅脂&#xff0c;可还是没有什么用&#xff0c;经过不懈努力终于发现了解决方法 右键电源图标&#xff0c;电源选项&#xff0c;更改计划设置&#xff0c;更改高级电…

小米8成功刷入Win11ARM64完整版系统

本文转载自IT之家 IT之家 6 月 29 日消息 今天凌晨&#xff0c;微软面向 Dev 开发频道发布了第一个 Windows 11 Insider Preview 版本&#xff0c;即 Build 22000.51! 微软表示&#xff0c;随着我们在未来几个月内完成产品的定型&#xff0c;我们将与你一起验证这一体验。在这…

小米Note4、小米8、一加6刷机(三方rec+rom+root)

刷机的大致流程&#xff1a; 解手机bootloader锁&#xff08;各个品牌手机解锁方式各不相同&#xff09;刷入三方recovery进入三方rec模式&#xff0c;进行双清刷入rommagisk&#xff08;root&#xff09; 备注&#xff1a;所有的相关刷机包&#xff0c;应和手机机型和系统相匹…

小米8刘海屏适配

1.前言 最近在开发一个小说阅读器APP&#xff0c;在阅读界面碰到了适配问题&#xff0c;把解决问题的方法及过程记录一下。因为我只有小米8一个测试机&#xff0c;所以方法不保证其他手机的兼容性&#xff0c;只是提供一个思路&#xff0c;希望能给到其他人帮助。 2.全面屏适…

小米8原生Android9,小米8,Android9.0 crash

这个是语音合成sdkdemo里报的错&#xff0c;这是不是也是 28编译产物在android9.0上运行的问题 --------- beginning of crash E/AndroidRuntime: FATAL EXCEPTION: Thread-28 Process: com.baidu.tts.sample, PID: 413 java.lang.NoClassDefFoundError: Failed resolution of…

小米8配哪个版本的MIUI?

小米8之前我是忠实的魅粉&#xff0c;魅族手机用过M8&#xff0c;MX3&#xff0c;note5&#xff0c;MX6 pro。 魅族真的是被联发科的cpu坑了&#xff0c;一核有难&#xff0c;八核围观。 入手小米8&#xff0c;miui是9&#xff0c;一路跟着系统自动更新&#xff0c;更新到了12。…