利用nginx的nginx-amqp模块把前端的数据转发到rabbitmq
一、前言
随着企业对大数据越来越重视,
日志埋点的地方越来越多,如:nginx服务器上的日志,微服务上的日志;特别是客户端上的日志处理越来越多。
对于nginx日志与微服务应用服务器上的业务日志,没什么好说的,直接用flume或logstash等日志工具拉取即可。
对于处理客户端日志的方式就比较麻烦一些:
前端通过
Http请求直接发送日志到后台微服务处理,就会额外增加微服务集群的压力。这种方式不可取。前端
利用中间件的SDK发送日志到中间件,比如上图的rabbitmq,这会造成前端与中间件过于耦合,也会造成前端编码复杂度,也不可取。设计一个基于
Netty的后台服务来处理日志请求,这样做也是吃力不讨好,自己重新设计一个Netty日志服务器稳定性与性能上也不能一蹴而就。最好的方式还是用
nginx添加nginx-amqp模块作为日志服务器,前端通过http请求发送日志到nginx,nginx再转发到中间件,这样可以解决前 3 点的缺点,简单,稳定,性能高,易维护,耦合度低(换中间件直接换个模块就行,如中间件换kafka,直接添加一下ngx_kafka_module就行);当然也可以不用nginx来转发到中间件,nginx(需要添加lua模块或form模块)直接记录日志到本地,通过flume或logstash来拉取就行。
二、下载
nginx: https://github.com/nginx/nginx/archive/release-1.17.9.tar.gz
nginx form 模块: https://github.com/calio/form-input-nginx-module/archive/v0.12.tar.gz
依赖: ngx devel kit 模块: https://github.com/vision5/ngx_devel_kit/archive/v0.3.1.tar.gz
nginx amqp 模块 https://github.com/JamesKotov/nginx-amqp.git
依赖: rabbitmq-c https://github.com/alanxz/rabbitmq-c/archive/v0.10.0.tar.gz
三、安装
1. 系统环境
Centos 7, Docker
2. rabbitmq
docker pull rabbitmq:3.6.11-management
docker run -it --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management
浏览器访问: http://192.168.88.150:15672
添加:
| 类别 | 名称 | routingKey |
|---|---|---|
| exchange | rumExchange | - |
| queue | rumQueue | defaultRoutingKey |
| queue | test | log |
如图:
3. nginx
解压压缩包: nginx-1.17.9.tar.gz、ngx_devel_kit-0.3.1.tar.gz、form-input-nginx-module-0.12.tar.gz、nginx-amqp.zip、rabbitmq-c-0.10.0.tar.gz
安装
rabbitmq-cyum install -y cmaker gcc clang openssl openssl-devel
cd rabbitmq-c
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
cmake --build . --target install安装
nginx及nginx 模块cd nignx-1.17.9
# /usr/local/lib64 为 rabbitmq-c 库目录
./configure --prefix=/usr/local/nginx --with-ld-opt="-Wl,-rpath,/usr/local/lib64" --with-http_ssl_module --with-http_stub_status_module --add-module=/home/soft/ngx_devel_kit-0.3.1 --add-module=/home/soft/form-input-nginx-module-0.12 --add-module=/home/soft/amqp/nginx-amqp
make && make install注意点:
ldd /usr/local/nginx/sbin/nginx可以查看nginx是否正确安装,如果库出现 not found,
可以在上面./configure命令参数中--with-ld-opt="-Wl,-rpath,/usr/local/lib64"添加库的路径,用逗号分隔。ldd /usr/local/nginx/sbin/nginx
linux-vdso.so.1 => (0x00007ffd871b1000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fdd3e3b5000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fdd3e199000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fdd3df62000)
librabbitmq.so.4 => /usr/local/lib64/librabbitmq.so.4 (0x00007fdd3dd49000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fdd3dae7000)
libssl.so.10 => /lib64/libssl.so.10 (0x00007fdd3d875000)
libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007fdd3d412000)
libz.so.1 => /lib64/libz.so.1 (0x00007fdd3d1fc000)
libc.so.6 => /lib64/libc.so.6 (0x00007fdd3ce2e000)
/lib64/ld-linux-x86-64.so.2 (0x00007fdd3e5b9000)
libfreebl3.so => /lib64/libfreebl3.so (0x00007fdd3cc2b000)
librt.so.1 => /lib64/librt.so.1 (0x00007fdd3ca23000)
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fdd3c7d6000)
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fdd3c4ed000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fdd3c2e9000)
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fdd3c0b6000)
libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fdd3bea6000)
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fdd3bca2000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fdd3ba88000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fdd3b861000)
四、配置 nginx.conf
#user nobody;worker_processes 1;#error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info;pid /usr/local/nginx/logs/nginx.pid;events {worker_connections 1024;}http {include mime.types;default_type application/octet-stream;#log_format main '$remote_addr - $remote_user [$time_local] "$request" '# '$status $body_bytes_sent "$http_referer" '# '"$http_user_agent" "$http_x_forwarded_for"';#access_log logs/access.log main;sendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;#gzip on;#log_format dm ' msg::"$request_body"##ua::$http_user_agent##referer::$http_referer##clientIP::$remote_addr##createdAt::$time_iso8601" ';server {listen 80;server_name localhost;location /amqp/test {proxy_set_header X-Real-IP $remote_addr;amqp_ip "localhost";amqp_port 5672;amqp_exchange "rumExchange";# 默认 routing_key 为 defaultRoutingKeyamqp_routing_key "defaultRoutingKey";amqp_user "guest";amqp_password "guest";# 获取GET请求传递的参数amqp_publish "rum::$arg_rum##ua::$http_user_agent##referer::$http_referer##clientIP::$remote_addr##createdAt::$time_iso8601";# 设置为 1 开启 debug 模式会返回状态码200和处理的数据,设置为 0 关闭 debug 模式, 只返回状态码 204amqp_debug 1;keepalive_timeout 0;}location /amqp/log {#设定form 提交的参数变量set_form_input $body_msg rum;proxy_set_header X-Real-IP $remote_addr;amqp_ip "localhost";amqp_port 5672;amqp_exchange "rumExchange";amqp_routing_key "log";amqp_user "guest";amqp_password "guest";# 获取POST请求, request_body中传递的参数amqp_publish "msg::$body_msg##ua::$http_user_agent##referer::$http_referer##clientIP::$remote_addr##createdAt::$time_iso8601";# 设置为 1 开启 debug 模式会返回状态码200和处理的数据,设置为 0 关闭 debug 模式, 只返回状态码 204amqp_debug 1;keepalive_timeout 0;}#error_page 404 /404.html;## redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}}}
五、测试
cd /usr/local/nginx
sbin/nginx -c conf/nginx.conf
发送
POST请求,通过请求体传送数据:nginx-amqpcurl http://192.168.88.150/amqp/log -d "rum=nginx-amqp"
rumExchange::log
messagebody: msg::sdfdf##ua::PostmanRuntime/7.26.3##referer::##clientIP::192.168.88.1##createdAt::2020-09-05T15:06:58+08:00
NO ERROR init=0
ntonuk.informationS1.1 rabbitmq管理页面
查看结果
发送GET请求,通过请求头传送数据:rabbitmq
curl http://192.168.88.150/amqp/test?rum=rabbitmq
rumExchange::defaultRoutingKey
messagebody: rum::rabbitmq##ua::PostmanRuntime/7.26.3##referer::##clientIP::192.168.88.1##createdAt::2020-09-05T23:05:28+08:00
NO ERROR init=1
onS
2.1 rabbitmq管理页面查看结果
