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: false
    fetch-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-provider

eureka:
  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-consumer

eureka:
  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 {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/showUser")
    @ResponseBody
    public 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
    @LoadBalanced
    public 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;

    @Autowired
    public ConsumerService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String consumeService() {
        // 使用服务名称而不是具体的URL
        String 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 发现服务,实现解耦的服务调用。
动态感知
与适应性
负载均衡器和服务注册中心能够动态感知实例变化,保持对系统变化的及时适应性。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何构建多种系统架构支持的 Docker 镜像

如何构建多种系统架构支持的 Docker 镜像 1.概述2.解决方案3.使用manifest案例 1.概述 我们知道使用镜像创建一个容器&#xff0c;该镜像必须与 Docker 宿主机系统架构一致&#xff0c;例如 Linux x86_64 架构的系统中只能使用 Linux x86_64 的镜像创建容器 例如我们在 Linux…

python Flask 写一个简易的 web 端上传文件程序 (附demo)

python Flask 写一个简易的 web 端上传文件程序 &#xff08;附demo&#xff09; 需求介绍核心代码&#xff1a; 文件结构前端文件后端文件 完整代码演示 需求 在当今数字化时代&#xff0c;文件上传需求日益普遍。无论是个人还是企业&#xff0c;都可能需要实现文件上传功能。…

商业智能(BI)数据分析、挖掘概念

商业智能&#xff08;BI&#xff09;数据分析挖掘概念 一、商业智能&#xff08;BI&#xff09;数据分析挖掘概念 数据挖掘目前在各类企业和机构中蓬勃发展。因此我们制作了一份此领域常见术语总结。 1.分析型客户关系管理&#xff08;Analytical CRM/aCRM 用于支持决策&…

MySQL集群 1主1从 主从复制(原理 及配置命令)

CSDN 成就一亿技术人&#xff01; 今天分享一期 MySQL集群方案&#xff1a;主从集群 也是最常用的一种 CSDN 成就一亿技术人&#xff01; 目录 使用主从复制的原因&#xff08;优点&#xff09; 主从复制的过程&#xff08;原理&#xff09; 了解两大线程&#xff08; I/O…

day 19 (进阶)

一 首先 昨日内容回顾 思维导图&#xff1a;&#xff08;日更附 养成习惯 加油&#xff09; 补充Linux思维导图 衔接一下之前学过的 二 课堂知识提炼 练习&#xff1a;统计文件行数 想查看是否正确就用 grep -c “文件名” 来看 会输出结果 练习&#xff1a;把file.c里面的…

数据包跟踪器-实施 DHCPv4

实验大纲 第 1 部分&#xff1a;把路由器配置为 DHCP 服务器 步骤 1&#xff1a;配置要排除在外的 IPv4 地址 步骤 2&#xff1a;在 R2 上 给 R1 LAN 创建一个 DHCP 池 步骤 3&#xff1a;在 R2 上 给 R3 LAN 创建一个 DHCP 池 第 2 部分&#xff1a;配置 DHCP 中继 步骤…

爱上算法:每日算法(24-2月4号)

&#x1f31f;坚持每日刷算法&#xff0c;&#x1f603;将其变为习惯&#x1f91b;让我们一起坚持吧&#x1f4aa; 文章目录 [232. 用栈实现队列](https://leetcode.cn/problems/implement-queue-using-stacks/)思路CodeJavaC 复杂度 [225. 用队列实现栈](https://leetcode.cn/…

Maven配置笔记

1、下载Maven 在Maven的官网即可下载&#xff0c;点击访问Apache Maven。 2、配置环境变量 chcp 65001 echo off set mvnhomeE:\apache-maven-3.8.4 rem LPY echo. echo ************************************************************ echo * …

手写分布式存储系统v0.3版本

引言 承接 手写分布式存储系统v0.2版本 &#xff0c;今天开始新的迭代开发。主要实现 服务发现功能 一、什么是服务发现 由于咱们的服务是分布式的&#xff0c;那从服务管理的角度来看肯定是要有一个机制来知道具体都有哪些实例可以提供服务。举个例子就是&#xff0c;张三家…

ConcurrentHashMap的使用以及源码分析

一、ConcurrentHashMap&#xff1f; 1.1 存储结构 ConcurrentHashMap是线程安全的HashMap ConcurrentHashMap在JDK1.8中是以CASsynchronized实现的线程安全 CAS&#xff1a;在没有hash冲突时&#xff08;Node要放在数组上时&#xff09; synchronized&#xff1a;在出现ha…

Linux实验记录:使用BIND提供域名解析服务

前言&#xff1a; 本文是一篇关于Linux系统初学者的实验记录。 参考书籍&#xff1a;《Linux就该这么学》 实验环境&#xff1a; VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 备注&#xff1a; 为了降低用户访问网络资源的门槛&am…

解决IntellIJ Idea内存不足

突然有一天我在IDEA打开两个项目时&#xff0c;发生了报错&#xff0c;说我内存不足&#xff0c;我这电脑内存16G怎么会内存不足。下面是我的解决方案。 IntelliJ IDEA 报告内存不足的原因通常与以下几个因素有关&#xff1a; 项目规模较大&#xff1a;如果您正在开发的项目非…

【Python之Git使用教程001】Git简介与安装

一、简介 Git其实就是一个分布式版本的控制系统&#xff0c;在分布式版本的控制系统&#xff0c;大家都拥有一个完整的版本库&#xff0c;不需要联网也可以提交修改&#xff0c;所以中心服务器就显得不那么重要。由于大家都拥有一个完整的版本库&#xff0c;所有只需要把各自的…

假期刷题打卡--Day23

1、MT1190分数乘法 输入5组分数&#xff0c;对他们进行乘法运算&#xff0c;输出结果。不考虑分母为0等特殊情况。 格式 输入格式&#xff1a; 输入整型&#xff0c;每组一行&#xff0c;如样例所示。 输出格式&#xff1a; 输出计算结果实型&#xff0c;如样例所示。 样…

Centos 7.5 安装 NVM 详细步骤

NVM&#xff08;Node Version Manager&#xff09;是一个用于管理Node.js版本的工具&#xff0c;它可以让你轻松地在多个版本之间切换。NVM 通过下载和管理 Node.js 的多个版本&#xff0c;为用户提供了一种灵活的方式来使用不同版本的 Node.js。如果你需要更多关于NVM的信息&a…

【MySQL进阶】事务原理

文章目录 事务机制基本介绍事务管理基本操作提交方式事务 ID 隔离级别四种级别加锁分析 原子特性实现方式实现原理undo log 隔离特性实现方式MVCC实现原理隐藏字段undo logRead View RC RR 持久特性实现方式redo log 一致特性 面试题MySQL的ACID特性分别是怎么实现的&#xff1…

工信部颁发的《计算机视觉处理设计开发工程师》中级证书

计算机视觉&#xff08;Computer Vision&#xff09;是一门研究如何让计算机能够理解和分析数字图像或视频的学科。简单来说&#xff0c;计算机视觉的目标是让计算机能够像人类一样对视觉信息进行处理和理解。为实现这个目标&#xff0c;计算机视觉结合了图像处理、机器学习、模…

在java中获取excel的cell值的时候报错

在获取cell的时候&#xff0c;通常会有报错类型不匹配的问题&#xff0c;这是因为你的cell中存储的数据类型和使用的方法不匹配的原因&#xff0c;假如说cell中存储了一个数字&#xff0c;但是使用的cell.getStringCellValue()获取值&#xff0c;就会有如下错误 java.lang.Ill…

属性“xxxx”在类型“ArrayConstructor”上不存在。是否需要更改目标库? 请尝试将 “lib” 编译器选项更改为“es2015”或更高版本。

使用vscode编写vue&#xff0c;在使用elementUI时&#xff0c;发现代码中的form报错如下&#xff1a; 属性“form”在类型“ArrayConstructor”上不存在。是否需要更改目标库? 请尝试将 “lib” 编译器选项更改为“es2015”或更高版本。 解决方法&#xff1a; 打开jsconfig.…

智能边缘计算网关实现高效数据处理与实时响应-天拓四方

在当今时代&#xff0c;数据已经成为驱动业务决策的关键因素。然而&#xff0c;传统的数据处理方式往往存在延迟&#xff0c;无法满足实时性要求。此时&#xff0c;智能边缘计算网关应运而生&#xff0c;它能够将数据处理和分析的能力从中心服务器转移至设备边缘&#xff0c;大…