ActiveMQ连接工厂、连接详解

JMS(ActiveMQ) PTP和PUB/SUB模式实例:[url]http://donald-draper.iteye.com/blog/2347445[/url]
在前文中我们讲过PTP和PUB/SUB模式实例,今天我们来看一下ActiveMQ是如何生产消息的
实例主要生产者代码片段:
ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,url);  

Connection :JMS 客户端到JMS Provider 的连接
Connection connection = connectionFactory.createConnection();

Connection 启动
connection.start();  

System.out.println("Connection is start...");
Session: 一个发送或接收消息的线程
Session session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);

Queue :消息的目的地;消息发送给谁.
Queue  destination = session.createQueue(qname);  

MessageProducer:消息发送者
MessageProducer producer = session.createProducer(destination); 

设置持久化,此处学习,实际根据项目决定
producer.setDeliveryMode(DeliveryMode.PERSISTENT); 

构造消息,此处写死,项目就是参数,或者方法获取
sendMessage(session, producer);  
session.commit();
connection.close();

我们依次来看上面的连接工厂,连接,会话,消息队列和订阅主题,生产者及发送消息
1.连接工厂
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,url); 
//ActiveMQConnectionFactory
public class ActiveMQConnectionFactory extends JNDIBaseStorable
implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory, StatsCapable, Cloneable
{
private static final Logger LOG;
private static final String DEFAULT_BROKER_HOST;//默认ip
private static final int DEFAULT_BROKER_PORT;//默认端口
public static final String DEFAULT_BROKER_BIND_URL;//broker默认绑定地址
public static final String DEFAULT_BROKER_URL;//默认broker URL
public static final String DEFAULT_USER = null;//默认用户
public static final String DEFAULT_PASSWORD = null;//默认密码
public static final int DEFAULT_PRODUCER_WINDOW_SIZE = 0;//默认生产者窗口大小
protected URI brokerURL;//broker URL
protected String userName;//用户名
protected String password;//密码
protected String clientID;//客户端id
protected boolean dispatchAsync;
protected boolean alwaysSessionAsync;
JMSStatsImpl factoryStats;
private IdGenerator clientIdGenerator;
private String clientIDPrefix;
private IdGenerator connectionIdGenerator;
private String connectionIDPrefix;//连接id前缀
private ActiveMQPrefetchPolicy prefetchPolicy;
private RedeliveryPolicyMap redeliveryPolicyMap;
private BlobTransferPolicy blobTransferPolicy;
private MessageTransformer transformer;
private boolean disableTimeStampsByDefault;
private boolean optimizedMessageDispatch;
private long optimizeAcknowledgeTimeOut;
private long optimizedAckScheduledAckInterval;
private boolean copyMessageOnSend;//是否拷贝消息
private boolean useCompression;//是否压缩消息
private boolean objectMessageSerializationDefered;
private boolean useAsyncSend;//是否异步发送消息
private boolean optimizeAcknowledge;
private int closeTimeout;//关闭连接超时时间
private boolean useRetroactiveConsumer;
private boolean exclusiveConsumer;
private boolean nestedMapAndListEnabled;
private boolean alwaysSyncSend;//是否总是异步发送
private boolean watchTopicAdvisories;
private int producerWindowSize;//生产窗口大小
private long warnAboutUnstartedConnectionTimeout;
private int sendTimeout;
private boolean sendAcksAsync;//是否发送异步ACK
private TransportListener transportListener;// transport监听器
private ExceptionListener exceptionListener;
private int auditDepth;
private int auditMaximumProducerNumber;
private boolean useDedicatedTaskRunner;
//当集群master宕机,重新选举master时,消费者等待重新消费的时间
private long consumerFailoverRedeliveryWaitPeriod;
private boolean checkForDuplicates;
private ClientInternalExceptionListener clientInternalExceptionListener;//消费内部监听器
private boolean messagePrioritySupported;//是否支持消息优先级
private boolean transactedIndividualAck;
private boolean nonBlockingRedelivery;//是否非阻塞传输
private int maxThreadPoolSize;//最大线程池
private TaskRunnerFactory sessionTaskRunner;//session任务工厂
private RejectedExecutionHandler rejectedTaskHandler;
protected int xaAckMode;
private boolean rmIdFromConnectionId;
private boolean consumerExpiryCheckEnabled;//是否检查消费者超时

static
{
LOG = LoggerFactory.getLogger(org/apache/activemq/ActiveMQConnectionFactory);
String host = null;
String port = null;
try
{
host = (String)AccessController.doPrivileged(new PrivilegedAction() {

public String run()
{
String result = System.getProperty("org.apache.activemq.AMQ_HOST");
result = result != null && !result.isEmpty() ? result : System.getProperty("AMQ_HOST", "localhost");
return result;
}

public volatile Object run()
{
return run();
}

});
port = (String)AccessController.doPrivileged(new PrivilegedAction() {

public String run()
{
String result = System.getProperty("org.apache.activemq.AMQ_PORT");
result = result != null && !result.isEmpty() ? result : System.getProperty("AMQ_PORT", "61616");
return result;
}

public volatile Object run()
{
return run();
}

});
}
catch(Throwable e)
{
LOG.debug("Failed to look up System properties for host and port", e);
}
//默认ip为localhost,端口为61616
host = host != null && !host.isEmpty() ? host : "localhost";
port = port != null && !port.isEmpty() ? port : "61616";
DEFAULT_BROKER_HOST = host;
DEFAULT_BROKER_PORT = Integer.parseInt(port);
String defaultURL = (new StringBuilder()).append("tcp://").append(DEFAULT_BROKER_HOST).append(":").append(DEFAULT_BROKER_PORT).toString();
String bindURL = null;
try
{
bindURL = (String)AccessController.doPrivileged(new PrivilegedAction(defaultURL) {

public String run()
{
String result = System.getProperty("org.apache.activemq.BROKER_BIND_URL");
result = result != null && !result.isEmpty() ? result : System.getProperty("BROKER_BIND_URL", defaultURL);
return result;
}

public volatile Object run()
{
return run();
}

final String val$defaultURL;


{
defaultURL = s;
super();
}
});
}
catch(Throwable e)
{
LOG.debug("Failed to look up System properties for host and port", e);
}
//默认url为tcp://localhost8:61616
bindURL = bindURL != null && !bindURL.isEmpty() ? bindURL : defaultURL;
DEFAULT_BROKER_BIND_URL = bindURL;
//默认broke url为failover://tcp://localhost8:61616
DEFAULT_BROKER_URL = (new StringBuilder()).append("failover://").append(DEFAULT_BROKER_BIND_URL).toString();
}
}

