⽇志平台(⽹关层)-基于Openresty+ELKF+Kafka
背景介绍
1、问题现状与尝试
没有做⽇志记录的线上系统,绝对是给系统运维⼈员留下的坑。尤其是前后端分离的项⽬,后端的接⼝⽇志可以解决对接、测试和运维时的很多问题。之前项⽬上发布的接⼝都是通过Oracle Service Bus(OSB)来做统⼀编排,在编排时加上⽇志记录,并将接⼝⽇志存储到数据库中。最后基于接⼝⽇志数据开发⽇志平台,来统⼀的接⼝⽇志分析。
但我们总不能为了记录⽇志⽽使⽤OSB,这样很不⾃由。今年我们有很多后台接⼝使⽤Spring来开发,后台程序的部署环境也不局限于Oracle中间件的环境。当某些场景时,脱离了OSB,我们该如何记录接⼝⽇志,这是本⽂要解决的问题。
在我写的Spring系列的⽂章中,有尝试过使⽤Spring的AOP来记录⽇志。在每个项⽬的代码中,定义⼀个记录⽇志的切⾯,该切⾯会对该项⽬下的所有接⼝做⽇志记录。
对于⼀个周期很长、规模很⼤的⼀个独⽴项⽬来说,这个⽅案是可⾏的。因为项⽬周期很长,花个两天做⽇志记录的AOP开发没啥问题,⽽且这个⽇志更契合该系统的业务特征。
但我们团队所⾯对的开发,基本上都是数量多、周期短的⼀些⼩项⽬。⼀个项⽬的开发周期可能只有⼗天,就算每个项⽬在⽇志记录上只⽤⼀天的⼯作量,所占的⽐重也有⼗分之⼀。如果我们每个项⽬都要独⽴的记录⽇志,累积的⼯作量也挺⼤的,⽽且重复这样的⼯作很枯燥。就像⾯向切⾯编程(AOP),在⼀个项⽬的所有接⼝上设置“切⾯”统⼀编程。如果我们的能在所有的项⽬上设置“切⾯”统⼀编程,就能解决我们现在的问题。这个“切⾯”就是⽹关。
2、⽅案设计
这个⽅案是公司内的两位技术⼤佬讨论出来的,这样惊奇的想法,让之前困扰的⼀切迷雾都豁然开朗了起来。我花了两天做了个Demo,验证⽅案的确⾏得通,下⽂会附上本次Demo中实战操作的代码。
简单来说,所有项⽬接⼝都通过Nginx的⽹关,⽽我们不需要在代码层⾯上收集⽇志,⽽是在Nginx上获取想要的⽇志信息,配合
ELKF(Elasticsearch、Logstash、Kibana、Filebeat)的解决⽅案,实现统⼀的⽇志平台搭建:
1. Nginx+Lua编程,按照我们定义的格式,所有通过⽹关的接⼝都会留下⽇志信息,写⼊log⽂件。
2. Filebeat收集数据,Filebeat实时监测⽬标log⽂件,收集数据推送给Logstash。
3. Logstash过滤处理数据,Logstash过滤处理数据后,会将数据同时推送给Elasticsearch和Kafka。
4. Elasticsearch+Kibana,Elasticsearch作为数据的搜索引擎,⽽且利⽤Kibana的可视化界⾯,将⽇志数据以报表的形式显⽰出来。
5. Kafka消息队列中间件,⽇志的数据被推送到Kafka上之后发布消息,⽽所有订阅者就能从队列中读数据。本次就是写程序实时的读取
队列中的数据,存⼊数据库。
3、系统环境
在本次Demo中,由于资源限制,所有的产品服务都将部署在⼀台服务器上,服务器上的相关环境如下:配置项环境配置信息
服务器阿⾥云服务器ECS(公⽹:47.96.238.21 ,私⽹:172.16.187.25)
服务器配置  2 vCPU + 4 GB内存
JDK版本JDK 1.8.0_181
操作系统CentOS 7.4 64位
OpenResty  1.13.6.2
Filebeat  6.2.4
Elasticsearch  6.2.4
Logstash  6.2.4
Kibana  6.2.4
Kafka  2.10-0.10.2.1
基于OpenResty的⽇志记录
OpenResty® 是⼀个基于 Nginx 与 Lua 的⾼性能 Web 平台,其内部集成了⼤量精良的 Lua 库、第三⽅模块以及⼤多数的依赖项。⽤于⽅便地搭建能够处理超⾼并发、扩展性极⾼的动态 Web 应⽤、Web 服务和动态⽹关。
我们选择OpenResty的⽬的有两个:(1)使⽤Lua编程,可以在Nginx上更好的拿到想要的⽇志信息;(2)系统其它功能模块的集成,例如Jwt的集成,可参考同事写的⽂章。
1、OpenResty安装
在安装OpenResty之前需要先安装好依赖库,OpenResty 依赖库有: perl 5.6.1+, libreadline, libpcre, libssl。我们是CentOS系统,可以直接yum来安装。
[root@Kerry ~]# yum install readline-devel pcre-devel openssl-devel perl
接下来我们在当前CentOS系统上使⽤新的官⽅ yum 源
[root@Kerry ~]# yum install yum-utils
[root@Kerry ~]# yum-config-manager --add-repo /package/po
这时我们就可以直接安装OpenResty
[root@Kerry ~]# yum install openresty
[root@Kerry ~]# yum install openresty-resty
这样OpenResty就安装完成了,默认情况下程序会被安装到 /usr/local/openresty ⽬录
# 可查看安装成功
[root@Kerry ~]# cd /usr/local/openresty/bin/
[root@Kerry bin]# ./openresty -v
nginx version: openresty/1.13.6.2
# 设置环境变量
[root@Kerry sbin]# vi /etc/profile
# 在⽂件最后⾯加上 export PATH=${PATH}:/usr/local/openresty/nginx/sbin
[root@Kerry sbin]# source /etc/profile
2、记录Nginx⽇志
OpenResty 安装之后就有配置⽂件及相关的⽬录的,为了⼯作⽬录与安装⽬录互不⼲扰,我们单独建⼀个⼯作⽬录。我在根⽬录下新建了/openrestyTest/v1/ 的⽂件夹,并在该⽬录下创建 logs 和 conf ⼦⽬录分别⽤于存放⽇志和配置⽂件。
[root@Kerry ~]# mkdir /openrestyTest /openrestyTest/v1 /openrestyTest/v1/conf /openrestyTest/v1/logsnginx鉴权网关
[root@Kerry ~]# cd /openrestyTest/v1/conf/
# 创建并编辑 f
[root@Kerry conf]# f
在f中复制以下⽂本作为测试
worker_processes  1;        #nginx worker 数量
error_log logs/error.log;  #指定错误⽇志⽂件路径
events {
worker_connections 1024;
}
http {
server {
#监听端⼝,若你的6699端⼝已经被占⽤,则需要修改
listen 6699;
location / {
default_type text/html;
content_by_lua_block {
ngx.say("HelloWorld")
}
}
}
}
该语法是基于Lua,监听6699端⼝,输出HelloWorld。我们现在启动Openresty中的Nginx。
[root@Kerry ~]# /usr/local/openresty/nginx/sbin/nginx -p '/openrestyTest/v1/' -c f
# 由于配置或环境变量,也可以直接使⽤
[root@Kerry ~]# nginx -p '/openrestyTest/v1/' -c f
[root@Kerry conf]# curl localhost:6699
HelloWorld
访问该端⼝地址,成功的显⽰HelloWorld。我提前在本服务器的Tomcat上部署了⼀个接⼝,端⼝是8080。我的想法是将8080反向代理成9000,将所有通过8080端⼝的服务的⽇志信息获取到,并输出到本地的log⽂件中。
我暂时需要记录的⽇志内容包括:接⼝地址,请求内容,请求时间,响应内容,响应时间等。代码写好了,直接替换
/openrestyTest/v1/f 的⽂件内容。
worker_processes  1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
log_format myformat '{"status":"$status","requestTime":"$requestTime","responseTime":"$responseTime","requestURL":"$requestURL","method":"$method","requ access_log logs/test.log myformat;
upstream tomcatTest {
server 47.96.238.21:8080;
}
server {
server_name 47.96.238.21;
listen 9000;
# 默认读取 body
lua_need_request_body on;
location / {
log_escape_non_ascii off;
proxy_pass  tomcatTest;
set $requestURL '';
set $method '';
set $requestTime '';
set $responseTime '';
set $responseContent '';
body_filter_by_lua '
questTime=os.date("%Y-%m-%d %H:%M:%S")
questURL=ngx.var.scheme.."://"..ngx.var.server_name..":"..ngx.var.quest_uri
hod=quest_uri
local resp_body = string.sub(ngx.arg[1], 1, 1000)
if ngx.arg[2] then
sponseContent = buffered
end
sponseTime=os.date("%Y-%m-%d %H:%M:%S")
';
}
}
}
重新启动Nginx,然后进⾏验证
[root@Kerry conf]# nginx -p '/openrestyTest/v1/' -c f -s reload
[root@Kerry conf]#  tail -500f /openrestyTest/v1/logs/test.log
{"status":"200","requestTime":"2018-10-11 18:09:02","responseTime":"2018-10-11 18:09:02","requestURL":"47.96.238.21:9000/springboot-demo/hello","me 到此为⽌,提取经过Nginx⽹关的接⼝信息,并将其写⼊⽇志⽂件就完成了,所有的接⼝⽇志都写⼊了 test.log ⽂件中。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。