# 从浅入深 学习 SpringCloud 微服务架构(十五)

news2024/7/6 18:24:43

从浅入深 学习 SpringCloud 微服务架构(十五)

一、SpringCloudStream 的概述

  • 在实际的企业开发中,消息中间件是至关重要的组件之一。消息中间件主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。

  • 不同的中间件其实现方式,内部结构是不一样的。如常见的 RabbitMQ 和 Kafka,由于这两个消息中间件的架构上的不同,像 RabbitMQ 有 exchange,kafka 有 Topic,partitions 分区。

  • 这些中间件的差异性导致我们实际项目开发给我们造成了一定的困扰,我们如果用了两个消息队列的其中一种,后面的业务需求,我想往另外一种消息队列进行迁移,这时候无疑就是一个灾难性的,一大堆东西都要重新推倒重新做,因为它跟我们的系统耦合了,这时候 springcloud stream给我们提供了一种解耦合的方式。

  • Spring Cloud Stream 由一个中间件中立的核组成。应用通过 Spring Cloud Stream 插入的 input (相当于消费者 consumer,它是从队列中接收消息的)和 output (相当于生产者 producer,它是从队列中发送消息的。)通道与外界交流。通道通过指定中间件的 Binder 实现与外部代理连接。业务开发者不再关注具体消息中间件,只需关注 Binder 对应用程序提供的抽象概念来使用消息中间件实现业务即可。

二、SpringCloudStream 的实现思想,如下图:

1.png

说明:最底层是消息服务,中间层是绑定层,绑定层和底层的消息服务进行绑定,顶层是消息生产者和消息消费者,顶层可以向绑定层生产消息和和获取消息消费。

三、SpringCloudStream 的核心概念

1、核心概念 :绑定器

  • Binder 绑定器是 Spring Cloud Stream 中一个非常重要的概念。在没有绑定器这个概念的情况下,我们的 Spring Boot 应用要直接与消息中间件进行信息交互的时候,由于各消息中间件构建的初衷不同,它们的实现细节上会有较大的差异性,这使得我们实现的消息交互逻辑就会非常笨重,因为对具体的中间件实现细节有太重的依赖,当中间件有较大的变动升级、或是更换中间件的时候,我们就需要付出非常大的代价来实施。

  • 通过定义绑定器作为中间层,实现了应用程序与消息中间件(Middleware)细节之间的隔离。通过向应用程序暴露统一的 Channel 通过,使得应用程序不需要再考虑各种不同的消息中间件的实现。当需要升级消息中间件,或者是更换其他消息中间件产品时,我们需要做的就是更换对应的Binder绑定器而不需要修改任何应用逻辑 。甚至可以任意的改变中间件的类型而不需要修改一行代码。

  • 通过配置把应用和 spring cloud stream 的 binder 绑定在一起,之后我们只需要修改 binder 的配置来达到动态修改 topic、exchange、type 等一系列信息而不需要修改一行代码。

2、Spring Cloud Stream 支持各种 binder 实现,下表包含 GitHub 项目的链接。

  • RabbitMQ
  • Apache Kafka
  • Amazon Kinesis
  • Google PubSub (partner maintained)
  • Solace PubSub+(partner maintained)
  • Azure Event Hubs (partner maintained)

3、发布/订阅模型

在 Spring Cloud Stream 中的消息通信方式遵循了发布-订阅模式,当一条消息被投递到消息中间件之后,它会通过共享的 Topic 主题进行广播,消息消费者在订阅的主题中收到它并触发自身的业务逻辑处理。这里所提到的 Topic 主题是 Spring Cloud Stream 中的一个抽象概念,用来代表发布共享消息给消费者的地方。在不同的消息中间件中,Topic 可能对应着不同的概念,比如:在 RabbitMO 中的它对应了 Exchange、而在 Kakfa 中则对应了 Kafka 中的 Topic。

2.png

四、消息生产者的入门案例:上

1、下载安装语言环境 Eralng 和 消息中间件 rabbitmq-server 服务。

1.1 下载安装语言环境 Eralng (otp_win64_20.2.exe)
1.2 配置语言环境 Eralng 环境变量:
  • 新建系统变量名为:ERLANG_HOME 变量值:erlang 安装地址(如:D:\Program Files\erl9.2)
  • 将 系统变量 ERLANG_HOME 添加到 Path 目录下。

