【黑马头条】-day06自媒体文章上下架-Kafka


文章目录

  • 今日内容
  • 1 Kafka
    • 1.1 消息中间件对比
    • 1.2 kafka介绍
    • 1.3 kafka安装及配置
    • 1.4 kafka案例
      • 1.4.1 导入kafka客户端
      • 1.4.2 编写生产者消费者
      • 1.4.3 启动测试
      • 1.4.4 多消费者启动
    • 1.5 kafka分区机制
      • 1.5.1 topic剖析
    • 1.6 kafka高可用设计
    • 1.7 kafka生产者详解
      • 1.7.1 同步发送
      • 1.7.2 异步发送
      • 1.7.3 参数详解
        • 1.7.3.1 ack
        • 1.7.3.2 retries
        • 1.7.3.3 消息压缩
    • 1.8 kafka消费者详解
      • 1.8.1 消费者组
      • 1.8.2 消息有序性
      • 1.8.3 提交和偏移量
        • 1.8.3.1 同步提交
        • 1.8.3.2 异步提交
        • 1.8.3.3 同步异步混合提交
    • 1.9 Spring集成kafka
      • 1.9.1 导入依赖
      • 1.9.2 创建配置文件
      • 1.9.3 创建生产者
      • 1.9.4 创建消费者
      • 1.9.5 启动类
      • 1.9.6 测试
    • 1.10 kafka传递对象
      • 1.10.1 创建User
      • 1.10.2 添加User的发送和接收
  • 2 自媒体文章上下架
    • 2.1 接口定义
    • 2.2 Controller
    • 2.3 Service
    • 2.4 通知Article修改文章配置
      • 2.4.1 导入kafka依赖
      • 2.4.2 在Nacos中配置kafka的生产者
      • 2.4.3 自媒体通知Article
      • 2.4.4 在Nacos中配置kafka的消费者
      • 2.4.5 配置ap_article_config表
      • 2.4.6 article端监听
      • 2.4.7 测试


今日内容

在这里插入图片描述

1 Kafka

1.1 消息中间件对比

在这里插入图片描述

在这里插入图片描述

1.2 kafka介绍

在这里插入图片描述

在这里插入图片描述

1.3 kafka安装及配置

在这里插入图片描述

  • Docker安装zookeeper

拉取镜像

docker pull zookeeper:3.4.14

创建容器

docker run -d --name zookeeper -p 2181:2181 zookeeper:3.4.14
  • Docker安装kafka

下载镜像

docker pull wurstmeister/kafka:2.12-2.3.1

创建容器

docker run -d --name kafka \
--env KAFKA_ADVERTISED_HOST_NAME=192.168.204.129 \
--env KAFKA_ZOOKEEPER_CONNECT=192.168.204.129:2181 \
--env KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://192.168.204.129:9092 \
--env KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 \
--env KAFKA_HEAP_OPTS="-Xmx256M -Xms256M" \
--net=host wurstmeister/kafka:2.12-2.3.1

在这里插入图片描述

docker run -d --name kafka \
--env KAFKA_ADVERTISED_HOST_NAME=192.168.204.129 \
--env KAFKA_ZOOKEEPER_CONNECT=192.168.204.129:2181 \
--env KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://192.168.204.129:9092 \
--env KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 \
--env KAFKA_HEAP_OPTS="-Xmx256M -Xms256M" \
-p 9092:9092 wurstmeister/kafka:2.12-2.3.1

-p 9092:9092做端口映射

1.4 kafka案例

在这里插入图片描述

1.4.1 导入kafka客户端

在heima-leadnews-test模块中创建kafka-demo的模块

<dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId>
</dependency>

1.4.2 编写生产者消费者

创建com.heima.kafka.sample包

下面两个类ConsumerQuickStart和ProducerQuickStart类

生产者:

package com.heima.kafka.sample;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;import java.util.Properties;/*** 生产者*/
public class ProducerQuickStart {public static void main(String[] args) {//1.kafka的配置信息Properties properties = new Properties();//kafka的连接地址properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"192.168.204.129:9092");//发送失败,失败的重试次数properties.put(ProducerConfig.RETRIES_CONFIG,5);//消息key的序列化器properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");//消息value的序列化器properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");//2.生产者对象KafkaProducer<String,String> producer = new KafkaProducer<String, String>(properties);/*** 第一个参数:topic 第二个参数:key 第三个参数:value*///封装发送的消息ProducerRecord<String,String> record = new ProducerRecord<String, String>("topic-first","key-001","hello kafka");//3.发送消息producer.send(record);//4.关闭消息通道,必须关闭,否则消息发送不成功producer.close();}}

消费者:

public class ConsumerQuickStart {public static void main(String[] args) {//1.添加kafka的配置信息Properties properties = new Properties();//kafka的连接地址properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.204.129:9092");//消费者组properties.put(ConsumerConfig.GROUP_ID_CONFIG, "group1");//消息的反序列化器properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");//2.消费者对象KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(properties);//3.订阅主题consumer.subscribe(Collections.singletonList("topic-first"));//当前线程一直处于监听状态while (true) {//4.获取消息ConsumerRecords<String, String> consumerRecords = consumer.poll(Duration.ofMillis(1000));for (ConsumerRecord<String, String> consumerRecord : consumerRecords) {System.out.println(consumerRecord.key());System.out.println(consumerRecord.value());}}}}

1.4.3 启动测试

消费者成功收到消息

在这里插入图片描述

1.4.4 多消费者启动

同一个组下只能有一个消费者的收到消息

在这里插入图片描述

如果想一对多,则需要将消费者放在不同组中

在这里插入图片描述

1.5 kafka分区机制

在这里插入图片描述

1.5.1 topic剖析

在这里插入图片描述

在这里插入图片描述

ProducerRecord<String,String> record = new ProducerRecord<String, String>("topic-first","key-001",0,"hello kafka");

在发送消息时可以指定分区partition

1.6 kafka高可用设计

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.7 kafka生产者详解

1.7.1 同步发送

在这里插入图片描述

/*** 第一个参数:topic 第二个参数:key 第三个参数:value*/
//封装发送的消息
ProducerRecord<String,String> record = new ProducerRecord<String, String>("topic-first","key-001","hello kafka");//3.发送消息
//producer.send(record);//3.1 同步发送消息
RecordMetadata recordMetadata = producer.send(record).get();
System.out.println("同步发送消息结果:topic="+recordMetadata.topic()+",partition="+recordMetadata.partition()+",offset="+recordMetadata.offset());

发送结果:

同步发送消息结果:topic=topic-first,partition=0,offset=1

1.7.2 异步发送

在这里插入图片描述

//3.2 异步发送消息
producer.send(record, new Callback() {@Overridepublic void onCompletion(RecordMetadata recordMetadata, Exception e) {if(e!=null){e.printStackTrace();}else{System.out.println("异步发送消息结果:topic="+recordMetadata.topic()+",partition="+recordMetadata.partition()+",offset="+recordMetadata.offset());}}
});

发送结果:

异步发送消息结果:topic=topic-first,partition=0,offset=2

1.7.3 参数详解

1.7.3.1 ack

在这里插入图片描述

1.7.3.2 retries

在这里插入图片描述

1.7.3.3 消息压缩

在这里插入图片描述

1.8 kafka消费者详解

1.8.1 消费者组

在这里插入图片描述

1.8.2 消息有序性

在这里插入图片描述

在这里插入图片描述

1.8.3 提交和偏移量

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

手动提交

//手动提交偏移量
properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false");
1.8.3.1 同步提交

把enable.auto.commit设置为false,让应用程序决定何时提交偏移量。使用commitSync()提交偏移量,commitSync()将会提交poll返回的最新的偏移量,所以在处理完所有记录后要确保调用了commitSync()方法。否则还是会有消息丢失的风险。

只要没有发生不可恢复的错误,commitSync()方法会一直尝试直至提交成功,如果提交失败也可以记录到错误日志里。

在这里插入图片描述

while (true){ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));for (ConsumerRecord<String, String> record : records) {System.out.println(record.value());System.out.println(record.key());try {consumer.commitSync();//同步提交当前最新的偏移量}catch (CommitFailedException e){System.out.println("记录提交失败的异常:"+e);}}
}
1.8.3.2 异步提交

手动提交有一个缺点,那就是当发起提交调用时应用会阻塞。当然我们可以减少手动提交的频率,但这个会增加消息重复的概率(和自动提交一样)。另外一个解决办法是,使用异步提交的API :commitAsync()

在这里插入图片描述

 while (true){ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));for (ConsumerRecord<String, String> record : records) {System.out.println(record.value());System.out.println(record.key());}consumer.commitAsync(new OffsetCommitCallback() {@Overridepublic void onComplete(Map<TopicPartition, OffsetAndMetadata> map, Exception e) {if(e!=null){System.out.println("记录错误的提交偏移量:"+ map+",异常信息"+e);}}});
}
1.8.3.3 同步异步混合提交

异步提交也有个缺点,那就是如果服务器返回提交失败,异步提交不会进行重试

相比较起来,同步提交会进行重试直到成功或者最后抛出异常给应用。异步提交没有实现重试是因为,如果同时存在多个异步提交,进行重试可能会导致位移覆盖

举个例子,假如我们发起了一个异步提交commitA,此时的提交位移为2000,随后又发起了一个异步提交commitB且位移为3000;commitA提交失败但commitB提交成功,此时commitA进行重试并成功的话,会将实际上将已经提交的位移从3000回滚到2000,导致消息重复消费。

在这里插入图片描述

 try {while (true){ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));for (ConsumerRecord<String, String> record : records) {System.out.println(record.value());System.out.println(record.key());}consumer.commitAsync();}
}catch (Exception e){+e.printStackTrace();System.out.println("记录错误信息:"+e);
}finally {try {consumer.commitSync();}finally {consumer.close();}
}

1.9 Spring集成kafka

1.9.1 导入依赖

在kafka-demo中导入依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- kafkfa --><dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId><exclusions><exclusion><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency>
</dependencies>

1.9.2 创建配置文件

在resources下创建文件application.yml

server:port: 9991
spring:application:name: kafka-demokafka:bootstrap-servers: 192.168.204.129:9092producer:retries: 10key-serializer: org.apache.kafka.common.serialization.StringSerializervalue-serializer: org.apache.kafka.common.serialization.StringSerializerconsumer:group-id: ${spring.application.name}-testkey-deserializer: org.apache.kafka.common.serialization.StringDeserializervalue-deserializer: org.apache.kafka.common.serialization.StringDeserializer

1.9.3 创建生产者

创建com.heima.kafka.controller.HelloController类,负责发送消息

@RestController
public class HelloController {@Autowiredprivate KafkaTemplate<String, String> kafkaTemplate;@GetMapping("/hello")public String hello() {kafkaTemplate.send("itcast-topic", "hello kafka");return "success";}
}

1.9.4 创建消费者

建com.heima.kafka.listener.HelloListener类,负责监听消息

@Component
public class HelloListener {@KafkaListener(topics = "itcast-topic")public void listen(String message) {if(!StringUtils.isEmpty(message)) {System.out.println("message = " + message);}}
}

1.9.5 启动类

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

1.9.6 测试

打开localhost:9991/hello

在这里插入图片描述

已经接收到消息

1.10 kafka传递对象

在这里插入图片描述

1.10.1 创建User

创建com.heima.kafka.pojo.User

@Data
public class User {private String username;private Integer age;
}

1.10.2 添加User的发送和接收

使用fastjson进行转换

Controller:

@GetMapping("/user")
public String user() {User user = new User();user.setUsername("zhangsan");user.setAge(20);kafkaTemplate.send("user-topic", JSON.toJSONString(user));return "success";
}

Listener:

@KafkaListener(topics = "user-topic")
public void listenUser(String message) {if(!StringUtils.isEmpty(message)) {User user = JSON.parseObject(message, User.class);System.out.println(user);}
}

