SpringCloud-生产者和消费者

一、生产者和消费者的定义

在 Spring Cloud 中,术语 "生产者" 和 "消费者" 用于描述微服务架构中的两种基本角色。

角色定义
生产者
Provider
生产者是提供具体服务或功能的模块。它将业务逻辑封装成服务,供其他模块调用。生产者向服务注册中心注册自己提供的服务,使其他模块可以通过服务注册中心发现并调用这些服务。
消费者
Consumer
消费者是通过调用生产者提供的服务来完成特定功能的模块。消费者从服务注册中心获取生产者的信息,然后调用生产者的服务接口。消费者在运行时动态发现并连接到可用的生产者。

示例:一个在线商城系统中,订单服务可以被视为生产者,提供创建订单、查询订单等服务。购物车服务可以是一个消费者,它调用订单服务的创建订单服务来完成用户购物车中商品的下单。

简单在线商城购物流程服务结构图:

 

稍微复杂一点的在线商城系统的购物流程服务结构图:


二、生产者和消费者代码演示

1、创建父工程

在构建微服务项目时,首先需要创建一个父工程,以便统一管理依赖版本和项目属性。

我们来新建项目 SpringCloudTest。

父工程不需要太多引入,勾选 spring web 这一项即可。 

删除多余内容:

pom.xml 新增 packaging 标签


2、创建服务注册中心

微服务架构中,服务注册中心是整个系统的核心,负责服务的注册与发现。使用 Spring Cloud 的Eureka 组件,可以轻松搭建一个高可用的服务注册中心。在创建 Eureka 注册中心时,需要在项目中引入相应的依赖,并通过注解标记该服务为 Eureka Server。

新建模块 euraka-server。

勾选 eureka server。 

创建完成后,我们修改 eureka-server 的 pom.xml,使它的 <parent></parent> 标签里的内容对应父工程。

父工程:

eureka-server 的 pom.xml:

<parent><groupId>com.example</groupId><artifactId>SpringCloudTest</artifactId><version>0.0.1-SNAPSHOT</version><relativePath/>
</parent>

同时,我们需要在父工程的 pom.xml 里添加子模块的依赖关系。 

<modules><module>eureka-server</module>
</modules>

创建 eureka-server 的 application.properties 配置文件重命名为 application.yml。

内容修改为: 

#服务端口
server:port: 8081
#服务名称
spring:application:name: eureka-server#eureka地址
eureka:client:service-url:defaultZone: http://127.0.0.1:8081/eureka/register-with-eureka: falsefetch-registry: false

启动类上添加 @EnableEurekaServer 注解。 

测试启动 eurake 服务,选中 EurekaServerApplication 右键运行,启动 eurake-server 服务。确认控制台正常加载,在控制台上能够看到服务实例的信息,表示 Eureka 注册中心已成功启动。

访问我们设置的 eurake-server 服务的地址:localhost:8081,可以看到 Eureka 服务界面。


3、创建生产者

生产者是负责提供服务的模块,它将特定的业务逻辑封装成服务,供其他模块调用。在创建生产者时,需要定义服务接口,并使用 @RestController 或 @Service 等注解将业务逻辑发布为 RESTful API 或 RPC 服务。生产者将服务注册到 Eureka 注册中心,使消费者能够发现并调用这些服务。

① 创建生产者模块

父工程下创建模块 eureka-provider:

勾选 Eureka Discovery Client,用于注册到 eureka-server 服务注册中心。 

类似于 eureka-server 服务注册中心的创建,我们需要在 pom.xml 里引入父类标签,可以参考上面eureka-server 服务注册中心创建时的写法,内容是一样的,都指向父工程。

<parent><groupId>com.example</groupId><artifactId>SpringCloudTest</artifactId><version>0.0.1-SNAPSHOT</version><relativePath/>
</parent>

同理,为父工程增加新的子模块:eureka-provider:

<modules><module>eureka-server</module><module>eureka-provider</module>
</modules>

在主类上使用 @EnableEurekaClient 注解,注册该服务到 Eureka Server。


② 添加消费者配置

将 eureka-provider 的 application.properties 配置文件重命名为 application.yml。

配置 eureka-provider 的相关属性,如服务端口、注册中心地址等。

# 服务器端口
server:port: 8082# 配置发布服务地址
spring:application:name: eureka-providereureka:client:service-url:defaultZone: http://localhost:8081/eureka


③ 编写生产者代码 

