ActiveMQ持久化方式(转)
消息持久性对于可靠消息传递来说应该是一种比较好的方法,有了消息持久化,即使发送者和接受者不是同时在线或者消息中心在发送者发送消息后宕机了,在消息 中心重新启动后仍然可以将消息发送出去,如果把这种持久化和ReliableMessaging结合起来应该是很好的保证了消息的可靠传送。
消息持久性的原理很简单,就是在发送者将消息发送出去后,消息中心首先将消息存储到本地数据文件、内存数据库或者远程数据库等,然后试图将消息发送 给接收者,发送成功则将消息从存储中删除,失败则继续尝试。消息中心启动以后首先要检查制定的存储位置,如果有未发送成功的消息,则需要把消息发送出去。
ActiveMQ持久化方式:AMQ、KahaDB、JDBC、LevelDB。
1、AMQ
AMQ是一种文件存储形式,它具有写入速度快和容易恢复的特点。消息存储在一个个文件中,文件的默认大小为32M,如果一条消息的大小超过了 32M,那么这个值必须设置大一点。当一个存储文件中的消息已经全部被消费,那么这个文件将被标识为可删除,在下一个清除阶段,这个文件被删除。AMQ适用于ActiveMQ5.3之前的版本。默认配置如下:
1
2
3
|
< persistenceAdapter >
< amqPersistenceAdapter directory = "activemq-data" maxFileLength = "32mb" />
</ persistenceAdapter >
|
属性如下:
属性名称 |
默认值 |
描述 |
directory |
activemq-data |
消息文件和日志的存储目录 |
useNIO |
true |
使用NIO协议存储消息 |
syncOnWrite |
false |
同步写到磁盘,这个选项对性能影响非常大 |
maxFileLength |
32Mb |
一个消息文件的大小 |
persistentIndex |
true |
消息索引的持久化,如果为false,那么索引保存在内存中 |
maxCheckpointMessageAddSize |
4kb |
一个事务允许的最大消息量 |
cleanupInterval |
30000 |
清除操作周期,单位ms |
indexBinSize |
1024 |
索引文件缓存页面数,缺省为1024,当amq扩充或者缩减存储时,会锁定整个broker,导致一定时间的阻塞,所以这个值应该调整到比较大,但是代码中实现会动态伸缩,调整效果并不理想。 |
indexKeySize |
96 |
索引key的大小,key是消息ID |
indexPageSize |
16kb |
索引的页大小 |
directoryArchive |
archive |
存储被归档的消息文件目录 |
archiveDataLogs |
false |
当为true时,归档的消息文件被移到directoryArchive,而不是直接删除 |
2、KahaDB
KahaDB是基于文件的本地数据库储存形式,虽然没有AMQ的速度快,但是它具有强扩展性,恢复的时间比AMQ短,从5.4版本之后KahaDB做为默认的持久化方式。默认配置如下:
KahaDB的属性如下:
属性名称 |
默认值 |
描述 |
directory |
activemq-data |
消息文件和日志的存储目录 |
indexWriteBatchSize |
1000 |
一批索引的大小,当要更新的索引量到达这个值时,更新到消息文件中 |
indexCacheSize |
10000 |
内存中,索引的页大小 |
enableIndexWriteAsync |
false |
索引是否异步写到消息文件中 |
journalMaxFileLength |
32mb |
一个消息文件的大小 |
enableJournalDiskSyncs |
true |
是否讲非事务的消息同步写入到磁盘 |
cleanupInterval |
30000 |
清除操作周期,单位ms |
checkpointInterval |
5000 |
索引写入到消息文件的周期,单位ms |
ignoreMissingJournalfiles |
false |
忽略丢失的消息文件,false,当丢失了消息文件,启动异常 |
checkForCorruptJournalFiles |
false |
检查消息文件是否损坏,true,检查发现损坏会尝试修复 |
checksumJournalFiles |
false |
产生一个checksum,以便能够检测journal文件是否损坏。 |
5.4版本之后有效的属性: |
||
archiveDataLogs |
false |
当为true时,归档的消息文件被移到directoryArchive,而不是直接删除 |
directoryArchive |
null |
存储被归档的消息文件目录 |
databaseLockedWaitDelay |
10000 |
在使用负载时,等待获得文件锁的延迟时间,单位ms |
maxAsyncJobs |
10000 |
同个生产者产生等待写入的异步消息最大量 |
concurrentStoreAndDispatchTopics |
false |
当写入消息的时候,是否转发主题消息 |
concurrentStoreAndDispatchQueues |
true |
当写入消息的时候,是否转发队列消息 |
5.6版本之后有效的属性: |
||
archiveCorruptedIndex |
false |
是否归档错误的索引 |
每个KahaDB的实例都可以配置单独的适配器,如果没有目标队列提交给filteredKahaDB,那么意味着对所有的队列有效。如果一个队列没有对应的适配器,那么将会抛出一个异常。配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
< persistenceAdapter >
< mKahaDBdirectory = "${activemq.base}/data/kahadb" >
< filteredPersistenceAdapters >
<!-- match all queues -->
< filteredKahaDBqueue =">">
< persistenceAdapter >
< kahaDBjournalMaxFileLength = "32mb" />
</ persistenceAdapter >
</ filteredKahaDB >
<!-- match all destinations -->
< filteredKahaDB >
< persistenceAdapter >
< kahaDBenableJournalDiskSyncs = "false" />
</ persistenceAdapter >
</ filteredKahaDB >
</ filteredPersistenceAdapters >
</ mKahaDB >
</ persistenceAdapter >
|
如果filteredKahaDB的perDestination属性设置为true,那么匹配的目标队列将会得到自己对应的KahaDB实例。配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
< persistenceAdapter >
< mKahaDBdirectory = "${activemq.base}/data/kahadb" >
< filteredPersistenceAdapters >
<!-- kahaDB per destinations -->
< filteredKahaDB perDestination = "true" >
< persistenceAdapter >
< kahaDBjournalMaxFileLength = "32mb" />
</ persistenceAdapter >
</ filteredKahaDB >
</ filteredPersistenceAdapters >
</ mKahaDB >
</ persistenceAdapter >
|
3、JDBC
可以将消息存储到数据库中,例如:Mysql、SQL Server、Oracle、DB2。
配置JDBC适配器:
1
2
3
|
< persistenceAdapter >
< jdbcPersistenceAdapterdataSource = "#mysql-ds" createTablesOnStartup = "false" />
</ persistenceAdapter >
|
dataSource指定持久化数据库的bean,createTablesOnStartup是否在启动的时候创建数据表,默认值是true,这样每次启动都会去创建数据表了,一般是第一次启动的时候设置为true,之后改成false。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
Mysql持久化bean:
< bean id = "mysql-ds" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" >
< property name = "driverClassName" value = "com.mysql.jdbc.Driver" />
< property name = "url" value = "jdbc:mysql://localhost/activemq?relaxAutoCommit=true" />
< property name = "username" value = "activemq" />
< property name = "password" value = "activemq" />
< property name = "poolPreparedStatements" value = "true" />
</ bean >
SQL Server持久化bean:
< bean id = "mssql-ds" class = "net.sourceforge.jtds.jdbcx.JtdsDataSource" destroy-method = "close" >
< property name = "serverName" value = "SERVERNAME" />
< property name = "portNumber" value = "PORTNUMBER" />
< property name = "databaseName" value = "DATABASENAME" />
< property name = "user" value = "USER" />
< property name = "password" value = "PASSWORD" />
</ bean >
Oracle持久化bean:
< bean id = "oracle-ds" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" >
< property name = "driverClassName" value = "oracle.jdbc.driver.OracleDriver" />
< property name = "url" value = "jdbc:oracle:thin:@10.53.132.47:1521:activemq" />
< property name = "username" value = "activemq" />
< property name = "password" value = "activemq" />
< property name = "maxActive" value = "200" />
< property name = "poolPreparedStatements" value = "true" />
</ bean >
DB2持久化bean:
< bean id = "db2-ds" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" >
< property name = "driverClassName" value = "com.ibm.db2.jcc.DB2Driver" />
< property name = "url" value = "jdbc:db2://hndb02.bf.ctc.com:50002/activemq" />
< property name = "username" value = "activemq" />
< property name = "password" value = "activemq" />
< property name = "maxActive" value = "200" />
< property name = "poolPreparedStatements" value = "true" />
</ bean >
|
4、LevelDB
这种文件系统是从ActiveMQ5.8之后引进的,它和KahaDB非常相似,也是基于文件的本地数据库储存形式,但是它提供比KahaDB更快的持久性。与KahaDB不同的是,它不是使用传统的B-树来实现对日志数据的提前写,而是使用基于索引的LevelDB。
默认配置如下:
?
1
2
3
|
< persistenceAdapter >
< levelDBdirectory = "activemq-data" />
</ persistenceAdapter >
|
属性如下:
属性名称 |
默认值 |
描述 |
directory |
"LevelDB" |
数据文件的存储目录 |
readThreads |
10 |
系统允许的并发读线程数量 |
sync |
true |
同步写到磁盘 |
logSize |
104857600 (100 MB) |
日志文件大小的最大值 |
logWriteBufferSize |
4194304 (4 MB) |
日志数据写入文件系统的最大缓存值 |
verifyChecksums |
false |
是否对从文件系统中读取的数据进行校验 |
paranoidChecks |
false |
尽快对系统内部发生的存储错误进行标记 |
indexFactory |
org.fusesource.leveldbjni.JniDBFactory, org.iq80.leveldb.impl.Iq80DBFactory |
在创建LevelDB索引时使用 |
indexMaxOpenFiles |
1000 |
可供索引使用的打开文件的数量 |
indexBlockRestartInterval |
16 |
Number keys between restart points for delta encoding of keys. |
indexWriteBufferSize |
6291456 (6 MB) |
内存中索引数据的最大值 |
indexBlockSize |
4096 (4 K) |
每个数据块的索引数据大小 |
indexCacheSize |
268435456 (256 MB) |
使用缓存索引块允许的最大内存 |
indexCompression |
snappy |
适用于索引块的压缩类型 |
logCompression |
none |
适用于日志记录的压缩类型 |
5、 下面详细介绍一下如何将消息持久化到Mysql数据库中
Ø 需要将mysql的驱动包放置到ActiveMQ的lib目录下
Ø 修改activeMQ的配置文件:
?
1
2
3
|
< persistenceAdapter >
< jdbcPersistenceAdapter dataDirectory = "${activemq.base}/data" dataSource = "#mysql-ds" createTablesOnStartup = "false" />
</ persistenceAdapter >
|
在配置文件中的broker节点外增加:
?
1
2
3
4
5
6
7
8
|
< beanid = "mysql-ds" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" >
< propertyname = "driverClassName" value = "com.mysql.jdbc.Driver" />
< property name = "url" value = "jdbc:mysql://localhost:3306/activemq?relaxAutoCommit=true" />
< property name = "username" value = "root" />
< property name = "password" value = "root" />
< property name = "maxActive" value = "200" />
< propertyname = "poolPreparedStatements" value = "true" />
</ bean >
|
从配置中可以看出数据库的名称是activemq,需要手动在MySql中建立这个数据库。
然后重新启动activeMQ,会发现activemq多了三张表:
1:activemq_acks
2:activemq_lock
3:activemq_msgs
Ø 点到点类型
Sender类:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Sender {
private static final int SEND_NUMBER = 2000 ;
public static void main(String[] args) {
// ConnectionFactory :连接工厂,JMS用它创建连接
ConnectionFactory connectionFactory;
// Connection :JMS客户端到JMS Provider的连接
Connection connection = null ;
// Session:一个发送或接收消息的线程
Session session;
// Destination :消息的目的地;消息发送给谁.
Destination destination;
// MessageProducer:消息发送者
MessageProducer producer;
// TextMessage message;
// 构造ConnectionFactory实例对象,此处采用ActiveMq的实现
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616" );
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
//启动
connection.start();
//获取操作连接
session = connection.createSession( false , Session.AUTO_ACKNOWLEDGE);
//获取session,FirstQueue是一个服务器的queue destination = session.createQueue("FirstQueue");
// 得到消息生成者【发送者】
producer = session.createProducer(destination);
//设置不持久化
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
//构造消息
sendMessage(session, producer);
//session.commit();
connection.close();
}
catch (Exception e){
e.printStackTrace();
} finally {
if ( null != connection){
try {
connection.close();
} catch (JMSException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
}
public static void sendMessage(Session session, MessageProducer producer) throws Exception{
for ( int i= 1 ; i<=SEND_NUMBER; i++){
TextMessage message = session.createTextMessage( "ActiveMQ发送消息" +i);
System.out.println( "发送消息:ActiveMQ发送的消息" +i);
producer.send(message);
}
}
}
|
Receiver类:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Receiver {
public static void main(String[] args) {
// ConnectionFactory :连接工厂,JMS用它创建连接
ConnectionFactory connectionFactory;
// Connection :JMS客户端到JMS Provider的连接
Connection connection = null ;
// Session:一个发送或接收消息的线程
Session session;
// Destination :消息的目的地;消息发送给谁.
Destination destination;
// 消费者,消息接收者
MessageConsumer consumer;
connectionFactory = newActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616" );
try {
//得到连接对象
connection =connectionFactory.createConnection();
// 启动
connection.start();
// 获取操作连接
session = connection.createSession( false ,
Session.AUTO_ACKNOWLEDGE);
// 创建Queue
destination = session.createQueue( "FirstQueue" );
consumer =session.createConsumer(destination);
while ( true ){
//设置接收者接收消息的时间,为了便于测试,这里定为100s
TextMessagemessage = (TextMessage)consumer.receive( 100000 );
if ( null != message){
System.out.println( "收到消息" +message.getText());
} else break ;
}
} catch (Exception e){
e.printStackTrace();
} finally {
try {
if ( null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
}
|
测试:
测试一:
A、 先运行Sender类,待运行完毕后,运行Receiver类
B、 在此过程中activemq数据库的activemq_msgs表中没有数据
C、 再次运行Receiver,消费不到任何信息
测试二:
A、 先运行Sender类
B、 重启电脑
C、 运行Receiver类,无任何信息被消费
测试三:
A、 把Sender类中的producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);改为producer.setDeliveryMode(DeliveryMode.PERSISTENT);
B、 先运行Sender类,待运行完毕后,运行Receiver类
C、 在此过程中activemq数据库的activemq_msgs表中有数据生成,运行完Receiver类后,数据清除
测试四:
A、 把Sender类中的producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);改为producer.setDeliveryMode(DeliveryMode.PERSISTENT);
B、 运行Sender类
C、 重启电脑
D、 运行Receiver类,有消息被消费
结论:
通过以上测试,可以发现,在P2P类型中当DeliveryMode设置为NON_PERSISTENCE时,消息被保存在内存中,而当 DeliveryMode设置为PERSISTENCE时,消息保存在broker的相应的文件或者数据库中。而且P2P中消息一旦被Consumer消 费就从broker中删除。
Ø 发布/订阅类型
Sender类:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Sender {
private static final int SEND_NUMBER = 100 ;
public static void main(String[] args) {
// ConnectionFactory :连接工厂,JMS用它创建连接
ConnectionFactory connectionFactory;
// Connection :JMS客户端到JMS Provider的连接
Connection connection = null ;
// Session:一个发送或接收消息的线程
Session session;
// MessageProducer:消息发送者
MessageProducer producer;
// TextMessage message;
// 构造ConnectionFactory实例对象,此处采用ActiveMq的实现
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616" );
try {
//得到连接对象
connection = connectionFactory.createConnection();
//启动
connection.start();
//获取操作连接
session = connection.createSession( false , Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic( "MQ_test" );
// 得到消息生成者【发送者】
producer = session.createProducer(topic);
//设置持久化
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
//构造消息
sendMessage(session, producer);
//session.commit();
connection.close();
}
catch (Exception e){
e.printStackTrace();
} finally {
if ( null != connection){
try {
connection.close();
} catch (JMSException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
}
public static void sendMessage(Session session, MessageProducer producer) throws Exception{
for ( int i= 1 ; i<=SEND_NUMBER; i++){
TextMessage message = session.createTextMessage( "ActiveMQ发送消息" +i);
System.out.println( "发送消息:ActiveMQ发送的消息" +i);
producer.send(message);
}
}
}
|
Receiver类:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Receiver {
public static void main(String[] args) {
// ConnectionFactory :连接工厂,JMS用它创建连接
ConnectionFactory connectionFactory;
// Connection :JMS客户端到JMS Provider的连接
Connection connection = null ;
// Session:一个发送或接收消息的线程
Session session;
// 消费者,消息接收者
MessageConsumer consumer;
connectionFactory = newActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616" );
try {
// 构造从工厂得到连接对象
connection =connectionFactory.createConnection();
connection.setClientID( "clientID001" );
// 启动
connection.start();
// 获取操作连接
session = connection.createSession( false ,
Session.AUTO_ACKNOWLEDGE);
// 获取session
Topic topic = session.createTopic( "MQ_test" );
// 得到消息生成者【发送者】
consumer = session.createDurableSubscriber(topic, "MQ_sub" );
while ( true ){
//设置接收者接收消息的时间,为了便于测试,这里谁定为100s
TextMessagemessage = (TextMessage)consumer.receive( 100000 );
if ( null != message){
System.out.println( "收到消息" +message.getText());
} else break ;
}
} catch (Exception e){
e.printStackTrace();
} finally {
try {
if ( null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
}
|
测试:
测试一:
A、先启动Sender类
B、再启动Receiver类
C、结果无任何记录被订阅
测试二:
A、先启动Receiver类,让Receiver在相关主题上进行订阅
B、停止Receiver类,再启动Sender类
C、待Sender类运行完成后,再启动Receiver类
D、结果发现相应主题的信息被订阅
http://www.cnblogs.com/adolfmc/p/4462580.html
ActiveMQ持久化方式(转)相关推荐
- ActiveMQ持久化方式
ActiveMQ持久化方式 发表于8个月前(2014-09-04 15:55) 阅读(686) | 评论(0) 17人收藏此文章, 我要收藏 赞1 慕课网,程序员升职加薪神器,点击免费学习 摘要 ...
- 消息中间件ActiveMQ 5:可持久化方式AMQ和KahaDB
文章目录 ActiveMQ 的持久化方式 一.需要进行消息持久化的原因 二.持久化方式 1.AMQ message Store(了解) 2.KahaDB消息存储(默认) ActiveMQ 的持久化方式 ...
- Redis 缓存穿透、雪崩、缓存数据库不一致、持久化方式、分布式锁、过期策略
1. Redis 缓存穿透 1.1 Redis 缓存穿透概念 访问了不存在的 key,缓存未命中,请求会穿透到 DB,量大时可能会对 DB 造成压力导致服务异常. 由于不恰当的业务功能实现,或者外部恶 ...
- redis的两种持久化方式详解
一.背景 在实际开发中,为了保证数据的完整性,防止数据丢失,我们除了在原有的传统数据库保存数据的同时,最好是再用redis持久化再保存一次数据.如果仅仅是使用redis而不进行持久化配置的话,当red ...
- 012_Redis的aof持久化方式
1. appendonly file(缩写aof)的持久化方式, 使用aof时, Redis会将每次更新操作后进行日志记录, 当Redis重新启动时会重新执行文件中保存的写命令来在内存中重建这个数据库 ...
- redis同步效率秒_redis过期策略、内存淘汰策略、持久化方式、主从复制
一.Redis的过期策略以及内存淘汰策略: 1.过期策略:定期删除+惰性删除: ①定期删除:redis默认每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果有过期就删除.注意这里 ...
- Redis专题-持久化方式
很多时候我们为了缓解数据库的压力,都会使用缓存来作为数据的存储方式,最常用的就是使用redis.将热点数据缓存在redis中可以有效缓解数据库的压力.但是如果redis挂了那些重要的数据怎么办?red ...
- Redis两种持久化方式(RDBAOF)
爬虫和转载请注明原文地址;博客园蜗牛:http://www.cnblogs.com/tdws/p/5754706.html Redis的持久化过程中并不需要我们开发人员过多的参与,我们要做的是什么呢? ...
- ActiveMQ持久化到mysql
ActiveMQ持久化到mysql 配置 1.找到apache-activemq-5.15.2/examples/conf下面的activemq-jdbc-performance.xml 2.打开ac ...
最新文章
- Qt 事件系统的解读
- 项望烽:iOS App开发的那些事儿
- Linux shell 条件判断if
- 1949年-2021年历史县级行政区划分布数据 中国行政村边界数据、乡镇街道边界、行政区划边界
- 好架构师都是写代码写出来的
- restful接口实战 更新用put 新增用post 获取get 删除detele
- Ubuntu终端打不开
- 当时光匆匆才知道梦想遥不可及
- 不到3000块钱,如何支撑起每月500万次访问量及80TB流量的网站?
- 随手查_python
- 腾讯云 mysql 远程_腾讯云服务器 MySQL 远程连接设置
- caj打印PDF提示打印超范围应该怎么办?
- 电脑速度慢的原因及解决方法
- 为什么说 Compose 的声明式代码最简洁 ?Compose/React/Flutter/SwiftUI 语法对比
- 网络安全与网站安全及计算机安全:如何利用Kali Linux的MSF进行MS10-046安全演练
- Verilog——补码转换
- 庆阳顺盛铝合金模板CAD系统
- html倒计时还有多少天,2020年只剩70天 2021年倒计时还有多少天?
- 刘宇凡:什么是内链?什么是外链?
- Python EFZ文件 气象_你要偷偷的学Python,然后惊呆所有人(第四天) - python阿喵
热门文章
- SCI论文需要什么程度的统计学
- 计算机网络实验二:应用层和传输层网络协议分析
- 公共界面_小区公共区域广告收益究竟归谁?
- macOS配置Visual Studio Code开发Java项目
- CentOS 7安装教程
- 神经网络 | 单层感知器从0到1(附Python源代码)
- 安装 | Windows 10下基于Anaconda的TensorFlow详细安装步骤(续)——Pycharm运行tensorflow
- msp430g2553串口接受数据_MSP430G2553串口通信
- 基于pygame的射击小游戏制作(五)绘制开始按钮
- android 闪退解决方案,Android apk无法安装及闪退问题解决办法