从ActiveMQConnectionFactory属性主要为broker url,用户密码,是否压缩、异步发送消息、
支持消息优先级、非阻塞传输,最大线程数,生产窗口大小等属性;
静态语句块,从系统获取url,port,broker url,如果系统中不存在相关属性,赋予默认值。


再来看ActiveMQConnectionFactory构造:
 public ActiveMQConnectionFactory(String userName, String password, String brokerURL)
{
dispatchAsync = true;//默认异步分发
alwaysSessionAsync = true;//异步发送消息
factoryStats = new JMSStatsImpl();
prefetchPolicy = new ActiveMQPrefetchPolicy();
redeliveryPolicyMap = new RedeliveryPolicyMap();
redeliveryPolicyMap.setDefaultEntry(new RedeliveryPolicy());
blobTransferPolicy = new BlobTransferPolicy();
optimizedMessageDispatch = true;
optimizeAcknowledgeTimeOut = 300L;
optimizedAckScheduledAckInterval = 0L;
copyMessageOnSend = true;
closeTimeout = 15000;//关闭超时时间
nestedMapAndListEnabled = true;
watchTopicAdvisories = true;
producerWindowSize = 0;//消息窗口大小
warnAboutUnstartedConnectionTimeout = 500L;
sendTimeout = 0;//发送超时时间
sendAcksAsync = true;//异步发送ACK
auditDepth = 2048;
auditMaximumProducerNumber = 64;
consumerFailoverRedeliveryWaitPeriod = 0L;
checkForDuplicates = true;
messagePrioritySupported = false;//默认不支持消息优先级
transactedIndividualAck = false;
nonBlockingRedelivery = false;//默认为阻塞模式
maxThreadPoolSize = ActiveMQConnection.DEFAULT_THREAD_POOL_SIZE;//最大线程池大小
rejectedTaskHandler = null;
xaAckMode = -1;
rmIdFromConnectionId = false;
consumerExpiryCheckEnabled = true;
//设置用户密码,broker url
setUserName(userName);
setPassword(password);
setBrokerURL(brokerURL);
}

从构造可以看出,主要初始化为broker url,用户密码,是否压缩、异步发送消息、
支持消息优先级、非阻塞传输,最大线程数,生产窗口大小等属性;

下面来看一下连接的获取
2.连接
Connection connection = connectionFactory.createConnection();  
//ActiveMQConnectionFactory
public Connection createConnection()
throws JMSException
{
return createActiveMQConnection();
}
protected ActiveMQConnection createActiveMQConnection()
throws JMSException
{
return createActiveMQConnection(userName, password);
}
//最终ActiveMQ创建连接方法,返回的为ActiveMQConnection
protected ActiveMQConnection createActiveMQConnection(String userName, String password)
throws JMSException
{
ActiveMQConnection connection;
if(brokerURL == null)
throw new ConfigurationException("brokerURL not set.");
connection = null;
//创建transport
Transport transport = createTransport();
//创建连接
connection = createActiveMQConnection(transport, factoryStats);
//设置连接用户密码
connection.setUserName(userName);
connection.setPassword(password);
//配置连接
configureConnection(connection);
//启动transport
transport.start();
if(clientID != null)
connection.setDefaultClientID(clientID);
return connection;
catch(Throwable throwable1) { }
throw JMSExceptionSupport.create((new StringBuilder()).append("Could not connect to broker URL: ").append(brokerURL).append(". Reason: ").append(e).toString(), e);
}

我们分别来看以上几点
a.创建transport
Transport transport = createTransport();


protected Transport createTransport()
throws JMSException
{
//由TransportFactory工厂连接brokerURL创建Transport
return TransportFactory.connect(brokerURL);
Exception e;
e;
throw JMSExceptionSupport.create((new StringBuilder()).append("Could not create Transport. Reason: ").append(e).toString(), e);
}

再看TransportFactory
//TransportFactory
public abstract class TransportFactory
{
private static final FactoryFinder TRANSPORT_FACTORY_FINDER = new FactoryFinder("META-INF/services/org/apache/activemq/transport/");
private static final FactoryFinder WIREFORMAT_FACTORY_FINDER = new FactoryFinder("META-INF/services/org/apache/activemq/wireformat/");
//ConcurrentHashMap<BrokerURI.getSchema(),TransportFactory>,broker uri协议与TransportFactory的映射
private static final ConcurrentMap TRANSPORT_FACTORYS = new ConcurrentHashMap();
private static final String WRITE_TIMEOUT_FILTER = "soWriteTimeout";
private static final String THREAD_NAME_FILTER = "threadName";
public static Transport connect(URI location)
throws Exception
{
//跟Broker URI 获取TransportFactory
TransportFactory tf = findTransportFactory(location);
//获取连接
return tf.doConnect(location);
}
}

//从TRANSPORT_FACTORYS获取borkerURI对应的TransportFactory,没有则,
TRANSPORT_FACTORY_FINDER根据brokerURI创建对应的TransportFactory的实例放入TRANSPORT_FACTORYS中
public static TransportFactory findTransportFactory(URI location)
throws IOException
{
String scheme = location.getScheme();
if(scheme == null)
throw new IOException((new StringBuilder()).append("Transport not scheme specified: [").append(location).append("]").toString());
TransportFactory tf = (TransportFactory)TRANSPORT_FACTORYS.get(scheme);
if(tf == null)
try
{
//TRANSPORT_FACTORY_FINDER根据协议名创建TransportFactory实例
tf = (TransportFactory)TRANSPORT_FACTORY_FINDER.newInstance(scheme);
TRANSPORT_FACTORYS.put(scheme, tf);
}
catch(Throwable e)
{
throw IOExceptionSupport.create((new StringBuilder()).append("Transport scheme NOT recognized: [").append(scheme).append("]").toString(), e);
}
return tf;
}

