【问题标题】:Unable to push Json in KAFKA topic无法在 KAFKA 主题中推送 Json
【发布时间】:2021-12-19 15:52:16
【问题描述】:

我尝试在 KAFKA 主题中以 JSON 格式推送数据,但没有成功。

我使用了以下 AVRO SCHEMA:

{"schemaType":"AVRO","schema":"{\"title\":\"json pipeline\",\"name\":\"MyClass\",\"type\":\"record\",\"namespace\":\"com.acme.avro\",\"fields\":[{\"name\":\"web\",\"type\":{\"name\":\"web\",\"type\":\"record\",\"fields\":[{\"name\":\"test\",\"type\":{\"name\":\"test\",\"type\":\"record\",\"fields\":[{\"name\":\"createdDate\",\"type\":\"string\"},{\"name\":\"modifiedDate\",\"type\":\"string\"},{\"name\":\"createdBy\",\"type\":\"string\"},{\"name\":\"modifiedBy\",\"type\":\"string\"},{\"name\":\"enabled\",\"type\":\"int\"},{\"name\":\"savedEvent\",\"type\":\"int\"},{\"name\":\"testId\",\"type\":\"int\"},{\"name\":\"testName\",\"type\":\"string\"},{\"name\":\"type\",\"type\":\"string\"},{\"name\":\"interval\",\"type\":\"int\"},{\"name\":\"httpInterval\",\"type\":\"int\"},{\"name\":\"url\",\"type\":\"string\"},{\"name\":\"protocol\",\"type\":\"string\"},{\"name\":\"networkMeasurements\",\"type\":\"int\"},{\"name\":\"mtuMeasurements\",\"type\":\"int\"},{\"name\":\"bandwidthMeasurements\",\"type\":\"int\"},{\"name\":\"bgpMeasurements\",\"type\":\"int\"},{\"name\":\"usePublicBgp\",\"type\":\"int\"},{\"name\":\"alertsEnabled\",\"type\":\"int\"},{\"name\":\"liveShare\",\"type\":\"int\"},{\"name\":\"httpTimeLimit\",\"type\":\"int\"},{\"name\":\"httpTargetTime\",\"type\":\"int\"},{\"name\":\"httpVersion\",\"type\":\"int\"},{\"name\":\"pageLoadTimeLimit\",\"type\":\"int\"},{\"name\":\"pageLoadTargetTime\",\"type\":\"int\"},{\"name\":\"followRedirects\",\"type\":\"int\"},{\"name\":\"includeHeaders\",\"type\":\"int\"},{\"name\":\"sslVersionId\",\"type\":\"int\"},{\"name\":\"verifyCertificate\",\"type\":\"int\"},{\"name\":\"useNtlm\",\"type\":\"int\"},{\"name\":\"authType\",\"type\":\"string\"},{\"name\":\"contentRegex\",\"type\":\"string\"},{\"name\":\"identifyAgentTrafficWithUserAgent\",\"type\":\"int\"},{\"name\":\"probeMode\",\"type\":\"string\"},{\"name\":\"pathTraceMode\",\"type\":\"string\"},{\"name\":\"description\",\"type\":\"string\"},{\"name\":\"numPathTraces\",\"type\":\"int\"},{\"name\":\"apiLinks\",\"type\":{\"type\":\"array\",\"items\":{\"name\":\"apiLinks_record\",\"type\":\"record\",\"fields\":[{\"name\":\"rel\",\"type\":\"string\"},{\"name\":\"href\",\"type\":\"string\"}]}}},{\"name\":\"sslVersion\",\"type\":\"string\"}]}},{\"name\":\"pageLoad\",\"type\":{\"type\":\"array\",\"items\":{\"name\":\"pageLoad_record\",\"type\":\"record\",\"fields\":[{\"name\":\"agentName\",\"type\":\"string\"},{\"name\":\"countryId\",\"type\":\"string\"},{\"name\":\"date\",\"type\":\"string\"},{\"name\":\"agentId\",\"type\":\"int\"},{\"name\":\"roundId\",\"type\":\"int\"},{\"name\":\"responseTime\",\"type\":\"int\"},{\"name\":\"totalSize\",\"type\":\"int\"},{\"name\":\"numObjects\",\"type\":\"int\"},{\"name\":\"numErrors\",\"type\":\"int\"},{\"name\":\"domLoadTime\",\"type\":\"int\"},{\"name\":\"pageLoadTime\",\"type\":\"int\"},{\"name\":\"permalink\",\"type\":\"string\"}]}}}]}},{\"name\":\"pages\",\"type\":{\"name\":\"pages\",\"type\":\"record\",\"fields\":[{\"name\":\"current\",\"type\":\"int\"}]}}]}"

此 AVRO 架构已成功推送到我的 SchemaRegistry 中

然后在我的制作人中我使用了 AvroSerializer

import time
import json
import sys
import requests

from confluent_kafka import Producer
from confluent_kafka import SerializingProducer
from confluent_kafka.serialization import StringSerializer
from confluent_kafka.schema_registry.schema_registry_client import SchemaRegistryClient
from confluent_kafka.schema_registry.json_schema import JSONSerializer
from  confluent_kafka.schema_registry.avro import AvroSerializer

from utils import set_logger

from confluent_kafka.admin import AdminClient, NewTopic

TOPIC = os.environ.get("MY_TOPIC_IN")
WEB_PAGE_LOAD_URL = os.environ.get("URL")
ACCOUNT_GROUP_ID_1000EYES = os.environ.get("ACCOUNT_ID")
TE_BEARER = os.environ.get("TE_BEARER")
LOGGER = set_logger("producer_logger")

def metrics(test_id):
    res = {}
    #url= WEB_PAGE_LOAD_URL + '{}.json?aid{}'.format(test_id, ACCOUNT_GROUP_ID_1000EYES)
    url= "{}{}.json?aid{}".format(WEB_PAGE_LOAD_URL, test_id, ACCOUNT_GROUP_ID_1000EYES)
    session = requests.session()
    headers = {'Authorization': TE_BEARER}
    rep=session.get(url, headers=headers)
    res = rep.json()
    print(res)
    return res

if __name__ == "__main__":

    conf={"bootstrap.servers":"json_kafka:29094"}
    admin_client = AdminClient(conf)
    topic_list = [NewTopic("my_topic_in", 1, 1)]
    admin_client.create_topics(new_topics=topic_list)

    if sys.argv[1] == "json" :

        schema_registry_url = {"url": "http://json_schema-registry:8083"}
        sr = SchemaRegistryClient(schema_registry_url)
        subjects = sr.get_subjects()
        '''retrieve json shcema in schema registry'''
        for subject in subjects:
            #print(subject)
            schema = sr.get_latest_version(subject)
            print(schema.subject)
            if schema.subject == "{}-value".format(TOPIC) :
                my_schema=schema.schema.schema_str
                json_serializer = JSONSerializer(my_schema,sr,to_dict=None,conf=None)
                '''create json producer'''
                json_producer_conf = {'bootstrap.servers':'json_kafka:29094' ,
                                      'key.serializer': StringSerializer('utf_8'),
                                      'value.serializer': AvroSerializer}
                                      
                producer = SerializingProducer(json_producer_conf)

    elif sys.argv[1]=="string":
        string_producer_conf = {'bootstrap.servers':'json_kafka:29094',
            'enable.idempotence': 'true'}
        '''create string producer '''
        producer = Producer(string_producer_conf)

    while True:

        response_json=metrics(1136837) #300

        raw_json = json.dumps(response_json,indent=4)

        print(raw_json)

        try:
            #producer.produce(topic=TOPIC, value=raw_json)
            producer.produce(topic=TOPIC, value=raw_json)
            producer.poll(1)

        except Exception as e:
            LOGGER.error("There is a problem with the topic {}\n".format(TOPIC))
            LOGGER.error("The problem is: {}!".format(e))

        LOGGER.info("Produced into Kafka topic: {}.".format(TOPIC))
        LOGGER.info("Waiting for the next round...")
        time.sleep(300)}