在这里插入图片描述

2 自媒体文章上下架

在这里插入图片描述

2.1 接口定义

在这里插入图片描述

2.2 Controller

@PostMapping("/down_or_up")
public ResponseResult downOrUp(@RequestBody WmNewsDto wmNewsDto){return wmNewsService.downOrUp(wmNewsDto);
}

2.3 Service

接口

ResponseResult downOrUp(WmNewsDto wmNewsDto);

实现

@Override
public ResponseResult downOrUp(WmNewsDto wmNewsDto) {// 1.参数检查if(wmNewsDto.getId()==null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"文章id不能为空");}// 2.查询文章WmNews wmNews = getById(wmNewsDto.getId());if(wmNews == null){return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章不存在");}// 3.修改文章状态if(!wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode())){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"只有已发布的文章才能上下架");}if(wmNewsDto.getEnable()==null){return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"enable不能为空");}wmNews.setEnable(wmNewsDto.getEnable());updateById(wmNews);// 4.返回结果return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}

2.4 通知Article修改文章配置

2.4.1 导入kafka依赖

在heima-leadnews-common模块下导入kafka依赖

<!-- kafkfa -->
<dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId>
</dependency>
<dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId>
</dependency>

2.4.2 在Nacos中配置kafka的生产者

在自媒体端的nacos配置中心配置kafka的生产者,在heima-leadnews-wemedia下的配置文件中配置kafka

spring:kafka:bootstrap-servers: 192.168.204.129:9092producer:retries: 10key-serializer: org.apache.kafka.common.serialization.StringSerializervalue-serializer: org.apache.kafka.common.serialization.StringSerializer

在这里插入图片描述

2.4.3 自媒体通知Article

创建com.heima.common.constants.mNewsMessageConstants常量类,保存kafka的topic.

public class WmNewsMessageConstants {public static final String WM_NEWS_UP_OR_DOWN_TOPIC="wm.news.up.or.down.topic";
}

注入kafka

@Autowired
private KafkaTemplate<String,String> kafkaTemplate;

发送消息,通知article端修改文章配置

//发送消息,通知article端修改文章配置
if(wmNews.getArticleId() != null){Map<String,Object> map = new HashMap<>();map.put("articleId",wmNews.getArticleId());map.put("enable",dto.getEnable());kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC,JSON.toJSONString(map));
}

2.4.4 在Nacos中配置kafka的消费者

在article端的nacos配置中心配置kafka的消费者

spring:kafka:bootstrap-servers: 192.168.204.129:9092consumer:group-id: ${spring.application.name}key-deserializer: org.apache.kafka.common.serialization.StringDeserializervalue-deserializer: org.apache.kafka.common.serialization.StringDeserializer

在这里插入图片描述

2.4.5 配置ap_article_config表

因为需要修改ap_article_config,所以需要创建对应service和mapper

在这里插入图片描述

创捷Service,com.heima.article.service.ApArticleConfigService接口

public interface ApArticleConfigService extends IService<ApArticleConfig> {/*** 修改文章配置* @param map*/public void updateByMap(Map map);
}

实现