从FactoryFinder,可以看到有一个META-INF/services/org/apache/activemq/transport/路径
private static final FactoryFinder TRANSPORT_FACTORY_FINDER = new FactoryFinder("META-INF/services/org/apache/activemq/transport/");
找到这个路径,可以看到有一些文本文件http,nio,amqp,failover,ssl,tcp,vm等;
tcp这个就是我们找到,打开文件如下:
class=org.apache.activemq.transport.tcp.TcpTransportFactory
TcpTransportFactory看到这个想到了什么,就是我们要找的,FactoryFinder就是根据
BrokerURI的协议来找META-INF/services/org/apache/activemq/transport/下的对应文件,
然后加载class属性对应的类,由于我们的broker地址,为tcp://192.168.126.128:61616,所以协议为TCP
对应的为TcpTransportFactory,好了到这里TransportFactory工厂创建完毕。这里只是猜测
//回看一下FactoryFinder
public class FactoryFinder
{
private static ObjectFactory objectFactory = new StandaloneObjectFactory();
private final String path;
//根据brokerUri协议创建TransportFactory实例
public Object newInstance(String key)
throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException
{
return objectFactory.create((new StringBuilder()).append(path).append(key).toString());
}
protected static class StandaloneObjectFactory
implements ObjectFactory
{
//ConcurrentHashMap<BrokeURI.getSchema(),TransportFactory>
final ConcurrentMap classMap = new ConcurrentHashMap();
//根据broker URI协议创建TransportFactory
public Object create(String path)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IOException
{
Class clazz = (Class)classMap.get(path);
if(clazz == null)
{

clazz = loadClass(loadProperties(path));
classMap.put(path, clazz);
}
return clazz.newInstance();
}
//加载class对应的TransportFactory
public static Class loadClass(Properties properties)
throws ClassNotFoundException, IOException
{
String className = properties.getProperty("class");
if(className == null)
throw new IOException("Expected property is missing: class");
Class clazz = null;
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if(loader != null)
try
{
clazz = loader.loadClass(className);
}
catch(ClassNotFoundException classnotfoundexception) { }
if(clazz == null)
clazz = org/apache/activemq/util/FactoryFinder.getClassLoader().loadClass(className);
return clazz;
}
//加载属性文件
public static Properties loadProperties(String uri)
throws IOException
{
InputStream in;
BufferedInputStream reader;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader == null)
classLoader = org/apache/activemq/util/FactoryFinder$StandaloneObjectFactory.getClassLoader();
in = classLoader.getResourceAsStream(uri);
if(in == null)
{
in = org/apache/activemq/util/FactoryFinder.getClassLoader().getResourceAsStream(uri);
if(in == null)
throw new IOException((new StringBuilder()).append("Could not find factory class for resource: ").append(uri).toString());
}
reader = null;
Properties properties1;
reader = new BufferedInputStream(in);
Properties properties = new Properties();
properties.load(reader);
properties1 = properties;
}
}
}

再看从TransportFactory工厂获取连接:
//获取连接
return tf.doConnect(location);

TransportFactory获取连接
public Transport doConnect(URI location)
throws Exception
{
Transport rc;
Map options = new HashMap(URISupport.parseParameters(location));
if(!options.containsKey("wireFormat.host"))
options.put("wireFormat.host", location.getHost());
WireFormat wf = createWireFormat(options);
创建transport
Transport transport = createTransport(location, wf);
配置transport
rc = configure(transport, wf, options);
return rc;
}

//待父类扩展
    protected Transport createTransport(URI location, WireFormat wf)
throws MalformedURLException, UnknownHostException, IOException
{
throw new IOException("createTransport() method not implemented!");
}

再看其父类
public class TcpTransportFactory extends TransportFactory
{
protected Transport createTransport(URI location, WireFormat wf)
throws UnknownHostException, IOException
{
URI localLocation = null;
String path = location.getPath();
if(path != null && path.length() > 0)
{
int localPortIndex = path.indexOf(':');
try
{
Integer.parseInt(path.substring(localPortIndex + 1, path.length()));
String localString = (new StringBuilder()).append(location.getScheme()).append(":/").append(path).toString();
localLocation = new URI(localString);
}
}
//创建socket的工场
SocketFactory socketFactory = createSocketFactory();
//创建TcpTransport
return createTcpTransport(wf, socketFactory, location, localLocation);
}
}

