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入门之四--ActiveMQ持久化方式
消息持久性对于可靠消息传递来说应该是一种比较好的方法,有了消息持久化,即使发送者和接受者不是同时在线或者消息中心在发送者发送消息后宕机了,在消息中心重新启动后仍然可以将消息发送出去,如果把这种持久化和 ...
- ActiveMQ持久化及测试(转)
转:http://blog.csdn.net/xyw_blog/article/details/9128219 ActiveMQ持久化 消息持久性对于可靠消息传递来说应该是一种比较好的方法,有了消息持 ...
- ActiveMQ持久化消息
ActiveMQ的另一个问题就是只要是软件就有可能挂掉,挂掉不可怕,怕的是挂掉之后把信息给丢了,所以本节分析一下几种持久化方式: 一.持久化为文件 ActiveMQ默认就支持这种方式,只要在发消息时设 ...
- ActiveMQ持久化消息(转)
ActiveMQ的另一个问题就是只要是软件就有可能挂掉,挂掉不可怕,怕的是挂掉之后把信息给丢了,所以本节分析一下几种持久化方式: 一.持久化为文件 ActiveMQ默认就支持这种方式,只要在发消息时设 ...
- ActiveMQ持久化到MySQL以及使用SSL协议通讯
最近公司事情稍微少了点,研究下怎么优化几个系统的交互,因为我们目前使用的是长链接的同步接口,就考虑用下MQ来处理下.由于公司对安全有要求且和CA业务有关,则使用了SSL协议.此文使用的是Activem ...
- ActiveMQ持久化
ActiveMQ中,持久化是值对消息数据的持久化.在ActiveMQ中,默认的消息是保存在内存中的.当内存容量不足的时候,或ActiveMQ正常关闭的时候,会将内存中的未处理的消息持久化到磁盘中.具体 ...
- Activemq持久化之kahadb特性
介绍数据的持久化是很多系统都会涉及到的一个问题,尤其是redis,activemq这些数据主要是存储在内存中的.既然存在内存中,就会面临宕机时数据丢失的风险.这一问题的解决方案就是通过某种方式将数据写 ...
- Redis两种持久化方式(RDB&AOF)
爬虫和转载请注明原文地址;博客园蜗牛:http://www.cnblogs.com/tdws/p/5754706.html Redis所需内存 超过可用内存怎么办 Redis修改数据多线程并发—Red ...
随机推荐
- Spark1.5.1的安装与部署 每一步详细测试截图
转载或借鉴请注明转自 http://www.cnblogs.com/FG123/p/5101733.html 谢谢! 1.安装Spark之前需要先安装Java,Scala及Python(个人喜欢用p ...
- JAVA排序(二) Comparator接口
接着说关于Comparator接口, java.util Interface Comparator<T>(该泛型指定的是被比较的类),使用该接口不需要在待比较类进行比较操作,即在不修改源码 ...
- Phonegap-----Media
Everything in the code: <!DOCTYPE html> <html> <head> <title>Media Example&l ...
- git 解决冲突的办法
在项目中使用git管理,冲突是在所难免的.假设没办法解决冲突,能够试试这个办法. 第一步.对project进行备份,最好是复制到其它目录中 第二步.在cmd命令栏上,进入到project文件夹下.这里 ...
- 国外稳定的免费PHP空间byethost.com
byethost.com是一个老牌的免费空间商,从2006年起就開始提供免费空间了,其免费服务很稳定(看完下文你就知道有多稳定了). 提供5.5G的免费空间,200G的月流量,能够绑定50个域名,也能 ...
- js实现无限级树形导航列表
- Hadoop集群的安装与配置(centos 6.5)
一.Hadoop搭建准备(centOs6.5 且每个系统都要有同一个用户,如:hadoop) 1.IP的配置 包括Master和Slaves的IP配置,之间能够相互ping通: 例如: ...
- MVC中Controller里写alert的问题
controller: Viewbag.a=true; 页面中 @if(Viewbag.a!=null) { <script> alert('XXX'); </script> ...
- mongodb副本集自动切换修复节点解决方案
副本集部署 1.启动mongod 在每台运行mongod服务的机器上增加配置文件/etc/mongodb-rs.conf,内容为: [root@MongodbF-A etc]# vi /etc/mon ...
- GREENPLUM简单介绍
原帖:http://www.itpub.net/thread-1409964-1-1.html 什么是GREENPLUM? 对于非常多IT人来说GREENPLUM是个陌生的名字.简单的说它就是一个与O ...