producer的源码结构如下:
DefaultMQProducer producer = new DefaultMQProducer("producerGroupName");
producer.setNamesrvAddr(namesrv);
producer.start();
producer.send(msg);
所以就从DefaultMQProducer 开始说起吧:
一、DefaultMQProducer继承ClientConfig类同时实现了MQProducer接口,同时包含一个重要的属性
public class DefaultMQProducer extends ClientConfig implements MQProducer {
protected final transient DefaultMQProducerImpl defaultMQProducerImpl;
DefaultMQProducer作为rocketmq生产者的默认实现,其实它并没有做任何实现,其内部引用一个DefaultMQProducerImpl实例进行具体消息发送。
它有一些基础配置,比如多长时间内消息发送多少次还是没成功则放弃(默认为4秒内发送3次,每次发消息默认超时间为3秒)
- 重要字段
1 String producerGroup 生产者的组名。
一个jvm内,具有相同producerGroup名字的生产者实例只有一个。
2 retryAnotherBrokerWhenNotStoreOK
消息没有存储成功是否发送到另外一个broker.
3 sendMsgTimeout
发送消息超时时间,默认为3秒 - 重要方法
send(Message msg)
发送消息,调用DefaultMQProducerImpl .send()发送
ClientConfig类就是客户端的公共配置参数说明:
amesrvAddr //namesrv地址列表,多个地址列表用分号隔开
clientIP //本机ip
instanceName //客户端实例名称,客户端创建的多个producer,consumer实际上共用的一个内部实例(包含网络数据和线程资源)
clientCallbackExecutorThreads //通信层异步回调线程数
pollNameServerInterval //轮询namesrv时间间隔 默认30秒
heartbeatBrokerInterval //向broker发送心跳时间间隔 默认30秒
persistConsumerOffsetInterval //持久化consumer消费进度的时间间隔
包括我们的producer.setNamesrvAddr(namesrv);其实就是调用了ClientConfig.setNamesrvAddr(namesrv);
当然,里面还包括了一些不常用,但也很重要的方法,比如
ClientConfig.resetClientConfig(final ClientConfig cc) //自定义一个客户端配置
ClientConfig.cloneClientConfig() //克隆一个已有的客户端配置
至于MQProducer接口就不用说了,定义了一组接口,例如
start(); //启动
producersend (final Message msg, final SendCallback sendCallback, final long timeout) ; //发送消息
.........
DefaultMQProducerImpl:
非常重要的一个方法,start(),也就是producer的启动方法,该方法的大致流程如下:
public void start(final boolean startFactory) throws MQClientException {
switch (this.serviceState) {
case CREATE_JUST: 1、
this.serviceState = ServiceState.START_FAILED; 2、
this.checkConfig(); 3、
if (!this.defaultMQProducer.getProducerGroup().equals(MixAll.CLIENT_INNER_PRODUCER_GROUP)) {
this.defaultMQProducer.changeInstanceNameToPID(); 4、
}
this.mQClientFactory = MQClientManager.getInstance().getAndCreateMQClientInstance(this.defaultMQProducer, rpcHook); 5、
boolean registerOK = mQClientFactory.registerProducer(this.defaultMQProducer.getProducerGroup(), this); 6、
this.topicPublishInfoTable.put(this.defaultMQProducer.getCreateTopicKey(), new TopicPublishInfo()); 7、
if (startFactory) {
mQClientFactory.start(); 8、
}
this.serviceState = ServiceState.RUNNING;
}
this.mQClientFactory.sendHeartbeatToAllBrokerWithLock(); 9、
1、检查DefaultMQProducerImpl.ServiceState的状态(初始化状态为ServiceState.CREATE_JUST);只有状态为CREATE_JUST时才启动该Producer;其他状态均不执行启动过程;
2、将DefaultMQProducerImpl.ServiceState置为start_failed,以免客户端同一个进程中重复启动;
3、检查producerGroup是否合法:不能为空、不能有非法字符、长度不能大于255、不能等于"DEFAULT_PRODUCER";若不合法则直接向应用层抛出MQClientException异常;若producerGroup不等于"CLIENT_INNER_PRODUCER"则设置Producer的实例名(instanceName);调用java的ManagementFactory.getRuntimeMXBean()方法获取该进程的PID作为该Producer的实例名(instanceName);