//创建socket的工场
SocketFactory socketFactory = createSocketFactory();
protected SocketFactory createSocketFactory()
throws IOException
{
return SocketFactory.getDefault();
}
//DefaultSocketFactory
public abstract class SocketFactory
{
public static SocketFactory getDefault()
{
synchronized(javax/net/SocketFactory)
{
if(theFactory == null)
theFactory = new DefaultSocketFactory();
}
return theFactory;
}

//创建TcpTransport,socketFactory为DefaultSocketFactory
return createTcpTransport(wf, socketFactory, location, localLocation);
protected TcpTransport createTcpTransport(WireFormat wf, SocketFactory socketFactory, URI location, URI localLocation)
throws UnknownHostException, IOException
{
//返回的是TcpTransport
return new TcpTransport(wf, socketFactory, location, localLocation);
}
//TcpTransport
public class TcpTransport extends TransportThreadSupport
implements Transport, Service, Runnable
{
protected final URI remoteLocation;//远程URI
protected final URI localLocation;//本地URI
protected final WireFormat wireFormat;
protected int connectionTimeout;//连接超时时间
protected int soTimeout;
protected int socketBufferSize;//socket的缓存大小
protected int ioBufferSize;
protected boolean closeAsync;
protected Socket socket;
protected DataOutputStream dataOut;//socket的输出流
protected DataInputStream dataIn;//socket的输入流
protected TimeStampStream buffOut;
protected int trafficClass;
private boolean trafficClassSet;
protected boolean diffServChosen;
protected boolean typeOfServiceChosen;
protected boolean trace;
protected String logWriterName;
protected boolean dynamicManagement;
protected boolean startLogging;
protected int jmxPort;
protected boolean useLocalHost;
protected int minmumWireFormatVersion;
protected SocketFactory socketFactory;
protected final AtomicReference stoppedLatch;
protected volatile int receiveCounter;
private Map socketOptions;
private int soLinger;
private Boolean keepAlive;//是否保活
private Boolean tcpNoDelay;//tcp是否为非延时
private Thread runnerThread;
public TcpTransport(WireFormat wireFormat, SocketFactory socketFactory, URI remoteLocation, URI localLocation)
throws UnknownHostException, IOException
{
connectionTimeout = 30000;
socketBufferSize = 65536;
ioBufferSize = 8192;
closeAsync = true;
buffOut = null;
trafficClass = 0;
trafficClassSet = false;
diffServChosen = false;
typeOfServiceChosen = false;
trace = false;
logWriterName = TransportLoggerSupport.defaultLogWriterName;
dynamicManagement = false;
startLogging = true;
jmxPort = 1099;
useLocalHost = false;
stoppedLatch = new AtomicReference();
soLinger = -2147483648;
this.wireFormat = wireFormat;
this.socketFactory = socketFactory;
try
{
//默认SOCKET工厂创建socket
socket = socketFactory.createSocket();
}
this.remoteLocation = remoteLocation;
this.localLocation = localLocation;
setDaemon(false);
}
}

//DefaultSocketFactory
class DefaultSocketFactory extends SocketFactory
{
DefaultSocketFactory()
{
}
public Socket createSocket()
{
return new Socket();
}
}

配置transport
rc = configure(transport, wf, options);
public Transport configure(Transport transport, WireFormat wf, Map options)
throws Exception
{
//配置写超时时间
transport = compositeConfigure(transport, wf, options);
//创建MutexTransport
transport = new MutexTransport(transport);
//创建ResponseCorrelator
transport = new ResponseCorrelator(transport);
return transport;
}
//配置写超时时间
public Transport compositeConfigure(Transport transport, WireFormat format, Map options)
{
if(options.containsKey("soWriteTimeout"))
{
transport = new WriteTimeoutFilter(transport);
String soWriteTimeout = (String)options.remove("soWriteTimeout");
if(soWriteTimeout != null)
((WriteTimeoutFilter)transport).setWriteTimeout(Long.parseLong(soWriteTimeout));
}
IntrospectionSupport.setProperties(transport, options);
return transport;
}

//MutexTransport,添加锁机制
public class MutexTransport extends TransportFilter
{
private final ReentrantLock writeLock;
private boolean syncOnCommand;
public MutexTransport(Transport next)
{
super(next);
writeLock = new ReentrantLock();
syncOnCommand = false;
}
public void onCommand(Object command)
{
if(!syncOnCommand)
break MISSING_BLOCK_LABEL_47;
writeLock.lock();
transportListener.onCommand(command);
writeLock.unlock();
break MISSING_BLOCK_LABEL_57;
Exception exception;
exception;
writeLock.unlock();
throw exception;
transportListener.onCommand(command);
}
...
}
//ResponseCorrelator,请求协调器
public class ResponseCorrelator extends TransportFilter
{
private final Map requestMap;
private IntSequenceGenerator sequenceGenerator;
private final boolean debug;
private IOException error;
public ResponseCorrelator(Transport next)
{
this(next, new IntSequenceGenerator());
}
public void oneway(Object o)
throws IOException
{
Command command = (Command)o;
command.setCommandId(sequenceGenerator.getNextSequenceId());
command.setResponseRequired(false);
next.oneway(command);
}

public FutureResponse asyncRequest(Object o, ResponseCallback responseCallback)
throws IOException
{
...
}

public Object request(Object command)
throws IOException
{
.....
}


public void onCommand(Object o)
{
....
}
}

小节一下创建transport:
TransportFactory创建Transport,从TransportFactory的ConcurrentHashMap<BrokerURI.getSchema(),TransportFactory>
获取brokerURI协议对应的TransportFactory,没有则根据brokerURI协议从FactoryFinder的获取,没有则加载,相应的实例。

b.创建连接

从上面看到transport为TransportFactory,factoryStats为JMSStatsImpl
先看一下JMSStatsImpl
public class JMSStatsImpl extends StatsImpl
{
private List connections;
public JMSStatsImpl()
{
//获取线程安全的connections集合
connections = new CopyOnWriteArrayList();
}
public JMSConnectionStatsImpl[] getConnections()
{
Object connectionArray[] = connections.toArray();
int size = connectionArray.length;
JMSConnectionStatsImpl answer[] = new JMSConnectionStatsImpl[size];
for(int i = 0; i < size; i++)
{
ActiveMQConnection connection = (ActiveMQConnection)connectionArray[i];
answer[i] = connection.getConnectionStats();
}

return answer;
}
public void addConnection(ActiveMQConnection connection)
{
connections.add(connection);
}
public void removeConnection(ActiveMQConnection connection)
{
connections.remove(connection);
}
public void dump(IndentPrinter out)
{
out.printIndent();
out.println("factory {");
out.incrementIndent();
JMSConnectionStatsImpl array[] = getConnections();
for(int i = 0; i < array.length; i++)
{
JMSConnectionStatsImpl connectionStat = array[i];
connectionStat.dump(out);
}

out.decrementIndent();
out.printIndent();
out.println("}");
out.flush();
}
public void setEnabled(boolean enabled)
{
super.setEnabled(enabled);
JMSConnectionStatsImpl stats[] = getConnections();
int size = stats.length;
for(int i = 0; i < size; i++)
stats[i].setEnabled(enabled);

}

}

从上JMSStatsImpl为管理连接的ActiveMQConnection
回到
connection = createActiveMQConnection(transport, factoryStats);

//ActiveMQConnectionFactory
protected ActiveMQConnection createActiveMQConnection(Transport transport, JMSStatsImpl stats)
throws Exception
{
ActiveMQConnection connection = new ActiveMQConnection(transport, getClientIdGenerator(), getConnectionIdGenerator(), stats);
return connection;
}

//ActiveMQConnection
public class ActiveMQConnection
implements Connection, TopicConnection, QueueConnection, StatsCapable, Closeable, TransportListener, EnhancedConnection
{
//默认用户密码brokerURL,线程池大小
public static final String DEFAULT_USER;
public static final String DEFAULT_PASSWORD;
public static final String DEFAULT_BROKER_URL;
public static int DEFAULT_THREAD_POOL_SIZE = 1000;
private static final Logger LOG = LoggerFactory.getLogger(org/apache/activemq/ActiveMQConnection);
//TempDestinations
public final ConcurrentMap activeTempDestinations = new ConcurrentHashMap();
protected boolean dispatchAsync;//是否异步分发消息
protected boolean alwaysSessionAsync;
private TaskRunnerFactory sessionTaskRunner;//会话任务线程工厂
private final ThreadPoolExecutor executor;//线程执行器
private final ConnectionInfo info;//连接信息
private ExceptionListener exceptionListener;
private ClientInternalExceptionListener clientInternalExceptionListener;
private boolean clientIDSet;
private boolean isConnectionInfoSentToBroker;
private boolean userSpecifiedClientID;
private ActiveMQPrefetchPolicy prefetchPolicy;
private BlobTransferPolicy blobTransferPolicy;
private RedeliveryPolicyMap redeliveryPolicyMap;
private MessageTransformer transformer;
private boolean disableTimeStampsByDefault;
private boolean optimizedMessageDispatch;
private boolean copyMessageOnSend;
private boolean useCompression;//是否压缩
private boolean objectMessageSerializationDefered;
private boolean useAsyncSend;//是否异步发送
private boolean optimizeAcknowledge;
private long optimizeAcknowledgeTimeOut;
private long optimizedAckScheduledAckInterval;
private boolean nestedMapAndListEnabled;
private boolean useRetroactiveConsumer;
private boolean exclusiveConsumer;
private boolean alwaysSyncSend;
private int closeTimeout;//连接关闭超时时间
private boolean watchTopicAdvisories;
private long warnAboutUnstartedConnectionTimeout;
private int sendTimeout;//发送超时时间
private boolean sendAcksAsync;//是否异步发送Acks
private boolean checkForDuplicates;
private boolean queueOnlyConnection;//是否为队列连接
private boolean consumerExpiryCheckEnabled;
private final Transport transport;//transport
private final IdGenerator clientIdGenerator;
private final JMSStatsImpl factoryStats;//连接状态管理器
private final JMSConnectionStatsImpl stats;
//启动动关闭状态AtomicBoolean
private final AtomicBoolean started = new AtomicBoolean(false);
private final AtomicBoolean closing = new AtomicBoolean(false);
private final AtomicBoolean closed = new AtomicBoolean(false);
private final AtomicBoolean transportFailed = new AtomicBoolean(false);
//会话,消费者连接,
private final CopyOnWriteArrayList sessions = new CopyOnWriteArrayList();
private final CopyOnWriteArrayList connectionConsumers = new CopyOnWriteArrayList();
private final CopyOnWriteArrayList transportListeners = new CopyOnWriteArrayList();
//dispatchers
private final ConcurrentMap dispatchers = new ConcurrentHashMap();
//生产者
private final ConcurrentMap producers = new ConcurrentHashMap();
//会话消费者id
private final LongSequenceGenerator sessionIdGenerator = new LongSequenceGenerator();
private final SessionId connectionSessionId;
private final LongSequenceGenerator consumerIdGenerator = new LongSequenceGenerator();
private final LongSequenceGenerator tempDestinationIdGenerator = new LongSequenceGenerator();
private final LongSequenceGenerator localTransactionIdGenerator = new LongSequenceGenerator();
private AdvisoryConsumer advisoryConsumer;
private final CountDownLatch brokerInfoReceived = new CountDownLatch(1);
//broker信息
private BrokerInfo brokerInfo;
private IOException firstFailureError;
private int producerWindowSize;
private final AtomicInteger protocolVersion = new AtomicInteger(11);
private final long timeCreated = System.currentTimeMillis();
private final ConnectionAudit connectionAudit = new ConnectionAudit();
private DestinationSource destinationSource;
private final Object ensureConnectionInfoSentMutex = new Object();
private boolean useDedicatedTaskRunner;
protected AtomicInteger transportInterruptionProcessingComplete;
private long consumerFailoverRedeliveryWaitPeriod;
//调度器
private Scheduler scheduler;
private boolean messagePrioritySupported;
private boolean transactedIndividualAck;
private boolean nonBlockingRedelivery;
private boolean rmIdFromConnectionId;
private int maxThreadPoolSize;
private RejectedExecutionHandler rejectedTaskHandler;

static
{
DEFAULT_USER = ActiveMQConnectionFactory.DEFAULT_USER;
DEFAULT_PASSWORD = ActiveMQConnectionFactory.DEFAULT_PASSWORD;
DEFAULT_BROKER_URL = ActiveMQConnectionFactory.DEFAULT_BROKER_URL;
}
}

再看起构造
   protected ActiveMQConnection(final Transport transport, IdGenerator clientIdGenerator, IdGenerator connectionIdGenerator, JMSStatsImpl factoryStats)
throws Exception
{
dispatchAsync = true;
alwaysSessionAsync = true;
prefetchPolicy = new ActiveMQPrefetchPolicy();
optimizedMessageDispatch = true;
copyMessageOnSend = true;
optimizeAcknowledgeTimeOut = 0L;
optimizedAckScheduledAckInterval = 0L;
nestedMapAndListEnabled = true;
closeTimeout = 15000;
watchTopicAdvisories = true;
warnAboutUnstartedConnectionTimeout = 500L;
sendTimeout = 0;
sendAcksAsync = true;
checkForDuplicates = true;
queueOnlyConnection = false;
consumerExpiryCheckEnabled = true;
producerWindowSize = 0;
transportInterruptionProcessingComplete = new AtomicInteger(0);
messagePrioritySupported = false;
transactedIndividualAck = false;
nonBlockingRedelivery = false;
rmIdFromConnectionId = false;
maxThreadPoolSize = DEFAULT_THREAD_POOL_SIZE;
rejectedTaskHandler = null;
this.transport = transport;
this.clientIdGenerator = clientIdGenerator;
this.factoryStats = factoryStats;
executor = new ThreadPoolExecutor(1, 1, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue(), new ThreadFactory() {

public Thread newThread(Runnable r)
{
Thread thread = new Thread(r, (new StringBuilder()).append("ActiveMQ Connection Executor: ").append(transport).toString());
return thread;
}
//ThreadPoolExecutor关联一个Transport和ActiveMQConnection
final Transport val$transport;
final ActiveMQConnection this$0;


{
this$0 = ActiveMQConnection.this;
transport = transport1;
super();
}
});
//连接信息
String uniqueId = connectionIdGenerator.generateId();
info = new ConnectionInfo(new ConnectionId(uniqueId));
info.setManageable(true);
info.setFaultTolerant(transport.isFaultTolerant());
//会话信息
connectionSessionId = new SessionId(info.getConnectionId(), -1L);
this.transport.setTransportListener(this);
//将连接信息,添加到连接管理器
stats = new JMSConnectionStatsImpl(sessions, this instanceof XAConnection);
this.factoryStats.addConnection(this);
connectionAudit.setCheckForDuplicates(transport.isFaultTolerant());
}


c.设置连接用户密码
connection.setUserName(userName);
connection.setPassword(password);

