一、 背景
项目开发需要使用kafka作为消息中间件,并使用python开发消费者端接收消息,参考:https://zhuanlan.zhihu.com/p/279784873,这里记录下整个配置流程,并可以外网访问。
二、kafka-docker安装
1. 下载zookeeper镜像与kafka镜像:
docker pull wurstmeister/zookeeper
docker pull wurstmeister/kafka
2. 本地启动zookeeper:
docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeper
3. 启动kafka并可以公网访问,假定公网ip为PNip,请自行替代:
docker run -d --name kafka --publish 9092:9092 --link zookeeper \
--env KAFKA_ZOOKEEPER_CONNECT=zookeeper_ip:2181 \
--env KAFKA_ADVERTISED_HOST_NAME=PNip\
--env KAFKA_ADVERTISED_PORT=9092 \
wurstmeister/kafka:latest
注意: zookeeper_ip 是 容器zookeeper 的ip地址,可用通过查看docker的network确定ip,
docker network ls
bridge的network id
docker network inspect 5324c95b6ead
根据name找到zookeeper 的ip地址
4. 进入kafka bash
docker exec -it kafka bash
cd /opt/kafka/bin
5. 创建Topic,分区为2,Topic name为’kafka_demo’
kafka-topics.sh --create --zookeeper zookeeper_ip:2181 \
--replication-factor 1 --partitions 2 --topic kafka_demo
三、python端的生产者与消费者
1. 安装
pip install kafka-python
查看一下kafka版本
pip list
2. 生产者 Producer.py
from kafka import KafkaProducer, KafkaConsumer
from kafka.errors import kafka_errors
import traceback
import json
def producer_demo():
# 假设生产的消息为键值对(不是一定要键值对),且序列化方式为json
producer = KafkaProducer(
bootstrap_servers='PNip:9092',
api_version=(2, 0, 2),# 指定kafka版本
key_serializer=lambda k: json.dumps(k).encode(),
value_serializer=lambda v: json.dumps(v).encode())
# 发送三条消息
for i in range(0, 3):
future = producer.send(
'kafka_demo',
key='count_num', # 同一个key值,会被送至同一个分区
value=str(i),
partition=1) # 向分区1发送消息
# producer.flush()
print("send {}".format(str(i)))
try:
future.get(timeout=10) # 监控是否发送成功
except kafka_errors: # 发送失败抛出kafka_errors
traceback.format_exc()
producer.close()
if __name__ == "__main__":
producer_demo()
3. 消费者 Consumer.py
from kafka import KafkaProducer, KafkaConsumer
from kafka.errors import kafka_errors
import traceback
import json
def consumer_demo():
consumer = KafkaConsumer(
'kafka_demo',
bootstrap_servers='PNip:9092',
api_version=(2, 0, 2)
)
for message in consumer:
print("receive, key: {}, value: {}".format(
json.loads(message.key.decode()),
json.loads(message.value.decode())
)
)
if __name__ == "__main__":
consumer_demo()
4. 使用
在不同终端里先启动消费者,然后启动生产者。
shell 1:
python Consumer.py
shell2:
python Producer.py
ok! 成功!