81,119
社区成员
发帖
与我相关
我的任务
分享
Exception in thread "main" org.apache.rocketmq.client.exception.MQClientException: Send [3] times, still failed, cost [475]ms, Topic: TopicTest, BrokersSent: [MS-20160803HVCK, MS-20160803HVCK, MS-20160803HVCK]
See http://rocketmq.apache.org/docs/faq/ for further details.
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:586)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1223)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1173)
at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:214)
at com.example.demo.test2.SyncProducer.main(SyncProducer.java:29)
Caused by: org.apache.rocketmq.client.exception.MQBrokerException: CODE: 14 DESC: service not available now, maybe disk full, CL: 0.97 CQ: 0.97 INDEX: 0.97, maybe your broker machine memory too small.
For more information, please visit the url, http://rocketmq.apache.org/docs/faq/
at org.apache.rocketmq.client.impl.MQClientAPIImpl.processSendResponse(MQClientAPIImpl.java:556)
at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessageSync(MQClientAPIImpl.java:358)
at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:340)
at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:294)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendKernelImpl(DefaultMQProducerImpl.java:761)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:505)
... 4 more
if (!this.runningFlags.isWriteable()) {
long value = this.printTimes.getAndIncrement();
if ((value % 50000) == 0) {
log.warn("message store is not writeable, so putMessage is forbidden " + this.runningFlags.getFlagBits());
}
return new PutMessageResult(PutMessageStatus.SERVICE_NOT_AVAILABLE, null);
} else {
this.printTimes.set(0);
}
runningFlags是RunningFlags.java类中的一个属性初始值是0,isWriteable()是把这个flags做按位与按位或运算,判断结果是否为0,为0返回true,非0返回false 判断如下
public boolean isWriteable() {
if ((this.flagBits & (NOT_WRITEABLE_BIT | WRITE_LOGICS_QUEUE_ERROR_BIT | DISK_FULL_BIT | WRITE_INDEX_FILE_ERROR_BIT)) == 0) {
return true;
}
return false;
}
这块判断的逻辑我不是很懂,是判断磁盘是否不足?因为在上面第一段的代码中!this.runningFlags.isWriteable()成立的话会执行 return new PutMessageResult(PutMessageStatus.SERVICE_NOT_AVAILABLE, null);,而等于SERVICE_NOT_AVAILABLE的话在外面的方法中会给response的code值复制为14,然后给remarks赋值报错的磁盘不足的信息。我对flagBits 这个字段作用不是很理解,比如第一次进入它的值是0,下一次进入值就变为16了,然后就返回false接着逻辑就往报错的方向走了,找了半天也没找着这个flagBits 的值是什么时候变化的,是怎么变化的。我调试源码把.isWriteable()的返回值都设为true后 rocketmq生产消费多少次都没问题了,在多少秒内消费也都不会报错了
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=SYNC_MASTER
flushDiskType=ASYNC_FLUSH
diskMaxUsedSpaceRatio=95
启动指令是mqbroker.cmd -n localhost:9876 autoCreateTopicEnable=true -c ../conf/2m-2s-sync/broker-a.properties
@ImportantField
private String deleteWhen = "04";
private int diskMaxUsedSpaceRatio = 75;
if (commandLine.hasOption('c')) {
String file = commandLine.getOptionValue('c');
if (file != null) {
configFile = file;
InputStream in = new BufferedInputStream(new FileInputStream(file));
properties = new Properties();
properties.load(in);
properties2SystemEnv(properties);
MixAll.properties2Object(properties, brokerConfig);
MixAll.properties2Object(properties, nettyServerConfig);
MixAll.properties2Object(properties, nettyClientConfig);
MixAll.properties2Object(properties, messageStoreConfig);
BrokerPathConfigHelper.setBrokerConfigPath(file);
in.close();
}
}
public static void properties2Object(final Properties p, final Object object) {
Method[] methods = object.getClass().getMethods();
for (Method method : methods) {
String mn = method.getName();
if (mn.startsWith("set")) {
try {
String tmp = mn.substring(4);
String first = mn.substring(3, 4);
String key = first.toLowerCase() + tmp;
String property = p.getProperty(key);
if (property != null) {
Class<?>[] pt = method.getParameterTypes();
if (pt != null && pt.length > 0) {
String cn = pt[0].getSimpleName();
Object arg = null;
if (cn.equals("int") || cn.equals("Integer")) {
arg = Integer.parseInt(property);
} else if (cn.equals("long") || cn.equals("Long")) {
arg = Long.parseLong(property);
} else if (cn.equals("double") || cn.equals("Double")) {
arg = Double.parseDouble(property);
} else if (cn.equals("boolean") || cn.equals("Boolean")) {
arg = Boolean.parseBoolean(property);
} else if (cn.equals("float") || cn.equals("Float")) {
arg = Float.parseFloat(property);
} else if (cn.equals("String")) {
arg = property;
} else {
continue;
}
method.invoke(object, arg);
}
}
} catch (Throwable ignored) {
}
}
}
private boolean isSpaceToDelete() {
double ratio = DefaultMessageStore.this.getMessageStoreConfig().getDiskMaxUsedSpaceRatio() / 100.0;
cleanImmediately = false;
{
String storePathPhysic = DefaultMessageStore.this.getMessageStoreConfig().getStorePathCommitLog();
double physicRatio = UtilAll.getDiskPartitionSpaceUsedPercent(storePathPhysic);
if (physicRatio > diskSpaceWarningLevelRatio) {
boolean diskok = DefaultMessageStore.this.runningFlags.getAndMakeDiskFull();
if (diskok) {
DefaultMessageStore.log.error("physic disk maybe full soon " + physicRatio + ", so mark disk full");
}
cleanImmediately = true;
} else if (physicRatio > diskSpaceCleanForciblyRatio) {
cleanImmediately = true;
} else {
boolean diskok = DefaultMessageStore.this.runningFlags.getAndMakeDiskOK();
if (!diskok) {
DefaultMessageStore.log.info("physic disk space OK " + physicRatio + ", so mark disk ok");
}
}
if (physicRatio < 0 || physicRatio > ratio) {
DefaultMessageStore.log.info("physic disk maybe full soon, so reclaim space, " + physicRatio);
return true;
}
}
public int getDiskMaxUsedSpaceRatio() {
if (this.diskMaxUsedSpaceRatio < 10)
return 10;
if (this.diskMaxUsedSpaceRatio > 95)
return 95;
return diskMaxUsedSpaceRatio;
}
class CleanCommitLogService {
private final static int MAX_MANUAL_DELETE_FILE_TIMES = 20;
private final double diskSpaceWarningLevelRatio =
Double.parseDouble(System.getProperty("rocketmq.broker.diskSpaceWarningLevelRatio", "0.90"));
private final double diskSpaceCleanForciblyRatio =
Double.parseDouble(System.getProperty("rocketmq.broker.diskSpaceCleanForciblyRatio", "0.85"));
private long lastRedeleteTimestamp = 0;
private volatile int manualDeleteFileSeveralTimes = 0;
private volatile boolean cleanImmediately = false;
public void excuteDeleteFilesManualy() {
this.manualDeleteFileSeveralTimes = MAX_MANUAL_DELETE_FILE_TIMES;
DefaultMessageStore.log.info("executeDeleteFilesManually was invoked");
}