 protected void setUserName(String userName)
{
info.setUserName(userName);
}

public class ConnectionInfo extends BaseCommand
{
public static final byte DATA_STRUCTURE_TYPE = 3;
protected ConnectionId connectionId;
protected String clientId;
protected String clientIp;
protected String userName;
protected String password;
protected BrokerId brokerPath[];
protected boolean brokerMasterConnector;//是否为集群
protected boolean manageable;
protected boolean clientMaster;
protected boolean faultTolerant;
protected boolean failoverReconnect;
protected transient Object transportContext;
}


d.配置连接
configureConnection(connection);

 protected void configureConnection(ActiveMQConnection connection)
throws JMSException
{
//配置连接会话连接属性
connection.setPrefetchPolicy(getPrefetchPolicy());
connection.setDisableTimeStampsByDefault(isDisableTimeStampsByDefault());
connection.setOptimizedMessageDispatch(isOptimizedMessageDispatch());
connection.setCopyMessageOnSend(isCopyMessageOnSend());
connection.setUseCompression(isUseCompression());
connection.setObjectMessageSerializationDefered(isObjectMessageSerializationDefered());
connection.setDispatchAsync(isDispatchAsync());
connection.setUseAsyncSend(isUseAsyncSend());
connection.setAlwaysSyncSend(isAlwaysSyncSend());
connection.setAlwaysSessionAsync(isAlwaysSessionAsync());
connection.setOptimizeAcknowledge(isOptimizeAcknowledge());
connection.setOptimizeAcknowledgeTimeOut(getOptimizeAcknowledgeTimeOut());
connection.setOptimizedAckScheduledAckInterval(getOptimizedAckScheduledAckInterval());
connection.setUseRetroactiveConsumer(isUseRetroactiveConsumer());
connection.setExclusiveConsumer(isExclusiveConsumer());
connection.setRedeliveryPolicyMap(getRedeliveryPolicyMap());
connection.setTransformer(getTransformer());
connection.setBlobTransferPolicy(getBlobTransferPolicy().copy());
connection.setWatchTopicAdvisories(isWatchTopicAdvisories());
connection.setProducerWindowSize(getProducerWindowSize());
connection.setWarnAboutUnstartedConnectionTimeout(getWarnAboutUnstartedConnectionTimeout());
connection.setSendTimeout(getSendTimeout());
connection.setCloseTimeout(getCloseTimeout());
connection.setSendAcksAsync(isSendAcksAsync());
connection.setAuditDepth(getAuditDepth());
connection.setAuditMaximumProducerNumber(getAuditMaximumProducerNumber());
connection.setUseDedicatedTaskRunner(isUseDedicatedTaskRunner());
connection.setConsumerFailoverRedeliveryWaitPeriod(getConsumerFailoverRedeliveryWaitPeriod());
connection.setCheckForDuplicates(isCheckForDuplicates());
connection.setMessagePrioritySupported(isMessagePrioritySupported());
connection.setTransactedIndividualAck(isTransactedIndividualAck());
connection.setNonBlockingRedelivery(isNonBlockingRedelivery());
connection.setMaxThreadPoolSize(getMaxThreadPoolSize());
connection.setSessionTaskRunner(getSessionTaskRunner());
connection.setRejectedTaskHandler(getRejectedTaskHandler());
connection.setNestedMapAndListEnabled(isNestedMapAndListEnabled());
connection.setRmIdFromConnectionId(isRmIdFromConnectionId());
connection.setConsumerExpiryCheckEnabled(isConsumerExpiryCheckEnabled());
if(transportListener != null)
connection.addTransportListener(transportListener);
if(exceptionListener != null)
connection.setExceptionListener(exceptionListener);
if(clientInternalExceptionListener != null)
connection.setClientInternalExceptionListener(clientInternalExceptionListener);
}

e.启动transport
transport.start();

//启动TcpTransport线程

public class TcpTransport extends TransportThreadSupport
implements Transport, Service, Runnable{
public void run()
{
LOG.trace((new StringBuilder()).append("TCP consumer thread for ").append(this).append(" starting").toString());
runnerThread = Thread.currentThread();
for(; !isStopped(); doRun());
}
protected void doRun()
throws IOException
{
try
{
//消费命令
Object command = readCommand();
//开始消费
doConsume(command);
}
}


而doConsume在TcpTransport中没有,TransportThreadSupport也没有,看TransportSupport
public abstract class TransportThreadSupport extends TransportSupport
implements Runnable
//TransportSupport
public abstract class TransportSupport extends ServiceSupport
implements Transport
{
TransportListener transportListener;//消息监听器
public void doConsume(Object command)
{
if(command != null)
if(transportListener != null)
//启动监听器,监听消息,如果消息监听器不为空,
transportListener.onCommand(command);
else
LOG.error((new StringBuilder()).append("No transportListener available to process inbound command: ").append(command).toString());
}
}

//service辅助类
public abstract class ServiceSupport
implements Service
{
private AtomicBoolean started;
private AtomicBoolean stopping;
private AtomicBoolean stopped;
private List serviceListeners;
public ServiceSupport()
{
started = new AtomicBoolean(false);
stopping = new AtomicBoolean(false);
stopped = new AtomicBoolean(false);
//新建线程安全的服务监听器
serviceListeners = new CopyOnWriteArrayList();
}
//终于找这个了,因为在TcpTransPort中看到dostart(),就不知道怎么调的,
//ActiveMQ的Service和Tomcat的lifecyle是一回事,管理组件生命周期
public void start()
throws Exception
{
boolean success;
if(!started.compareAndSet(false, true))
break MISSING_BLOCK_LABEL_93;
success = false;
stopped.set(false);
preStart();
//调用dostart而,doStart为抽象函数待父类扩展
doStart();
success = true;
started.set(success);
//启动service监听器
for(Iterator i$ = serviceListeners.iterator(); i$.hasNext(); l.started(this))
l = (ServiceListener)i$.next();

}
}
//待父类扩展
protected abstract void doStart()
throws Exception;
}


看TcpTransport
public class TcpTransport extends TransportThreadSupport
implements Transport, Service, Runnable
{
protected void doStart()
throws Exception
{
//连接
connect();
stoppedLatch.set(new CountDownLatch(1));
//启动TransportThreadSupport线程
super.doStart();
}
}

来看
//连接
connect();

protected void connect()
throws Exception
{
if(socket == null && socketFactory == null)
throw new IllegalStateException("Cannot connect if the socket or socketFactory have not been set");
InetSocketAddress localAddress = null;
InetSocketAddress remoteAddress = null;
if(localLocation != null)
//如果是localhost地址,则创建InetSocketAddress
localAddress = new InetSocketAddress(InetAddress.getByName(localLocation.getHost()), localLocation.getPort());
if(remoteLocation != null)
{
//如果是ip地址,则根据ip创建InetSocketAddress
String host = resolveHostName(remoteLocation.getHost());
remoteAddress = new InetSocketAddress(host, remoteLocation.getPort());
}
trafficClassSet = setTrafficClass(socket);
if(socket != null)
{
if(localAddress != null)
socket.bind(localAddress);
if(remoteAddress != null)
if(connectionTimeout >= 0)
//socket连接broker
socket.connect(remoteAddress, connectionTimeout);
else
socket.connect(remoteAddress);
} else
if(localAddress != null)
socket = socketFactory.createSocket(remoteAddress.getAddress(), remoteAddress.getPort(), localAddress.getAddress(), localAddress.getPort());
else
socket = socketFactory.createSocket(remoteAddress.getAddress(), remoteAddress.getPort());
//初始化socket
initialiseSocket(socket);
//初始化输入输出流
initializeStreams();
}

初始化socket
initialiseSocket(socket);

protected void initialiseSocket(Socket sock)
throws SocketException, IllegalArgumentException
{
if(socketOptions != null)
{
Map copy = new HashMap(socketOptions);
IntrospectionSupport.setProperties(socket, copy);
if(!copy.isEmpty())
throw new IllegalArgumentException((new StringBuilder()).append("Invalid socket parameters: ").append(copy).toString());
}
try
{
//设置socket接收与发送缓存区大小
sock.setReceiveBufferSize(socketBufferSize);
sock.setSendBufferSize(socketBufferSize);
}
catch(SocketException se)
{
LOG.warn((new StringBuilder()).append("Cannot set socket buffer size = ").append(socketBufferSize).toString());
LOG.debug((new StringBuilder()).append("Cannot set socket buffer size. Reason: ").append(se.getMessage()).append(". This exception is ignored.").toString(), se);
}
//设置socket写超时时间
sock.setSoTimeout(soTimeout);
if(keepAlive != null)
//设置socket保活
sock.setKeepAlive(keepAlive.booleanValue());
if(soLinger > -1)
sock.setSoLinger(true, soLinger);
else
if(soLinger == -1)
sock.setSoLinger(false, 0);
if(tcpNoDelay != null)
//设置socket是否有延时
sock.setTcpNoDelay(tcpNoDelay.booleanValue());
if(!trafficClassSet)
trafficClassSet = setTrafficClass(sock);
}

初始化输入输出流
initializeStreams();

