Openresty学习使用(一)记录爬虫结果日志

Openresty学习使用(一)记录爬虫结果日志

    • 业务场景
    • openresty安装
    • openresty配置
    • Java调用
    • 问题

业务场景

日志记录很多时候是一种高并发场景的解决方案,对于不那么重要或者及时的场景可以通过异步记录日志的方式,异步将日志存储成文件,可以加快业务的返回,后续可以用ELK等框架对日志进行分析处理。
本文所说的爬虫都是垂直领域的爬虫,结果都以JSON格式进行返回。由于爬虫整体的不稳定性,我们把爬虫结果分为两大部分,一部分是基本的状态信息,包含爬取站点,爬取参数,爬取状态等,一部分是爬取结果,我们将基本的状态信息利用ELK进行处理,利用ELK对日志进行分析,对爬虫整体情况进行分析统计告警,将另一部分爬取结果写入Hbase,用于结果存储。当然也可以是其他存储实现。
由于爬虫机器很多,如果每台机器都用Log4j等方式进行输出的话,部署都很麻烦,且对磁盘空间也有要求,所以我们采取了Nginx的方式,将日志统一收集到几台机器进行处理。
由于需要一些像lua脚本进行文件夹创建等操作,我们采用了openresty。

openresty安装

sudo yum install yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
sudo yum install openresty

openresty是淘宝大神维护的产品,相对于nginx的高门槛,通过集成lua等方式,给我们提供了对nginx操作的更多可能

openresty配置

    //记录消息体
    log_format  main  '{ "timestamp":"$time_local",'
                      '"result":"$request_body"}';
    
    client_body_buffer_size 1m;
    client_body_in_single_buffer on;
    log_escape_non_ascii off;
    open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;
        #access_log  logs/host.access.log  main;

        location ~ /(.+)/(.+)$ {
                if (!-e /data/server/nginx/logs/$1) {
                         //lua脚本 自动创建目录
                        content_by_lua '
                                local uri = ngx.var.request_uri
                                local t = string.match(uri,"/(.+)/.+")
                                local dir = "/data/server/nginx/logs/"..t
                                os.execute("mkdir " .. dir)               
                        ';
                }
                access_log /data/server/nginx/logs/$1/$2.log main;
                echo_read_request_body;
        }

说明
client_body_buffer_size设置nginx可以处理的最大request body大小。
client_body_in_single_buffer 让Nginx将所有的request body存储在一个缓冲当中
启用它可以优化读取$request_body变量时的I/O性能。
对于每一条日志记录,日志文件都将先打开文件,再写入日志记录,然后马上关闭。 为了提高包含变量的日志文件存放路径的性能,需要使用 open_log_file_cache 指令设置经常被使用的日志文件描述符缓存。
open_log_file_cache 指令的各项参数说明如下:
max: 设置缓存中的最大文件描述符数量。如果超过设置的最大文件描述符数量,则采用 LRU (Least Recently Used) 算法清除"较不常使用的文件描述符"。 LRU (Least Recently Used) 算 法的基本概念是:当内存缓冲区剩余的可用空间不够时,缓冲区尽可能地先保留使用者最常使用的数据,将最近未使用的数据移出内存,腾出空间来加载另外的数据。
inactive: 设置一个时间,如果在设置的时间内没有使用此文件描述符,则自动删除此描述符。 此参数为可选参数,默认的时间为 10 秒钟。
min_uses: 在参数 inactive 指定的时间范围内,如果日志文件超过被使用的次数,则将该日志文件的描述符记入缓存。默认次数为 1。
valid: 设置多长时间检查一次,看一看变量指定的日志文件路径与文件名是否仍然存在。默 认时间为 60秒。
off: 禁止使用缓存。

Java调用

 static{
	ConnectingIOReactor ioReactor;
	try {
		ioReactor = new DefaultConnectingIOReactor();
		PoolingNHttpClientConnectionManager cm = new PoolingNHttpClientConnectionManager(ioReactor);
	    cm.setMaxTotal(500); 
	    httpAsyncClient = HttpAsyncClients.custom().setConnectionManager(cm).build();
	        httpAsyncClient.start();
	} catch (IOReactorException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
     
}

public static void doPost(String tag,String xml){
	try {
		String htmlurl = PRE_URL+tag;
		HttpPost post = new HttpPost(htmlurl);
		post.setEntity(new  StringEntity(xml,"utf-8"));
		httpAsyncClient.execute(post, null);
	 } catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
}

java侧采用HttpAsyncClient, HttpAsyncClient的出现并不是为了替换 HttpClient,而是作为一个补充,用于需要大量并发连接,对性能要求非常高的基于HTTP的原生数据通信,而且提供了事件驱动的 API。

问题

1.文件请求体太大,导致request_body返回内容为-
参考nginx配置中的client_body_buffer_size client_body_in_single_buffer 配置
2.x22格式的问题
nginx配置增加 log_escape_non_ascii off;
3.安全性问题
最好是能够在内网访问,如果是外网,最好添加白名单

你可能感兴趣的:(java,数据采集,nginx)