生产者模块需要将特定的业务逻辑封装成服务,供其他模块调用。所以我们需要创建实体类并且写一些供我们调用的接口。

这里是创建 eureka-provider 模块时勾选 Eureka Discovery Client 自带的代码,包含两个控制器接口类和一个实体类,我们直接拿来用就可以。

实体类 User 如下:

控制器基类 BaseController: 


④ 测试生产者服务可用

接着,我们运行应用,根据我们刚刚的配置,运行地址是 localhost:8082,我们看看访问这个地址能否显示 Hello World 的主页。如果可以访问,说明项目运行成功,我们再来访问 Eureka Server 的控制台,确保 eureka-provider 成功注册到服务注册中心。 


4、创建消费者

消费者是通过调用生产者提供的服务来完成特定功能的模块。在创建消费者时,需要引入 Eureka 客户端依赖,以便消费者能够从服务注册中心发现并调用生产者提供的服务。通过使用 @LoadBalanced 注解配置 RestTemplate,可以实现基于服务名称的负载均衡。

① 创建消费者模块

父工程下创建模块 eureka-consumer:

勾选 Eureka Discovery Client,用于注册到 eureka-server 服务注册中心。  

类似于 eureka-server 服务注册中心的创建,我们需要在 pom.xml 里引入父类标签,可以参考上面eureka-server 服务注册中心创建时的写法,内容是一样的,都指向父工程。

<parent><groupId>com.example</groupId><artifactId>SpringCloudTest</artifactId><version>0.0.1-SNAPSHOT</version><relativePath/>
</parent>

同理,为父工程增加新的子模块:eureka-consumer:

<modules><module>eureka-server</module><module>eureka-provider</module><module>eureka-consumer</module>
</modules>

 在主类上使用 @EnableEurekaClient 注解,注册该服务到 Eureka Server。


② 添加消费者配置

将 eureka-consumer 的 application.properties 配置文件重命名为 application.yml。

配置 eureka-consumer 的相关属性,如服务端口、注册中心地址等。 

# 服务器端口
server:port: 8083# 配置发布服务地址
spring:application:name: eureka-consumereureka:client:service-url:defaultZone: http://localhost:8081/eureka


③ 编辑消费者代码 

使用 RestTemplate 或 Feign 等方式调用生产者提供的服务,确保服务的负载均衡。
这里我们使用的是 RestTemplate。

启动类里添加:

@Bean   // 交给spring容器管理
@LoadBalanced  // 支持使用服务名称发现服务进行调用,且支持负载
public RestTemplate getRestTemplate() {return new RestTemplate();
}

创建调用生产者服务的接口类 UserController。

UserController: 

package com.example.eurekaconsumer.demos.web;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.List;@RestController
public class UserController {@Autowiredprivate RestTemplate restTemplate;@RequestMapping("/showUser")@ResponseBodypublic User showUser() {String baseUrl = "http://" + "eureka-provider" + "/user";User userInfo = restTemplate.getForObject(baseUrl, User.class);return userInfo;}}

我们这里的接口调用地址是 /showUser,调用的是生产者服务的 /user 接口。


④ 测试消费者服务可用 

接着,我们运行应用,根据我们刚刚的配置,运行地址是 localhost:8083,我们看看访问这个地址能否显示 Hello World 的主页。如果可以访问,说明项目运行成功,我们再来访问 Eureka Server 的控制台,确保 eureka-consumer 成功注册到服务注册中心。 


5、消费者调用生产者服务

生产者和消费者模块准备完成之后,我们就来演示消费者调用生产者服务的过程。

首先,我们启动项目,按照 eureka-server、eureka-provier 、eureka-consumer 的顺序启动。

然后,我们来直接调用生产者 eureka-provier 的用户服务接口 /user。访问地址:localhost:8082/user,可以看到成功返回给我们一个 User 对象。

接着,我们来通过消费者 eureka-consumer 来调用生产者 eureka-provier 的用户服务接口,访问地址:localhost:8083/showUser,可以看到也是成功返回给我们一个 User 对象。这里的对象就是eureka-provier 的用户服务接口 /user 返回给我们的。

以上就是消费者服务调用生产者服务的简单示例。


三、实现服务调用的负载均衡

在上面代码的演示中,我们已经用到了负载均衡的措施,这一节,我就再系统描述一下 Spring Cloud 中基于 RestTemplate 实现负载均衡的具体步骤。

