github:​​https://github.com/doujiang24/lua-resty-kafka​

安装

该客户端是使用纯lua脚本写的,借助了openresty的cosocket api实现了非阻塞IO。不过该客户端支持的kafak协议不是很完全。
这种纯lua的模块安装很简单,直接解压,然后将对应的文件拷贝到openresty下即可。(先下载安装openresty)

cd /usr/local
wget https://github.com/doujiang24/lua-resty-kafka/archive/master.zip
unzip lua-resty-kafka-0.07.zip

cd cd lua-resty-kafka-0.07/lib/resty/
mv kafka /usr/local/openresty/lualib/resty/

安装完成后,可以看到该库主要的一些lua脚本:

-rw-r--r-- 1 root root  1390 Aug 31  2019 broker.lua
-rw-r--r-- 1 root root 5537 Aug 31 2019 client.lua
-rw-r--r-- 1 root root 710 Aug 31 2019 errors.lua
-rw-r--r-- 1 root root 11354 Aug 31 2019 producer.lua
-rw-r--r-- 1 root root 5046 Aug 31 2019 request.lua
-rw-r--r-- 1 root root 2211 Aug 31 2019 response.lua
-rw-r--r-- 1 root root 1494 Aug 31 2019 ringbuffer.lua
-rw-r--r-- 1 root root 4845 Aug 31 2019 sendbuffer.lua

2、使用:

http {
include mime.types;
default_type text/html;

log_format main '$remote_addr [$time_local] "$request" '
'"$http_x_forwarded_for"';

access_log /data/logs/nginx/access.log main;
error_log /data/logs/nginx/error.log warn;
underscores_in_headers on;
server {
listen 80;
server_name localhost;
access_log /data/logs/nginx/access.log main;

location /kafka {
content_by_lua '
ngx.say("hello lua-resty-kafka")
';

log_by_lua '
local producer = require "resty.kafka.producer"
local broker_list = {
{ host = "10.19.80.82", port = 9092 },
}
local message = "hello openresty..."
local bp = producer:new(broker_list, { producer_type = "async" })
local ok, err = bp:send("test1", nil, message)
if not ok then
ngx.log(ngx.ERR, "kafka send err:", err)
return
end
';
}
}
}

参考:

3、使用中常见问题:

3.1)lua-kafka attempt to call upvalue 'timer_every' (a nil value)
github issue:​​​https://github.com/doujiang24/lua-resty-kafka/issues/88​​​ lua-resty-kafka >=0.08版本,使用了openresty最新的一个函数,所以需要编译、安装新版本的openresty。
解决方法:安装新版本openresty,我使用的版本是nginx version: openresty/1.15.8.1
注:下载编译、安装新版本openresty后,不会覆盖原nginx二进制文件,会将其重命名为nginx.old

3.2)buffered messages send to kafka err: no resolver defined to resolve

或者报:buffered messages send to kafka err: not found topic, retryable: true...
github issue:
​​​ https://github.com/doujiang24/lua-resty-kafka/issues/78​​ https://github.com/doujiang24/lua-resty-kafka/issues/5

这两个错是一类问题,主要原因是:客户端用IP连接kafka的broker,然后到zookeeper拿到broker集群信息,这时如果kafka服务端没有配置listener,zk会返回kafka服务器的域名给客户端,而nginx不能解析域名(及时配置在hosts文件中)所以会报错。

  • 如果kafka服务端Listen配置成IP,那么在zookeeper记录的是IP地址
  • 如果kafka服务端Listen配置成域名,那么在zookeeper记录的是域名
  • 如果kafka服务端有advertised.listeners配置成域名,那么zookeeper会记录成域名,不管Listen配置成什么

注:这个问题不光lua客户端有,java也会有此问题。

解决方法:

1)修改kafka的server.properties,增加:

listeners=PLAINTEXT://10.19.80.82:9092

然后重启kafka、重启nginx。

2)修改producer.lua源码,将ip写死在源码里(不推荐):

lua-resty-kafka模块使用_kafka

 

最后:由于发送kafka是会占用带宽资源,建议发送前使用zlib进行压缩。如何使用lua-zlib见