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

SpringBoot整合RocketMQ笔记

SpringBoot版本为2.3.12.Release

RocketMQ对比kafka

在这里插入图片描述

学习链接

https://zhuanlan.zhihu.com/p/335216381 代码实战

https://www.cnblogs.com/RedOrange/p/17401238.html Centos安装rocketmq

https://blog.csdn.net/chuige2013/article/details/123783612 RocketMQ详细配置与使用详解

https://rocketmq-1.gitbook.io/rocketmq-connector/quick-start/qian-qi-zhun-bei/ji-qun-huan-jing 官网学习地址

前言

淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用MySQL作为消息存储媒介,支持水平扩容。为了进一步降低成本,阿里中间件团队认为Notify可进一步优化。

2011年初,Linkedin开源了kafka, 阿里中间件团队在对kafka做了充分的review之后,被kafka的无限消息堆积能力、高效的持久化速度深深吸引,但同时发现kafka主要定位于日志传输,对于使用在淘宝交易、订单、充值等场景下,还有若干特性不满足。因此,阿里中间件团队基于Java重新编写了RocketMQ,定位于不仅限于日志场景的可靠消息传输。

目前,RocketMQ在阿里集团被广泛应用于订单、充值、交易、流计算、消息推送、日志流式处理、binlog分发等场景。

RocketMQ与kafka的不同

1、数据可靠性
RocketMQ:支持异步实时刷盘、同步刷盘、同步复制、异步复制。
kafka:使用异步刷盘方式,异步复制/同步复制。

总结:
1、RocketMQ支持kafka所不具备的“同步刷盘”功能,在单机可靠性上比kafka更高,不会因为操作系统Crash而导致数据丢失。
2、kafka的同步replication理论上性能低于RocketMQ的replication,这是因为kafka的数据以partition为单位,这样一个kafka实例上可能多上百个partition。而一个RocketMQ实例上只有一个partition,RocketMQ可以充分利用IO组的commit机制,批量传输数据。同步replication与异步replication相比,同步replication性能上损耗约20%-30%。

一句话概括:RocketMQ新增了同步刷盘机制,保证了可靠性;一个RocketMQ实例只有一个partition, 在replication时性能更好。

2、性能对比
1、kafka单机写入TPS月在百万条/秒,消息大小为10个字节。
2、RocketMQ单机写入TPS单实例约7万条/秒,若单机部署3个broker,可以跑到最高12万条/秒,消息大小为10个字节。

总结:
kafka的单机TPS能跑到每秒上百万,是因为Producer端将多个小消息合并,批量发向broker。

那么RocketMQ为什么没有这样做呢?

发送消息的Producer通常是用Java语言,缓存过多消息,GC是个很严重的问题。(问题:难道kafka用scala不需要GC?)
Producer发送消息到broker, 若消息发送出去后,未达到broker,就通知业务消息发送成功,若此时Broker宕机,则会导致消息丢失,从而导致业务出错。
Producer通常为分布式系统,且每台机器都是多线程发送,通常来说线上单Producer产生的消息数量不会过万。
消息合并功能完全可由上层业务来做。
一句话概括:RocketMQ写入性能上不如kafka, 主要因为kafka主要应用于日志场景,而RocketMQ应用于业务场景,为了保证消息必达牺牲了性能,且基于线上真实场景没有在RocketMQ层做消息合并,推荐在业务层自己做。

3、单机支持的队列数
1、kafka单机若超过了64个partition/队列,CPU load会发生明显飙高,partition越多,CPU load越高,发消息的响应时间变长。
2、RocketMQ单机支持最高5万个队列,CPU load不会发生明显变化。

队列多有什么好处呢?
1、单机可以创建更多个topic, 因为每个topic都是有一组队列组成。
2、消费者的集群规模和队列数成正比,队列越多,消费类集群可以越大。

一句话概括:RocketMQ支持的队列数远高于kafka支持的partition数,这样RocketMQ可以支持更多的consumer集群。

4、消息投递的实时性
1、kafka采用短轮询的方式,实时性取决于轮询时间间隔,0.8以后版本支持长轮询。
2、RocketMQ使用长轮询,同Push实时性一致,消息投递的延迟通常在几毫秒内,

一句话:kafka与RocketMQ都支持长轮询,消息投递的延迟在几毫秒内。

