|
我是做性能测试的,最近接了一个项目,测试我们这边将要使用的weblogic的JMS中间件,想测一下JMS的收发效率,目标是每秒2.5-3W笔,最TM无语的是还让我们这些做测试的编程小白自己弄环境和写代码.无奈把百度来的代码东拼西凑写好了收发代码,测试了最多速度只有1W笔/秒。 Sender代码 import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Properties; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.DeliveryMode; import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.MapMessage; import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; //import JMSrecevier.MyTherad; public class TestMessage { private int currentNum = 0; private Session currentObj; private List<Session> pool; private Connection conn = null; public void sendMessage() throws JMSException, NamingException{ pool = Collections.synchronizedList(new LinkedList<Session>()); try { final String CONNECTION_FACTORY_JNDI = "ConnectionFactory-1" ; Context ctx = getInitialContext(); ConnectionFactory connFactory = (ConnectionFactory)ctx.lookup(CONNECTION_FACTORY_JNDI); Destination dest = (Destination)ctx.lookup("Queue-1"); conn = connFactory.createConnection(); conn.start(); for(int i=0;i<2000;i++) { new Thread(new MyTherad(dest)).start(); } //conn.close(); } catch (Exception e) { e.printStackTrace(); } } public class MyTherad implements Runnable { private Destination dest; public MyTherad(Destination dest) { this.dest=dest; } @Override public void run() { try { while(true) { Session session=getSession(); MessageProducer sender = session.createProducer(dest); sender.setDeliveryMode(DeliveryMode.PERSISTENT); //sender.setTimeToLive(20000); MapMessage msg = session.createMapMessage(); msg.setStringProperty("message","hello"); sender.send(msg); returnSession(session); //System.out.println(currentNum); } } catch (Exception e) { e.printStackTrace(); } } } private Context getInitialContext(){ Context ctx = null; Properties props = new Properties(); props.put( Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); props.put( Context.PROVIDER_URL, "t3://10.243.32.44:8001"); try { ctx = new InitialContext(props); } catch (NamingException e) { e.printStackTrace(); } return ctx; } public static void main(String args[]){ TestMessage mp = new TestMessage(); try { mp.sendMessage(); } catch (JMSException e) { e.printStackTrace(); } catch (NamingException e) { e.printStackTrace(); } } public synchronized Session getSession() throws Exception { if (pool.size() == 0 && currentNum < 2000) { currentObj = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); pool.add(currentObj); System.out.println(pool.size()); currentNum++; } else if (pool.size() == 0 && currentNum >= 2000) { while (pool.size() == 0) { } currentObj = (Session)pool.remove(0); } else { currentObj = (Session)pool.remove(0); } return currentObj; } public void returnSession(Session session) { pool.add(session); } public Connection getConn() { return conn; } } Receiver代码 package JMS;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class JMSReceiver {
private int currentNum = 0; // 该对象池当前已创建的对象数目
private Session currentObj;// 该对象池当前可以借出的对象
private List<Session> pool;// 用于存放对象的池
private Connection conn = null;
public void receiveMessage() throws JMSException, NamingException{
pool = Collections.synchronizedList(new LinkedList<Session>());
try {
final String CONNECTION_FACTORY_JNDI = "ConnectionFactoryQueue" ;
//
Context ctx = getInitialContext();
//
ConnectionFactory connFactory = (ConnectionFactory)ctx.lookup(CONNECTION_FACTORY_JNDI);
//
Destination dest = (Destination)ctx.lookup("QueueHezh");
conn = connFactory.createConnection();
//
conn.start();
for(int i=0;i<2000;i++){
new Thread(new MyTherad(dest)).start();
}
//conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public class MyTherad implements Runnable{
private Destination dest;
public MyTherad(Destination dest){
this.dest=dest;
}
@Override
public void run() {
try {
while(true){
Session session=getSession();
MessageConsumer receiver = session.createConsumer(dest);
MapMessage msg = (MapMessage)receiver.receive();
//System.out.println(msg);
returnSession(session);
System.out.println(currentNum);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private Context getInitialContext(){
Context ctx = null;
Properties props = new Properties();
props.put( Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
props.put( Context.PROVIDER_URL, "t3://192.168.43.170:7001");
try {
ctx = new InitialContext(props);
} catch (NamingException e) {
e.printStackTrace();
}
return ctx;
}
public static void main(String args[]){
JMSReceiver s = new JMSReceiver();
try {
s.receiveMessage();
} catch (JMSException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
}
/**
* session连接池
* @author Li Bangsen 2012-12-19 下午02:34:06
*/
public synchronized Session getSession() throws Exception {
if (pool.size() == 0 && currentNum < 100) {
// 如果当前池中无对象可用,而且已创建的对象数目小于所限制的最大值,创建一个新的对象
currentObj = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
pool.add(currentObj);
System.out.println(pool.size());
currentNum++;
} else
if (pool.size() == 0 && currentNum >= 100) {
// 如果当前池中无对象可用,而且所创建的对象数目已达到所限制的最大值, 就只能等待其它线程返回对象到池中
while (pool.size() == 0) {
}
currentObj = (Session)pool.remove(0);
} else {
// 如果当前池中有可用的对象,就直接从池中取出对象
currentObj = (Session)pool.remove(0);
}
return currentObj;
}
public void returnSession(Session session) {
pool.add(session);
}
public Connection getConn() {
return conn;
}
}
|
|
![]() |
顶一下.
大触求指导1!1 |
![]() |
没人吗?!没人吗。!
|
![]() 70分 |
给你稍微改了一下,主要是两点
1.pool 不用List 而用ArrayLockingQueue 2.单独用一个线程去创建session 3.你这线程数太多了,线程太多会增加上下文切换的开销,反而影响性能,另外就是加剧共享变量的竞争 主要改的是TestMessage类
package jms;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
//import JMSrecevier.MyTherad;
public class TestMessage {
private ArrayBlockingQueue<Session> pool = new ArrayBlockingQueue<Session>(2000);
private Connection conn = null;
public void sendMessage() throws JMSException, NamingException {
try {
final String CONNECTION_FACTORY_JNDI = "ConnectionFactory-1";
Context ctx = getInitialContext();
ConnectionFactory connFactory = (ConnectionFactory) ctx.lookup(CONNECTION_FACTORY_JNDI);
Destination dest = (Destination) ctx.lookup("Queue-1");
conn = connFactory.createConnection();
conn.start();
new Thread(new SessionCreateThread()).start();
Thread.sleep(500);
for (int i = 0; i < 100; i++) {
new Thread(new MyTherad(dest)).start();
}
// conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public class MyTherad implements Runnable {
private Destination dest;
public MyTherad(Destination dest){
this.dest = dest;
}
@Override
public void run() {
try {
while (true) {
Session session = getSession();
MessageProducer sender = session.createProducer(dest);
sender.setDeliveryMode(DeliveryMode.PERSISTENT);
// sender.setTimeToLive(20000);
MapMessage msg = session.createMapMessage();
msg.setStringProperty("message", "hello");
sender.send(msg);
returnSession(session);
// System.out.println(currentNum);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class SessionCreateThread implements Runnable {
@Override
public void run() {
Session currentObj;
try {
currentObj = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
returnSession(currentObj);
} catch (JMSException e) {
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
private Context getInitialContext() {
Context ctx = null;
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
props.put(Context.PROVIDER_URL, "t3://10.243.32.44:8001");
try {
ctx = new InitialContext(props);
} catch (NamingException e) {
e.printStackTrace();
}
return ctx;
}
public static void main(String args[]) {
TestMessage mp = new TestMessage();
try {
mp.sendMessage();
} catch (JMSException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
}
public synchronized Session getSession() throws Exception {
return pool.take();
}
public void returnSession(Session session) {
try {
pool.put(session);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Connection getConn() {
return conn;
}
}
|
![]() 15分 |
weblogic自带JMS线程池,你测试代码为啥要自己实现一个池来发JMS消息呢?
用一个Test类main里面直接send JMS测试数据,然后loadrunner直接加并发即可 |
![]() |
只是我们本机是路由不通他们的测试主机的,用不了loadrunner的,还只能通过在他们的主机上跑代码来测试.上个礼拜测试结果出来了,才 1000笔/秒。
略蛋疼.接下来还要连接数据库来测试,数据库还是altibase,网上这数据库的资源太少了, |
![]() |
同时运行几次这个代码 等同于与loadrunner的加并发吗?还是会加大资源消耗? |
![]() |
请问下,我想最大化的测出JMS的收发速度,这个速度只要是与代码有关,还是主机性能或者weblogic设置有关呢? |
![]() 15分 |
JMS的收发速度与主机性能肯定有关,但是与代码优化和WebLogic设置也有关系。
|

