public void start(final boolean startFactory) throws MQClientException {
    switch (this.serviceState) {
      case CREATE_JUST:
        this.serviceState = ServiceState.START_FAILED;

        this.checkConfig();

        this.mQClientFactory =
            MQClientManager.getInstance().getAndCreateMQClientFactory(this.defaultMQProducer);

        boolean registerOK =
            mQClientFactory.registerProducer(this.defaultMQProducer.getProducerGroup(), this);
        if (!registerOK) {
          this.serviceState = ServiceState.CREATE_JUST;
          throw new MQClientException(
              "The producer group["
                  + this.defaultMQProducer.getProducerGroup()
                  + "] has been created before, specify another name please."
                  + FAQUrl.suggestTodo(FAQUrl.GROUP_NAME_DUPLICATE_URL),
              null);
        }

        // 默认Topic注册
        this.topicPublishInfoTable.put(
            this.defaultMQProducer.getCreateTopicKey(), new TopicPublishInfo());

        if (startFactory) {
          mQClientFactory.start();
        }

        log.info("the producer [{}] start OK", this.defaultMQProducer.getProducerGroup());
        this.serviceState = ServiceState.RUNNING;
        break;
      case RUNNING:
      case START_FAILED:
      case SHUTDOWN_ALREADY:
        throw new MQClientException(
            "The producer service state not OK, maybe started once, " //
                + this.serviceState //
                + FAQUrl.suggestTodo(FAQUrl.CLIENT_SERVICE_NOT_OK),
            null);
      default:
        break;
    }

    this.mQClientFactory.sendHeartbeatToAllBrokerWithLock();
  }
 private void makeSureStateOK() throws MQClientException {
   if (this.serviceState != ServiceState.RUNNING) {
     throw new MQClientException(
         "The producer service state not OK, " //
             + this.serviceState //
             + FAQUrl.suggestTodo(FAQUrl.CLIENT_SERVICE_NOT_OK),
         null);
   }
 }
  private void makesureInstanceNameIsOnly(final String instanceName) throws MQClientException {
    int udpPort = 33333;

    int value = instanceName.hashCode();
    if (value < 0) {
      value = Math.abs(value);
    }

    udpPort += value % 10000;

    try {
      this.datagramSocket = new DatagramSocket(udpPort);
    } catch (SocketException e) {
      throw new MQClientException(
          "instance name is a duplicate one["
              + instanceName
              + ","
              + udpPort
              + "], please set a new name"
              + FAQUrl.suggestTodo(FAQUrl.CLIENT_INSTACNCE_NAME_DUPLICATE_URL),
          e);
    }
  }
  private SendResult sendDefaultImpl( //
      Message msg, //
      final CommunicationMode communicationMode, //
      final SendCallback sendCallback //
      ) throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
    // 有效性检查
    this.makeSureStateOK();
    Validators.checkMessage(msg, this.defaultMQProducer);

    final long beginTimestamp = System.currentTimeMillis();
    long endTimestamp = beginTimestamp;
    TopicPublishInfo topicPublishInfo = this.tryToFindTopicPublishInfo(msg.getTopic());
    if (topicPublishInfo != null && topicPublishInfo.ok()) {
      MessageQueue mq = null;
      Exception exception = null;
      SendResult sendResult = null;
      int timesTotal = 1 + this.defaultMQProducer.getRetryTimesWhenSendFailed();
      for (int times = 0;
          times < timesTotal
              && (endTimestamp - beginTimestamp) < this.defaultMQProducer.getSendMsgTimeout();
          times++) {
        String lastBrokerName = null == mq ? null : mq.getBrokerName();
        MessageQueue tmpmq = topicPublishInfo.selectOneMessageQueue(lastBrokerName);
        if (tmpmq != null) {
          mq = tmpmq;
          try {
            sendResult = this.sendKernelImpl(msg, mq, communicationMode, sendCallback);
            endTimestamp = System.currentTimeMillis();
            switch (communicationMode) {
              case ASYNC:
                return null;
              case ONEWAY:
                return null;
              case SYNC:
                if (sendResult.getSendStatus() != SendStatus.SEND_OK) {
                  if (this.defaultMQProducer.isRetryAnotherBrokerWhenNotStoreOK()) {
                    continue;
                  }
                }

                return sendResult;
              default:
                break;
            }
          } catch (RemotingException e) {
            log.warn("sendKernelImpl exception", e);
            log.warn(msg.toString());
            exception = e;
            endTimestamp = System.currentTimeMillis();
            continue;
          } catch (MQClientException e) {
            log.warn("sendKernelImpl exception", e);
            log.warn(msg.toString());
            exception = e;
            endTimestamp = System.currentTimeMillis();
            continue;
          } catch (MQBrokerException e) {
            log.warn("sendKernelImpl exception", e);
            log.warn(msg.toString());
            exception = e;
            endTimestamp = System.currentTimeMillis();
            switch (e.getResponseCode()) {
              case MQResponseCode.TOPIC_NOT_EXIST_VALUE:
              case MQResponseCode.SERVICE_NOT_AVAILABLE_VALUE:
              case ResponseCode.SYSTEM_ERROR_VALUE:
              case MQResponseCode.NO_PERMISSION_VALUE:
                continue;
              default:
                if (sendResult != null) {
                  return sendResult;
                }

                throw e;
            }
          } catch (InterruptedException e) {
            log.warn("sendKernelImpl exception", e);
            log.warn(msg.toString());
            throw e;
          }
        } else {
          break;
        }
      } // end of for

      if (sendResult != null) {
        return sendResult;
      }

      throw new MQClientException("Retry many times, still failed", exception);
    }

    List<String> nsList = this.getmQClientFactory().getMQClientAPIImpl().getNameServerAddressList();
    if (null == nsList || nsList.isEmpty()) {
      // 说明没有设置Name Server地址
      throw new MQClientException(
          "No name server address, please set it."
              + FAQUrl.suggestTodo(FAQUrl.NAME_SERVER_ADDR_NOT_EXIST_URL),
          null);
    }

    throw new MQClientException(
        "No route info of this topic, "
            + msg.getTopic()
            + FAQUrl.suggestTodo(FAQUrl.NO_TOPIC_ROUTE_INFO),
        null);
  }