SpringCloud-生产者和消费者

举报
Damon小智 发表于 2024/02/16 21:01:17 2024/02/16
【摘要】 本文介绍SpringCloud微服务架构中常用的两个基本角色——生产者和消费者。生产者是提供具体服务或功能的模块。它将业务逻辑封装成服务,供其他模块调用。生产者向服务注册中心注册自己提供的服务,使其他模块可以通过服务注册中心发现并调用这些服务。

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

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

角色

定义

生产者 Provider

生产者是提供具体服务或功能的模块。它将业务逻辑封装成服务,供其他模块调用。生产者向服务注册中心注册自己提供的服务,使其他模块可以通过服务注册中心发现并调用这些服务。

消费者 Consumer

消费者是通过调用生产者提供的服务来完成特定功能的模块。消费者从服务注册中心获取生产者的信息,然后调用生产者的服务接口。消费者在运行时动态发现并连接到可用的生产者。

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

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

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


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

1、创建父工程

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

我们来新建项目 SpringCloudTest

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

删除多余内容:

pom.xml 新增 packaging 标签。


2、创建服务注册中心

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

新建模块 euraka-server

模块命名为 euraka-server

勾选 eureka server

修改 eureka-server 模块的 pom.xml,将其中的 parent 标签内容,指向父工程。

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

parent 标签内容为父工程的 pom.xml 里的内容:

在父级 pom 中添加该子模块。

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

子类会继承父类的依赖,可以利用这个特性,精简依赖项配置。

创建 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 注解。

选中 EurekaServerApplication 右键运行,启动 eurake-server 服务.

确认控制台正常加载,在控制台上能够看到服务实例的信息,表示Eureka注册中心已成功启动。

使用浏览器访问 Eureka 控制台地址,通常为 http://localhost:8761 我们这里自定义为 8081 端口。


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-provider 的相关属性,如服务端口、注册中心地址等。

# 服务器端口
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-servereureka-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 进行服务调用。使用服务名称而不是硬编码的 URLRibbon 会根据服务名称自动选择可用的实例:

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 是服务提供者的服务名称,而不是具体的服务实例的URLRibbon 会根据负载均衡策略选择一个可用的服务实例进行调用。

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


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

生产者(Provider):

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

要点

内容

服务注册

生产者将自身注册到服务注册中心,使其他模块能够发现并调用这些服务。

服务标识

生产者有唯一的标识,通常是服务的名称,通过服务注册中心进行标识和发现。

服务提供

实现具体的服务接口,可以是RESTful API或RPC接口,对外提供服务功能。

负载均衡

通过服务注册中心和负载均衡器,使请求能够均匀分布到多个生产者实例,提高性能和可用性。

消费者(Consumer):

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

要点

内容

服务发现

消费者通过服务注册中心获取生产者的实例信息,实现动态发现服务。

负载均衡

使用负载均衡器决定选择哪个生产者实例进行服务调用,确保请求分发均衡。

服务调用

通过 HTTP RESTful API 或 RPC 调用生产者的服务接口,完成特定的业务需求。

动态感知

消费者能够动态感知生产者实例的上线和下线,保持与服务注册中心的实时同步。

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

要点

内容

Ribbon
负载均衡器

作为客户端负载均衡器,通过配置策略决定选择哪个生产者实例进行服务调用。

Eureka
服务注册中心

用于生产者注册和消费者服务发现,提供服务实例信息和状态。

服务发现
与注册

生产者通过 Eureka 注册服务,消费者通过 Eureka 发现服务,实现解耦的服务调用。

动态感知
与适应性

负载均衡器和服务注册中心能够动态感知实例变化,保持对系统变化的及时适应性。

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

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。