@Service
@Slf4j
@Transactional
public class ApArticleConfigServiceImpl extends ServiceImpl<ApArticleConfigMapper, ApArticleConfig> implements ApArticleConfigService {/*** 修改文章配置* @param map*/@Overridepublic void updateByMap(Map map) {//0 下架 1 上架Object enable = map.get("enable");boolean isDown = true;if(enable.equals(1)){isDown = false;}//修改文章配置update(Wrappers.<ApArticleConfig>lambdaUpdate().eq(ApArticleConfig::getArticleId,map.get("articleId")).set(ApArticleConfig::getIsDown,isDown));}
}

2.4.6 article端监听

在article端编写监听,接收数据

@Component
@Slf4j
public class ArtilceIsDownListener {@Autowiredprivate ApArticleConfigService apArticleConfigService;@KafkaListener(topics = WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC)public void onMessage(String message){if(StringUtils.isNotBlank(message)){Map map = JSON.parseObject(message, Map.class);apArticleConfigService.updateByMap(map);log.info("article端文章配置修改,articleId={}",map.get("articleId"));}}
}

2.4.7 测试

启动相应启动类

在这里插入图片描述

打开自媒体管理界面,准备下架这个新闻

在这里插入图片描述

下架该文件,发现两张表都已经修改,完美进行下架

在这里插入图片描述

说明我们kafka的消息传递已经成功。

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

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

相关文章

配置vlan和vlan间路由、配置vlan的ip和vrrp、mstp和主次根

简单的通信实验 拓扑图&#xff1a; 1.配置vlan和链路聚合 Sw1 & sw2 undo info-center enable vlan batch 10 20 30 40 int eth-trunk 1 trunkport g 0/0/1 to 0/0/2 port link-type trunk port trunk allow-pass vlan 10 20 30 40 int g0/0/3 port link-type trunk p…

Unity 布局 HorizontalLayoutGroup 多行 换行

演示Gif&#xff1a; 现象: 子元素宽度不同&#xff0c;超出父元素后不会换行 GridLayout则是固定宽度也不能用&#xff0c; 需求 水平排版的同时&#xff0c;超出父级后换行 代码&#xff1a; 催更就展示[狗头]

Linux:Redis7.2.4的简单在线部署(1)

注意&#xff1a;我写的这个文章是以最快速的办法去搭建一个redis的基础环境&#xff0c;作用是为了做实验简单的练习&#xff0c;如果你想搭建一个相对稳定的redis去使用&#xff0c;可以看我下面这个文章 Linux&#xff1a;Redis7.2.4的源码包部署&#xff08;2&#xff09;-…

CSS 基础:设置背景的 5 个属性及简写 background 注意点

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。大专生&#xff0c;一枚程序媛&#xff0c;感谢关注。回复 “前端基础题”&#xff0c;可免费获得前端基础 100 题汇总&#xff0c;回复 “前端工具”&#xff0c;可获取 Web 开发工具合集 263篇…

给你的Qt软件加个授权

写在前面 环境&#xff1a; Win11 64位 VS2019 Qt5.15.2 核心思路&#xff1a; 将授权相关信息加密保存到License.txt中&#xff0c;软件运行时获取并解密授权信息&#xff0c;判断是否在限制期限内即可。 加解密部分使用第三方openssl库进行&#xff0c;因此需要手动在…

家庭网络防御系统搭建-虚拟机安装siem/securityonion网络连接问题汇总

由于我是在虚拟机中安装的security onion&#xff0c;在此过程中&#xff0c;遇到很多的网络访问不通的问题&#xff0c;通过该文章把网络连接问题做一下梳理。如果直接把securityonion 安装在物理机上&#xff0c;网络问题则会少很多。 NAT无法访问虚拟机 security onion虚拟…

多目标跟踪 | 基于anchor-free目标检测+ReID的实时一阶多类多目标跟踪算法实现

项目应用场景 面向多目标检测跟踪场景&#xff0c;项目采用 anchor-free 目标检测ReID 的实时一阶段多类多目标跟踪算法实现&#xff0c;效果嘎嘎好。 项目效果 项目细节 > 具体参见项目 README.md (1) 类别支持 1~10 object classes are what we need non-interest-…

SpringCloud学习(9)-GateWay网关-自定义拦截器

GateWay Filter详细配置说明 gateway Filter官网:Spring Cloud Gateway 作用&#xff1a; 请求鉴权异常处理记录接口调用时长统计 过滤器类别 全局默认过滤器&#xff1a;官网&#xff1a;Spring Cloud Gateway&#xff0c;出厂默认已有的&#xff0c;直接用&#xff0c;作…

Qt栅格布局的示例

QGridLayout * layoutnew QGridLayout;for(int i0;i<10;i){for(int j0;j<6;j){QLabel *labelnew QLabel(this);label->setText(QString("%1行%2列").arg(i).arg(j));layout->addWidget(label,i,j);}}ui->widget->setLayout(layout); 这样写程序会崩…

【vue】v-bind动态属性绑定

v-bind 简写:value <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><styl…

NC65 查询默认密码(sql)

NC65 使用sql查询设置的默认密码&#xff08;如果系统设置有&#xff09;&#xff1a; select * from sm_user_defaultpwd

深入理解图形处理器(GPU):加速人工智能和大数据计算的引擎

文章目录 1. 什么是GPU&#xff1f;2. GPU的工作原理3. GPU的应用领域4. GPU与CPU的比较参考与推荐 前言&#xff1a; 图形处理器&#xff08;GPU&#xff09;不再仅仅是用于图形渲染的硬件设备。如今&#xff0c;GPU已经成为加速人工智能、大数据计算和科学研究的关键引擎。本…

提高大型语言模型 (LLM) 性能的四种数据清理技术

原文地址&#xff1a;four-data-cleaning-techniques-to-improve-large-language-model-llm-performance 2024 年 4 月 2 日 检索增强生成&#xff08;RAG&#xff09;过程因其增强对大语言模型&#xff08;LLM&#xff09;的理解、为它们提供上下文并帮助防止幻觉的潜力而受…

故障诊断 | 基于LSTM的滚动轴承故障诊断

效果 概述 基于LSTM(长短期记忆网络)的滚动轴承故障诊断是一种利用深度学习技术来预测滚动轴承是否存在故障的方法。下面是一个基本的滚动轴承故障诊断的流程: 数据收集:首先,需要收集与滚动轴承相关的振动信号数据。这些数据可以通过传感器或振动监测系统获取。收集的数…

关于HTTP1.0、1.1、1.x、2.0、3.0与HTTPS之间的理解

关于HTTP1.0、1.1、1.x、2.0、3.0与HTTPS之间的理解 HTTP的由来 HTTP是Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;的缩写。它的发展是万维网协会&#xff08;World Wide Web Consortium&#xff09;和Internet工作小组IETF&#xff08;Internet Eng…

蓝桥杯备赛刷题——css

新鲜的蔬菜 这题需要使用grid 我不会 去学一下 一.什么是grid Grid 布局与 Flex 布局有一定的相似性&#xff0c;都可以指定容器内部多个项目的位置。但是&#xff0c;它们也存在重大区别。 Flex 布局是轴线布局&#xff0c;只能指定"项目"针对轴线的位置&#…

前端三剑客 —— JavaScript (第二节)

目录 内容回顾 数据类型 基本数据类型&#xff1a; 引用数据类型&#xff1a; 常见运算 算术运算符 比较运算符 逻辑运算符 赋值运算符 自增/减运算符 三目运算符 位运算符 内容回顾 1.概述 2.基本数据 1.使用方式&#xff08;行内、页面、外部&#xff09; 2.对话框…

《手把手教你》系列基础篇(八十四)-java+ selenium自动化测试-框架设计基础-TestNG日志-上篇(详解教程)

宏哥微信粉丝群&#xff1a;https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 1.简介 TestNG还为我们提供了测试的记录功能-日志。例如&#xff0c;在运行测试用例期间&#xff0c;用户希望在控制台中记录一些信息。信息可以是任何细节取决于目的。牢记我们正在使…

Failed to delete XXXX.jar

Failed to delete XXXX.jar 问题&#xff1a;idea控制台报Failed to clean project:Failed to delete idea中点击maven->对应pom->lifecycle->clean时&#xff0c;报错 原因&#xff1a;target文件可能时编译的文件被其他程序占用&#xff0c;导致资源无法回收 解…

thinkphp6中使用监听事件和事件订阅

目录 一&#xff1a;场景介绍 二&#xff1a;事件监听 三&#xff1a;配置订阅 一&#xff1a;场景介绍 在项目开发中有很多这样的场景&#xff0c;比如用户注册完了&#xff0c;需要通知到第三方或者发送消息。用户下单了&#xff0c;需要提示给客服等等。这些场景都有一个…