Java tutorial
/* * (C) 2007-2012 Alibaba Group Holding Limited. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * Authors: * wuhua <wq163@163.com> , boyan <killme2008@gmail.com> */ package com.alibaba.napoli.metamorphosis.client.consumer.storage; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.I0Itec.zkclient.ZkClient; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.alibaba.napoli.metamorphosis.client.ZkClientChangedListener; import com.alibaba.napoli.metamorphosis.client.consumer.TopicPartitionRegInfo; import com.alibaba.napoli.metamorphosis.cluster.Partition; import com.alibaba.napoli.metamorphosis.utils.MetaZookeeper; import com.alibaba.napoli.metamorphosis.utils.MetaZookeeper.ZKGroupTopicDirs; import com.alibaba.napoli.metamorphosis.utils.ZkUtils; /** * zkoffset * * @author boyan * @Date 2011-4-28 * */ public class ZkOffsetStorage implements OffsetStorage, ZkClientChangedListener { private volatile ZkClient zkClient; private final MetaZookeeper metaZookeeper; @Override public void onZkClientChanged(final ZkClient newClient) { log.info("Update ZkOffsetStorage's zkClient..."); this.zkClient = newClient; } public ZkOffsetStorage(final MetaZookeeper metaZookeeper, final ZkClient zkClient) { super(); this.metaZookeeper = metaZookeeper; this.zkClient = zkClient; } static final Log log = LogFactory.getLog(ZkOffsetStorage.class); @Override public void commitOffset(final String group, final Collection<TopicPartitionRegInfo> infoList) { if (this.zkClient == null || infoList == null || infoList.isEmpty()) { return; } List<TopicPartitionRegInfo> shouldDeleteList = new ArrayList<TopicPartitionRegInfo>(); for (final TopicPartitionRegInfo info : infoList) { final String topic = info.getTopic(); final ZKGroupTopicDirs topicDirs = this.metaZookeeper.new ZKGroupTopicDirs(topic, group); long newOffset = -1; long msgId = -1; // ???msgIdoffset synchronized (info) { // ?? if (!info.isModified()) { continue; } newOffset = info.getOffset().get(); msgId = info.getMessageId(); // false info.setModified(false); } try { if (!ZkUtils.pathExists(this.zkClient, topicDirs.consumerOffsetDir + "/" + info.getPartition().toString())) { Partition partition = info.getPartition(); int brokerId = partition.getBrokerId(); String brokerTopicPath = this.metaZookeeper.brokerTopicsPathOf(topic, brokerId, -1); if (!ZkUtils.pathExists(this.zkClient, brokerTopicPath)) { shouldDeleteList.add(info); continue; } } // zk?msgId-offset // ?offset1.4msgId-offset,?? ZkUtils.updatePersistentPath(this.zkClient, topicDirs.consumerOffsetDir + "/" + info.getPartition().toString(), msgId + "-" + newOffset); } catch (final Throwable t) { log.error("exception during commitOffsets", t); } if (log.isDebugEnabled()) { log.debug("Committed offset " + newOffset + " for topic " + info.getTopic()); } } if (shouldDeleteList.size() > 0) { for (TopicPartitionRegInfo deleteInfo : shouldDeleteList) { log.warn(deleteInfo.getTopic() + " remove form borked[" + deleteInfo.getPartition().getBrokerId() + "]"); } infoList.remove(shouldDeleteList); } } @Override public TopicPartitionRegInfo load(final String topic, final String group, final Partition partition) { final ZKGroupTopicDirs topicDirs = this.metaZookeeper.new ZKGroupTopicDirs(topic, group); final String znode = topicDirs.consumerOffsetDir + "/" + partition.toString(); final String offsetString = ZkUtils.readDataMaybeNull(this.zkClient, znode); if (offsetString == null) { return null; } else { // ? final int index = offsetString.lastIndexOf("-"); if (index > 0) { // 1.4 final long msgId = Long.parseLong(offsetString.substring(0, index)); final long offset = Long.parseLong(offsetString.substring(index + 1)); return new TopicPartitionRegInfo(topic, partition, offset, msgId); } else { // ? final long offset = Long.parseLong(offsetString); return new TopicPartitionRegInfo(topic, partition, offset); } } } @Override public void close() { // do nothing } @Override public void initOffset(final String topic, final String group, final Partition partition, final long offset) { // do nothing } }