当前位置: 首页 > news >正文

【RocketMQ】快速入门

文章目录

  • 消费模式
  • 同步消息
  • 异步消息
  • 单向消息
  • 延迟消息
  • 批量消息
  • 顺序消息
  • 事务消息
  • Tag标签和Key键
    • Tag的使用
    • Key的使用

首先引入rocketmq的依赖

<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>4.9.2</version>
</dependency>

然后我们编写一个简单的生产者和消费者

@SpringBootTest
public class RocketMQTest {/*** 对于生产者 同一组的生产者可以向不同的topic队列发送消息*/@Testpublic void produce() throws MQClientException, MQBrokerException, RemotingException, InterruptedException {DefaultMQProducer producer = new DefaultMQProducer("test-producer-group");producer.setNamesrvAddr(MQConstant.NAMESRV);producer.start();Message message = new Message("testTopic","一个简单的消息".getBytes());SendResult sendResult = producer.send(message);System.out.println(sendResult.getSendStatus());producer.shutdown();}/*** 对于消费者 同一组的消费者只能接收同一个topic的消息* 并且如果存在多个消费者组,他们都监听同一个topic的消息* 那么就可以选择使用  负载均衡策略 或者 广播策略*/@Testpublic void consume() throws MQClientException, IOException {//创建一个消费者DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("test-producer-group");consumer.setNamesrvAddr(MQConstant.NAMESRV);// * 标识订阅这个主题中的所有消息  后期会有消息过滤consumer.subscribe("testTopic", "*");//设置一个监听器 (他会一直监听,然后是一个异步回调的机制)//那么我们就不能让他start之后这个方法就返回结束 需要挂起当前的JVM(test模式得这样子)//正常运行项目的时候项目的JVM会正常运行的 不需要挂起consumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext context) {//这个就是对应的消费方法  业务处理//消息如果消费失败 那么就要重新放入到消费队列System.out.println("我是消费者");System.out.println(list.get(0).toString());System.out.println("消息上下文"+context);//返回值如果为null/报错/RECONSUMER_LATER 代表消费失败//消息会重新回到队列 然后过一会在投递给当前消费者或者其他消费者return ConsumeConcurrentlyStatus.RECONSUME_LATER;}});//启动consumer.start();//挂起当前的JVMSystem.in.read();}
}

这里需要注意的是,对于Rocketmq,如果在你的监听器中,也就是这个MessageListenerConcurrently中,你的返回值为null,或者ConsumeConcurrentlyStatus.RECONSUME_LATER,亦或者抛出了一个异常,那么这条消息都会重新的被放回到我们的队列中,等待其他消费者或者当前消费者再一次消费。

消费模式

MQ的消费模式可以大致分为两种,一种是推Push,一种是拉Pull。
Push是服务端【MQ】主动推送消息给客户端,优点是及时性较好,但如果客户端没有做好流控,一旦服务端推送大量消息到客户端时,就会导致客户端消息堆积甚至崩溃。
Pull是客户端需要主动到服务端取数据,优点是客户端可以依据自己的消费能力进行消费,但拉取的频率也需要用户自己控制,拉取频繁容易造成服务端和客户端的压力,拉取间隔长又容易造成消费不及时。
Push模式也是基于pull模式的,只能客户端内部封装了api,一般场景下,上游消息生产量小或者均速的时候,选择push模式。在特殊场景下,例如电商大促,抢优惠券等场景可以选择pull模式

同步消息

上面的快速入门就是发送同步消息,发送过后会有一个返回值,也就是mq服务器接收到消息后返回的一个确认,这种方式非常安全,但是性能上并没有这么高,而且在mq集群中,也是要等到所有的从机都复制了消息以后才会返回,所以针对重要的消息可以选择这种方式

异步消息

异步消息通常用在对响应时间敏感的业务场景,即发送端不能容忍长时间地等待Broker的响应。发送完以后会有一个异步消息通知。

@Test
public void testAsyncProducer() throws Exception {// 创建默认的生产者DefaultMQProducer producer = new DefaultMQProducer("test-producer-group");// 设置nameServer地址producer.setNamesrvAddr(MQConstant.NAMESRV);// 启动实例producer.start();Message msg = new Message("testTopic", ("异步消息").getBytes());producer.send(msg, new SendCallback() {@Overridepublic void onSuccess(SendResult sendResult) {System.out.println("发送成功");}@Overridepublic void onException(Throwable e) {System.out.println("发送失败");}});System.out.println("看看谁先执行");// 挂起jvm 因为回调是异步的不然测试不出来System.in.read();// 关闭实例producer.shutdown();
}

单向消息

这种方式主要用在不关心发送结果的场景,这种方式吞吐量很大,但是存在消息丢失的风险,例如日志信息的发送。

@Test
public void testOnewayProducer() throws Exception {// 创建默认的生产者DefaultMQProducer producer = new DefaultMQProducer("test-producer-group");// 设置nameServer地址producer.setNamesrvAddr(MQConstant.NAMESRV);// 启动实例producer.start();Message msg = new Message("testTopic", ("单向消息").getBytes());// 发送单向消息producer.sendOneway(msg);// 关闭实例producer.shutdown();
}

延迟消息

消息放入mq后,过一段时间,才会被监听到,然后消费
比如下订单业务,提交了一个订单就可以发送一个延时消息,30min后去检查这个订单的状态,如果还是未付款就取消订单释放库存。
这里注意的是RocketMQ不支持任意时间的延时
只支持以下几个固定的延时等级,等级1就对应1s,以此类推,最高支持2h延迟
private String messageDelayLevel = “1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h”;

@Test
public void testDelayProducer() throws Exception {// 创建默认的生产者DefaultMQProducer producer = new DefaultMQProducer("test-group");// 设置nameServer地址producer.setNamesrvAddr("localhost:9876");// 启动实例producer.start();Message msg = new Message("TopicTest", ("延迟消息").getBytes());// 给这个消息设定一个延迟等级// messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2hmsg.setDelayTimeLevel(3);// 发送单向消息producer.send(msg);// 打印时间System.out.println(new Date());// 关闭实例producer.shutdown();
}

批量消息

批量消息就是一次性发送一个消息集合出去。

@Test
public void testBatchProducer() throws Exception {// 创建默认的生产者DefaultMQProducer producer = new DefaultMQProducer("test-producer-group");// 设置nameServer地址producer.setNamesrvAddr(MQConstant.NAMESRV);// 启动实例producer.start();List<Message> messages = Arrays.asList(new Message("testTopic", "批量消息1".getBytes()),new Message("testTopic", "批量消息2".getBytes()),new Message("testTopic", "批量消息3".getBytes()));producer.send(messages);System.out.println("批量执行任务");// 挂起jvm 因为回调是异步的不然测试不出来System.in.read();// 关闭实例producer.shutdown();
}

顺序消息

我们知道一个topic中可以有多个队列,那么如果我们的消息发送到多个队列中去,那么很明显我们的消息消费就是并行消费的,也就是没有了顺序性。
因此如果我们需要发送顺序消息,也就是希望MQ那边的消费者顺序的消费一些消息,我们就得按照如下方式发送顺序消息。
消息有序指的是可以按照消息的发送顺序来消费(FIFO)。RocketMQ可以严格的保证消息有序,可以分为:分区有序或者全局有序。
可能大家会有疑问,mq不就是FIFO吗?
rocketMq的broker的机制,导致了rocketMq会有这个问题
因为一个broker中对应了四个queue。

不同的queue(分区队列);而消费消息的时候从多个queue上拉取消息,这种情况发送和消费是不能保证顺序。但是如果控制发送的顺序消息只依次发送到同一个queue中,消费的时候只从这个queue上依次拉取,则就保证了顺序。当发送和消费参与的queue只有一个,则是全局有序;如果多个queue参与,则为分区有序,即相对每个queue,消息都是有序的。
下面用订单进行分区有序的示例。一个订单的顺序流程是:下订单、发短信通知、物流、签收。订单顺序号相同的消息会被先后发送到同一个队列中,消费时,同一个顺序获取到的肯定是同一个队列。

package zhang.blossom.seckillbyrocketmq;import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.*;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.message.MessageQueue;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import zhang.blossom.seckillbyrocketmq.constant.MQConstant;
import zhang.blossom.seckillbyrocketmq.entity.MsgModel;import java.io.IOException;
import java.util.Arrays;
import java.util.List;/*** @author: 张锦标* @date: 2023/8/17 9:58* OrderedRocketMQTest类*/@SpringBootTest
public class OrderedRocketMQTest {private List<MsgModel> msgModels = Arrays.asList(new MsgModel("qwer", 1L, "下单"),new MsgModel("qwer", 1L, "短信"),new MsgModel("qwer", 1L, "物流"),new MsgModel("zxcv", 2L, "下单"),new MsgModel("zxcv", 2L, "短信"),new MsgModel("zxcv", 2L, "物流"));//发送顺序消息@Testpublic void orderedProducer() throws MQClientException, MQBrokerException, RemotingException, InterruptedException {DefaultMQProducer producer = new DefaultMQProducer("test-producer-group");producer.setNamesrvAddr(MQConstant.NAMESRV);producer.start();//发送顺序消息 发送时要确保有序  并且要发送到同一个队列下面去msgModels.forEach(msgModel -> {Message message = new Message("testTopic",msgModel.toString().getBytes());try {//发送  相同的订单号应该去相同的队列producer.send(message, new MessageQueueSelector() {//这里的send方法的第三个参数arg 就是这个队列选择器的第三个参数 会传递过来@Overridepublic MessageQueue select(List<MessageQueue> list, Message message, Object arg) {//这个方法的返回值就是要选择的队列//这里可以用hash的方式就可以选择到同样的队列了int hash = arg.toString().hashCode();int index = hash % list.size();return list.get(index);}}, msgModel.getOrderSn());} catch (MQClientException e) {throw new RuntimeException(e);} catch (RemotingException e) {throw new RuntimeException(e);} catch (MQBrokerException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);}});producer.shutdown();System.out.println("发送完毕");}@Testpublic void orderedConsumer() throws MQClientException, IOException {DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("test-producer-group");consumer.setNamesrvAddr(MQConstant.NAMESRV);consumer.subscribe("testTopic", "*");//MessageListenerConcurrently 并发模式  多线程的  失败后最多重试16次 然后放入死信队列//MessageListenerOrderly 顺序模式 单线程的  失败后无限次重试 Integer.MAX_VALUEconsumer.registerMessageListener(new MessageListenerOrderly() {//顺序模式只有一个线程来执行消费@Overridepublic ConsumeOrderlyStatus consumeMessage(List<MessageExt> list,ConsumeOrderlyContext consumeOrderlyContext) {//这里的一个线程是一个队列一个线程System.out.println(new String(list.get(0).getBody()));return ConsumeOrderlyStatus.SUCCESS;}});consumer.start();System.in.read();}
}

事务消息

一般我们不使用RocketMQ的事务消息,所以有兴趣的可以看看其他的实现。

Tag标签和Key键

Rocketmq提供消息过滤功能,通过tag或者key进行区分。
我们往一个主题里面发送消息的时候,根据业务逻辑,可能需要区分,比如带有tagA标签的被A消费,带有tagB标签的被B消费,还有在事务监听的类里面,只要是事务消息都要走同一个监听,我们也需要通过过滤才区别对待。

Tag的使用

@Test
public void tagProducer() throws Exception {DefaultMQProducer producer = new DefaultMQProducer("test-producer-group");producer.setNamesrvAddr(MQConstant.NAMESRV);producer.start();Message message1 = new Message("testTopic", "test1","test1的消息".getBytes() );Message message2 = new Message("testTopic", "test2","test2的消息".getBytes() );producer.send(message1);producer.send(message2);producer.shutdown();System.out.println("消息发送成功");
}@Test
public void test1Consumer() throws MQClientException, IOException {DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("test-producer-group");consumer.setNamesrvAddr(MQConstant.NAMESRV);consumer.subscribe("testTopic", "test1");consumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list,ConsumeConcurrentlyContext consumeConcurrentlyContext) {System.out.println("消费test1的消息"+new String(list.get(0).getBody()));return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();System.in.read();
}
@Test
public void test2Consumer() throws MQClientException, IOException {DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("test-producer-group");consumer.setNamesrvAddr(MQConstant.NAMESRV);consumer.subscribe("testTopic", "test1 || test2");consumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list,ConsumeConcurrentlyContext consumeConcurrentlyContext) {System.out.println("消费test1/test2的消息"+new String(list.get(0).getBody()));return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();System.in.read();
}

什么时候该用Topic,什么时候该用 Tag?
总结:不同的业务应该使用不同的Topic如果是相同的业务里面有不同表的表现形式,那么我们要使用tag进行区分
可以从以下几个方面进行判断:
1.消息类型是否一致:如普通消息、事务消息、定时(延时)消息、顺序消息,不同的消息类型使用不同的 Topic,无法通过 Tag 进行区分。
2.业务是否相关联:没有直接关联的消息,如淘宝交易消息,京东物流消息使用不同的 Topic 进行区分;而同样是天猫交易消息,电器类订单、女装类订单、化妆品类订单的消息可以用 Tag 进行区分。
3.消息优先级是否一致:如同样是物流消息,盒马必须小时内送达,天猫超市 24 小时内送达,淘宝物流则相对会慢一些,不同优先级的消息用不同的 Topic 进行区分。
4.消息量级是否相当:有些业务消息虽然量小但是实时性要求高,如果跟某些万亿量级的消息使用同一个 Topic,则有可能会因为过长的等待时间而“饿死”,此时需要将不同量级的消息进行拆分,使用不同的 Topic。
总的来说,针对消息分类,您可以选择创建多个Topic,或者在同一个 Topic 下创建多个 Tag。但通常情况下,不同的 Topic 之间的消息没有必然的联系,而 Tag 则用来区分同一个 Topic 下相互关联的消息,例如全集和子集的关系、流程先后的关系。

Key的使用

在rocketmq中的消息,默认会有一个messageId当做消息的唯一标识,我们也可以给消息携带一个key,用作唯一标识或者业务标识,包括在控制面板查询的时候也可以使用messageId或者key来进行查询。

@Test
public void testKeyProducer() throws Exception {// 创建默认的生产者DefaultMQProducer producer = new DefaultMQProducer("test-producer-group");// 设置nameServer地址producer.setNamesrvAddr(MQConstant.NAMESRV);// 启动实例producer.start();Message msg = new Message("testTopic","test1","key", "我是一个带标记和key的消息".getBytes());SendResult send = producer.send(msg);System.out.println(send);// 关闭实例producer.shutdown();
}@Test
public void testKeyConsumer() throws Exception {// 创建默认消费者组DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("test-producer-group");// 设置nameServer地址consumer.setNamesrvAddr(MQConstant.NAMESRV);// 订阅一个主题来消费   表达式,默认是*,支持"tagA || tagB || tagC" 这样或者的写法 只要是符合任何一个标签都可以消费consumer.subscribe("testTopic", "test1 || test2 || test3");// 注册一个消费监听 MessageListenerConcurrently是并发消费// 默认是20个线程一起消费,可以参看 consumer.setConsumeThreadMax()consumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,ConsumeConcurrentlyContext context) {// 这里执行消费的代码 默认是多线程消费System.out.println(Thread.currentThread().getName() + "----" + new String(msgs.get(0).getBody()));System.out.println(msgs.get(0).getTags());System.out.println(msgs.get(0).getKeys());return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});consumer.start();System.in.read();
}

相关文章:

【RocketMQ】快速入门

文章目录 消费模式同步消息异步消息单向消息延迟消息批量消息顺序消息事务消息Tag标签和Key键Tag的使用Key的使用 首先引入rocketmq的依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><ve…...

AB跳转轮询:让你的独立站收款智能化

独立站在近两年成为跨境电商的热门布局之一&#xff0c;特别是在亚马逊封号潮后&#xff0c;许多卖家开始转向独立站运营。然而&#xff0c;在迅速发展的同时&#xff0c;也不可避免地出现了一些问题&#xff0c;比如很多卖家的资金经常被不同程度地冻结&#xff0c;好不容易出…...

所有用户都能使用sudo吗

是的&#xff0c;Linux系统中的普通用户可以通过配置访问 sudo 命令来获得超级用户&#xff08;root&#xff09;权限的临时访问权。这使得普通用户可以在需要时执行需要管理员权限的操作&#xff0c;而无需永久性地切换到超级用户账户。 通过 sudo 命令&#xff0c;系统管理员…...

【广州华锐视点】VR警务教育实训系统模拟真实场景进行实践训练

随着科技的发展&#xff0c;虚拟现实技术在教育领域得到了广泛的应用。VR警务教育实训系统就是其中的一种应用&#xff0c;该系统由广州华锐互动开发&#xff0c;可以模拟真实的警务场景&#xff0c;让学生通过虚拟现实技术进行实践训练&#xff0c;提高学生的实践能力和技能水…...

【深入浅出C#】章节 7: 文件和输入输出操作:处理文本和二进制数据

文件和输入输出操作在计算机编程中具有重要性&#xff0c;因为它们涉及数据的持久化存储和交互。数据可以是不同类型的&#xff0c;例如文本、图像、音频、视频和二进制数据。这些不同类型的数据具有不同的存储需求。 文本数据是最常见的数据类型之一&#xff0c;用于存储和传输…...

Matlab中图例的位置(图例放在图的上方、下方、左方、右方、图外面)等

一、图例默认位置 默认的位置在NorthEast r 10; a 0; b 0; t0:0.1:2.1*pi; xar*cos(t); ybr*sin(t); A1plot(x,y,r,linewidth,4);%圆 hold on axis equal A2plot([0 0],[1 10],b,linewidth,4);%直线 legend([A1,A2],圆形,line)二、通过Location对legend的位置进行改变 变…...

【算法学习】两数之和II - 输入有序数组

题目描述 原题链接 给你一个下标从 1 开始的整数数组 numbers &#xff0c;该数组已按 非递减顺序排列 &#xff0c;请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] &#xff0c;则 1 < index1 < …...

聚观早报|京东称在技术投入没有止境;木蚁机器人完成B2轮融资

【聚观365】8月18日消息 京东零售CEO表示在技术上投入没有止境 木蚁机器人完成B2轮超亿元融资 耐能推出AI芯片KL730 三星电子泰勒晶圆厂首家客户是AI半导体厂商 韩国新能源汽车7月出口额同比大增36% 京东零售CEO表示在技术上投入没有止境 近日&#xff0c;京东零售CEO辛利…...

C语言:选择+编程(每日一练)

目录 选择题&#xff1a; 题一&#xff1a; 题二&#xff1a; 题三&#xff1a; 题四&#xff1a; 题五&#xff1a; 编程题&#xff1a; 题一&#xff1a;尼科彻斯定理 示例1 题二&#xff1a;等差数列 示例2 本人实力有限可能对一些地方解释和理解的不够清晰&…...

信道数据传输速率、码元传输速率、调制速度,信号传播速度之间的关系

1、信道数据传输速率&#xff08;bit/s&#xff09; 举例&#xff1a;移动通信中的数据传输速率。假设你的手机连接到4G网络&#xff0c;该网络的最大理论数据传输速率为100 Mbps。这意味着在理想情况下&#xff0c;你的手机可以以每秒100兆比特的速度传输数据。 2、码元传输速…...

docker的使用方法总结

Docker是一个非常强大的工具&#xff0c;它可以用于创建、部署和运行应用程序。以下是一些docker相关的常用指令&#xff0c; 1、查看docker版本 docker version 2、查看正在运行的Docker容器 docker ps 3、查看所有的docker容器&#xff08;包括没有运行的容器&#xff0…...

【C#】条码管理操作手册

前言&#xff1a;本文档为条码管理系统操作指南&#xff0c;介绍功能使用、参数配置、资源链接&#xff0c;以及异常的解决等。思维导图如下&#xff1a; 一、思维导图 二、功能操作–条码打印&#xff08;客户端&#xff09; 2.1 参数设置 功能介绍&#xff1a;二维码图片样…...

RabbitMq-发布确认高级(避坑指南版)

在初学rabbitMq的时候&#xff0c;伙伴们肯定已经接触到了“发布确认”的概念&#xff0c;但是到了后期学习中&#xff0c;会接触到“springboot”中使用“发布确认”高级的概念。后者主要是解决什么问题呢&#xff1f;或者是什么样的场景引出这样的概念呢&#xff1f; 在生产环…...

Blender增强现实3D模型制作指南【AR】

推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 将静态和动画 3D 内容集成到移动增强现实 (AR) 体验中是增强用户沉浸感和参与度的高效方法。 然而&#xff0c;为 AR 创建 3D 对象可能相当艰巨&#xff0c;尤其是对于那些缺乏 3D 建模经验的人来说。 与添加视频或照片 AR…...

Java查看https证书过期时间(JKS,CERT)

在这里需要使用X.509 证书的抽象类 X509Certificate 。此类提供了一种访问 X.509 证书所有属性的标准方式。 这些证书被广泛使用以支持 Internet 安全系统中的身份验证和其他功能。常见的应用包括增强保密邮件 (PEM)、传输层安全 (SSL)、用于受信任软件发布的代码签名和安全电…...

关于vue,记录一次修饰符.stop和.once的使用,以及猜想。

内置指令 | Vue.js 在vue的api里&#xff0c;关于v-on有stop和once两个事件标签。 .stop - 调用 event.stopPropagation()。.once - 最多触发一次处理函数。 原有主要代码和页面效果 &#xff08;无stop和once&#xff09;: ...<div class"div" click"di…...

解决git reset --soft HEAD^撤销commit时报错

今天在使用git回退功能的时候&#xff0c;遇到以下错误&#xff1a; 解决git reset --soft HEAD^撤销commit时报错 问题&#xff1a; 在进行完commit后&#xff0c;想要撤销该commit&#xff0c;于是使用了git reset --soft HEAD^命令&#xff0c;但是出现如下报错&#xff1…...

【BASH】回顾与知识点梳理(三十四)

【BASH】回顾与知识点梳理 三十四 三十四. 认识系统服务&#xff08;二&#xff09;34.1 systemctl 针对 service 类型的配置文件systemctl 配置文件相关目录简介systemctl 配置文件的设定项目简介[Unit] 部份[Service] 部份[Install] 部份 两个 vsftpd 运作的实例多重的重复设…...

Python可视化在量化交易中的应用(11)_Seaborn折线图

举个栗子&#xff0c;用seaborn绘制折线图。 Seaborn中折线图的绘制方法 在seaborn中&#xff0c;我们一般使用sns作为seaborn模块的别名&#xff0c;因此&#xff0c;在下文中&#xff0c;均以sns指代seaborn模块。 seaborn中绘制折线图使用的是sns.plot()函数&#xff1a; …...

无涯教程-TensorFlow - TensorBoard可视化

TensorFlow包含一个可视化工具&#xff0c;称为TensorBoard&#xff0c;它用于分析数据流图&#xff0c;还用于了解机器学习模型。 TensorBoard的重要功能包括查看有关垂直对齐的任何图形的参数和详细信息的不同类型统计的视图。 深度神经网络包括多达36&#xff0c;000个节点…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...