-
1. Re: Performance numbers
adrian.brock Jun 24, 2003 7:19 AM (in response to speakmon)The numbers I get are (using local sockets):
persistent 300 msgs/sec ~ 1 Million per hour
non-persistent 3000 msgs/sec ~ 10 Million per hour
This is using jdbc2/hsqldb as the persistence manager
That is about what I would expect, about a
factor of 10 between the serialize/don't serialize option.
Regards,
Adrian -
2. Re: Performance numbers
adrian.brock Jun 24, 2003 7:21 AM (in response to speakmon)Forgot to mention:
1GHz single processor pentium III,
java running with the default 64M ram.
Regards,
Adrian -
3. Re: Performance numbers
speakmon Jun 24, 2003 12:54 PM (in response to speakmon)Those numbers are more in line with what I expected. Is there any reason you can think of why mine would be so slow?
I'm including the small test program I'm using. Am I doing something really silly? (I'm using the OIL2 ConnectionFactory).
Thanks again,
--Ben
/*
* JMSTester.java
*
* Created on June 23, 2003, 11:05 AM
*/
import java.util.Date;
import java.util.Hashtable;
import javax.naming.*;
import javax.jms.*;
/**
*
* @author bspeakmo
*/
public final class JMSTester {
private static Context context;
private static QueueConnectionFactory factory;
private static QueueConnection queueConn;
private static QueueSession qSession;
private static Queue smsQueue;
private static QueueSender sender;
/** Creates a new instance of JMSTester */
public JMSTester() {
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
Hashtable jndi = new Hashtable();
jndi.put(Context.PROVIDER_URL, "jnp://localhost:9888/");
jndi.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
jndi.put(Context.URL_PKG_PREFIXES, "org.jnp.interfaces.NamingContextFactory");
Context context = new InitialContext(jndi);
System.out.println("JNDI context initialized");
// get JMS objects and queues
factory = (QueueConnectionFactory) context.lookup("ConnectionFactory");
queueConn = factory.createQueueConnection();
qSession = queueConn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
smsQueue = (Queue) context.lookup("queue/sms_queue_mo_mobliss");
sender = qSession.createSender(smsQueue);
sender.setDeliveryMode(DeliveryMode.PERSISTENT);
System.out.println("JMS connection established");
System.out.println("Starting test run: " + new Date().toString());
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
TextMessage textMsg = qSession.createTextMessage("test message");
sender.send(textMsg);
}
System.out.println("Run complete: " + new Date().toString());
long elapsedSeconds = (System.currentTimeMillis() - start) / 1000;
System.out.println("Sent 10000 messages at " + ((float) 10000 / elapsedSeconds) + " msgs/sec");
} catch (Exception e) {
e.printStackTrace();
}
}
} -
4. Re: Performance numbers
genman Jun 24, 2003 3:58 PM (in response to speakmon)
It depends on your network needs, but I find the vanilla OIL service to be fastest for remote access. Also, performance depends on your persistance manager configuration, DB and/or filesystem and disks.
I see you're from Mobliss, eh? -
5. Re: Performance numbers
speakmon Jun 24, 2003 7:48 PM (in response to speakmon)After another day of tweaking I'm still no closer. I've included relevant config below; am I doing anything wrong with Jboss?
Thanks very much,
--Ben
MSSQLDB-ds.xml:
----------------------
<xa-datasource>
<jndi-name>MSSQLXADS</jndi-name>
<xa-datasource-class>com.jnetdirect.jsql.JSQLXADataSource</xa-datasource-class>
<xa-datasource-property name="ServerName">dbServerName</xa-datasource-property>
<xa-datasource-property name="Database">dbName</xa-datasource-property>
<user-name>dbUser</user-name>
dbPass
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
<min-pool-size>5</min-pool-size>
<max-pool-size>100</max-pool-size>
<blocking-timeout-millis>5000</blocking-timeout-millis>
<idle-timeout-minutes>15</idle-timeout-minutes>
</xa-datasource>
jbossmq-service.xml:
---------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: jbossmq-service.xml,v 1.10.2.9 2003/04/24 12:51:10 ejort Exp $ -->
<!-- ==================================================================== -->
<!-- JBossMQ -->
<!-- ==================================================================== -->
<!-- ==================================================================== -->
<!-- Invocation Layers -->
<!-- ==================================================================== -->
<!--
| InvocationLayers are the different transport methods that can
| be used to access the server.
-->
<!--
<depends optional-attribute-name="Invoker">jboss.mq:service=Invoker
RMIConnectionFactory
RMIXAConnectionFactory
60000
-->
<!--
<depends optional-attribute-name="Invoker">jboss.mq:service=Invoker
ConnectionFactory
XAConnectionFactory
8090
60000
true
-->
<depends optional-attribute-name="Invoker">jboss.mq:service=Invoker
ConnectionFactory
XAConnectionFactory
8092
60000
true
<!--
New Unified Invocation Layer as of 3.0.7 - experimental
Synchronization moved to the message level to improve throughput
-->
<!--
<depends optional-attribute-name="Invoker">jboss.mq:service=Invoker
UIL2ConnectionFactory
UIL2XAConnectionFactory
8093
60000
true
-->
<!-- Used to disconnect the client if there is no activity -->
<!-- Ensure this is greater than the ping period -->
<!--70000-->
<!-- The size of the buffer (in bytes) wrapping the socket -->
<!-- The buffer is flushed after each request -->
<!--2048-->
<!-- Large messages may block the ping/pong -->
<!-- A pong is simulated after each chunk (in bytes) for both reading and writing -->
<!-- It must be larger than the buffer size -->
<!--
1000000
-->
<!--
| The HTTP IL is configured in the deploy directory and available by
| default in both the "default" and "all" server configurations. To customize
| its attributes please see the jboss-service.xml file included in
| the META-INF directory of jbossmq-httpil.sar directory. The rationale
| for not including its configuration here is due to the fact that it
| includes a required dependant web module which would have required
| a stand alone WAR file. It was elected, therefore, to put everything
| in the deploy directory.
-->
<!-- ==================================================================== -->
<!-- JBossMQ Interceptor chain configuration -->
<!-- ==================================================================== -->
<!-- To tune performance, you can have the Invoker skip over the TracingInterceptor -->
<!-- and/or the SecurityManager, but then you loose the ability to trace and/or enforce security. -->
<depends optional-attribute-name="NextInterceptor">jboss.mq:service=SecurityManager
<!--
org.jboss.mq.server.TracingInterceptor
<depends optional-attribute-name="NextInterceptor">jboss.mq:service=SecurityManager
-->
<depends optional-attribute-name="NextInterceptor">jboss.mq:service=DestinationManager
<!--
| The ClientMonitorInterceptor disconnects clients that have been idle for to long.
| This interceptor is not enabled by default since the server might disconnect clients
| when the it is under high load.
-->
<!--
80000
<depends optional-attribute-name="NextInterceptor">jboss.mq:service=ClientReconnectInterceptor
-->
<!--
| The ClientReconnectInterceptor is used to allow a client to connect to the server even
| if it's clientID is allready being used by another client. This interceptor will disconnect
| the previously connected client to allow the new connection to succeed. This is not enabled
| by default since the JMS spec states that the 2nd client connecting to the server with the same
| id should get an exception.
-->
<!--
org.jboss.mq.server.ClientReconnectInterceptor
<depends optional-attribute-name="NextInterceptor">jboss.mq:service=DestinationManager
-->
<depends optional-attribute-name="PersistenceManager">jboss.mq:service=PersistenceManager
<depends optional-attribute-name="StateManager">jboss.mq:service=StateManager
<!--
| The MessageCache decides where to put JBossMQ message that
| are sitting around waiting to be consumed by a client.
|
| The memory marks are in Megabytes. Once the JVM memory usage hits
| the high memory mark, the old messages in the cache will start getting
| stored in the DataDirectory. As memory usage gets closer to the
| Max memory mark, the amount of message kept in the memory cache aproaches 0.
|
| ATTENTION: When the "file" or "rollinglogged" Persistence Manager is used
| you have to set the "CacheStore" to the CacheStore (the commented out line)
| and not to the PM itself.
-->
128
196
<!--
<depends optional-attribute-name="CacheStore">jboss.mq:service=CacheStore
-->
jboss.mq:service=PersistenceManager
<!--
| The CacheStore decides where to store JBossMQ message that
| that the MessageCache has decided to move in secondary storage.
|
| Now you can specify a absolut path by using an ULR like:
| file:///c:/temp
| ATTENTION: the directory MUST exists because it will not be
| created.
-->
tmp/jbossmq
<!--
| The StateManager is used to keep JMS persistent state data.
| For example: what durable subscriptions are active.
-->
<!-- This file is pulled from the configuration URL of the server -->
jbossmq-state.xml
<!--
| The PersistenceManager is used to store messages to disk.
|
| Now you can specify a absolut path by using an ULR like:
| file:///c:/temp
| ATTENTION: the directory MUST exists because it will not be
| created. Also for the "file" Persistance Manager the directory
| MUST be empty otherwise the startup fails ("rollinglogged" works
| fine.
-->
<!--
data/jbossmq/file
<depends optional-attribute-name="MessageCache">jboss.mq:service=MessageCache
-->
<!--
| The jdbc2 PersistenceManager is the new improved JDBC implementation.
| This implementation allows you to control how messages are stored in
| the database.
|
| Use this PM if you want the reliablity a relational database can offer
| you. The default configuration is known to work with hsqldb, other databases
| will requrie teaking of the SqlProperties.
-->
<depends optional-attribute-name="MessageCache">jboss.mq:service=MessageCache
<!--
<depends optional-attribute-name="ConnectionManager">jboss.jca:service=LocalTxCM,name=MSSQLDS
-->
<depends optional-attribute-name="ConnectionManager">jboss.jca:service=XATxCM,name=MSSQLXADS
BLOB_TYPE=BYTES_BLOB
INSERT_TX = INSERT INTO JMS_TRANSACTIONS (TXID) values(?)
INSERT_MESSAGE = INSERT INTO JMS_MESSAGES (MESSAGEID, DESTINATION, MESSAGEBLOB, TXID, TXOP) VALUES(?,?,?,?,?)
SELECT_ALL_UNCOMMITED_TXS = SELECT TXID FROM JMS_TRANSACTIONS
SELECT_MAX_TX = SELECT MAX(TXID) FROM JMS_MESSAGES
SELECT_MESSAGES_IN_DEST = SELECT MESSAGEID, MESSAGEBLOB FROM JMS_MESSAGES WHERE DESTINATION=?
SELECT_MESSAGE = SELECT MESSAGEID, MESSAGEBLOB FROM JMS_MESSAGES WHERE MESSAGEID=? AND DESTINATION=?
MARK_MESSAGE = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE MESSAGEID=? AND DESTINATION=?
UPDATE_MESSAGE = UPDATE JMS_MESSAGES SET MESSAGEBLOB=? WHERE MESSAGEID=? AND DESTINATION=?
UPDATE_MARKED_MESSAGES = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE TXOP=?
UPDATE_MARKED_MESSAGES_WITH_TX = UPDATE JMS_MESSAGES SET TXID=?, TXOP=? WHERE TXOP=? AND TXID=?
DELETE_MARKED_MESSAGES_WITH_TX = DELETE FROM JMS_MESSAGES WHERE TXID IN (SELECT TXID FROM JMS_TRANSACTIONS) AND TXOP=?
DELETE_TX = DELETE FROM JMS_TRANSACTIONS WHERE TXID = ?
DELETE_MARKED_MESSAGES = DELETE FROM JMS_MESSAGES WHERE TXID=? AND TXOP=?
DELETE_MESSAGE = DELETE FROM JMS_MESSAGES WHERE MESSAGEID=? AND DESTINATION=?
CREATE_MESSAGE_TABLE = CREATE TABLE JMS_MESSAGES ( MESSAGEID INTEGER NOT NULL, \
DESTINATION VARCHAR(255) NOT NULL, TXID INTEGER, TXOP CHAR(1), \
MESSAGEBLOB IMAGE, PRIMARY KEY (MESSAGEID, DESTINATION) )
CREATE_TX_TABLE = CREATE TABLE JMS_TRANSACTIONS ( TXID INTEGER )
<!-- ==================================================================== -->
<!-- System Destinations -->
<!-- ==================================================================== -->
<!-- Dead Letter Queue -->
<depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager
<!--<depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager--> -
6. Re: Performance numbers
adrian.brock Jun 24, 2003 10:48 PM (in response to speakmon)The only difference I can see between your
test and mine is that you are creating the message
inside the loop.
On the configuration:
jdbc2 doesn't need an XA driver, it is implementing
the local branch operations of an XA transaction.
What numbers do you get if you use
the default hsqldb?
Regards,
Adrian -
7. Re: Performance numbers
speakmon Jun 24, 2003 10:51 PM (in response to speakmon)Hi Adrian,
Thanks for the help!
I'm using the actual XADataSource driver because I wondered if the connection pooling that my driver supports would help performance any. Testing showed that it didn't.
I'll run against hsqldb in the morning and report results.
Thanks,
--Ben -
8. Re: Performance numbers
speakmon Jun 25, 2003 3:24 PM (in response to speakmon)Results from this morning's testing:
(after moving the TextMessage creation outside of the sending loop)
MSSQL: ~101 msgs/sec
hsqldb: ~294 msgs/sec
Seems hsqldb is a lot faster. Not very surprising.
Thanks for your help, Adrian. I'm good to go here. :) -
9. Re: Performance numbers for Oracle and MS SQL
xibin Mar 10, 2004 7:14 PM (in response to speakmon)I confirm the number with Hypersonic on JBoss3.2.2, which is about 300/s. I'm sending ObjectMessage with small objects to a queue, no subscribers.
However, I cannot get Oracle and MS SQL server to get even close to that number:
Oracle - 75 msgs/second
MS SQL - 50 msgs/second
Adrian, where should I go about improving this number? Our DBA changed the BLOB to be stored inline in the row....did not help much. I wanted to make sure that JBoss is using prepared statement. I looked at the mssql-jdbc2-service.xml and oracle-jdbc2-service.xml and it is not clear to me where to improve.
I got java.lang.OutOfMemory from Hypersonic when I tried to inject 20000 messages in a loop.
To give you some perspective, if I inserted the messages through JDBC directly using autocommit, I get 150 msgs/second. If I commited at the end of my insert loop, the numer jumps to 600 msgs/second. We sort of figured that JBoss JMS needs to commit for each message, so 150 msgs/second is probably the limit. But we are not getting that through JBoss JMS and jdbc2 PM.
Do you or anybody else have any suggestions on this subject?
Thanks
Xibin