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