负载均衡是一种将网络或计算负载分配到多个服务器或网络路径的技术,以实现资源的均匀利用和提高系统的可用性。在微服务架构中,负载均衡起到了关键的作用,确保请求能够被均匀分发到多个服务实例上,避免某个实例过载而影响系统性能。 

在 Spring Cloud 中,RestTemplate 通过整合 Ribbon 负载均衡器,可以实现在服务消费者端的负载均衡。以下是使用 RestTemplate 进行负载均衡的基本用法:

1、引入Ribbon依赖

在消费者项目的 pom.xml 中引入 Spring Cloud Netflix Ribbon 依赖:

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

2、创建RestTemplate

在消费者的配置类或者项目启动类中创建一个带有 @LoadBalanced 注解的 RestTemplate Bean,该注解启用了 Ribbon 的负载均衡功能:

启动类里添加方法:

@Bean   // 交给spring容器管理
@LoadBalanced  // 支持使用服务名称发现服务进行调用,且支持负载
public RestTemplate getRestTemplate() {return new RestTemplate();
}

配置类例子:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class AppConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

3. 使用RestTemplate进行服务调用

在消费者的服务类中使用 RestTemplate 进行服务调用。使用服务名称而不是硬编码的 URL,Ribbon 会根据服务名称自动选择可用的实例:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;@Service
public class ConsumerService {private final RestTemplate restTemplate;@Autowiredpublic ConsumerService(RestTemplate restTemplate) {this.restTemplate = restTemplate;}public String consumeService() {// 使用服务名称而不是具体的URLString serviceUrl = "http://producer-service/produce";return restTemplate.getForObject(serviceUrl, String.class);}
}

上述代码中,http://producer-service 是服务提供者的服务名称,而不是具体的服务实例的URL。Ribbon 会根据负载均衡策略选择一个可用的服务实例进行调用。

通过这种方式,RestTemplate 在消费者端实现了对服务提供者的负载均衡。你可以根据具体的业务需求选择不同的负载均衡策略,例如轮询、随机、权重等。


四、生产者和消费者知识总结

生产者(Provider):

生产者是提供具体服务或功能的模块,将业务逻辑封装成服务,供其他模块调用。

要点内容
服务注册生产者将自身注册到服务注册中心,使其他模块能够发现并调用这些服务。
服务标识生产者有唯一的标识,通常是服务的名称,通过服务注册中心进行标识和发现。
服务提供实现具体的服务接口,可以是RESTful API或RPC接口,对外提供服务功能。
负载均衡通过服务注册中心和负载均衡器,使请求能够均匀分布到多个生产者实例,提高性能和可用性。

消费者(Consumer):

消费者是通过调用生产者提供的服务来完成特定功能的模块,使用其他服务以满足业务需求。

要点内容
服务发现消费者通过服务注册中心获取生产者的实例信息,实现动态发现服务。
负载均衡使用负载均衡器决定选择哪个生产者实例进行服务调用,确保请求分发均衡。
服务调用通过 HTTP RESTful API 或 RPC 调用生产者的服务接口,完成特定的业务需求。
动态感知消费者能够动态感知生产者实例的上线和下线,保持与服务注册中心的实时同步。

负载均衡与服务注册中心:

要点内容
Ribbon
负载均衡器
作为客户端负载均衡器,通过配置策略决定选择哪个生产者实例进行服务调用。
Eureka
服务注册中心
用于生产者注册和消费者服务发现,提供服务实例信息和状态。
服务发现
与注册
生产者通过 Eureka 注册服务,消费者通过 Eureka 发现服务,实现解耦的服务调用。
动态感知
与适应性
负载均衡器和服务注册中心能够动态感知实例变化,保持对系统变化的及时适应性。

以上知识点总结了生产者和消费者在微服务架构中的基本概念和操作,强调了服务注册中心和负载均衡在实现服务发现和调用过程中的关键作用。这些概念为搭建稳健、高性能的微服务系统提供了基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/453330.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有趣的CSS - 鼠标悬浮线条动态变化

鼠标悬浮线条动态变化 整体效果核心代码html 代码&#xff1a;css 部分代码&#xff1a; 完整代码如下html 页面&#xff1a;css 样式&#xff1a;页面渲染效果&#xff1a; 整体效果 这个链接悬浮效果主要用 css3 的 animation 属性配合 :hover 伪选择器来实现的。 此效果可以…

Rust 本地文档的使用:rustup doc

Rust 是一种系统级编程语言&#xff0c;以其安全性、速度和内存控制能力而闻名。为了方便开发者更好地了解并利用 Rust 标准库和工具链中的功能&#xff0c;Rust 提供了一种内置的文档浏览方式——通过 rustup doc 命令。 安装 rustup 在查阅 Rust 文档之前&#xff0c;确保你…

08:LED点阵

LED点阵 1、什么是LED点阵2、如何驱动LED点整3、原理图分析4、74HC595的接法分析5、74HC595芯片分析6、编程实践&#xff08;全屏点亮&#xff09; 1、什么是LED点阵 如图为16x16的LED点阵&#xff0c;每一个点里面都有一个LED灯 上图为一个8x8点阵LED原理图&#xff08;横向为…

Sklearn、TensorFlow 与 Keras 机器学习实用指南第三版(一)

原文&#xff1a;Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 机器学习海啸 2006 年&#xff0c;Geoffrey Hinton 等人发表了一篇论文&#xff0c;展示了如何训练一个能够以最先进的精度…

CodeFuse成功支持通义千问算法大赛,评测方案已开源

前段时间&#xff0c; 首届通义千问AI挑战赛成功举办&#xff0c;CodeFuse 为大赛提供技术支持&#xff0c;模型微调框架 MFTCoder 和 CodeFuseEval 评测框架为大赛保驾护航&#xff0c;助力大赛圆满完成。我们基于leetcode 阿里和蚂蚁最新面试题库建设了“模型赛马”在线打榜的…

【GAMES101】Lecture 15 全局光照

本节继承上一节的难度并继续加深&#xff0c;讲这个BRDF&#xff0c;然后理解反射方程和渲染方程&#xff0c;最终实现全局光照&#xff0c;以下内容很抽象……如果想要深入理解建议到隔壁基于物理着色&#xff1a;BRDF - 知乎 (zhihu.com)或者多看几遍视频&#xff0c;我也是回…

VScode+PlatformIO 物联网Iot开发平台环境搭建

1.vscode &#xff08;1&#xff09;安装platformIO插件 &#xff08;2&#xff09;新建项目或导入已有的arduino项目 Name&#xff1a;需要填写你项目的名称&#xff1b; Board&#xff1a;点开是一个下拉框&#xff0c;但是可以输入你想要的开发板&#xff0c;这里选择&quo…

华为配置OSPF与BFD联动示例

配置OSPF与BFD联动示例 组网图形 图1 配置OSPF与BFD联动组网图 OSPF与BFD联动简介配置注意事项组网需求配置思路操作步骤配置文件 OSPF与BFD联动简介 双向转发检测BFD&#xff08;Bidirectional Forwarding Detection&#xff09;是一种用于检测转发引擎之间通信故障的检测…

什么是前端工程化,请举例说明

前端工程化 前端工程化的定义为什么需要前端工程化前端工程化的核心概念 模块化开发&#xff1a;组件化开发&#xff1a;规范化开发&#xff1a;自动化开发&#xff1a;持续集成 前端工程化的主要工具前端工程化的应用总结&#xff1a; 前端工程化 前端工程化的定义 前端工程…

本地缓存Ehcache的应用实践 | 京东云技术团队

java本地缓存包含多个框架&#xff0c;其中常用的包括&#xff1a;Caffeine、Guava Cache和Ehcache&#xff0c; 其中Caffeine号称本地缓存之王&#xff0c;也是近年来被众多程序员推崇的缓存框架&#xff0c;同时也是SpringBoot内置的本地缓存实现。但是除了Caffeine之外&…

MySQL操作问题汇总

MySQL操作问题汇总 1.无法远程连接Ubuntu的MySQL2.ubuntu忘记mysql的root密码时的操作 1.无法远程连接Ubuntu的MySQL (1) 需要检查防火墙状态 > sudo ufw status #如果防火墙开启的情况&#xff0c;添加规则&#xff1a;允许3306端口开启 > sudo ufw allow 3306 (2) 需要…

3D DRAM引领存储变革,重塑智能时代计算格局

3D DRAM作为一种应对DRAM技术挑战的解决方案&#xff0c;正逐渐被视为未来内存市场的关键发展方向。与3D NAND类似&#xff0c;3D DRAM采用了立体堆叠技术来突破传统二维平面架构的局限。 在传统DRAM中&#xff0c;存储单元由一个晶体管和一个电容器组成&#xff0c;晶体管负责…