RabbitMQ 笔记

Message durability

确保消息在server 出现问题或者recovery能恢复: declare it as durable in the producer and consumer code.

boolean durable = true;
channel.queueDeclare("hello", durable, false, false, null);

Queue 指定

//使用指定的queue,以便协同,注意各方声明时候属性要一致channel.queueDeclare(RPC_QUEUE_NAME, false, false, false, null);channel.queuePurge(RPC_QUEUE_NAME);

Fair dispatch

In order to defeat that we can use the basicQos method with the prefetchCount = 1 setting. This tells RabbitMQ not to give more than one message to a worker at a time.


exchange

rabbitmqctl list_exchanges
Listing exchanges for vhost / …
name type
amq.headers headers
amq.rabbitmq.trace topic
amq.topic topic
amq.match headers
direct
amq.direct direct
amq.fanout fanout

There are a few exchange types available: direct, topic, headers and fanout

默认exchange

default exchange, which we identify by the empty string (“”).

channel.basicPublish("", "hello", null, message.getBytes());

将queue与exchange 进行bind

channel.queueBind(queueName, EXCHANGE_NAME, "black");

The meaning of a binding key depends on the exchange type

Direct exchange

  • We were using a fanout exchange, which doesn’t give us much flexibility - it’s only capable of mindless broadcasting.

  • We will use a direct exchange instead. The routing algorithm behind a direct exchange is simple - a message goes to the queues whose binding key exactly matches the routing key of the message.

  • bind multiple queues with the same binding key. 基于全量match,即string equal

  • can’t do routing based on multiple criteria.


Topics