 protected void initializeStreams()
throws Exception
{
//创建Tcp缓存区输入流
TcpBufferedInputStream buffIn = new TcpBufferedInputStream(socket.getInputStream(), ioBufferSize) {

public int read()
throws IOException
{
receiveCounter++;
return super.read();
}

public int read(byte b[], int off, int len)
throws IOException
{
receiveCounter++;
return super.read(b, off, len);
}

public long skip(long n)
throws IOException
{
receiveCounter++;
return super.skip(n);
}

protected void fill()
throws IOException
{
receiveCounter++;
super.fill();
}

final TcpTransport this$0;


{
this$0 = TcpTransport.this;
super(x0, x1);
}
};
//创建数据输入流
dataIn = new DataInputStream(buffIn);
//创建tcp输出流
TcpBufferedOutputStream outputStream = new TcpBufferedOutputStream(socket.getOutputStream(), ioBufferSize);
//创建数据输出流
dataOut = new DataOutputStream(outputStream);
buffOut = outputStream;
}

再看TransportThreadSupport
//TransportThreadSupport
public abstract class TransportThreadSupport extends TransportSupport
implements Runnable
{
private boolean daemon;
private Thread runner;
private long stackSize;
//启动TransportThread线程
protected void doStart()
throws Exception
{
runner = new Thread(null, this, (new StringBuilder()).append("ActiveMQ Transport: ").append(toString()).toString(), stackSize);
runner.setDaemon(daemon);
runner.start();
}

}

从上可以看出启动transport,就是启动transport监听器和Service监听器,同时初始化Socket及
transport的数据输入DataInputStream,输出流DataOutputStream

再来看
启动连接
connection.start(); 
public void start()
throws JMSException
{
checkClosedOrFailed();
ensureConnectionInfoSent();
if(started.compareAndSet(false, true))
{
ActiveMQSession session;
//启动会话
for(Iterator i = sessions.iterator(); i.hasNext(); session.start())
session = (ActiveMQSession)i.next();
}
}

今天现将这么多剩下的下一篇来讲,总结一下:
[color=green]ActiveMQConnectionFactory的创建过程,主要为初始化为broker url,用户密码,是否压缩、异步发送消息、支持消息优先级、非阻塞传输,最大线程数,生产窗口大小等属性;从ActiveMQConnectionFactory创建连接,首先通过TcpTransportFacotory创建TcpTransport,然后保证成待锁机制的MutexTransport,最后包装成
ResponseCorrelator;根据TcpTransport和ActiveMQConnection状态管理器JMSStatsImpl创建ActiveMQConnection,创建ActiveMQConnection过程中,主要是是否异步分发消息,线程执行器,连接状态管理器,调度器等;然后设置连接用户密码通过ConnectionInfo,配置是否支持消息优先级、非阻塞传输,最大线程数,生产窗口大小,Transport监听器transportListener;
最后启动TcpTransport和Connection,启动TcpTransport主要是初始化socket,
ip,端口,输入输出缓存区,输入输出流DataI/OnputStream,启动连接主要启动会话ActiveMQSession,这个我们在后面再看,以及3,4,5,6。[/color]


3.会话
Session session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE); 

