/** * Get machine identifier * * @return integer Should be a 10-bit int (decimal 0 to 1023) */ public function getMachine() { $machineId = NULL; $this->createParentIfNeeded($this->parentPath); // get info about _this_ machine $machineInfo = $this->getMachineInfo(); // get current machine list $children = $this->zk->getChildren($this->parentPath); foreach ($children as $child) { $info = $this->zk->get("{$this->parentPath}/{$child}"); $info = json_decode($info, TRUE); if (isset($info['macAddress']) && $info['macAddress'] === $machineInfo['macAddress']) { $machineId = (int) $child; } } // find an unused machine number for ($i = 0; $i < 1024, $machineId === NULL; $i++) { $machineNode = $this->machineToNode($i); if (in_array($machineNode, $children)) { continue; // already used } // attempt to claim $created = $this->zk->create("{$this->parentPath}/{$machineNode}", json_encode($machineInfo), array(array('perms' => \Zookeeper::PERM_ALL, 'scheme' => 'world', 'id' => 'anyone'))); if ($created !== NULL) { $machineId = $i; break; } } if ($machineId === NULL) { throw new \RuntimeException("Cannot locate and claim a free machine ID via ZK"); } echo "Claimed machine ID {$machineId} for " . json_encode($machineInfo) . "\n"; return (int) $machineId; }
/** * Get machine identifier. * * @throws RuntimeException Thrown, when obtaining machine ID has failed. * * @return int Should be a 10-bit int (decimal 0 to 1023) */ public function getMachine() { $machineId = null; $this->createParentIfNeeded($this->parentPath); // get info about _this_ machine $machineInfo = $this->getMachineInfo(); // get current machine list $children = $this->zk->getChildren($this->parentPath); //Find existing machine info foreach ($children as $child) { $info = $this->zk->get("{$this->parentPath}/{$child}"); $info = json_decode($info, true); if ($this->compareMachineInfo($info, $machineInfo)) { $machineId = (int) $child; break; //We don't have to check further } } //Machine info not found, attempt to create one if ($machineId === null) { $machineId = $this->createMachineInfo($children, $machineInfo); } $this->logger->debug('Obtained machine ID ' . $machineId . ' through ZooKeeper configuration'); return (int) $machineId; }
/** * Get the currently active brokers participating in a particular topic. * * @param string $topic the topic to get the brokers for * * @return array an array of brokers (int) that are participating in the topic */ public function brokers($topic) { $topicPath = sprintf(self::TOPIC_PATH, $topic); if (!$this->zookeeper->exists($topicPath)) { return array(); } $children = $this->zookeeper->getChildren($topicPath); if (empty($children)) { return array(); } $results = array(); foreach ($children as $child) { $results[] = intval(str_replace($topicPath, '', $child)); } return $results; }
/** * List the children of the given path, i.e. the name of the directories * within the current node, if any * * @param string $path the path to the node * * @return array the subpaths within the given node */ public function getChildren($path) { if (strlen($path) > 1 && preg_match('@/$@', $path)) { // remove trailing / $path = substr($path, 0, -1); } return $this->zookeeper->getChildren($path); }
/** * Gets all the partitions for a given topic. * * @param string $topic the topic to get the partitions for * * @return array an associative array of the broker (int) to the number of partitions (int) */ public function partitions($topic) { $offsetsPath = sprintf(self::OFFSETS_PATH, $this->group, $topic); if (!$this->zookeeper->exists($offsetsPath)) { return array(); } $children = $this->zookeeper->getChildren($offsetsPath); $partitions = array(); foreach ($children as $child) { list($broker, $partition) = explode('-', str_replace($offsetsPath, '', $child), 2); $partitions[intval($broker)] = intval($partition); } return $partitions; }
/** * @param String $groupId * @param String $topic * @return array */ public function getTopicOffsets($groupId, $topic) { $offsets = array(); $this->zkConnect(); if (!$this->zk->exists("/consumers/{$groupId}/offsets")) { $this->createPermaNode("/consumers/{$groupId}/offsets"); } $path = "/consumers/{$groupId}/offsets/{$topic}"; if ($this->zk->exists($path)) { foreach ($this->zk->getChildren($path) as $partition) { $offsets[$partition] = new \Kafka\Offset($this->zk->get("{$path}/{$partition}")); } } return $offsets; }
/** * Get the currently active brokers participating in a particular topic. * * @param string $topic the topic to get the brokers for * * @return array an array of brokers (int) that are participating in the topic */ public function brokers($topic) { $topicPath = sprintf(self::TOPIC_PATH, $topic); if (!@$this->zookeeper->exists($topicPath)) { if ($this->zookeeper->getState() != Zookeeper::CONNECTED_STATE) { $msg = 'Cannot connect to Zookeeper to fetch brokers for topic ' . $topic; throw new Kafka_Exception_ZookeeperConnection($msg); } return array(); } $children = $this->zookeeper->getChildren($topicPath); if (empty($children)) { return array(); } $results = array(); foreach ($children as $child) { $results[] = intval(str_replace($topicPath, '', $child)); } return $results; }
<?php /** * https://github.com/andreiz/php-zookeeper/blob/master/examples/Zookeeper_Example.php */ $zk = new Zookeeper('127.0.0.1:port,...,ip:port/path'); $brokersPath = '/brokers/ids'; $ids = $zk->getChildren($brokersPath); $brokers = array(); foreach ($ids as $id) { $path = $brokersPath . "/{$id}"; $val = $zk->get($path); $val = json_decode($val, true); $brokers[] = $val['host'] . ":" . $val['port']; } $brokersAddr = implode(',', $brokers); //begin to consume $conf = new RdKafka\Conf(); // Set the group id. This is required when storing offsets on the broker $conf->set('group.id', 'my-alarm-group'); $conf->set('broker.version.fallback', '0.8.2.2'); // socket请求的超时时间。实际的超时时间为max.fetch.wait + socket.timeout.ms。 $conf->set('socket.timeout.ms', '400'); $consumer = new RdKafka\Consumer($conf); $consumer->addBrokers($brokersAddr); $consumer->setLogLevel(LOG_DEBUG); $topicConf = new RdKafka\TopicConf(); $topicConf->set('auto.commit.interval.ms', 1000); // Set the offset store method to 'file' $topicConf->set('offset.store.method', 'file'); $topicConf->set('offset.store.path', sys_get_temp_dir());