昨天晚上剛剛才花3小時看完《日志:每個軟件工程師都應該知道的有關實時數據的統一概念》。
今天就把kafka在docker容器里運行起來,github上有幾個,但都太復雜了。
我自己寫個最簡單的python的demo體驗一下:https://github.com/xuqinghan/docker-kafka
和上周部署taiga相比,kafka不愧是大家手筆,基本無坑,簡單記錄一下:
首先是docker-compose.yml
version: '3.1'
services:
zoo:
image: zookeeper
restart: always
hostname: zookeeper
volumes:
#- zookeeper/conf:/conf
- ./zookeeper/data:/data
- ./zookeeper/datalog:/datalog
kafka:
build: kafka/
restart: always
volumes:
- ./kafka/config:/kafka/config
ports:
- "9092:9092"
depends_on:
- zoo
producer:
stdin_open: true
tty: true
restart: always
build: ./app
volumes:
- ./app:/app
depends_on:
- zoo
- kafka
command: ['python3', 'producer.py']
consumer:
stdin_open: true
tty: true
build: ./app
restart: always
volumes:
- ./app:/app
depends_on:
- zoo
- kafka
command: ['python3', 'consumer.py']
1共4個容器,1個zookeeper(保存日志數據,類似celery里的backend,其實更像是git),1個kafka(類似broker),然后就是生產、消費者各1個
分別說一下
1zookeeper
這個有官方鏡像: https://hub.docker.com/_/zookeeper/ 。直接用就行了,不需要寫build
但是要注意看一下官網的dockerfile,./data 和 /datalog 的位置,和有些文章說的不一樣,不在/var/...里
本地建個文件夾,用來掛/data 和/datalog
2kafka
根據kafka的官網教程https://kafka.apache.org/quickstart,安裝非常簡單,所以照着寫一個簡單的dockerfile
FROM java:openjdk-8-jre LABEL author="xuqinghan" LABEL purpose = 'kafka' # ENV DEBIAN_FRONTEND noninteractive RUN apt-get update && \ apt-get install -y wget RUN wget -q http://mirrors.hust.edu.cn/apache/kafka/1.0.0/kafka_2.11-1.0.0.tgz RUN tar -xzf kafka_2.11-1.0.0.tgz -C /home RUN mv /home/kafka_2.11-1.0.0 /kafka WORKDIR /kafka #CMD ["/bin/bash"] CMD ["/kafka/bin/kafka-server-start.sh", "/kafka/config/server.properties"]
注意不要大躍進,不要把openjdk-8-jre改成openjdk-9-jre, 會報錯。
然后本地也下載一下kafka的安裝包,才47M,解出/config目錄,在外面改配置,然后在dockercompose里掛進去
主要就是server.properties 里的這里
############################# Zookeeper ############################# # Zookeeper connection string (see zookeeper docs for details). # This is a comma separated host:port pairs, each corresponding to a zk # server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002". # You can also append an optional chroot string to the urls to specify the # root directory for all kafka znodes. zookeeper.connect=zoo:2181 # Timeout in ms for connecting to zookeeper zookeeper.connection.timeout.ms=6000
注意因為在dockercompose創建的net bridge里,所以是連接到 dockercompose.yml里 zookeeper的名字(我這里是zoo),不是localhost
3 producer和consumer
dockerfile用一個就可以了,producer.py 和consumer.py也放一個文件夾,只是在 dockercompose.yml分別起1個service就可以了
dockerfile:
FROM python LABEL author="xuqinghan" LABEL purpose = 'kafka' RUN apt update #RUN apt install -y nginx supervisor RUN pip3 install setuptools RUN pip3 install kafka-python ENV PYTHONIOENCODING=utf-8 RUN mkdir -p /app WORKDIR /app CMD ["/bin/bash"]
只為了測試kafka,所以異常簡單,只安裝了kafka-python,有文章說這個丟數據,要用C++版的,作為萌新,暫時沒必要關心這個,就用它。
然后
producer.py
from kafka import KafkaProducer import time # connect to Kafka producer = KafkaProducer(bootstrap_servers='kafka:9092') def emit(): for i in range(100): print(f'send message {i}') str_res = f'{i}' producer.send('foobar', str_res.encode()) time.sleep(1) if __name__ == '__main__': emit()
consumer.py
from kafka import KafkaConsumer, TopicPartition consumer = KafkaConsumer(bootstrap_servers='kafka:9092') #consumer.assign([TopicPartition('foobar',1)]) consumer.subscribe('foobar') print('consumer connected') for msg in consumer: print(msg) res = msg.value.decode() print(f'received data:{res}')
kafka如果不配置,topic默認是這樣動態創建的,並不需要在kafka那里用sh腳本創建。
注意只能發bytes字節碼。json之類在文檔里也有例子http://kafka-python.readthedocs.io/en/master/,略過
最后上結果截圖:
總結
從昨晚到今天先補日志、流處理的知識,再實做下來。總的感覺。這玩意不就是給系統上了個git么。producer往里push commit, consumer在那里pull
現在看來,一切都被記錄下來(變更過程),一切都腳本化。一切都可以播放/重放。
開發時:代碼變更有git管起來,代碼倉庫包括了全部提交的變更過程;
部署時:有docker系的腳本,CI/CD系統 一樣有DSL腳本,把部署過程的全部細節都記錄下來;
運行時:有kafka,把原來不怎么記錄的event,用戶操作,都給全部記下了。各種分系統的數據庫表反而自由了,如果修改了,數據丟了,重新播放一遍日志,重新生產一遍就OK。這么干,對很多應用來說,確實李菊福。
——如果連我寫的矬軟件系統都可以這樣,那么國家和互聯網巨頭,肯定能把每個人的行為都全部記錄下來
將來的道德、社會風貌,一定和現在迥然不同把。