4.消息队列和订阅主题
Queue  destination = session.createQueue(qname);
Topic destination = session.createTopic(tname)
;
5.创建生产者
MessageProducer producer = session.createProducer(destination);  
producer.setDeliveryMode(DeliveryMode.PERSISTENT);


6.发送消息
sendMessage(session, producer);
Queue
public static void sendMessage(Session session, MessageProducer producer)
throws Exception {
for (int i = 1; i <= 5; i++) {//有限制,达到1000就不行
TextMessage message = session.createTextMessage("向ActiveMq发送的Queue消息" + i);
// 发送消息到目的地方
System.out.println("发送消息:" + "ActiveMq 发送的Queue消息" + i);
producer.send(message);
}
}
Topic
/**
*
* @param session
* @param producer
* @throws Exception
*/
public static void sendMessage(Session session, MessageProducer producer)
throws Exception {
Order order = new Order();
order.setId(1);
order.setAmount(150.62);
order.setGoodsId(15);
order.setGoodsAmount(2);
order.setShopId(5656);
//我们也可以将Object转换为Json String,作为TextMessage来传送,在消费再反Json String 为Obejct
ObjectMessage orderMess = session.createObjectMessage(order);
System.out.println("向ActiveMq:"+tname+"发送订单信息:" + "ActiveMq 发送的Topic消息");
producer.send(orderMess);
}