a message sent with a particular routing key will be delivered to all the queues that are bound with a matching binding key
基于表达式的分发

  • star(*) can substitute for exactly one word.
  • hash( #) can substitute for zero or more words.

When a queue is bound with “#” (hash) binding key - it will receive all the messages, regardless of the routing key - like in fanout exchange.
When special characters, “*” (star) and “#” (hash), aren’t used in bindings, the topic exchange will behave just like a direct one.


Headers Exchange

A headers exchange is designed for routing on multiple attributes that are more easily expressed as message headers than a routing key. Headers exchanges ignore the routing key attribute. Instead, the attributes used for routing are taken from the headers attribute. A message is considered matching if the value of the header equals the value specified upon binding.
It is possible to bind a queue to a headers exchange using more than one header for matching. In this case, the broker needs one more piece of information from the application developer, namely, should it consider messages with any of the headers matching, or all of them? This is what the “x-match” binding argument is for. When the “x-match” argument is set to “any”, just one matching header value is sufficient. Alternatively, setting “x-match” to “all” mandates that all the values must match.
For “any” and “all”, headers beginning with the string x- will not be used to evaluate matches. Setting “x-match” to “any-with-x” or “all-with-x” will also use headers beginning with the string x- to evaluate matches.
Headers exchanges can be looked upon as “direct exchanges on steroids”. Because they route based on header values, they can be used as direct exchanges where the routing key does not have to be a string; it could be an integer or a hash (dictionary) for example.

plugins

I have no name!@bca0cb31ba36:/$ rabbitmq-plugins listListing plugins with pattern "." ...Configured: E = explicitly enabled; e = implicitly enabled| Status: * = running on rabbit@queue-ram1|/[  ] rabbitmq_amqp1_0                  3.12.10[  ] rabbitmq_auth_backend_cache       3.12.10[  ] rabbitmq_auth_backend_http        3.12.10[  ] rabbitmq_auth_backend_ldap        3.12.10[  ] rabbitmq_auth_backend_oauth2      3.12.10[  ] rabbitmq_auth_mechanism_ssl       3.12.10[  ] rabbitmq_consistent_hash_exchange 3.12.10[  ] rabbitmq_event_exchange           3.12.10[  ] rabbitmq_federation               3.12.10[  ] rabbitmq_federation_management    3.12.10[  ] rabbitmq_jms_topic_exchange       3.12.10[  ] rabbitmq_management               3.12.10[E] rabbitmq_management_agent         3.12.10
[  ] rabbitmq_mqtt                     3.12.10
[  ] rabbitmq_peer_discovery_aws       3.12.10
[  ] rabbitmq_peer_discovery_common    3.12.10
[  ] rabbitmq_peer_discovery_consul    3.12.10
[  ] rabbitmq_peer_discovery_etcd      3.12.10
[  ] rabbitmq_peer_discovery_k8s       3.12.10
[E*] rabbitmq_prometheus               3.12.10
[  ] rabbitmq_random_exchange          3.12.10
[  ] rabbitmq_recent_history_exchange  3.12.10
[  ] rabbitmq_sharding                 3.12.10
[  ] rabbitmq_shovel                   3.12.10
[  ] rabbitmq_shovel_management        3.12.10
[  ] rabbitmq_stomp                    3.12.10
[  ] rabbitmq_stream                   3.12.10
[  ] rabbitmq_stream_management        3.12.10
[  ] rabbitmq_top                      3.12.10
[  ] rabbitmq_tracing                  3.12.10
[  ] rabbitmq_trust_store              3.12.10
[e*] rabbitmq_web_dispatch             3.12.10
[  ] rabbitmq_web_mqtt                 3.12.10
[  ] rabbitmq_web_mqtt_examples        3.12.10
[  ] rabbitmq_web_stomp                3.12.10
[  ] rabbitmq_web_stomp_examples       3.12.10

参考 URL
Firehose Tracer Firehose Tracer — RabbitMQ

Plugin Development Basics — RabbitMQ


Queue Properties

Queues have properties that define how they behave. There is a set of mandatory properties and a map of optional ones:

  • Name
  • Durable (the queue will survive a broker restart)
  • Exclusive (used by only one connection and the queue will be deleted when that connection closes)
  • Auto-delete (queue that has had at least one consumer is deleted when last consumer unsubscribes)
  • Arguments (optional; used by plugins and broker-specific features such as message TTL, queue length limit, etc)

Queue type (e.g. quorum or classic) -推荐quorum,单quorum不支持messsage priority,对应append-only的log 类,推荐使用stream -Stream Plugin — RabbitMQ

在这里插入图片描述

Consumer priorities allow you to ensure that high priority consumers receive messages while they are active, with messages only going to lower priority consumers when the high priority consumers block.

When Not to Use Quorum Queues

In some cases quorum queues should not be used. They typically involve:

  • Temporary nature of queues: transient or exclusive queues, high queue churn (declaration and deletion rates)
  • Lowest possible latency: the underlying consensus algorithm has an inherently higher latency due to its data safety features
  • When data safety is not a priority (e.g. applications do not use manual acknowledgements and publisher confirms are not used)
  • Very long queue backlogs (streams are likely to be a better fit)

不同队列类型支持的属性

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Durability

Transient queues will be deleted on node boot. They therefore will not survive a node restart, by design. Messages in transient queues will also be discarded.
Durable queues will be recovered on node boot, including messages in them published as persistent

Exclusive Queues

An exclusive queue can only be used (consumed from, purged, deleted, etc) by its declaring connection.

Replicated and Distributed Queues

Quorum queues is replicated, data safety and consistency-oriented queue type. Classic queues historically supported replication but it is deprecated and should be avoided.
Queues can also be federated across loosely coupled nodes or clusters.
Note that intra-cluster replication and federation are orthogonal features and should not be considered direct alternatives.
Streams is another replicated data structure supported by RabbitMQ, with a different set of supported operations and features.

Time-to-Live and Length Limit

Queues can have their length limited. Queues and messages can have a TTL.


RabbitMQ中的消息优先级是如何实现的?

注意 只有classic的队列支持优先级。

By default, RabbitMQ classic queues do not support priorities. When creating priority queues, a maximum priority can be chosen as you see fit. When choosing a priority value, the following factors need to be considered:

  • There is some in-memory and on-disk cost per priority level per queue. There is also an additional CPU cost, especially when consuming, so you may not wish to create huge numbers of levels.
  • The message priority field is defined as an unsigned byte, so in practice priorities should be between 0 and 255.
  • Messages without priority property are treated as if their priority were 0. Messages with a priority which is higher than the queue’s maximum are treated as if they were published with the maximum priority.

channels

Maximum Number of Channels per Connection
On the server side, the limit is controlled using the channel_max:

# no more 100 channels can be opened on a connection at the same time
channel_max = 100
Clients can be configured to allow fewer channels per connection. With RabbitMQ Java client, ConnectionFactory#setRequestedChannelMax is the method that controls the limit:ConnectionFactory cf = new ConnectionFactory();
// Ask for up to 32 channels per connection. Will have an effect as long as the server is configured
// to use a higher limit, otherwise the server's limit will be used.
cf.setRequestedChannelMax(32);

Acknowledgements -确认

delivery tag -每个消息的唯一识别标志

When manual acknowledgements are used, any delivery (message) that was not acked is automatically requeued when the channel (or connection) on which the delivery happened is closed. This includes TCP connection loss by clients, consumer application (process) failures, and channel-level protocol exceptions (covered below).

Consumer Acknowledgement Modes and Data Safety Considerations

  • basic.ack is used for positive acknowledgements
  • basic.nack is used for negative acknowledgements (note: this is a RabbitMQ extension to AMQP 0-9-1)
  • basic.reject is used for negative acknowledgements but has one limitation compared to basic.nack

channel.basicAck 支持批量确认
Manual acknowledgements can be batched to reduce network traffic. This is done by setting the multiple field of acknowledgement methods (see above) to true.

    // AMQImpl.Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
// 每次处理1 条消息channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + message + "'");try {doWork(message);} finally {System.out.println(" [x] Done");// false 待办单个channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);}};//    public String basicConsume(String queue, boolean autoAck, DeliverCallback deliverCallback, CancelCallback cancelCallback) throws IOException {// 第二次参数标志是否自动ackchannel.basicConsume(TASK_QUEUE_NAME, false, deliverCallback, consumerTag -> { });

Negative Acknowledgement and Requeuing of Deliveries

This behaviour is controlled by the requeue field. When the field is set to true, the broker will requeue the delivery (or multiple deliveries, as will be explained shortly) with the specified delivery tag. Alternatively, when this field is set to false, the message will be routed to a Dead Letter Exchange if it is configured, otherwise it will be discarded.

 // negatively acknowledge, the message will// be discardedchannel.basicReject(deliveryTag, false);
交给其它consumer 处理// requeue the deliverychannel.basicReject(deliveryTag, true);basic.nack 和Basic.Reject 的差异是支持批量// requeue all unacknowledged deliveries up to// this delivery tagchannel.basicNack(deliveryTag, true, true);

三者的实现代码

public void basicAck(long deliveryTag, boolean multiple) throws IOException {this.transmit(new AMQImpl.Basic.Ack(deliveryTag, multiple));this.metricsCollector.basicAck(this, deliveryTag, multiple);
}public void basicNack(long deliveryTag, boolean multiple, boolean requeue) throws IOException {this.transmit(new AMQImpl.Basic.Nack(deliveryTag, multiple, requeue));this.metricsCollector.basicNack(this, deliveryTag);
}public void basicReject(long deliveryTag, boolean requeue) throws IOException {this.transmit(new AMQImpl.Basic.Reject(deliveryTag, requeue));this.metricsCollector.basicReject(this, deliveryTag);
}

Publisher Confirms -生产者确认

  • To enable confirms, a client sends the confirm.select method. Depending on whether no-wait was set or not, the broker may respond with a confirm.select-ok. Once the confirm.select method is used on a channel, it is said to be in confirm mode.

  • 通过计数来确认

  • Once a channel is in confirm mode, both the broker and the client count messages (counting starts at 1 on the first confirm.select). The broker then confirms messages as it handles them by sending a basic.ack on the same channel.

  • 如要百分百确认消息落盘了,可以用confirm模式
    In order to guarantee persistence, a client should use confirms. If the publisher’s channel had been in confirm mode, the publisher would not have received an ack for the lost message (since the message hadn’t been written to disk yet).

  • 可以在发送后同步获取( channel.waitForConfirmsOrDie(5_000);),也可以异步获取是否发送成功(channel.addConfirmListener((sequenceNumber, multiple) -> {
    ) 参考PublisherConfirms类

Channel Prefetch Setting (QoS)

获取数量

  • A value of 0 means “no limit”, allowing any number of unacknowledged messages.
  • The QoS setting can be configured for a specific channel or a specific consumer. The Consumer Prefetch guide explains the effects of this scoping.
 // 每次处理1 条消息channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), "UTF-8");System.out.println(" [x] Received '" + message + "'");try {doWork(message);} finally {System.out.println(" [x] Done");// false 待办单个channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);}};//    public String basicConsume(String queue, boolean autoAck, DeliverCallback deliverCallback, CancelCallback cancelCallback) throws IOException {// 第二次参数标志是否自动ackchannel.basicConsume(TASK_QUEUE_NAME, false, deliverCallback, consumerTag -> { });channel.consum//channel.getDefaultConsumer().handleCancel();

Single Consumer

The following basic example in Java will receive a maximum of 10 unacknowledged messages at once:

Channel channel = ...;
Consumer consumer = ...;
channel.basicQos(10); // Per consumer limit
channel.basicConsume("my-queue", false, consumer);

A value of 0 is treated as infinite, allowing any number of unacknowledged messages.

Channel channel = ...;
Consumer consumer = ...;
channel.basicQos(0); // No limit for this consumer
channel.basicConsume("my-queue", false, consumer);

Independent Consumers

This example starts two consumers on the same channel, each of which will independently receive a maximum of 10 unacknowledged messages at once:

Channel channel = ...;
Consumer consumer1 = ...;
Consumer consumer2 = ...;
channel.basicQos(10); // Per consumer limit
channel.basicConsume("my-queue1", false, consumer1);
channel.basicConsume("my-queue2", false, consumer2);

Multiple Consumers Sharing the Limit

Channel channel = ...;
Consumer consumer1 = ...;
Consumer consumer2 = ...;
channel.basicQos(10, false); // Per consumer limit
channel.basicQos(15, true);  // Per channel limit
channel.basicConsume("my-queue1", false, consumer1);
channel.basicConsume("my-queue2", false, consumer2);

Configurable Default Prefetch

RabbitMQ can use a default prefetch that will be applied if the consumer doesn’t specify one. The value can be configured as rabbit.default_consumer_prefetch in the advanced configuration file:
%% advanced.config file
[
{rabbit, [
{default_consumer_prefetch, {false,250}}
]
}
].

Queue Length Limit

The default behaviour for RabbitMQ when a maximum queue length or size is set and the maximum is reached is to drop or dead-letter messages from the front of the queue (i.e. the oldest messages in the queue). To modify this behaviour, use the overflow setting described below.

Queue Overflow Behaviour

Use the overflow setting to configure queue overflow behaviour. If overflow is set to reject-publish or reject-publish-dlx, the most recently published messages will be discarded. In addition, if publisher confirms are enabled, the publisher will be informed of the reject via a basic.nack message. If a message is routed to multiple queues and rejected by at least one of them, the channel will inform the publisher via basic.nack. The message will still be published to all other queues which can enqueue it. The difference between reject-publish and reject-publish-dlx is that reject-publish-dlx also dead-letters rejected messages.

What is a Lazy Queue

A “lazy queue” is a classic queue which is running in lazy mode. When the “lazy” queue mode is set, messages in classic queues are moved to disk as early as practically possible. These messages are loaded into RAM only when they are requested by consumers.

Exchange to Exchange Bindings

Java Client Example
Use the Channel#exchangeBind method. The following example binds an exchange “destination” to “source” with routing key “routingKey”.

Channel ch = conn.createChannel();
ch.exchangeBind("destination", "source", "routingKey");
---

Consumer Cancel Notification

  • 用于优雅推出消费端
  • if the client issues a basic.cancel on the same channel, which will cause the consumer to be cancelled and the server replies with a basic.cancel-ok.
public void basicCancel(final String consumerTag) throws IOException {
处理异常退出
channel.queueDeclare(queue, false, true, false, null);
Consumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleCancel(String consumerTag) throws IOException {// consumer has been cancelled unexpectedly}
};
channel.basicConsume(queue, consumer);
boolean autoAck = false;
channel.basicConsume(queueName, autoAck, "myConsumerTag",new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body)throws IOException{String routingKey = envelope.getRoutingKey();String contentType = properties.getContentType();long deliveryTag = envelope.getDeliveryTag();// (process the message components here ...)channel.basicAck(deliveryTag, false);}});channel.basicCancel(consumerTag);

rabbitmq cluster

默认通过cookie 识别为同一cluster

In case of a node failure, clients should be able to reconnect to a different node, recover their topology and continue operation. For this reason, most client libraries accept a list of endpoints (hostnames or IP addresses) as a connection option. The list of hosts will be used during initial connection as well as connection recovery, if the client supports it. See documentation guides for individual clients to learn more.

Node Failure Handling

RabbitMQ brokers tolerate the failure of individual nodes. Nodes can be started and stopped at will, as long as they can contact a cluster member node known at the time of shutdown.
Quorum queue allows queue contents to be replicated across multiple cluster nodes with parallel replication and a predictable leader election and data safety behavior as long as a majority of replicas are online.

Non-replicated classic queues can also be used in clusters. Non-mirrored queue behaviour in case of node failure depends on queue durability.

client 端

Using Lists of Endpoints
It is possible to specify a list of endpoints to use when connecting. The first reachable endpoint will be used. In case of connection failures, using a list of endpoints makes it possible for the application to connect to a different node if the original one is down.
To use multiple of endpoint, provide a list of Addresses to ConnectionFactory#newConnection. An Address represents a hostname and port pair.

Address[] addrArr = new Address[]{ new Address(hostname1, portnumber1), new Address(hostname2, portnumber2)};
Connection conn = factory.newConnection(addrArr);

Disconnecting from RabbitMQ: To disconnect, simply close the channel and the connection:

channel.close();
conn.close();

RAM node

RAM node不落盘,可以选择RAM 对外提升性能,DISC node作为mirror和落盘保证。

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

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

相关文章

【古月居《ros入门21讲》学习笔记】14_参数的使用与编程方法

目录 说明&#xff1a; 1. 参数模型&#xff08;全局字典&#xff09; 2. 实现过程&#xff08;C&#xff09; 创建功能包 参数命令行的使用 YAML参数文件 rosparam命令 使用示例 编程方法&#xff08;C&#xff09; 配置代码编译规则 编译并运行 编译 运行 3. 实…

基于springboot + vue体育馆使用预约平台

qq&#xff08;2829419543&#xff09;获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;springboot 前端&#xff1a;采用vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xf…

Wireshark 协议插件Lua开发 -数据包内嵌协议的解释

概述 因为公司项目涉及的协议打包&#xff0c;协议包内又嵌了一层IP包的奇葩套娃结构&#xff0c;为了方便抓包调试&#xff0c;利用Wireshark的协议插件开发功能&#xff0c;写了一个插件&#xff0c;博文记录以备忘。 环境信息 Wireshark 4.0.3 协议结构体套娃图 插件安装…

C++基础 -35- string类

string类的格式 string a;如下图&#xff0c;使用string类比常规的字符串处理方便很多 而且需要进行的字符串处理&#xff0c;在类中都能完成 #include "iostream"using namespace std;extern "C" {#include "string.h" }int main() {//c的写…

从零开始:PHP实现阿里云直播的简单方法!

1. 配置阿里云直播的推流地址和播放地址 使用阿里云直播功能前&#xff0c;首先需要在阿里云控制台中创建直播应用&#xff0c;然后获取推流地址和播放地址。 推流地址一般格式为&#xff1a; rtmp://{Domain}/{AppName}/{StreamName}?auth_key{AuthKey}-{Timestamp}-{Rand…

C# 使用HtmlAgilityPack解析提取HTML内容

写在前面 HtmlAgilityPack是一个HTML解析类库&#xff0c;日常用法就是爬虫获取到内容后&#xff0c;先用XPath获取目标节点&#xff0c;再用正则进行匹配&#xff1b;使用XPath的目的主要是将目标节点或内容限定在一个较小的范围&#xff0c;如果一上来就用正则那效率肯定不…

Git Bash环境下用perl脚本获取uuid值

在Linux环境下&#xff0c;比如在ubuntu就直接有uuidgen命令直接获取uuid值。在Windows环境下常用的git bash中没有对应的命令&#xff0c;略有不便。这里用脚本写一个uuidgen&#xff0c;模拟Linux环境下的uuidgen命令。 #! /usr/bin/perl use v5.14; use Win32;sub uuidGen {…

Windows驱动中校验数字签名(使用 ci.dll)

1.背景 对于常规应用程序来说&#xff0c;校验数字签名认证在应用层可以使用 WinVerifyTrust, 在驱动层使用常规的 API无法使用&#xff0c;自己分析数据又太麻烦。 在内核中 ci.dll 包装了数据签名验证相关的功能&#xff0c;我们可以使用该 dll 来实现我们的数字签名验证。 详…

Blender学习笔记:小车狂奔动画

文章目录 路旁小树汽车尾气移动 教程地址&#xff1a;八个案例教程带你从0到1入门blender【已完结】 小车建模 路旁小树 1 添加摄像机&#xff0c;在小车下面拉一个平面&#xff0c;覆盖到摄像机的观察视窗。复制一层平面&#xff0c;收窄变成小车两侧的路面&#xff0c;编辑…

vue使用实现录音功能js-audio-recorder

前言 最近项目中需要实现一个录音上传功能&#xff0c;用于语音评论可以上录音。 下载插件&#xff1a; npm i js-audio-recorder完整代码 <template><div style"padding: 20px;"><h3>录音上传</h3><div style"font-size:14px"…

图推理:忠实且可解释的大型语言模型推理11.29

推理&#xff1a;忠实且可解释的大型语言模型推理 摘要1 引言&#xff12; 相关工作3 准备工作4 方法4.1 图推理&#xff1a;规划-检索-推理4.2 优化框架4.3 规划模块4.4 检索推理模块 5 实验5.1 实验设置5.2 RQ1&#xff1a;KGQA 性能比较 摘要 大型语言模型&#xff08;LLM&…

python爬虫AES魔改案例:某音乐素材下载网

声明&#xff1a; 该文章为学习使用&#xff0c;严禁用于商业用途和非法用途&#xff0c;违者后果自负&#xff0c;由此产生的一切后果均与作者无关 一、找出需要加密的参数 js运行 atob(‘aHR0cHM6Ly93d3cuYWlnZWkuY29tL3NvdW5kL2NsYXNzLw’) 拿到网址&#xff0c;F12打开调…

二.运算符

运算符 1.算术运算符2.比较运算符3.逻辑运算符 1.算术运算符 算数运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达式&#xff0c;对数值或表达式进行 - * / 和 取模%运算 1.加减法运算符 mysql> SELECT 100,100 0,100 - 0,100 50,100 50 - …

制作一个RISC-V的操作系统一-计算机系统漫游

文章目录 计算机的硬件组成两种架构程序的存储与执行程序语言的设计和进化一个mini计算机 编程语言的进化存储设备的层次结构操作系统 计算机的硬件组成 所有硬件由总线连接起来 两种架构 总线个数不同&#xff0c;Memory储存内容不同 程序的存储与执行 首先编译和链接某…

windows11 调整鼠标灵敏度方法

首先 我们打开电脑设置 或者在 此电脑/此计算机/我的电脑 右击选择属性 然后 有的电脑 左侧菜单中 直接就有 设备 然后在设备中直接就可以找到 鼠标 选项 调整光标速度即可 如果操作系统和我的一样 可以直接搜索鼠标 然后 选择 鼠标设置 然后 调整上面的鼠标指针速度即可

【Rust日报】2023-12-02 深度学习框架 Burn 发布 v0.11.0

深度学习框架 Burn 发布 v0.11.0 深度学习框架 Burn 发布 v0.11.0&#xff0c;新版本引入了自动内核融合&#xff08;Kernel Fusion&#xff09;功能&#xff0c;大大提升了访存密集型&#xff08;memory-bound&#xff09;操作的性能。同时宣布成立 Tracel AI (https://tracel…

安装错误_ImportError: cannot import name ‘XXX‘循环引用 绕晕TT(deepsolo)

这里写目录标题 error: Couldnt find a setup script in /tmp/easy_install-lfpvj6p4/scikit_image-0.22.0.tar.gzpip install -v -e . 和 python setup.py develop功能一样吗AttributeError: module ‘PIL.Image’ has no attribute ‘LINEAR’ImportError: cannot import nam…

【算法】前后缀分解题单⭐

文章目录 题单来源题目列表42. 接雨水238. 除自身以外数组的乘积2256. 最小平均差2483. 商店的最少代价代码1——前后缀数组代码2—— O ( 1 ) O(1) O(1)空间&#x1f402; 2420. 找到所有好下标2167. 移除所有载有违禁货物车厢所需的最少时间代码1——前后缀分解代码2——简洁…

3.4_1 java自制小工具 - pdf批量转图片

相关链接 目录参考文章&#xff1a;pdf转图片(apache pdfbox)参考文章&#xff1a;GUI界面-awt参考文章&#xff1a;jar包转exe(exe4j)参考文章&#xff1a;IDEA导入GIT项目参考文章&#xff1a;IDEA中使用Gitee管理代码gitee项目链接&#xff1a;pdf_2_image网盘地址&#xf…

基于CW32F030单片机的便携式多功能测试笔

一、产品背景 在日常的硬件调试工作中&#xff0c;我们最常使用的仪器仪表可能就是万用表了&#xff0c;虽然万用表号称“万用”&#xff0c;但大部分时候&#xff0c;我们需要使用到的功能无非是电压测量和通断测量。 作为调试的“得力干将”&#xff0c;万用表有时候也会存…