目录
[1.1 项目架构设计(单父工程 + 多子模块)](#1.1 项目架构设计(单父工程 + 多子模块))
[1.2 业务场景](#1.2 业务场景)
[2.搭建 Eureka 服务注册中心(servicecenter1)](#2.搭建 Eureka 服务注册中心(servicecenter1))
[2.1 新建项目](#2.1 新建项目)
[2.2 在项目clouddemo2中新建模块servercenter1](#2.2 在项目clouddemo2中新建模块servercenter1)
[2.3 修改模块servercenter1下的内容](#2.3 修改模块servercenter1下的内容)
[2.3.1 配置 pom.xml 依赖](#2.3.1 配置 pom.xml 依赖)
[2.3.2 配置 application.properties](#2.3.2 配置 application.properties)
[2.3.3 启动类编写](#2.3.3 启动类编写)
[2.3.4 启动测试](#2.3.4 启动测试)
[3.1 数据库前置准备](#3.1 数据库前置准备)
[3.2 配置 pom.xml 依赖](#3.2 配置 pom.xml 依赖)
[3.3 配置 application.properties](#3.3 配置 application.properties)
[3.4 核心业务代码编写](#3.4 核心业务代码编写)
[3.4.1 实体类:Classes(与 t_classes 表一一对应)](#3.4.1 实体类:Classes(与 t_classes 表一一对应))
[3.4.2 DAO 层:DBDao(MyBatis 数据访问层)](#3.4.2 DAO 层:DBDao(MyBatis 数据访问层))
[3.4.3 Controller 层:DBController(对外提供 HTTP 接口)](#3.4.3 Controller 层:DBController(对外提供 HTTP 接口))
[3.4.4 启动类编写](#3.4.4 启动类编写)
[3.5 启动测试](#3.5 启动测试)
[4.1 配置 pom.xml 依赖](#4.1 配置 pom.xml 依赖)
[4.2 配置 application.properties](#4.2 配置 application.properties)
[4.3 核心业务代码编写](#4.3 核心业务代码编写)
[4.3.1 核心配置类:RestTemplateConfig(解决循环依赖核心)](#4.3.1 核心配置类:RestTemplateConfig(解决循环依赖核心))
[4.3.2 实体类:Classes(与生产者完全一致)](#4.3.2 实体类:Classes(与生产者完全一致))
[4.3.3 Controller 层:UserController(远程调用 + 对外接口)](#4.3.3 Controller 层:UserController(远程调用 + 对外接口))
[4.3.4 启动类编写](#4.3.4 启动类编写)
[5.1 严格启动顺序(避免注册失败)](#5.1 严格启动顺序(避免注册失败))
[5.2 验证服务注册](#5.2 验证服务注册)
[5.3 验证远程调用与数据返回](#5.3 验证远程调用与数据返回)
[5.4 验证 Ribbon 客户端负载均衡](#5.4 验证 Ribbon 客户端负载均衡)
1.项目背景
本文将实战实现 Eureka 服务注册与发现、生产者(dbservice)操作 MySQL 数据库、消费者(users)远程 RPC 调用,同时整合 Ribbon 实现客户端负载均衡。
1.1 项目架构设计(单父工程 + 多子模块)
采用企业标准的父工程聚合子模块模式,职责划分清晰,便于维护和扩展:
java
springcloud-demo(父工程)
├─ servicecenter1(Eureka注册中心,端口8088):管理所有服务实例的注册、发现与状态监控
├─ dbservice(数据服务生产者,端口9091):操作MySQL数据库,提供标准化数据查询接口
└─ users(用户服务消费者,端口8025):远程调用dbservice,对外提供统一业务访问入口
1.2 业务场景
实现班级信息查询基础业务:
dbservice连接 MySQL,查询t_classes表数据,暴露/querydata接口;users通过RestTemplate(整合 Ribbon)以服务名远程调用dbservice;- 所有服务均注册到
servicecenter1,实现服务解耦与动态发现。
2.搭建 Eureka 服务注册中心(servicecenter1)
作为微服务架构的核心枢纽,Eureka 注册中心负责接收所有服务的注册请求,为消费者提供服务实例发现能力,是微服务通信的基础。
2.1 新建项目

2.2 在项目clouddemo2中新建模块servercenter1

2.3 修改模块servercenter1下的内容
2.3.1 配置 pom.xml 依赖
XML
<?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 https://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.7.18</version>
<relativePath/>
</parent>
<groupId>com.hy</groupId>
<artifactId>servercenter1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>servercenter1</name>
<description>Eureka服务注册中心</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2021.0.8</spring-cloud.version>
</properties>
<dependencies>
<!-- Spring Boot核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 单元测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Eureka Server核心依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<!-- Spring Cloud版本管理,强制统一版本,避免依赖冲突 -->
<dependencyManagement>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.3.2 配置 application.properties
核心配置 Eureka 服务端参数,关闭自身注册与发现(注册中心无需将自己注册到服务列表),指定服务端口和注册地址:
# 服务名称,唯一标识注册中心
spring.application.name=servercenter1
# Eureka服务端口
server.port=8088
# Eureka实例主机名
eureka.instance.hostname=localhost
# 关闭注册中心自身注册到Eureka(核心配置)
eureka.client.register-with-eureka=false
# 关闭注册中心从Eureka发现其他服务(核心配置)
eureka.client.fetch-registry=false
# Eureka注册地址,供其他服务注册使用
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka
# 关闭Eureka自我保护机制(开发环境建议开启,生产环境关闭)
eureka.server.enable-self-preservation=false
2.3.3 启动类编写
添加@EnableEurekaServer注解标记为 Eureka 服务端,配合@SpringBootApplication开启 Spring Boot 自动配置,代码极简:
java
package com.hy.servercenter1;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* Eureka服务注册中心启动类
* @EnableEurekaServer 开启Eureka服务端功能
*/
@EnableEurekaServer
@SpringBootApplication
public class Servercenter1Application {
public static void main(String[] args) {
SpringApplication.run(Servercenter1Application.class, args);
}
}
2.3.4 启动测试
运行启动类,无报错后访问 Eureka 控制台:http://localhost:8088,页面显示No instances available说明注册中心启动成功,等待生产者和消费者注册。


3.搭建数据服务生产者(dbservice)
dbservice作为服务生产者 ,是微服务的数据层服务 ,负责与 MySQL 数据库交互,提供标准化的 HTTP 数据接口,注册到 Eureka 后供消费者远程调用,是数据交互的核心节点。
3.1 数据库前置准备
在 MySQL 中创建数据库和表,插入测试数据
sql
-- 创建表 --
CREATE TABLE t_classes (
cid INT PRIMARY KEY AUTO_INCREMENT,
cname VARCHAR(20) NOT NULL,
cphone VARCHAR(200)
);
-- 删除数据库表,用于先前如果创建好的表 --
DROP TABLE t_classes
-- 插入数据 --
INSERT INTO t_classes(cname,cphone) VALUES("鸿蒙班","13800013800");
INSERT INTO t_classes(cname,cphone) VALUES("Java班","13700013700");
INSERT INTO t_classes(cname,cphone) VALUES("仓颉班","13600013600");
-- 查询表 --
SELECT * FROM t_classes

3.2 配置 pom.xml 依赖
引入 Eureka Client、Spring Web、MyBatis、MySQL 驱动、Ribbon 核心依赖,所有版本均由 Spring Cloud 2021.0.8 统一管理,无版本冲突:
XML
<?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 https://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.7.18</version>
<relativePath/>
</parent>
<groupId>com.hy</groupId>
<artifactId>dbservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>dbservice</name>
<description>数据服务生产者,操作MySQL数据库</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2021.0.8</spring-cloud.version>
<mybatis.version>2.2.2</mybatis.version>
<mysql.connector.version>8.0.33</mysql.connector.version>
</properties>
<dependencies>
<!-- Spring Web:提供HTTP接口能力 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Eureka Client:注册到Eureka注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Ribbon:客户端负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!-- MyBatis整合Spring Boot -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- MySQL驱动:适配MySQL8.0+ -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.connector.version}</version>
<scope>runtime</scope>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Spring Cloud版本管理 -->
<dependencyManagement>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.3 配置 application.properties
整合Eureka 注册 、数据库连接 、MyBatis三大核心配置,一步到位,无冗余参数:
sql
# 服务名称,消费者通过该名称调用(核心,必须与调用名一致)
spring.application.name=dbservice
# 服务端口
server.port=9091
# 注册到Eureka的地址(与注册中心保持一致)
eureka.client.service-url.defaultZone=http://127.0.0.1:8088/eureka
# 服务实例过期时间,加快服务剔除
eureka.instance.lease-expiration-duration-in-seconds=30
# MySQL数据库连接配置(适配8.0+)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mysql2026
spring.datasource.username=root
spring.datasource.password=yourpassword
# 连接池大小
spring.datasource.hikari.maximum-pool-size=10
# MyBatis配置
# 实体类包扫描
mybatis.type-aliases-package=com.hy.dbservice.model
# 开启DAO层日志,方便调试SQL
logging.level.com.hy.dbservice.dao=debug
3.4 核心业务代码编写
遵循MVC 分层思想 ,按实体类 ->DAO 层 ->Controller 层编写代码,结构清晰,符合企业开发规范。
3.4.1 实体类:Classes(与 t_classes 表一一对应)
java
package com.hy.dbservice.model;
/**
* 班级实体类,映射t_classes表
*/
public class Classes {
private int cid; // 班级ID
private String cname; // 班级名称
private String cphone; // 班级联系电话
// Getter和Setter方法
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getCphone() {
return cphone;
}
public void setCphone(String cphone) {
this.cphone = cphone;
}
}
3.4.2 DAO 层:DBDao(MyBatis 数据访问层)
使用注解式 MyBatis 实现 SQL 查询,无需编写 XML 映射文件,简化开发,适合简单查询场景,添加@Mapper注解让 Spring 自动扫描并创建实现类:
java
package com.hy.dbservice.dao;
import com.hy.dbservice.model.Classes;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 数据访问层,操作t_classes表
*/
@Mapper
public interface DBDao {
// 查询所有班级信息
@Select("select * from t_classes")
List<Classes> queryClassesInfo();
}
3.4.3 Controller 层:DBController(对外提供 HTTP 接口)
暴露/querydata接口作为消费者调用入口,注入 DAO 层对象实现数据库查询,返回 JSON 格式数据:
java
package com.hy.dbservice.controller;
import com.hy.dbservice.dao.DBDao;
import com.hy.dbservice.model.Classes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 数据服务控制器,提供数据查询接口
* @RestController 标记为REST风格控制器,返回JSON数据
*/
@RestController
public class DBController {
// 自动注入DAO层对象
@Autowired
private DBDao dbDao;
// 对外提供的班级信息查询接口
@RequestMapping("/querydata")
public List<Classes> queryData() {
System.out.println("DBController is queryData start... ");
// 调用DAO层查询数据库
List<Classes> lists = dbDao.queryClassesInfo();
return lists;
}
}
3.4.4 启动类编写
添加@EnableDiscoveryClient注解开启 Eureka 客户端能力,让服务自动注册到 Eureka 注册中心:
java
package com.hy.dbservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* 数据服务生产者启动类
* @EnableDiscoveryClient 开启Eureka客户端,实现服务注册与发现
*/
@EnableDiscoveryClient
@SpringBootApplication
public class DbserviceApplication {
public static void main(String[] args) {
SpringApplication.run(DbserviceApplication.class, args);
}
}
3.5 启动测试
- 确保 Eureka 注册中心已启动;
- 运行
DbserviceApplication,无报错即启动成功;- 访问 Eureka 控制台
http://localhost:8088,可看到DBSERVICE 服务状态为UP,说明注册成功;- 直接访问接口
http://localhost:9091/querydata,页面返回 JSON 格式的班级数据,说明数据库交互和接口正常。



4.搭建用户服务消费者(users)
users作为服务消费者 ,是微服务的应用层服务 ,不直接操作数据库,通过RestTemplate以服务名 方式远程调用dbservice的接口,对外提供统一的业务访问入口,实现服务解耦和业务分层。
4.1 配置 pom.xml 依赖
引入 Eureka Client、Spring Web、Ribbon 核心依赖,与生产者版本保持一致,保证微服务架构依赖统一:
XML
<?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 https://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.7.18</version>
<relativePath/>
</parent>
<groupId>com.hy</groupId>
<artifactId>users</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>users</name>
<description>用户服务消费者,远程调用数据服务</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2021.0.8</spring-cloud.version>
</properties>
<dependencies>
<!-- Spring Web:提供HTTP接口 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Eureka Client:注册到Eureka并发现服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Ribbon:开启客户端负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Spring Cloud版本管理 -->
<dependencyManagement>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4.2 配置 application.properties
简洁配置服务名、端口和 Eureka 注册地址,与注册中心、生产者保持配置一致:
# 服务名称
spring.application.name=users
# 服务端口
server.port=8025
# 注册到Eureka的地址
eureka.client.service-url.defaultZone=http://127.0.0.1:8088/eureka
# 开启服务发现
eureka.client.fetch-registry=true
4.3 核心业务代码编写
4.3.1 核心配置类:RestTemplateConfig(解决循环依赖核心)
将RestTemplate的 Bean 定义抽离为独立配置类,彻底解决循环依赖,也是企业开发中Bean 配置与业务代码解耦的标准写法:
java
package com.hy.users.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 全局Bean配置类,避免Bean循环依赖
*/
@Configuration // 标记为配置类,Spring会扫描并执行内部@Bean方法
public class RestTemplateConfig {
// 定义RestTemplate Bean,与UserController解耦
@Bean
@LoadBalanced // 保留负载均衡功能
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
4.3.2 实体类:Classes(与生产者完全一致)
消费者需要创建与生产者字段名、类型完全一致的实体类,用于接收远程调用返回的 JSON 数据并自动封装:
java
package com.hy.users.model;
/**
* 班级实体类,与dbservice中的实体类保持一致
*/
public class Classes {
private int cid;
private String cname;
private String cphone;
// Getter和Setter方法
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getCphone() {
return cphone;
}
public void setCphone(String cphone) {
this.cphone = cphone;
}
}
4.3.3 Controller 层:UserController(远程调用 + 对外接口)
核心实现RestTemplate 配置 (添加@LoadBalanced开启负载均衡)和远程服务调用 ,对外暴露/query统一访问接口,通过服务名 dbservice替代 IP + 端口,实现服务解耦:
java
package com.hy.users.controller;
import com.hy.users.model.Classes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
/**
* 用户服务控制器,远程调用dbservice并对外提供接口
*/
@RestController
public class UserController {
// 注入配置好的RestTemplate
@Autowired
private RestTemplate restTemplate;
/**
* 配置RestTemplate Bean
* @LoadBalanced 开启客户端负载均衡,支持通过服务名调用
*/
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
/**
* 对外提供的统一查询接口,内部远程调用dbservice
* @return 班级信息列表
*/
@RequestMapping("/query")
public List<Classes> loadData() {
System.out.println("UserController is loadData start...");
// 核心:通过服务名dbservice远程调用,由Eureka发现服务,Ribbon实现负载均衡
List<Classes> lists = this.restTemplate.getForObject("http://dbservice/querydata", List.class);
return lists;
}
}
4.3.4 启动类编写
添加@EnableDiscoveryClient注解,开启服务注册与发现能力,让消费者能从 Eureka 中发现dbservice服务实例:
java
package com.hy.users;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* 用户服务消费者启动类
*/
@EnableDiscoveryClient
@SpringBootApplication
public class UsersApplication {
public static void main(String[] args) {
SpringApplication.run(UsersApplication.class, args);
}
}
5.整体运行与全流程测试
5.1 严格启动顺序(避免注册失败)
微服务启动需遵循依赖顺序,确保注册中心先启动,再启动生产者,最后启动消费者:
- 第一步:启动 Eureka 注册中心
servercenter1(8088)- 第二步:启动数据服务生产者
dbservice(9091)- 第三步:启动用户服务消费者
users(8025)

5.2 验证服务注册
访问 Eureka 控制台http://localhost:8088,可看到DBSERVICE 和USERS 两个服务均为UP 状态,说明所有服务成功注册到 Eureka,服务治理生效。

5.3 验证远程调用与数据返回
访问消费者对外暴露的统一接口:http://localhost:8025/query,页面将以**JSON 格式** 返回 MySQL 中的班级信息,效果如下:

同时观察控制台日志:
- 消费者
users控制台:打印UserController is loadData start...- 生产者
dbservice控制台:打印DBController is queryData start...+ DAO 层 SQL 执行日志


说明微服务远程 RPC 调用成功 ,实现了从消费者接口 -> 生产者接口 -> MySQL 数据库的全流程数据交互。
5.4 验证 Ribbon 客户端负载均衡
为dbservice开启多实例部署 ,验证 Ribbon 的轮询负载均衡能力,步骤如下:
- 打开
dbservice的 IDEA 运行配置,勾选Allow multiple instances(允许多实例运行);- 修改
dbservice的application.properties中server.port为 9092,再次启动dbservice;- 访问 Eureka 控制台,可看到
dbservice有2 个实例(9091/9092),均为 UP 状态;- 多次刷新消费者接口
http://localhost:8025/query,生产者 9091 和 9092 的控制台会交替打印日志,说明 Ribbon 负载均衡生效,请求在多个生产者实例间轮询分发。