//ConnectionFactory
package javax.jms;
public interface ConnectionFactory
{

public abstract Connection createConnection()
throws JMSException;

public abstract Connection createConnection(String s, String s1)
throws JMSException;
}

//QueueConnectionFactory
package javax.jms;
public interface QueueConnectionFactory
extends ConnectionFactory
{

public abstract QueueConnection createQueueConnection()
throws JMSException;

public abstract QueueConnection createQueueConnection(String s, String s1)
throws JMSException;
}

//TopicConnectionFactory
package javax.jms;

public interface TopicConnectionFactory
extends ConnectionFactory
{

public abstract TopicConnection createTopicConnection()
throws JMSException;

public abstract TopicConnection createTopicConnection(String s, String s1)
throws JMSException;
}

//IdGenerator 客户端,连接ID产生器
public class IdGenerator
{
private static final String UNIQUE_STUB;
private static int instanceCount;
private static String hostName;
private String seed;
private final AtomicLong sequence;
private int length;
public static final String PROPERTY_IDGENERATOR_HOSTNAME = "activemq.idgenerator.hostname";
public static final String PROPERTY_IDGENERATOR_LOCALPORT = "activemq.idgenerator.localport";
public static final String PROPERTY_IDGENERATOR_PORT = "activemq.idgenerator.port";

public IdGenerator(String prefix)
{
sequence = new AtomicLong(1L);
synchronized(UNIQUE_STUB)
{
seed = (new StringBuilder()).append(prefix).append(UNIQUE_STUB).append(instanceCount++).append(":").toString();
length = seed.length() + "9223372036854775807".length();
}
}
public synchronized String generateId()
{
StringBuilder sb = new StringBuilder(length);
sb.append(seed);
sb.append(sequence.getAndIncrement());
return sb.toString();
}
}

//QueueConnection
public interface QueueConnection
extends Connection
{

public abstract QueueSession createQueueSession(boolean flag, int i)
throws JMSException;

public abstract ConnectionConsumer createConnectionConsumer(Queue queue, String s, ServerSessionPool serversessionpool, int i)
throws JMSException;
}


//TopicConnection
 public interface TopicConnection
extends Connection
{

public abstract TopicSession createTopicSession(boolean flag, int i)
throws JMSException;

public abstract ConnectionConsumer createConnectionConsumer(Topic topic, String s, ServerSessionPool serversessionpool, int i)
throws JMSException;

public abstract ConnectionConsumer createDurableConnectionConsumer(Topic topic, String s, String s1, ServerSessionPool serversessionpool, int i)
throws JMSException;
}


//Cloneable
package java.lang;

/**
* A class implements the <code>Cloneable</code> interface to
* indicate to the {@link java.lang.Object#clone()} method that it
* is legal for that method to make a
* field-for-field copy of instances of that class.
* <p>
* Invoking Object's clone method on an instance that does not implement the
* <code>Cloneable</code> interface results in the exception
* <code>CloneNotSupportedException</code> being thrown.
* <p>
* By convention, classes that implement this interface should override
* <tt>Object.clone</tt> (which is protected) with a public method.
* See {@link java.lang.Object#clone()} for details on overriding this
* method.
* <p>
* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface. Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.
*
* @author unascribed
* @see java.lang.CloneNotSupportedException
* @see java.lang.Object#clone()
* @since JDK1.0
*/
public interface Cloneable {
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值