5、消费失败重试
1、kafka不支持消费失败重试。
2、RocketMQ消费失败支持定时重试,每次重试间隔时间顺延。

总结:以充值类应用为例,若当前时刻调用运营商网管失败,可能运营商网关此时压力过大,稍后再调用就会成功。这里的重试指可靠的重试,即失败重试的消息不是因为consumer宕机而导致的消息丢失。

一句话概括:RocketMQ支持消费失败重试功能,主要用于第一次调用不成功,后面可调用成功的场景。而kafka不支持消费失败重试。

6、严格保证消息有序
1、kafka可保证同一个partition上的消息有序,但一旦broker宕机,就会产生消息乱序。
2、Rocket支持严格的消息顺序,一台broker宕机,发送消息会失败,但不会乱序。举例:MySQL的二进制日志分发需要保证严格的顺序。

一句话概括:kafka不保证消息有序,RocketMQ可保证严格的消息顺序,即使单台Broker宕机,仅会造成消息发送失败,但不会消息乱序。

7、定时消息
1、kafka不支持定时消息
2、开源版本的RocketMQ仅支持定时级别,定时级别用户可定制

8、分布式事务消息
1、kafka不支持分布式事务消息
2、RocketMQ支持分布式事务消息。

9、消息查询
1、kafka不支持消息查询
2、RocketMQ支持根据消息标识(发送消息时指定一个消息key, 任意字符串,如指定为订单编号)查询消息,也支持根据消息内容查询消息。

总结:消息查询功能对于定位消息丢失问题非常有用,例如某个订单处理失败,可用此功能查询是消息没收到,还是收到了但处理出错了。

一句话概括:RocketMQ支持按消息标识或消息内容查询消息,用于排查消息丢失问题;kafka不支持消息查询。

10、消息回溯
1、kafka可按照消息的offset来回溯消息
2、RocketMQ支持按照时间来回溯消息,精度到毫秒,例如从一天的几点几分几秒几毫秒来重新消费消息。

总结:RocketMQ按时间做回溯消息的典型应用场景为,consumer做订单分析,但是由于程序逻辑或依赖的系统发生故障等原因,导致今天处理
的消息全部无效,需要从昨天的零点重新处理。

11、消息并行度
1、kafka的消息并行度,依赖于topic里配置的partition数,如果partition数为10,那么最多10台机器来消费,每台机器只能开启一个线程;或者一台机器消费,最多开启10个线程。消费的并行度与partition个数一致。
2、RocketMQ并行消费分两种情况:
1)顺序消费方式的并行度与kafka一致。
2)乱序消费方式的并行度取决于consumer的线程数,如topic配置10个队列,10台机器消费,每台机器100个线程,那么并行度为1000。

一句话概括:kafka的消费并行度等于partition数;RocketMQ的消费并行度等于消费的线程数,不受队列数限制。

12、开发语言
1、kafka采用scala开发
2、RocketMQ采用Java开发

13、消息堆积能力
kafka比RocketMQ的消息堆积能力更强,不过RocketMQ单机也可支持亿级的消息积压能力,这个堆积能力也能够完全满足业务需求。

14、开源社区活跃度
1、kafka社区更新较慢
2、RocketMQ的Github社区有250人,公司用户登记了联系方式,QQ群超过1000人,
3、kafka原开发团队成立了新公司,暂时未看到相关产品。
4、RocketMQ已在阿里云商业化,目前以云服务形式供外部商用,并向用户承诺99.99%的可靠性,同时彻底解决了用户自己搭建MQ产品的运维复杂性问题。

15、应用领域成熟度
1、kafka在日志领域比较成熟
2、RocketMQ在阿里集团内部有大量的应用在使用,并顺利支持了多次天猫双十一的考验。

总结

kafka和RocketMQ的总体区别是,kafka设计初衷是用于日志传输,而RocketMQ的设计用于解决各类应用可靠的消息传输,阿里云官网承诺RocketMQ数据可靠性为10个9,服务可靠性为99.95%。

kafka相比RocketMQ的优势
1、单机吞吐量TPS可上百万,远高于RocketMQ的TPS7万每秒,适用于日志类消息。
2、kafka支持多语言的客户端

RocketMQ相比kafka的优势
1、保证消息不丢( 数据可靠性达10个9)
2、可严格保证消息有序
3、支持分布式事务消息
4、支持按时间做消息回溯(可精确到毫秒级)
5、支持按标识和内容查询消息,用于排查丢消息
6、支持消费失败重试
7、可支持更多的partition, 即更多的消费线程数

Linux快速安装RocketMQ

(1)Apache仓库:https://archive.apache.org/dist/rocketmq/
(2)官网:https://rocketmq.apache.org/zh/
(3)上传到centos7
(4)解压
在这里插入图片描述
在这里插入图片描述

(5)安装说明:https://blog.csdn.net/weixin_67767103/article/details/127260319

修改配置文件

进入bin文件加中修改三个文件:runserver.sh、runbroker.sh、tools.sh,主要是为了调整jvm堆内存,防止启动失败

进入bin目录,首先我们修改runsever.sh的。使用vim命令:vim runserver.sh

JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m"

接着修改runbroker.sh文件,同样vim runbroker.sh

JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m"

再接着,修改tools.sh,同样vim tools.sh

JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=200m"

启动mq,linux记得关防火墙

systemctl stop firewalld或者对9876端口开放访问

使用命令
nohup sh bin/mqnamesrv &

查看启动日志
tail -f ~/logs/rocketmqlogs/namesrv.log
The Name Server boot success…
在这里插入图片描述启动mqbroker服务
nohup sh bin/mqbroker -n localhost:9876 &
8976为rocketmq的默认端口

查看日志
tail -f ~/logs/rocketmqlogs/broker.log
The broker[%s, 172.30.30.233:10911] boot success…

在这里插入图片描述

测试RocketMQ

发送消息
设置环境变量 export NAMESRV_ADDR=localhost:9876 #
使用安装包的Demo发送消息 sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
在这里插入图片描述

接收消息
设置环境变量 export NAMESRV_ADDR=localhost:9876
接收消息 sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
在这里插入图片描述

关闭RocketMQ
关闭NameServer sh bin/mqshutdown namesrv
关闭Broker sh bin/mqshutdown broker

各角色介绍

Producer:消息的发送者;举例:发件者
Consumer:消息接收者;举例:收件人
Consumer Group:消费组;每一个 consumer 实例都属于一个 consumer group,每一条消息只会被同一个 consumer group 里的一个 consumer 实例消费。(不同consumer group可以同时消费同一条消息)
Broker:暂存和传输消息;举例:快递公司
NameServer:管理 Broker;举例:快递公司的管理机构
Topic:区分消息的种类;一个发送者可以发送消息给一个或者多个 Topic;一个消息的接收者可以订阅一个或者多个 Topic 消息
Message Queue:相当于是 Topic 的分区;用于并行发送和接收消息

可视化监控平台搭建

下载地址:https://github.com/apache/rocketmq-dashboard
拉下来配置maven和jdk,直接使用idea启动
配置mq地址
在这里插入图片描述
在这里插入图片描述
设置开机启动
将启动脚本挂载到系统init文件下
vim /etc/rc.d/rc.local

测试用例

Java语言的生产者消费者测试用例

初始化生产者消费者

入门建议手动创建连接。
发送同步消息步骤

1.创建DefaultMQProducer,输入组名
2.设置mq地址
3.启动producer
4.编写消息,设置topic、tag、body
5.发送mq消息
6.关闭producer排查Topic是否已创建
cat ~/logs/rocketmqlogs/broker.log  | grep topicName=自己的Topic启动broker时开启自动创建Topic或自己去手动创建
nohup sh mqbroker -n localhost:9876 autoCreateTopicEnable=true > ../broker.log &
手动创建topic:进入mq的安装目录 ,执行如下命令创建topic。mq安装的相对目录是rocketmq-all-4.4.0/distribution/target/apache-rocketmq/bin以下命令创建了一个名称是orderPay的topicsh mqadmin updateTopic -b localhost:10911 -t orderPay

涉及到的常量