在这里插入图片描述
在这里插入图片描述

1.3 验证语言环境 erlang 是否安装成功:

WIN + R 打开【运行】,输入【cmd】,打开命令提示符窗口,输入:erl 显示 erlang 版本号,说明安装成功。

在这里插入图片描述

1.4 下载安装消息中间件 rabbitmq-server-3.7.4.exe
1.5 进入 rabbitMQ 安装目录的 sbin 目录,安装管理界面 rabbitmq_management(插件)
rabbitmq-plugins enable rabbitmq_management

在这里插入图片描述

1.6 进入 rabbitMQ 安装目录的 sbin 目录,启动 rabbitmq-server.bat 服务:
rabbitmq-server.bat

在这里插入图片描述

1.7 验证消息中间件 rabbitmq 是否安装成功:

WIN + R 打开【运行】,输入【cmd】,打开命令提示符窗口,输入:rabbitmqctl status
出现如下界面,表示安装成功。

在这里插入图片描述

1.8 打开浏览器,地址栏输入 http://127.0.0.1:15672 ,进入消息中间件 rabbitmq 管理界面

默认用户名、密码都是:guest

在这里插入图片描述

2、SpringCloudStream 入门案例:

2.1 SpringCloudStream :入门案例–搭建环境,准备数据库数据表。

— 创建数据库:
create database shop;

— 使用数据库:
use shop;

