1)创建DefaultMQProducer实例
入参为生产者组名,其中会创建DefaultMQProducerImpl实例,在DefaultMQProducerImpl的构造方法中会创建缺省的异步消息任务线程池defaultAsyncSenderExecutor;DefaultMQProducer类继承了ClientConfig类,实际上与配置有关;DefaultMQProducer类充当了门面角色,采用了门面设计模式;
2)producer.start()
启动哪些:客户端netty,定时任务,一些线程等;
2.1)判断serviceState的状态
一共有四种,CREATE_JUST,RUNNING,SHUTDOWN_ALREADY ,START_FAILED;创建DefaultMQProducerImpl时,会初始化serviceState状态为CREATE_JUST;所以此时会先进入到CREATE_JUST分支,随后立马修改serviceState状态为START_FAILED;
2.2)创建MQClientInstance实例
调用getOrCreateMQClientInstance方法创建客户端实例;
2.2.1)创建clientId
调用buildMQClientId方法,如果unitName为null,则clientId为ip@pid,否则为ip@pid@unitName,所以说当一个jvm进程中有多个DefaultMQProducerImpl实例时,若每个实例都设置了不同的unitName,则会出现多个clientId,对应多个MQClientInstance;clientId由clientIp,instanceName和unitName决定,clientIp即客户端的 IP 地址;instanceName即实例名称,默认值为 DEFAULT,但在真正 clientConfig 的 getInstanceName 方法时如果实例名称为 DEFAULT,会自动将其替换为进程的 PID;unitName即单元名称,如果不为空,则会追加到 clientId 中。
2.2.2)实例化MQClientInstance
调用执行MQClientInstance有参构造方法;
2.2.2.1)与config相关
包括clientConfig和nettyClientConfig;
2.2.2.1.1)clientConfig作为入参赋给属性,ClientConfig类主要包括以下属性:namesrv地址,client的ip,客户端实例名称,客户端回调处理线程池的线程数,拉取消息,心跳,持久化等间隔时间以及其它;
2.2.2.1.2)实例化NettyClientConfig,在NettyClientConfig的构造方法中主要包括(全部都是保存一些值到属性中,并未进行任何实例化,在nettyRemotingClient中使用这些属性):
a)给客户端worker组的业务线程池defaultEventExecutorGroup的线程数赋值为4;注意worker组线程池和worker组业务线程池是不同的,前者中每个线程是nioEventLoop,每个线程中拥有一个selector,监听事件的;而后者是处理具体业务的;
b)保存客户端回调处理线程池的线程数到属性;
c)保存单向和异步请求的线程并发上限值到属性;
d)客户端连接服务端的超时时间3秒,客户端channel激活超时时间为60秒,客户端channel的最大空闲时间为120秒,客户端socket写和读缓冲大小均为65536字节即64kb;
2.2.2.2)实例化协议处理器和MQClientAPIImpl
2.2.2.2.1)实例化ClientRemotingProcessor,客户端用它去处理io事件;
2.2.2.2.2)实例化MQClientAPIImpl,它负责将MQ业务层的数据转换为网络层RemotingCommand对象,然后使用内部的NettyRemotingClient的invoke系列方法完成网络io;在MQClientAPIImpl的构造方法中会执行:
a)会实例化NettyRemotingClient,在NettyRemotingClient的构造方法中会设置如下(a1是发送相关,a2,a3是接收相关&