package club.xxx.mq.constants;public class MQAddrConst {/*** mq地址*/public static final String IP1 = "192.168.202.14:9876";public static final String TOPIC1 = "Order_Transaction_TopicTest";public static final String GROUP_NAME1 = "my_first_mq_test_group_name";public static final String TAG1 = "my_first_mq_test_tag";
}package club.xxx.mq.constants;public class OrderConst {public static final String ORDER1 = "ORDER_PREFIX:username:1702935568079523840";public static final String ORDER2 = "ORDER_PREFIX:username:1702935568083718144";public static final String ORDER3 = "ORDER_PREFIX:username:1702935568083718145";public static final String ORDER4 = "ORDER_PREFIX:username:1702935568083718146";public static final String ORDER5 = "ORDER_PREFIX:username:1702935568083718147";public static final String ORDER6 = "ORDER_PREFIX:username:1702935568083718148";public static final String ORDER7 = "ORDER_PREFIX:username:1702935568083718149";public static final String ORDER8 = "ORDER_PREFIX:username:1702935568083718150";
}

生产者代码

package club.xxx.mq._02myrawmq;import club.xxx.mq.constants.MQAddrConst;
import club.xxx.mq.constants.OrderConst;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;/*** 1、Producer端发送同步消息 这种可靠性同步地发送方式使用的比较广泛,比如:重要的消息通知,短信通知。*/
public class _01MySyncProducer {public static void main(String[] args) throws Exception {// 实例化消息生产者ProducerDefaultMQProducer producer = new DefaultMQProducer(MQAddrConst.GROUP_NAME1);// 设置NameServer的地址producer.setNamesrvAddr(MQAddrConst.IP1);// 启动Producer实例producer.start();// 创建消息,并指定Topic,Tag和消息体Message msg = new Message(MQAddrConst.TOPIC1/* Topic */,MQAddrConst.TAG1 /* Tag */,(OrderConst.ORDER1).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */);
//        msg.setKeys("KEY???");// 发送消息到一个BrokerSendResult sendResult = producer.send(msg);// 通过sendResult返回消息是否成功送达System.out.printf("sync send ok: %s%n", sendResult);// 如果不再发送消息,关闭Producer实例。producer.shutdown();}
}

消费者代码

package club.xxx.mq._02myrawmq;import club.xxx.mq.constants.MQAddrConst;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;import java.nio.charset.StandardCharsets;
import java.util.List;/*** 消费者*/
public class _02MyConsumer {public static void main(String[] args) throws InterruptedException, MQClientException {// 实例化消费者DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(MQAddrConst.GROUP_NAME1);// 设置NameServer的地址consumer.setNamesrvAddr(MQAddrConst.IP1);// 订阅一个或者多个Topic,以及Tag来过滤需要消费的消息consumer.subscribe(MQAddrConst.TOPIC1, MQAddrConst.TAG1); // subExpression <=> tags// 注册回调实现类来处理从broker拉取回来的消息consumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {String topic = msgs.get(0).getTopic();String tags = msgs.get(0).getTags();String msgId = msgs.get(0).getMsgId();String data = new String(msgs.get(0).getBody(), StandardCharsets.UTF_8);System.out.printf("收到订阅消息: %s, %s, %s, %s, %s\r\n", Thread.currentThread().getName(), topic, tags, msgId, data);// 手动标记消息已被消费/标记该消息已经被成功消费return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});// 启动消费者实例consumer.start();System.out.printf("Consumer Started.%n");}
}

TCC分布式事务消息

Java实现
jdk1.8
rocketmq-4.3.0
生产者

package club.xxx.mq._02myrawmq;import club.xxx.mq.constants.MQAddrConst;
import club.xxx.mq.constants.OrderConst;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;/*** <p>rocketmq-4.3.0</p>* 1、Producer端发送同步消息 这种可靠性同步地发送方式使用的比较广泛,比如:重要的消息通知,短信通知。*/
public class _01MySyncProducer {public static void main(String[] args) throws Exception {// 实例化消息生产者ProducerDefaultMQProducer producer = new DefaultMQProducer(MQAddrConst.GROUP_NAME1);// 设置NameServer的地址producer.setNamesrvAddr(MQAddrConst.IP1);// 启动Producer实例producer.start();// 创建消息,并指定Topic,Tag和消息体Message msg = new Message(MQAddrConst.TOPIC1/* Topic */,MQAddrConst.TAG1 /* Tag */,(OrderConst.ORDER1).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */);
//        msg.setKeys("KEY???");// 发送消息到一个BrokerSendResult sendResult = producer.send(msg);// 通过sendResult返回消息是否成功送达System.out.printf("sync send ok: %s%n", sendResult);// 如果不再发送消息,关闭Producer实例。producer.shutdown();}
}

消费者

package club.xxx.mq._02myrawmq;import club.xxx.mq.constants.MQAddrConst;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;import java.nio.charset.StandardCharsets;
import java.util.List;/*** <p>rocketmq-4.3.0</p>* 消费者*/
public class _02MyConsumer {public static void main(String[] args) throws InterruptedException, MQClientException {// 实例化消费者DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(MQAddrConst.GROUP_NAME1);// 设置NameServer的地址consumer.setNamesrvAddr(MQAddrConst.IP1);// 订阅一个或者多个Topic,以及Tag来过滤需要消费的消息consumer.subscribe(MQAddrConst.TOPIC1, MQAddrConst.TAG1); // subExpression <=> tags// 注册回调实现类来处理从broker拉取回来的消息consumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {String topic = msgs.get(0).getTopic();String tags = msgs.get(0).getTags();String msgId = msgs.get(0).getMsgId();String data = new String(msgs.get(0).getBody(), StandardCharsets.UTF_8);System.out.printf("收到订阅消息: %s, %s, %s, %s, %s\r\n", Thread.currentThread().getName(), topic, tags, msgId, data);// 手动标记消息已被消费/标记该消息已经被成功消费return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});// 启动消费者实例consumer.start();System.out.printf("Consumer Started.%n");}
}

事务消息生产者TCC简单实现

package club.xxx.mq._02myrawmq;import club.xxx.mq.constants.MQAddrConst;
import club.xxx.mq.constants.OrderConst;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.client.producer.TransactionMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.common.RemotingHelper;/*** <p>rocketmq-4.3.0</p>* 1、Producer端发送同步消息 这种可靠性同步地发送方式使用的比较广泛,比如:重要的消息通知,短信通知。*/
public class _03MyTransactionProducer {public static void main(String[] args) throws Exception {// 实例化消息生产者ProducerTransactionMQProducer producer = new TransactionMQProducer(MQAddrConst.GROUP_NAME1);// 设置NameServer的地址producer.setNamesrvAddr(MQAddrConst.IP1);// 启动Producer实例producer.start();producer.setTransactionListener(new TransactionListener() {@Overridepublic LocalTransactionState executeLocalTransaction(Message message, Object o) {// 这里做自己的事务操作return LocalTransactionState.COMMIT_MESSAGE;}@Overridepublic LocalTransactionState checkLocalTransaction(MessageExt messageExt) {// 事务回滚操作return LocalTransactionState.COMMIT_MESSAGE;}});// 创建事务消息,并指定Topic,Tag和消息体Message msg = new Message(MQAddrConst.TOPIC1/* Topic */,MQAddrConst.TAG1 /* Tag */,(OrderConst.ORDER1).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */);
//        msg.setKeys("KEY???");// 发送消息到一个BrokerSendResult sendResult = producer.sendMessageInTransaction(msg, null);// 通过sendResult返回消息是否成功送达System.out.printf("sync send ok: %s%n", sendResult);// 如果不再发送消息,关闭Producer实例。producer.shutdown();}
}

相关文章:

SpringBoot整合RocketMQ笔记

SpringBoot版本为2.3.12.Release RocketMQ对比kafka 学习链接 https://zhuanlan.zhihu.com/p/335216381 代码实战 https://www.cnblogs.com/RedOrange/p/17401238.html Centos安装rocketmq https://blog.csdn.net/chuige2013/article/details/123783612 RocketMQ详细配置与…...

【【萌新的RiscV学习之在写代码之前对于关键路径的分析-11】】

萌新的RiscV学习之在写代码之前对于关键路径的分析-11 首先我们最简单的control 模块 全分段 因为只有分段 &#xff0c; 分开使用之后 &#xff0c; 各个阶段的具体功能才会合理使用 就像是为了后续 “气泡” 赋值 为 0 还有单独比较前递这种 EX &#xff1a; ALUOP ALUSrc …...

A. Sequence with Digits

题目&#xff1a;样例&#xff1a; 输入 8 1 4 487 1 487 2 487 3 487 4 487 5 487 6 487 7输出 42 487 519 528 544 564 588 628 思路&#xff1a; 暴力模拟题&#xff0c;看这数据范围&#xff0c;有些人可能会被唬住&#xff0c;以为是高精度或者容易超时&#xff0c;实际上…...

gitlab配置webhook限制提交注释

一、打开gitlab相关配置项 vim /etc/gitlab/gitlab.rb gitlab_shell[custom_hooks_dir] "/etc/gitlab/custom_hooks" 二、创建相关文件夹 mkdir -p /etc/gitlab/custom_hooks mkdir -p /etc/gitlab/custom_hooks/post-receive.d mkdir -p /etc/gitlab/custom_h…...

蓝桥杯Python scratch C++选拔赛stema个人如何报名?

如果不会操作&#xff0c;可以微信makytony协助。...

Cesium实现动态旋转四棱锥(2023.9.11)

Cesium实现动态悬浮旋转四棱锥效果 2023.9.11 1、引言2、两种实现思路介绍2.1 思路一&#xff1a;添加已有的四棱锥&#xff08;金字塔&#xff09;模型实现&#xff08;简单但受限&#xff09;2.2 思路二&#xff1a;自定义四棱锥几何模型实现&#xff08;复杂且灵活&#xff…...

2023最新PS(photoshop)Win+Mac免费下载安装包及教程内置AI绘画-网盘下载

2023最新PS(photoshop)WinMac免费下载安装包及教程内置AI绘画-网盘下载 2023最新PS(photoshop)免费下载安装教程来咯&#xff5e; 「PhotoShop」全套&#xff0c;winmac&#xff1a; https://pan.quark.cn/s/9d8d8ef5c400#/list/share 所有版本都有 1&#xff0c;复制链接…...

【JAVA】为什么要使用封装以及如何封装

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 前言 Java的封装指的是在一个类中将数据和方法进行封装&#xff0c;使其可以保护起来&#xff0c;只能在该类内部访问&#xff0c;而不允许外部直接访问和修改。这是Java面向对象编程的三…...

18.示例程序(编码器接口测速)

STM32标准库开发-各章节笔记-查阅传送门_Archie_IT的博客-CSDN博客https://blog.csdn.net/m0_61712829/article/details/132434192?spm1001.2014.3001.5501 main.c #include "stm32f10x.h" // Device header #include "Delay.h" #incl…...

【超详细】Fastjson 1.2.24 命令执行漏洞复现-JNDI简单实现反弹shell(CVE-2017-18349)

前言&#xff1a; 看了很多别人关于漏洞复现过程&#xff0c;很多博客过程简洁&#xff0c;有的过程过于复杂&#xff0c;比如看到写java代码&#xff0c;用javac进行编译等等。所以我想写出比较详细的漏洞复现过程。 一&#xff0c;漏洞介绍 1-1 fastjson是什么 fastjson是…...

【牛客网】JZ39 数组中出现次数超过一半的数字

题目 思路 思路1 将数组排序,再保证有结果的情况下,此时数组中间的数字就是想要的结果 思路2 在保证有结果的情况下,此时数组的的众数是数组长度的一半以上 所以我们可以通过抵消的做法来找到最终的结果 我们可以从头遍历这个数组,如果两个数不相同,则消去这两个数,最坏的…...

【Mysql】Lock wait timeout exceeded; try restarting transaction

出现这种问题通常是有事务长时间未提交导致的 可以使用以下sql 查询事务进程 然后通过 kill 线程ID 的方式 ,结束该事务 SELECTtrx_id AS 事务ID,trx_mysql_thread_id AS 线程ID,trx_state AS 事务状态,trx_started AS 开始时间,trx_tables_locked AS 锁定的表,trx_query AS …...

python生成中金所期权行权价

参考沪深300股指期权的合约表&#xff0c;写一个工具函数&#xff1a; 使用方法 def get_format_option_gap(value: float, deviation: int 0): # 根据中证1000指数获取点位"""根据标准的行权价&#xff0c;生成不同档位的期权列表&#xff0c;适合中金所:…...

CentOS7.9 安装postgresql

# 添加postgres账户 sudo groupadd postgres sudo useradd -g postgres postgres # 修改postgres账号密码 passwd postgres # 安装postgresql cd ~tar zxvf postgresql-15.3.tar.gz cd postgresql-15.3./configure --prefix/usr/local/pgsql --without-readlinemake -j4 …...

qt线程介绍

目录 介绍 线程类 QThread 方式1 方式2 案例 线程资源释放 介绍 qt为多线程提供了完美的支持&#xff0c;实现多线程一般是从从QTHread中继承定义自己的线程类&#xff0c;QT也提供了QMutexLocker,QwaitCondition等类实现线程同步&#xff0c;与Linux系统或C中的线程库类似…...

记一次用dataframe进行数据清理

总结一下dataframe读取数据库&#xff0c;以及整理数据的过程。分为三个部分&#xff1a;数据读取&#xff0c;数据整理以及数据写入。 1、数据读取 从csv读取读取数据&#xff0c;使用pandas读的read_csv函数&#xff0c;传入两个参数&#xff0c;分别是path文件路径&#x…...

《Jetpack Compose从入门到实战》 第二章 了解常用UI组件

目录 常用的基础组件文字组件图片组件按钮组件选择器组件对话框组件进度条组件 常用的布局组件布局Scaffold脚手架 列表 书附代码 Google的图标库 常用的基础组件 文字组件 Composable fun TestText() {Column(modifier Modifier.verticalScroll(state rememberScrollState…...

Vue3 引入使用 vant组件详解

目录 Vue3 引入使用 vant组件详解1.安装2.引入2.1 全局引入2.2 按需引入2.2.1 vite项目:vite.config.js2.2.2 Webpack项目&#xff1a;webpack.config.js2.2.3 配置在vue.config.js中 3.使用 Vue3 引入使用 vant组件详解 Vant是一个强大的移动端组件库&#xff0c;目前Vant 官…...

NOSQL Redis Ubuntu系列 常用的配置 及密码登录

查看Ubuntu 版本 uname -a 配置redis.conf 查看redis 是否安装成功 ps -ef | grep redis 查看redis 服务状态 service redis status 查看redis 默认安装的路径 whereis redis #sudo vim /etc/redis.conf redis 密码登录...

C语言解析GPS源数据

文章目录 一、GPS数据格式介绍二、GPS字段含义三、C语言解析数据代码3.1 解析每个字段数据3.2 解析定位数据 一、GPS数据格式介绍 GPS&#xff08;全球定位系统&#xff09;数据格式常见的是NMEA 0183格式&#xff0c;NMEA 0183格式是一种用于导航设备间传输数据的标准格式&am…...

【论文阅读】(CVPR2023)用于半监督医学图像分割的双向复制粘贴

目录 前言方法BCPMean-teacher and Traning StrategyPre-Training via Copy-PasteBidirectional Copy-Paste ImagesBidirectional Copy-Paste Supervisory Signals Loss FunctionTesting Phase 结论 先看这个图&#xff0c;感觉比较清晰。它整个的思路就是把有标签的图片和无标…...

[Linux 基础] 一篇带你了解linux权限问题

文章目录 1、Linux下的两种用户2、文件类型和访问权限&#xff08;事物属性&#xff09;2.1 Linux下的文件类型2.2 基本权限2.3 文件权限值的表示方法&#xff08;1&#xff09;字符表示方法&#xff08;2&#xff09;8进制数值表示方法 2.4 文件访问权限的相关设置方法(1) chm…...

FPGA project :HDMI

实验目标&#xff1a;驱动HdMI显示十色等宽彩条。 本实验的重点是&#xff1a; 1掌握TMDS通信协议。 2rgb565转rgb888。 3编写HDMI驱动程序。 4学会看流程图编写代码。 值得注意的事情 1注意数据与解析数据的信号&#xff08;比如传入的数据中0或者1的个数&#xff09;&…...

基于微信小程序的物流快递信息查询平台同城急送小程序(亮点:寄件、发票申请、在线聊天)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…...

idea插件推荐

目录 一、插件安装方式 file->settings->plugins->macketplace 各个版本IDE插件界面略有不同&#xff0c;不一一赘述 二、常用插件 1、Background Image Plus 推荐指数&#xff1a;★★★★☆ 这款插件并不能直接提高你的开发效率&#xff0c;但是可以让你面对的ID…...

Arcgis快速计算NDVI

Arcgis快速计算NDVI 一、问题描述 如何使用Arcgis像ENVI一样波段计算NDVI的值&#xff0c;事实上&#xff0c;Arcgis更快速一些。 二、操作步骤 首先准备好影像 打开窗口-影像分析 点击左上角 点击确定 &#xff08;发现自己使用的遥感影像不对劲&#xff0c;是计算好了…...

SpringCloud Alibaba - 基于 FeignClient 整合 Sentinel,实现“线程隔离”和“熔断降级”

目录 一、FeignClient 整合 Sentinel 1.1、整合原因 1.2、实现步骤 1.2.1、修改 OrderService 中的 application.yml 文件 1.2.2、给 FeignClient 编写失败后的降级逻辑 二、线程隔离 2.1、线程隔离的两种方式 2.1.1、线程池隔离 2.1.2、信号量隔离&#xff08;Sentin…...

Acwing 906. 区间分组

Acwing 906. 区间分组 知识点题目描述思路讲解代码展示 知识点 贪心 题目描述 思路讲解 这段代码是用来维护一个最小堆&#xff0c;以确保右边界不相交的区间被正确地保留在堆中。让我详细解释这段代码&#xff1a; heap.empty()&#xff1a;这个条件检查最小堆 heap 是否为…...

阿里云 Oss 权限控制

前言 最近公司的私有 Oss 服务满了&#xff0c;且 Oss 地址需要设置权限&#xff0c;只有当前系统的登录用户才能访问 Oss 下载地址。一开始想着用 Nginx 做个转发来着&#xff0c;Nginx 每当检测当前请求包含特定的 Oss 地址就转发到我们的统一鉴权接口上去&#xff0c;但是紧…...

CSS详细基础(六)边框样式

本期是CSS基础的最后一篇~ 目录 一.border属性 二.边框属性复合写法 三.CSS修改表格标签 四.内边距属性 五.外边距属性 六.其他杂例 1.盒子元素水平居中 2.清除网页内外元素边距 3.外边距的合并与塌陷 4.padding不会撑大盒子的情况 七.综合案例——新浪导航栏仿真 …...

网站右侧二维码/外贸独立站怎么建站

P3909 异或之积 题目描述 对于A_1,A_2,A_3,\cdots,A_NA1​,A2​,A3​,⋯,AN​&#xff0c;求 (6\times \sum_{i1}^N\sum_{ji1}^N\sum_{kj1}^N A_i\times A_j\times A_k)\ mod\ (10^97)(6∑i1N​∑ji1N​∑kj1N​Ai​Aj​Ak​) mod (1097) 的值。 输入输出格式 输入格式&#xf…...

展馆设计施工一体化/外贸建站seo

近日&#xff0c;北京新数科技有限公司旗下核心软件产品ShinData DMP数据库云管理平台、ShinSight Pro监控和性能分析软件在华为云严选商城正式上架。两款产品完成和华为云GaussDB数据库的兼容性认证&#xff0c;为用户数据库管理体系建设提供快速落地的解决方案&#xff0c;助…...

一手房哪个网站做信息效果好/百度推广代理商有哪些

一开始是碰到没有caffe/caffe.hpp文件的问题&#xff0c;不知道怎么弄。通过百度&#xff0c;知道了在makefile文件里加入头文件路径和库文件路径就行。 首先是caffe.pb.h丢失问题&#xff0c;解决方法&#xff1a;https://github.com/muupan/dqn-in-the-caffe/issues/3 protoc…...

合肥网站制作哪家有名/网站设计公司模板

该书籍PDF下载地址&#xff1a;http://download.csdn.net/download/muyeju/10001473 52.推荐使用String直接赋值 通过String直接创建字符串的过程&#xff1a;创建一个字符串时&#xff0c;首先检查字符串常量池中有没有与字面值相等的字符串&#xff0c;如果有&#xff0c;就不…...

响应式网站用什么软件做效果/广州百度竞价开户

最近有一些烦&#xff0c;虚拟机跑代码&#xff0c;跑着跑着存储不够&#xff0c;我就去扩大磁盘&#xff0c;结果虚拟机崩了&#xff0c;试了一上午的修复办法&#xff0c;仍然无法修复&#xff0c;于是只能重装虚拟机&#xff0c;配置各种环境&#xff0c;这里总结一下Ubuntu…...

字母logo设计网站/搜索引擎推广的费用

2019独角兽企业重金招聘Python工程师标准>>> 控制输出 __str__() 自定义控制信息 # -*- coding:utf8 -*- class Text1: #定义类1pass class Text2: #定义类2def __str__(self): …...