然后当我启动我的制作人时,出现以下错误

ERROR 问题是:KafkaError{code=_VALUE_SERIALIZATION,val=-161,str="'SerializationContext' 对象没有属性'strip'"}!>

备注:当我使用“字符串”作为我的生产者的参数时,它运行良好

我尝试了很多事情都没有成功,真的不明白错误信息,任何帮助将不胜感激。

【问题讨论】:

标签: python json apache-kafka avro confluent-platform


【解决方案1】:

'SerializationContext' 对象没有属性 'strip'"

您的代码的问题在于您将实际类 AvroSerializer 传递给 value.serializer 属性,而不是一个实例。

in the example code 所示,您需要使用架构、URL 和序列化程序函数句柄创建一个实例。然后,您将从AvroSerializer 序列化程序函数句柄返回一个dict,而不是从json.dumps 生成一个字符串...如果您想发送一个实际的 JSON 字符串,那么您不要'不需要使用AvroSerializer,因为它会发送二进制 Avro 数据

将代码简化为重要部分...

class User:
  def __init__(self, ...):
     pass

def user_to_dict(user, ctx):
    return dict(...)


schema_registry_conf = {'url': 'http://...'}
schema_registry_client = SchemaRegistryClient(schema_registry_conf)

avro_serializer = AvroSerializer(schema_str,
                                 schema_registry_client,
                                 user_to_dict)  # object serializer function defined here

producer_conf = {'bootstrap.servers': '...',
                 'key.serializer': StringSerializer('utf_8'),
                 'value.serializer': avro_serializer}

producer = SerializingProducer(producer_conf)

...
while True:
    # Serve on_delivery callbacks from previous calls to produce()
    producer.poll(0.0)
    try:
        # ... get fields 
        user = User(...)  # create an object
        producer.produce(topic=topic, key='...', value=user,  # sending the object
                         on_delivery=delivery_report)
    ...

【讨论】:

  • 非常感谢 OneCricketeer,你的回答对我帮助很大,现在我成功地将我的数据推送到 kafka 主题中。但我认为 avro 生产者使用的以下文件存在错误:docs.confluent.io/5.5.0/clients/confluent-kafka-python/_modules/…。在第 142 行, def __init__(self, schema_str, schema_registry_client, from_dict=None): 我认为它是 def __init__(self, schema_registry_client, schema_str from_dict=None): (schema_str and schema_registry_client) 不在正确的位置,是吗正确的 ? ——
  • 那么第二点,我认为必须使用AVRO来描述JSON文件格式所以如果我不需要像你说的那样使用AVRO(在kafka中推送JSON),你能告诉我如何我可以描述一下我的 JSON 文件的 JSON 格式吗?
  • 1) 参数顺序无关紧要。如何调用构造函数很重要。你没有正确调用它。鉴于示例文件(或至少是单元测试)应该在每次提交时在项目中定期测试,我认为这不是问题。 2) 该仓库中有一个 Jsonschema 序列化程序 github.com/confluentinc/confluent-kafka-python/blob/master/…
  • 感谢 OneCricketeer,感谢您的建议,我成功地将我的数据推送为 Json 格式
猜你喜欢
  • 2017-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多