metaq生產者發送消息找不到指定partition調查

前記java

metaq,(metamorphosis),一款設計起源於kafka的,高可用、高性能、可擴展、分佈式的消息中間件,MetaQ具備消息存儲順序寫、吞吐量大和支持本地和XA事務等特性,適合大規模分佈式系統應用的特色深受一些互聯網企業的喜好。spring

      而最近,項目中用到metaq做爲消息隊列框架來處理消息,可是,最近出現消息沒有被消費的問題,查了消費端服務器日誌,沒有查到異常、又查了服務端發送消息的日誌,也沒有發現異常,還覺得是消息消費延遲,由於最近活動比較多,消息也多。後來等了大半天,仍是麼有結果。因而,我又從新檢查了一遍日誌,最終仍是發現了問題的蛛絲馬跡:
 - 2017-01-10 12:59:40,204 [// -  - ] INFO  com.api.pub.mq.MetaQUtils - topic info :api-quancart-log has send {"xxx":"x","xxx":xx,"xx":xx,"xx":xx} to metaq null

懷疑是否是異常被吞沒了,查找源碼,發現此方法的catch裏有可能被吃掉異常,因而調試,重寫MetaqTemplate類,加日誌以下:api

    /**
     * Send message built by message builder.Returns the sent result.
     * 
     * @param builder
     * @return
     * @throws InterruptedException
     * @since 1.4.5
     */
    private static final Logger logger = LoggerFactory.getLogger(MetaqTemplate.class);

    public SendResult send(MessageBuilder builder) throws InterruptedException {
        Message msg = builder.build(this.messageBodyConverter);
        final String topic = msg.getTopic();
        MessageProducer producer = this.getOrCreateProducer(topic);
        try {
            return producer.sendMessage(msg);
        } catch (MetaClientException e) {
            logger.error(e.getMessage(), e); return new SendResult(false, null, -1, ExceptionUtils.getFullStackTrace(e));
        }
    }

因而,就有了一下的異常棧:服務器

 - ................. 
[// - - ] ERROR com.taobao.metamorphosis.client.extension.spring.MetaqTemplate - Send message timeout in 3000 mills com.taobao.metamorphosis.exception.MetaOpeartionTimeoutException: Send message timeout in 3000 mills at com.taobao.metamorphosis.client.producer.SimpleMessageProducer.send0(SimpleMessageProducer.java:456) at com.taobao.metamorphosis.client.producer.SimpleMessageProducer.sendMessageToServer(SimpleMessageProducer.java:194) at com.taobao.metamorphosis.client.producer.SimpleMessageProducer.sendMessage(SimpleMessageProducer.java:171) at com.taobao.metamorphosis.client.producer.SimpleMessageProducer.sendMessage(SimpleMessageProducer.java:585) at com.taobao.metamorphosis.client.extension.spring.MetaqTemplate.send(MetaqTemplate.java:220) ..........

看來,果真是異常被吃掉了,SimpleMessageProducer 的456行以下圖:網絡

緣由算是找到了,怎麼解決呢?session

初步分析結果:網絡和超時時間這是超時時間致使,由於這段時間活動多網站流量高,進而影響了mq消息服務器的網絡,解決辦法,改善網絡情況,這一點有點可望而不可即,雖然說這是最根本的方法,可是鑑於公司的情況如今這上邊改善可能會花點錢,或者至少折騰下運維的兄弟們;再者,就是調大一點超時時間。框架

帶着這個疑問,看了下配置文件:運維

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

     <bean id="sessionFactory"
          class="com.taobao.metamorphosis.client.extension.spring.MetaqMessageSessionFactoryBean">
          <property name="zkConnect" value="${pom.metaq.zkConnect}" />
          <property name="zkSessionTimeoutMs" value="15000" />
          <property name="zkConnectionTimeoutMs" value="15000" />
          <property name="zkSyncTimeMs" value="15000" />
     </bean>

     <bean id="messageBodyConverter"
          class="com.taobao.metamorphosis.client.extension.spring.JavaSerializationMessageBodyConverter" />

     <bean id="metaqTemplate"
          class="com.taobao.metamorphosis.client.extension.spring.MetaqTemplate">
          <property name="messageSessionFactory" ref="sessionFactory" />
          <property name="messageBodyConverter" ref="messageBodyConverter" />
          <!--以共享一個MessageProducer來發送多個topic的消息 -->
          <property name="shareProducer" value="true" />
     </bean>

     <bean class="com.api.pub.mq.MetaQInitQBean" init-method="init">
          <property name="metaqTemplate" ref="metaqTemplate" />
     </bean>

</beans>

自定義的工具類沒有定義超時時間,用的默認的超時時間:分佈式

最後,解決辦法,在工具類com.api.pub.mq.MetaQInitQBean中增長變量,配置文件注入自定義超時時間,工具

private int customTimeout = 30;

    public int getCustomTimeout() {
        return customTimeout;
    }

    public void setCustomTimeout(int customTimeout) {
        this.customTimeout= customTimeout;
    }

改用MetaqTemplate中帶超時時間的方法

    /**
     * Send message built by message builder.Returns the sent result.
     * 
     * @param builder
     * @return
     * @throws InterruptedException
     * @since 1.4.5
     */
    public SendResult send(MessageBuilder builder, long timeout, TimeUnit unit) throws InterruptedException {
        Message msg = builder.build(this.messageBodyConverter);
        final String topic = msg.getTopic();
        MessageProducer producer = this.getOrCreateProducer(topic);
        try {
            return producer.sendMessage(msg, timeout, unit);
        } catch (MetaClientException e) {
            return new SendResult(false, null, -1, ExceptionUtils.getFullStackTrace(e));
        }
    }

問題解決!

相關文章
相關標籤/搜索