001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.activemq.benchmark; 018 019 import java.text.NumberFormat; 020 import java.util.ArrayList; 021 import java.util.List; 022 import java.util.concurrent.atomic.AtomicInteger; 023 024 import javax.jms.Connection; 025 import javax.jms.Destination; 026 import javax.jms.JMSException; 027 import javax.jms.Session; 028 029 import org.apache.activemq.ActiveMQConnectionFactory; 030 import org.apache.activemq.util.IdGenerator; 031 032 /** 033 * Abstract base class for some simple benchmark tools 034 * 035 * @author James Strachan 036 * @version $Revision$ 037 */ 038 public class BenchmarkSupport { 039 040 protected int connectionCount = 1; 041 protected int batch = 1000; 042 protected Destination destination; 043 protected String[] subjects; 044 045 private boolean topic = true; 046 private boolean durable; 047 private ActiveMQConnectionFactory factory; 048 private String url; 049 private int counter; 050 private List<Object> resources = new ArrayList<Object>(); 051 private NumberFormat formatter = NumberFormat.getInstance(); 052 private AtomicInteger connectionCounter = new AtomicInteger(0); 053 private IdGenerator idGenerator = new IdGenerator(); 054 private boolean timerLoop; 055 056 public BenchmarkSupport() { 057 } 058 059 public void start() { 060 System.out.println("Using: " + connectionCount + " connection(s)"); 061 subjects = new String[connectionCount]; 062 for (int i = 0; i < connectionCount; i++) { 063 subjects[i] = "BENCHMARK.FEED" + i; 064 } 065 if (useTimerLoop()) { 066 Thread timer = new Thread() { 067 public void run() { 068 timerLoop(); 069 } 070 }; 071 timer.start(); 072 } 073 } 074 075 public String getUrl() { 076 return url; 077 } 078 079 public void setUrl(String url) { 080 this.url = url; 081 } 082 083 public boolean isTopic() { 084 return topic; 085 } 086 087 public void setTopic(boolean topic) { 088 this.topic = topic; 089 } 090 091 public ActiveMQConnectionFactory getFactory() { 092 return factory; 093 } 094 095 public void setFactory(ActiveMQConnectionFactory factory) { 096 this.factory = factory; 097 } 098 099 public void setSubject(String subject) { 100 connectionCount = 1; 101 subjects = new String[] { 102 subject 103 }; 104 } 105 106 public boolean isDurable() { 107 return durable; 108 } 109 110 public void setDurable(boolean durable) { 111 this.durable = durable; 112 } 113 114 public int getConnectionCount() { 115 return connectionCount; 116 } 117 118 public void setConnectionCount(int connectionCount) { 119 this.connectionCount = connectionCount; 120 } 121 122 protected Session createSession() throws JMSException { 123 if (factory == null) { 124 factory = createFactory(); 125 } 126 Connection connection = factory.createConnection(); 127 int value = connectionCounter.incrementAndGet(); 128 System.out.println("Created connection: " + value + " = " + connection); 129 if (durable) { 130 connection.setClientID(idGenerator.generateId()); 131 } 132 addResource(connection); 133 connection.start(); 134 135 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 136 addResource(session); 137 return session; 138 } 139 140 protected ActiveMQConnectionFactory createFactory() { 141 ActiveMQConnectionFactory answer = new ActiveMQConnectionFactory(getUrl()); 142 return answer; 143 } 144 145 protected synchronized void count(int count) { 146 counter += count; 147 /* 148 * if (counter > batch) { counter = 0; long current = 149 * System.currentTimeMillis(); double end = current - time; end /= 1000; 150 * time = current; System.out.println("Processed " + batch + " messages 151 * in " + end + " (secs)"); } 152 */ 153 } 154 155 protected synchronized int resetCount() { 156 int answer = counter; 157 counter = 0; 158 return answer; 159 } 160 161 protected void timerLoop() { 162 int times = 0; 163 int total = 0; 164 int dumpVmStatsFrequency = 10; 165 Runtime runtime = Runtime.getRuntime(); 166 167 while (true) { 168 try { 169 Thread.sleep(1000); 170 } catch (InterruptedException e) { 171 e.printStackTrace(); 172 } 173 int processed = resetCount(); 174 double average = 0; 175 if (processed > 0) { 176 total += processed; 177 times++; 178 } 179 if (times > 0) { 180 average = total / (double) times; 181 } 182 183 System.out.println(getClass().getName() + " Processed: " + processed + " messages this second. Average: " + average); 184 185 if ((times % dumpVmStatsFrequency) == 0 && times != 0) { 186 System.out.println("Used memory: " + asMemoryString(runtime.totalMemory() - runtime.freeMemory()) + " Free memory: " + asMemoryString(runtime.freeMemory()) + " Total memory: " 187 + asMemoryString(runtime.totalMemory()) + " Max memory: " + asMemoryString(runtime.maxMemory())); 188 } 189 190 } 191 } 192 193 protected String asMemoryString(long value) { 194 return formatter.format(value / 1024) + " K"; 195 } 196 197 protected boolean useTimerLoop() { 198 return timerLoop; 199 } 200 201 protected Destination createDestination(Session session, String subject) throws JMSException { 202 if (topic) { 203 return session.createTopic(subject); 204 } else { 205 return session.createQueue(subject); 206 } 207 } 208 209 protected void addResource(Object resource) { 210 resources.add(resource); 211 } 212 213 public int getCounter() { 214 return counter; 215 } 216 217 public void setTimerLoop(boolean timerLoop) { 218 this.timerLoop = timerLoop; 219 } 220 221 protected static boolean parseBoolean(String text) { 222 return text.equalsIgnoreCase("true"); 223 } 224 }