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

从浅入深 学习 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.ymlserver:port: 7001  #服务端口
spring:application:nmae: stream_product  #指定服务名rabbitmq:addresses: 127.0.0.1username: guestpassword: guestcloud: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 {@Autowiredprivate MessageChannel output;@Overridepublic 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.ymlserver:port: 7002  #服务端口
spring:application:nmae: stream_consumer  #指定服务名rabbitmq:addresses: 127.0.0.1username: guestpassword: guestcloud: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 {@Autowiredprivate 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 {@Autowiredprivate MessageSender messageSender;@Testpublic 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.mzph.cn/diannao/9568.shtml

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

相关文章

【图像增强(空域)】基于直方图增强的图像增强及Matlab仿真

1. 摘要 图像的灰度直方图表示灰度图像中具有每种灰度像素的个数&#xff0c;反映了图像中每种灰度级出现的频率&#xff0c;是图像的基本统计特征之一。直方图均衡方法因为其有效性和简单性已成为图像对比度增强的最常用的方法。其基本思想是根据输入图像的灰度概率分布来确定…

【全开源】Java外卖霸王餐免费吃外卖小程序+APP+公众号+H5多端霸王餐源码

一、特色功能 霸王餐活动管理&#xff1a;允许商家发布和管理霸王餐活动&#xff0c;包括设置活动时间、具体优惠、活动规则等。用户参与与浏览&#xff1a;用户可以在小程序中浏览霸王餐活动列表&#xff0c;查看活动的详情信息&#xff0c;如商品或服务的免费赠送、活动规则…

原生微信小程序canvas签名功能

半个月前百度搜出来的&#xff0c;没存书签现在不知道是哪篇文章了&#xff0c;再搜也没搜出来那篇文章&#xff0c;还好当时把代码复制到本地跑了一下&#xff0c;现在再发csdn存一下。 sign.js Page({data: {ctx: null,width: null,height: null,drawCount: 0,drawState: &…

查找本机上的WIFI并查看密码。

在命令行模式下&#xff1a; 1。WIN 键 R&#xff0c;输入CMD&#xff0c;回车确认 2。在搜索框输入CMD&#xff0c;回车确认 以上的方法都可以打开命令行模式。也称终端&#xff0c;或者DOS模式。 查找本机上的WIFI密码&#xff0c;命令行如下&#xff1a; 首先&#xff…

汉诺塔问题和爬楼梯(递归)

感谢大佬的光临各位&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 个人主页&#xff1a;LaNzikinh-CSDN博客 c语言基础_LaNzikinh篮子的博客-CSDN博客 文章目录 一.爬楼梯问题二.汉诺塔问题总结 一.爬楼梯问题 假设你正…

Unity使用ToggleGroup对多个Toggle进行管理时,初始化默认选项失效的问题

问题描述&#xff1a; 在unity脚本的OnEnable中用代码设置Toggle集合中的其中一个对象的ison时&#xff0c;发现并没有根据设置发生变化。但是该Toggle的OnValueChange却发生过变化。 如果使用协程等待0.01s,那么对应组件的ison的修改才能生效&#xff0c;但是逐帧分析的话会发…

Elasticsearch:RBAC 和 RAG - 最好的朋友

作者&#xff1a;来自 Elastic Jeff Vestal 检索增强生成 (RAG) 通过提供额外的上下文或信息来增强大型语言模型 (LLM) 的知识&#xff0c;从而提高响应质量。 尽管 LLMs 拥有令人印象深刻的能力&#xff0c;但也有其局限性&#xff0c;例如无法在培训后保留新信息以及对不熟悉…

idea使用git不提示账号密码登录,而是输入token问题解决

idea 或者 webstream 等全家桶软件 使用git 推送代码时&#xff0c;不提示账号密码登录&#xff0c;而是输入token问题解决 你的代码仓库是gitlab 然后打开修改代码后推送时&#xff0c;会默认使用gitlab插件&#xff0c;所以提示数据token 解决方式就是把gitlab插件取消使用这…

ETL如何执行Java脚本

ETLCloud提供了执行 Java 脚本的方式&#xff0c;让用户能够灵活地处理数据并实现各种复杂的数据处理任务。 ETLCloud在数据处理领域的应用优势主要体现在以下几个方面&#xff1a; 灵活性&#xff1a;通过执行Java脚本&#xff0c;用户能够灵活定制数据处理逻辑&#xff0c;满…

