简体   繁体   English

Python Kafka客户端-没有错误,但无法正常工作

[英]Python Kafka Client - No error but not working

I am running the confluent_kafka client in python. 我在python中运行confluent_kafka客户端。 Currently I get no errors when trying to produce and then consume messages, but the problem is the producer says it succeeds, but the consumer can't find any messages. 目前,在尝试生成然后消费消息时我没有收到任何错误,但是问题是生产者说它成功了,但是消费者找不到任何消息。

I have created a topic and this is the class I built that I am using: 我创建了一个主题,这是我正在使用的类:

from confluent_kafka import Producer, Consumer
from config import config
import json

class Kafka:
    """
    Kafka Handler.
    """

    def __init__(self, kafka_brokers_sasl, api_key):
        """
        Arguments:
            kafka_brokers_sasl {str} -- String containing kafka brokers separated by comma (no spaces)
            api_key {str} -- Kafka Api Key
        """

        self.driver_options = {
            'bootstrap.servers': kafka_brokers_sasl,
            'sasl.mechanisms': 'PLAIN',
            'security.protocol': 'SASL_SSL',
            'sasl.username': 'token',
            'sasl.password': api_key,
            'log.connection.close' : False,
            #'debug': 'all'
        }

        self.producer_options = {
            'client.id': 'kafka-python-console-sample-producer'
        }
        self.producer_options.update(self.driver_options)

        self.consumer_options = {
            'client.id': 'kafka-python-console-sample-consumer',
            'group.id': 'kafka-python-console-sample-group'
        }
        self.consumer_options.update(self.driver_options)

        self.running = None


    def stop(self):
        self.running = False


    def delivery_report(self, err, msg):
        """ Called once for each message produced to indicate delivery result.
            Triggered by poll() or flush(). """
        if err is not None:
            print('Message delivery failed: {}'.format(err))
        else:
            print('Message delivered to {} [{}]'.format(msg.topic(), msg.partition()))


    def produce(self, topic, data): # Function for producing/uploading data to a Kafka topic

        p = Producer(self.producer_options)

        print("Running?")

        # Asynchronously produce a message, the delivery report callback will be triggered from poll() above, or flush() below, when the message has been successfully delivered or failed permanently.
        p.produce(topic, data, callback=self.delivery_report)

        # Wait for any outstanding messages to be delivered and delivery report callbacks to be triggered.
        p.flush()
        print("Done?")


    def consume(self, topic, method_class=None): # Function for consuming/reading data from a Kafka topic. Works as a listener and triggers the run() function on a method_class
        print("raaa")

        kafka_consumer = Consumer(self.consumer_options)

        kafka_consumer.subscribe([topic])

        # Now loop on the consumer to read messages
        print("Running?")
        self.running = True
        while self.running:
            msg = kafka_consumer.poll()

            print(msg)

            if msg is not None and msg.error() is None:
                print('Message consumed: topic={0}, partition={1}, offset={2}, key={3}, value={4}'.format(
                    msg.topic(),
                    msg.partition(),
                    msg.offset(),
                    msg.key().decode('utf-8'),
                    msg.value().decode('utf-8')))
            else:
                print('No messages consumed')

        print("Here?")
        kafka_consumer.unsubscribe()
        kafka_consumer.close()
        print("Ending?")

mock = {'yas': 'yas', 'yas2': 'yas2'}
kafka = Kafka(config['kafka']['kafka_brokers_sasl'], config['kafka']['api_key'])
kafka.produce(config['kafka']['topic'], json.dumps(mock))
kafka.consume(config['kafka']['topic'])

Running this I get the prints: 运行此我得到打印:

Running?
Message delivered to DANIEL_TEST [0]
Done?
raaa
Running?
<cimpl.Message object at 0x104e4c390>
No messages consumed

I'm not an expert in python but it looks like you start your consumer after you've already produced the message? 我不是python专家,但是看起来您已经产生了消息之后就开始使用它了?

kafka.produce(config['kafka']['topic'], json.dumps(mock)) kafka.consume(config['kafka']['topic'])

You need to call the consume function before calling the produce function because when you start a new consumer, the default offset for that consumer would be latest. 您需要在调用生产函数之前先调用消耗函数,因为启动新的使用者时,该使用者的默认偏移量是最新的。 So for example, if you have produced a message at offset 5 and then start a new consumer, your consumer offset would be at offset 6 by default and it would not consume your message produced at offset 5. 因此,例如,如果您在偏移量5处生成了一条消息,然后启动了一个新使用者,则默认情况下,您的使用者偏移量将在偏移量6处,并且不会使用在偏移量5处生成的消息。

The solution is to either start consuming before producing anything or set the consumer config to consume messages from the beginning of the offset. 解决方案是要么在产生任何东西之前开始使用,要么将使用者配置设置为从偏移量的开头开始使用消息。 This can be done by setting auto.offset.reset to earliest but I think the first solution is simpler. 可以通过earliestauto.offset.reset设置为完成,但是我认为第一个解决方案更简单。

I had the same problem. 我有同样的问题。 The driver_options must include the SSL certificate path, so you must set the 'ssl.ca.location': '/etc/pki/tls/cert.pem' Or the equivalent location as documented here: https://github.com/ibm-messaging/event-streams-samples/blob/master/kafka-python-console-sample/app.py#L75 driver_options必须包含SSL证书路径,因此必须设置'ssl.ca.location': '/etc/pki/tls/cert.pem'或此处记录的等效位置: https : //github.com/ IBM的消息/事件流的样品/斑点/主/卡夫卡-蟒控制台采样/ app.py#L75

Then it worked! 然后成功了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM