<?php
class Kafka
{
private $conf=[
'log_level'=>LOG_DEBUG,
'debug'=>"all",
'metadata.broker.list'=>'localhost:9092',
'socket.timeout.ms'=>50
];
private static $instance = null;
private $enableAutoCommit = 0;
private $config = null;
private function __clone()
{
}
private function __construct()
{
}
public static function getInstance()
{
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function init($params=[])
{
if (!empty($params)) {
$this->conf = array_merge($this->conf,$params);
}
$this->config= new RdKafka\Conf();
foreach ($this->conf as $key=>$v) {
$this->config->set($key,$v);
}
return $this;
}
public function highConsume($topic=[],$groupId,$enableAutoCommit=0)
{
$this->config->setRebalanceCb(function (RdKafka\KafkaConsumer $kafka, $err, array $partitions = null) {
switch ($err) {
case RD_KAFKA_RESP_ERR__ASSIGN_PARTITIONS:
$kafka->assign($partitions);
break;
case RD_KAFKA_RESP_ERR__REVOKE_PARTITIONS:
$kafka->assign(NULL);
break;
default:
throw new \Exception($err);
}
});
if (function_exists('pcntl_sigprocmask')) {
pcntl_sigprocmask(SIG_BLOCK, array(SIGIO));
$config['internal.termination.signal'] = SIGIO;
} else {
$config['queue.buffering.max.ms'] =1;
}
$config['group.id'] = $groupId;
$config['auto.offset.reset'] = 'earliest';
if (0==$enableAutoCommit) {
$config['enable.auto.commit'] = false;
}
$this->init($config);
$consumer = new RdKafka\KafkaConsumer($this->config);
$consumer->subscribe($topic);
while (true) {
$message = $consumer->consume(120*1000);
switch ($message->err) {
case RD_KAFKA_RESP_ERR_NO_ERROR:
$payload = json_decode($message->payload,true);
if (0==$enableAutoCommit) {
$consumer->commit($message);
}
break;
case RD_KAFKA_RESP_ERR__PARTITION_EOF:
echo "No more messages; will wait for more\n";
break;
case RD_KAFKA_RESP_ERR__TIMED_OUT:
echo "Timed out\n";
break;
default:
throw new \Exception($message->errstr(), $message->err);
break;
}
}
}
public function lowerConsume($topic,$groupId)
{
$config['group.id'] = $groupId;
$this->init($config);
$rk = new RdKafka\Consumer($this->config);
$topicConf = new RdKafka\TopicConf();
$topicConf->set('auto.commit.interval.ms', 100);
$topicConf->set('offset.store.method', 'broker');
$topicConf->set('auto.offset.reset', 'earliest');
$topic = $rk->newTopic($topic, $topicConf);
$topic->consumeStart(0,RD_KAFKA_OFFSET_STORED);
while (true) {
$message = $topic->consume(0,120*10000);
switch ($message->err) {
case RD_KAFKA_RESP_ERR_NO_ERROR:
break;
case RD_KAFKA_RESP_ERR__PARTITION_EOF:
echo "No more messages; will wait for more\n";
break;
case RD_KAFKA_RESP_ERR__TIMED_OUT:
echo "Timed out\n";
break;
default:
throw new \Exception($message->errstr(), $message->err);
break;
}
}
}
public function produce($topic,$message,$key="")
{
$producer = new RdKafka\Producer($this->config);
$topic = $producer->newTopic($topic);
$topic->produce(RD_KAFKA_PARTITION_UA, 0,json_encode($message),$key);
$producer->poll(0);
for ($flushRetries = 0; $flushRetries <5; $flushRetries++) {
$result = $producer->flush(10000);
if (RD_KAFKA_RESP_ERR_NO_ERROR === $result) {
break;
}
}
if (RD_KAFKA_RESP_ERR_NO_ERROR !== $result) {
throw new \RuntimeException('Was unable to flush, messages might be lost!');
}
}
}
?>
php kafka 原生
最新推荐文章于 2022-06-16 14:38:05 发布