— 创建数据表:

	CREATE TABLE `tb_product` (
	  `id` int NOT NULL AUTO_INCREMENT,
	  `product_name` varchar(40) DEFAULT NULL COMMENT '名称',
	  `status` int DEFAULT NULL COMMENT '状态',
	  `price` decimal(10,2) DEFAULT NULL COMMENT '单价',
	  `product_desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '描述',
	  `caption` varchar(255) DEFAULT NULL COMMENT '标题',
	  `inventory` int DEFAULT NULL COMMENT '库存',
	  PRIMARY KEY (`id`)
	) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3

— 插入数据:

insert into `tb_product` (`id`, `product_name`, `status`, `price`, `product_desc`, `caption`, `inventory`) values('1','iPhone 15 Pro','1','7999.00','iPhone 15 Pro 6.7 英寸或 6.1 英寸, 超视网膜 XDR 显示屏,ProMotion 自适应刷新率技术,钛金属搭配亚光质感玻璃背板, 灵动岛功能, A17 Pro 芯片,配备 6 核图形处理器, Pro 级摄像头系统,主摄 4800 万像素 | 超广角 | 长焦, 10 倍, 支持 USB 3, 视频播放最长可达 29 小时。 ','iPhone 15 Pro 巅峰之作','99');

2.2 SpringCloudStream :入门案例–搭建环境–打开 idea 创建父工程

创建 artifactId 名为 spring_cloud_demo 的 maven 工程。


	--> idea --> File 
	--> New --> Project 
	--> Maven 
		Project SDK: ( 1.8(java version "1.8.0_131" ) 
	--> Next 
	--> Groupld : ( djh.it )
		Artifactld : ( spring_cloud_demo )
		Version : 1.0-SNAPSHOT
	--> Name: ( spring_cloud_demo )
		Location: ( ...\spring_cloud_demo\ )	
	--> Finish
	
2.3 SpringCloudStream :入门案例–搭建环境–在父工程 spring_cloud_demo 的 pom.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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>djh.it</groupId>
    <artifactId>spring_cloud_demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>product_service</module>
        <module>order_service</module>
        <module>eureka_service</module>
        <module>import_eurekaserver_test</module>
        <module>api_zuul_service</module>
        <module>api_gateway_service</module>
        <module>stream_product</module>
        <module>stream_consumer</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- springcloudgateway 的内部是通过 netty + webflux 实现。
            webflux 实现和 springmvc 存在冲突,需要注销掉父工程中的 web 依赖,在各子模块中导入 web 依赖。
          -->
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-web</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>http://repo.spring.io/libs-snapshot-local</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>http://repo.spring.io/libs-milestone-local</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>http://repo.spring.io/libs-release-local</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>http://repo.spring.io/libs-snapshot-local</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>http://repo.spring.io/libs-milestone-local</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
<!-- spring_cloud_demo\pom.xml -->

3、SpringCloudStream:入门案例–搭建环境–在父工程 spring_cloud_demo 下,创建子工程 stream_product (子模块)。

3.1 创建 stream_product 子工程(子模块)
	--> 右键 spring_cloud_demo 父工程
	--> Modules 
	--> Maven 
	--> Groupld : ( djh.it )
		Artifactld : ( stream_product )
		Version : 1.0-SNAPSHOT
	--> Next 
	--> Module name: ( stream_product )
		Content root : ( \spring_cloud_demo\stream_product )
		Module file location: ( \spring_cloud_demo\stream_product )
	--> Finish
	
3.2 在子工程 stream_product (子模块)中的 pom.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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>djh.it</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>stream_product</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
        </dependency>
    </dependencies>
</project>
<!-- spring_cloud_demo\stream_product\pom.xml -->

3.3 在子工程 stream_product (子模块)中,创建配置文件 application.yml
##  spring_cloud_demo\stream_product\src\main\resources\application.yml

server:
  port: 7001  #服务端口
spring:
  application:
    nmae: stream_product  #指定服务名
  rabbitmq:
    addresses: 127.0.0.1
    username: guest
    password: guest
  cloud:
    stream:
      bindings:
        output:  #管道交互
          destination: djh-default  #指定消息发送的目的地,在 rabbitmq 中,发送到一个 djh-default 的交换机 exchange。
      binders:  #配置绑定器
        defaultRabbit:
          type: rabbit


3.4 在子工程 stream_product (子模块)中,创建启动类 ProducerApplication.java
/**
 *   spring_cloud_demo\stream_product\src\main\java\djh\it\stream\ProducerApplication.java
 *
 *   2024-5-9 SpringCloudStream 入门案例:启动类 ProducerApplication.java
 *      1)引入依赖。
 *      2)配置 application.yml 配置文件。
 *      3)发送消息的话,定义一个通道接口,通过接口中内置的 messagechannel,(sprngcloudtream 中内置接口 Source)
 *      4)@EnableBinding 注解 :绑定对应通道。
 *      5)发送消息的话,通过 MessageChannel 发送消息,如果需要 MessageChannel --> 通过绑定内置接口获取。
 */

package djh.it.stream;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;

import javax.annotation.Resource;

@EnableBinding(Source.class)
@SpringBootApplication
public class ProducerApplication implements CommandLineRunner {

    @Autowired
    private MessageChannel output;

    @Override
    public void run(String... args) throws Exception {
        //发送消息,使用 工具类 MessageBuilder 创建消息。
        output.send(MessageBuilder.withPayload("hello SpringCloudStrem").build());
    }

    public static void main(String[] args) {
        SpringApplication.run(ProducerApplication.class);
    }
}

五、SpringCloudStream:入门案例–消息生产者的入门案例:下

1、进入 rabbitMQ 安装目录的 sbin 目录,启动 rabbitmq-server.bat 服务:

rabbitmq-server.bat

在这里插入图片描述

2、打开浏览器,地址栏输入 http://127.0.0.1:15672 ,进入消息中间件 rabbitmq 管理界面

默认用户名、密码都是:guest
发现已经创建出我们自定义的交换机名称 djh-default 。

在这里插入图片描述

六、SpringCloudStream:入门案例—消息消费者子工程(子模块):

1、SpringCloudStream:入门案例–在父工程 spring_cloud_demo 下,创建子工程 stream_consumer (子模块)。

1、创建 stream_consumer 子工程(子模块)

	--> 右键 spring_cloud_demo 父工程
	--> Modules 
	--> Maven 
	--> Groupld : ( djh.it )
		Artifactld : ( stream_consumer )
		Version : 1.0-SNAPSHOT
	--> Next 
	--> Module name: ( stream_consumer )
		Content root : ( \spring_cloud_demo\stream_consumer )
		Module file location: ( \spring_cloud_demo\stream_consumer )
	--> Finish
	

2、在子工程 stream_consumer (子模块)中的 pom.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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_demo</artifactId>
        <groupId>djh.it</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>stream_consumer</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
        </dependency>
    </dependencies>
</project>
<!-- spring_cloud_demo\stream_consumer\pom.xml -->

3、在子工程 stream_consumer (子模块)中,创建配置文件 application.yml

##  spring_cloud_demo\stream_consumer\src\main\resources\application.yml

server:
  port: 7002  #服务端口
spring:
  application:
    nmae: stream_consumer  #指定服务名
  rabbitmq:
    addresses: 127.0.0.1
    username: guest
    password: guest
  cloud:
    stream:
      bindings:
        input:  #管道交互,内置的获取消息的通道,从 djh-default 中获取消息。
          destination: djh-default  #指定消息发送的目的地,在 rabbitmq 中,发送到一个 djh-default 的交换机 exchange。
      binders:  #配置绑定器
        defaultRabbit:
          type: rabbit


4、在子工程 stream_consumer (子模块)中,创建启动类 ConsumerApplication.java

/**
 *    spring_cloud_demo\stream_consumer\src\main\java\djh\it\stream\ConsumerApplication.java
 *
 *   2024-5-9 SpringCloudStream 入门案例:启动类 ConsumerApplication.java
 *      1)引入依赖。
 *      2)配置 application.yml 配置文件。
 *      3)定义一个通道接口,通过内置获取消息的接口:Sink
 *      4)绑定对应通道。
 *      5)配置一个监听方法 :当程序从中间件获取数据之后,执行的业务逻辑方法,需要在监听方法上配置 @StreamListener 注解。
 */

package djh.it.stream;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;

@EnableBinding(Sink.class)
@SpringBootApplication
public class ConsumerApplication {

    @StreamListener(Sink.INPUT)
    public void input(String message) {
        System.out.println("获取到的消息: " + message);
    }

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class);
    }
}


5、运行 ProducerApplication 和 ConsumerApplication 两个启动类,在 idea Run Dashboard 控制面板,会输出 “获取到的消息: hello SpringCloudStrem”

七、SpringCloudStream:基于入门案例的代码优化

1、在子工程 stream_product (子模块)中,抽取一个消息发送的工具类 MessageSender.java

/**
 *  spring_cloud_demo\stream_product\src\main\java\djh\it\stream\producer\MessageSender.java
 *
 *  2024-5-10  抽取一个消息发送的工具类 MessageSender.java
 */

package djh.it.stream.producer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

@Component
@EnableBinding(Source.class)
public class MessageSender {
    @Autowired
    private MessageChannel output;

    //发送消息
    public void send(Object obj){
        output.send(MessageBuilder.withPayload((obj)).build());
    }
}

2、在子工程 stream_product (子模块)中,修改 启动类 ProducerApplication.java

/**
 *   spring_cloud_demo\stream_product\src\main\java\djh\it\stream\ProducerApplication.java
 *
 *   2024-5-9 SpringCloudStream 入门案例:启动类 ProducerApplication.java
 *      1)引入依赖。
 *      2)配置 application.yml 配置文件。
 *      3)发送消息的话,定义一个通道接口,通过接口中内置的 messagechannel,(sprngcloudtream 中内置接口 Source)
 *      4)@EnableBinding 注解 :绑定对应通道。
 *      5)发送消息的话,通过 MessageChannel 发送消息,如果需要 MessageChannel --> 通过绑定内置接口获取。
 */

package djh.it.stream;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

3、在子工程 stream_product (子模块)中,创建一个测试类 ProducterTest.java

/**
 *  spring_cloud_demo\stream_product\src\test\java\djh\it\stream\ProducterTest.java
 *
 *  2024-5-10 创建一个测试类 ProducterTest.java
 */

package djh.it.stream;

import djh.it.stream.producer.MessageSender;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class ProducterTest {
    @Autowired
    private MessageSender messageSender;

    @Test
    public void testSend(){
        messageSender.send("hello 测试 工具类");
    }
}

4、在子工程 stream_consumer (子模块)中,创建一个获取消息工具类 MessageListener.java.java

/**
 *   spring_cloud_demo\stream_consumer\src\main\java\djh\it\stream\consumer\MessageListener.java
 *
 *   2024-5-10 创建一个获取消息工具类 MessageListener.java.java
 */

package djh.it.stream.consumer;

import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.stereotype.Component;

@Component
@EnableBinding(Sink.class)
public class MessageListener {

    //监听 binding 中的消息
    @StreamListener(Sink.INPUT)
    public void input(String message) {
        System.out.println("获取到的消息: " + message);
    }
}

5、在子工程 stream_consumer (子模块)中,修改 启动类 ConsumerApplication.java

/**
 *    spring_cloud_demo\stream_consumer\src\main\java\djh\it\stream\ConsumerApplication.java
 *
 *   2024-5-9 SpringCloudStream 入门案例:启动类 ConsumerApplication.java
 *      1)引入依赖。
 *      2)配置 application.yml 配置文件。
 *      3)定义一个通道接口,通过内置获取消息的接口:Sink
 *      4)绑定对应通道。
 *      5)配置一个监听方法 :当程序从中间件获取数据之后,执行的业务逻辑方法,需要在监听方法上配置 @StreamListener 注解。
 */

package djh.it.stream;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

6、运行 测试类 ProducterTest 和 ConsumerApplication 启动类,在 idea Run Dashboard 控制面板,会输出 “获取到的消息: hello 测试 工具类”

在这里插入图片描述

上一节关联链接请点击:
# 从浅入深 学习 SpringCloud 微服务架构(十四)微服务链路追踪

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

经开区创维汽车车辆交接仪式顺利举行,守护绿色出行助力低碳发展

5月10日&#xff0c;“创维新能源汽车进机关”交车仪式于徐州顺利举行&#xff0c;20辆创维EV6 II正式交付经开区政府投入使用。经开区陈琳副书记、党政办公室副主任张驰主任、经开区公车管理平台苑忠民科长、创维汽车总裁、联合创始人吴龙八先生、创维汽车营销公司总经理饶总先…

【计算机毕业设计】基于SSM++jsp的蜀都天香酒楼网站【源码+lw+部署文档+讲解】

目录 摘要 Abstract 目 录 1绪论 1.1研究背景与意义 1.2国内外研究现状 1.3研究内容 1.4论文结构 2相关技术介绍 2.1 B/S模式 2.2 MyEclipse开发环境 2.3 MySQL数据库 2.4 Java语言 2.5 JSP技术 2.6 Tomcat服务器 3系统分析 3.1需求分析 3.2可行性分析 3.2.1经济可行性 3.2.2技…

【MySQL探索之旅】JDBC (Java连接MySQL数据库)

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更…

机器学习算法 - 逻辑回归

逻辑回归是一种广泛应用于统计学和机器学习领域的回归分析方法&#xff0c;主要用于处理二分类问题。它的目的是找到一个最佳拟合模型来预测一个事件的发生概率。以下是逻辑回归的一些核心要点&#xff1a; 基本概念 输出&#xff1a;逻辑回归模型的输出是一个介于0和1之间的…

容器化Jenkins远程发布java应用(方式二:自定义镜像仓库远程拉取构建)

1.创建maven项目 2.配置git、maven 3.阿里控制台>容器镜像服务>镜像仓库>创建镜像仓库 4.执行shell脚本&#xff08;推送镜像到阿里云镜像仓库&#xff09; 使用到登录阿里云仓库命令 #!/bin/bash # 服务名称 SERVER_NAMEplanetflix-app # 镜像tag IMAGE_TAG1.0.0-SN…

每日两题 / 24. 两两交换链表中的节点 25. K 个一组翻转链表(LeetCode热题100)

24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 定义三个指针&#xff0c;交换前先保存ntnt指针为next->next&#xff0c;cur和next两个节点&#xff0c;然后将pre->next指向next 若pre为空&#xff0c;说明当前交换的节点为头两个节点&#xff0c;…

网络相关笔记

IPv4地址 IPv4地址通常以“点分十进制”形式书写&#xff0c;即四个0-255之间的十进制数&#xff0c;各数之间用英文句点&#xff08;.&#xff09;分隔&#xff0c;例如&#xff1a;192.0.2.1。总共32位的地址空间可以表示大约42亿个不同的地址。 IPv4地址结构包括&#xff…

金石传拓非遗研学基地 入驻蔚蓝书店

好消息&#xff01;&#xff01;&#xff01; 金石传拓非遗研学基地&#xff0c;正式入驻蔚蓝书店啦&#xff01;&#xff01;&#xff01; “缣竹易销&#xff0c;金石难灭&#xff0c;托以高山&#xff0c;永留不绝。”“金”指的是三代青铜器上的铭文。 “石”指的是石刻、…

PCIE协议-2-事务层规范---事务描述符

2.2.6.1 概览 事务描述符是请求者和完成器之间传输事务信息的机制。事务描述符由三个字段组成&#xff1a; 事务ID&#xff1a;标识未完成的事务属性字段&#xff1a;定义事务的特征流量类别&#xff08;TC&#xff09;字段&#xff1a;将事务与所需的服务类型关联起来 图2-…

PG的事务ID回卷逻辑

PG到目前为止使用的事务ID仍然是32位的&#xff0c;在内存计算时虽然已经使用64位事务ID&#xff0c;但是存储在页中tuple仍然使用32位事务ID&#xff0c;这就是说&#xff0c;事务ID回卷仍然是必须处理的问题。 所谓PG事务ID回卷&#xff0c;简单地说&#xff0c;就是在数据库…

LIN协议栈代码解读,纯干货

LIN协议栈概述 当前用的比较多的LIN协议栈&#xff0c;如果不是VECTOR平台的&#xff0c;那就是NXP的LIN协议栈。NXP的协议栈又分为两套&#xff0c;一套是独立工具生成配置文件&#xff0c;即STACK_Package_4.5.9&#xff0c;通过NCFGui生成配置文件&#xff0c;主要用在MC9S…

python数据分析——数据预处理

数据预处理 前言一、查看数据数据表的基本信息查看info&#xff08;&#xff09;示例 查看数据表的大小shape&#xff08;&#xff09;示例 数据格式的查看type()dtype&#xff08;&#xff09;dtypes&#xff08;&#xff09;示例一示例二 查看具体的数据分布describe()示例 二…

【matlab基础知识代码】(十六)代数方程的图解法多项式型方程的准解析解方法

>> ezplot(exp(-3*t)*sin(4*t2)4*exp(-0.5*t)*cos(2*t)-0.5,[0 5]), line([0 5],[0 0]) 验证 >> t0.6738; >> exp(-3*t)*sin(4*t2)4*exp(-0.5*t)*cos(2*t)-0.5 ans -2.9852e-04 >> ezplot(x^2*exp(-x*y^2/2)exp(-x/2)*sin(x*y)) >> hold on; …

Java数组(如果想知道Java中有关数组的知识点,那么只看这一篇就足够了!)

前言&#xff1a;数组对于每一门编程语言来说都是重要的数据结构之一&#xff0c;当然不同语言对数组的实现及处理也不尽相同,Java 语言中提供的数组是用来存储固定大小的同类型元素。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSD…

MOSFET数据手册你会看了吗?

目录 一、功率损耗Power dissipation ​编辑二、结温Junction temperature 三、热阻Thermal resistance 四、寄生电容Cisis/Coss/Crss 五、开关时间 Time 一、功率损耗Power dissipation 功率损耗主要分为两类&#xff1a;静态损耗和动态损耗。静态损耗主要由器件的导通电…

wordpress忘记后台密码,在数据库中修改回来,然后再修改回去。

源地址&#xff1a;https://www.ctvol.com/seoomethods/1421332.html 我们在做wordpess运维的时候&#xff0c;都会遇到很尴尬的时候&#xff0c;有时候在错误运维中&#xff0c;不知道删除了什么东西&#xff0c;造成wordpress后台不能登录&#xff0c;后台页面也直接失效&am…

【Web后端】web后端开发简介_Servlet简介

1.web后端开发简介 Java企业级开发&#xff0c;也就是学习]avaEE(Enterprise Edition)版本,是一种结构和一套标准。在应用中开发的标准就是Servlet、jsp和JavaBean技术。jsp技术现在已基本处于淘汰状态&#xff0c;简单了解即可web后端开发&#xff0c;基于B/S模式的开发体系。…

日本站群服务器提升网站用户体验的选择

日本站群服务器提升网站用户体验的选择 在当今数字化时代&#xff0c;网站的性能和用户体验对于在线业务的成功至关重要。为了确保网站能够提供快速、可靠和高效的访问体验&#xff0c;越来越多的网站管理员和企业选择了使用站群服务器。本文将深入探讨日本站群服务器的独特优…

CogVLM 本地部署体验(问题解决)

硬件要求&#xff08;模型推理&#xff09;&#xff1a; INT4 &#xff1a; RTX30901&#xff0c;显存24GB&#xff0c;内存32GB&#xff0c;系统盘200GB INT4 &#xff1a; RTX40901或RTX3090*2&#xff0c;显存24GB&#xff0c;内存32GB&#xff0c;系统盘200GB 模型微调硬件…

在k8s中部署Prometheus并实现对k8s集群的监控

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Prometheus&#xff1a;监控的神》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、k8s简介 2、 Prometheus概述 二、准备k8s环境 1、…