监控异地组网怎么组网?

监控异地组网是指在不同地域的网络环境下&#xff0c;实现对监控设备的远程访问和管理。在传统的网络环境下&#xff0c;由于网络限制和设备配置等问题&#xff0c;监控设备的远程访问往往受到一定的限制和困扰。为了解决这个问题&#xff0c;引入了天联组网技术&#xff0c;实…

安卓开发--按键背景图片,按键其他属性,按键按键按下变色

前面已经介绍了一个空白按键工程的建立以及响应方式&#xff0c;可以参考这里&#xff1a;安卓开发–新建工程&#xff0c;新建虚拟手机&#xff0c;按键事件响应。 安卓开发是页面跳转是基础&#xff01;&#xff01;&#xff01;所以本篇博客介绍利用按键实现页面跳转&#…

添加对象方法

添加对象方法的方法如下&#xff0c;这是一个通用模式 注意灵活运用。

数据库调优-SQL语句优化

2. SQL语句优化 sql 复制代码 # 请问这两条SQL语句有什么区别呢&#xff1f;你来猜一猜那条SQL语句执行查询效果更好&#xff01; select id from sys_goods where goods_name华为 HUAWEI 麦芒7 魅海蓝 6G64G 全网通; ​ select id from sys_goods where goods_id14967325985…

Redis学习1——redis简介、基础

介绍 redis简介 Redis(Remote Dictonary Server) 是由Salvatore Sanfilippo开发的key-value缓存数据库&#xff0c;基于C语言开发。目前市面上&#xff0c;Redis和MongoDB是当前使用最广泛的NoSQL&#xff0c;而就Redis技术而言&#xff0c;它的性能十分优越&#xff0c;可以…

rngd: Error writing /dev/tpm0

检查数据库时发现messages中一直有rngd报错&#xff0c;rngd一直未配置&#xff0c;直接关闭了 /var/log/messages-20240414:Apr 11 04:59:49 hydb2 rngd: Error writing /dev/tpm0 /var/log/messages-20240414:Apr 12 07:31:39 hydb2 rngd: Error writing /dev/tpm0 /var/log…

shell-for循环语句练习题

1.计算从1到100所有整数的和 [rootlocalhost ~]# vim 1.sh #!/bin/bash sum0 #定义变量sum初始值为0 for i in {1..100} #for循环 i取值从1到100 do sum$[ isum ] #在每次循环中&#xff0c;变量i的值会依次取1到100的整数值。 #sum是一个累加器&#xff0c;初始值…

echarts自定义图例显示名称、数值、占比

先上代码 legend: {orient: vertical,left: 10,top:20,data: data,textStyle: {color: #9FB7D5 // 设置图例文字颜色为白色},// type: plain, // 设置图例类型为普通类型itemWidth: 10, // 设置图例项的宽度itemHeight: 10, // 设置图例项的高度formatter: function(name) {let…

Python专题:十、字典(2)

字典定义x{} get()函数 get&#xff08;参数一&#xff0c;参数二&#xff09; 参数一&#xff1a; 需要查找的关键词 参数二&#xff1a; 如果关键词不存在get返回的默认值 字典的更新 update&#xff08;&#xff09;函数&#xff0c;字典y的元素&#xff0c;去更新字…

学生管理系统初级

根据题目要求生成大纲 总结: 1.在书写时&#xff0c;考虑到了书写时id可是是abc... 类型是String&#xff0c;但在根据id获取集合中元素时 list.get() &#xff0c;get&#xff08;&#xff09;里面是int类型。 2.在书写还有一点功能并不完全&#xff0c; 2.1查找时是打印所有…

十.吊打面试官系列-Tomcat优化-通过压测Tomcat调优实战

前言 上一篇文章我们讲解了一下Tomcat底层的结构和执行原理&#xff0c;我们需要重点去掌握的是Tomcat的高内聚低耦合的设计&#xff0c;以及责任链模式&#xff0c;以及Tomcat NIO编程模式&#xff0c;这些是Tomcat比较核心的点&#xff0c;本篇文章我们将对Tomcat的参数做一…