Hi,
I have looked to the purge mechanism to try to understand why it takes so
much time to clean a queue.

I have noticed something :

####
CLASS org.apache.activemq.store.jdbc.Statements
public String getFindMessageSequenceIdStatement() {
    if (findMessageSequenceIdStatement == null) {
        findMessageSequenceIdStatement = "SELECT ID, PRIORITY FROM " +
getFullMessageTableName()
            + " WHERE MSGID_PROD=? AND MSGID_SEQ=? AND CONTAINER=?";
    }
    return findMessageSequenceIdStatement;
}

public String getRemoveMessageStatement() {
        if (removeMessageStatement == null) {
            removeMessageStatement = "DELETE FROM " +
getFullMessageTableName() + " WHERE ID=?";
        }
        return removeMessageStatement;
    }
###

###
CLASS org.apache.activemq.store.jdbc.JDBCMessageStore

private long getStoreSequenceIdForMessageId(MessageId messageId) throws
IOException {
        long result = -1;
        TransactionContext c = persistenceAdapter.getTransactionContext();
        try {
            result = adapter.getStoreSequenceId(c, destination,
messageId)[0];
        } catch (SQLException e) {
            JDBCPersistenceAdapter.log("JDBC Failure: ", e);
            throw IOExceptionSupport.create("Failed to get store sequenceId
for messageId: " + messageId +", on: " + destination + ". Reason: " + e, e);
        } finally {
            c.close();
        }
        return result;
    }

public void removeMessage(ConnectionContext context, MessageAck ack) throws
IOException {

        long seq = getStoreSequenceIdForMessageId(ack.getLastMessageId());

        // Get a connection and remove the message from the DB
        TransactionContext c =
persistenceAdapter.getTransactionContext(context);
        try {
            adapter.doRemoveMessage(c, seq);
        } catch (SQLException e) {
            JDBCPersistenceAdapter.log("JDBC Failure: ", e);
            throw IOExceptionSupport.create("Failed to broker message: " +
ack.getLastMessageId() + " in container: " + e, e);
        } finally {
            c.close();
        }
    }
###

Could it be better to use only one request to remove a row, which is :
"DELETE FROM " + getFullMessageTableName() + " WHERE MSGID_PROD=? AND
MSGID_SEQ=? AND CONTAINER=?" ?
or is there a case where it is not working ?

Could it be better to create an index based on MSGID_PROD, MSGID_SEQ
and CONTAINER
(this index could be UNIQUE ?) ?

I have checked that it takes 1min30 to dequeue my 16000 messages using the
purge method with these two modifications. I noticed that the page size is
200 messages and it waits every 200 row to read from the database to be able
to purge it, i never noticed this limit before.

So it increases the rate from about 40 msgs/sec to about 170 msgs/sec to
purge a queue (does it can also apply to other components reading the queue
?).

I don't have enough JMS broker and database mechanism knowledges to say if
it is a good or a bad idea.

Anyone can help me for this ?

Thanks for answers.
Hervé

2011/7/29 Hervé BARRAULT <herve.barra...@gmail.com>

> Hi,
> I am using ActiveMQ 5.4.0 with persistence (using an oracle 11g R2 server)
> and i am doing some performance tests.
>
> I'm sending 16000 messages through web services (using one port) and it
> takes about 1 min to manage all messages and fill the JMS queue.
>
> When i use a consumer to dequeue this queue (without adding new messages)
> and fill another one, it takes about 6 min and 30 seconds. I was expecting
> that i have some code which slow down the consumption.
>
> But i have tried to use the purge method and it takes the same time.
>
> Is there a way to increase the consumption rate ?
>
> Thanks for answers.
>

Reply via email to