Rootop 服务器运维与web架构

2020-04-13
发表者 Venus
nginx屏蔽HEAD OPTIONS请求方法日志已关闭评论

nginx屏蔽HEAD OPTIONS请求方法日志

比如nginx日志里有options方法的请求,对分析日志没实际作用,就需要在记录日志时候屏蔽掉。
{“remote_addr”:”192.168.1.141″,”X-Forwarded-For”:””,”remote_user”:””,”time_local”:”13/Apr/2020:09:58:28 +0800″,”request”:”OPTIONS /login HTTP/1.1″,”method“:”OPTIONS”,”uri”:”/login”,”server_protocol”:”HTTP/1.1″,”request_body”:”userid=11″,”status”:”200″,”body_bytes_sent”:”0″,”http_referer”:””,”user_agent”:”PostmanRuntime/7.24.0″,”upstream_response_time”:”0.006″}

网上有说用if判断请求方法是options,则不记录日志(access_log off),不生效,不是无效,是配置的位置不对。

# 演示下错误的配置方法

server
{
	listen 80;
	server_name admin;

	access_log  /usr/local/nginx/logs/admin_access.log;
	error_log   /usr/local/nginx/logs/admin_error.log;

	if ($request_method = "OPTIONS")
	{
		access_log off;
	}

	location /
	{
		proxy_pass http://192.168.10.60:10102;
	}
}

# 重启nginx

(base) [root@localhost vhost]# /usr/local/nginx/sbin/nginx -t
nginx: [emerg] "access_log" directive is not allowed here in /usr/local/nginx/conf/vhost/admin.conf:11

这个提示就是说access_log配置指令不允许出现在这里。
官方文档表明,access_log 是允许出现在 http, server, location, if in location, limit_except 这几个配置段中。
如果用了if判断,则需要配置在location中。

# 正确方式

server
{
	listen 80;
	server_name admin;

	access_log  /usr/local/nginx/logs/admin_access.log;
	error_log   /usr/local/nginx/logs/admin_error.log;
	
	location /
	{
		proxy_pass http://192.168.10.60:10102;
		
		if ($request_method = "OPTIONS")
		{
			access_log off;
		}
	}
}

如果有多个方法需要屏蔽可以用正则,比如屏蔽options和head方法

if ($request_method ~* OPTIONS|HEAD)
{
    access_log off;
}

这样才可以实现不记录OPTIONS方法日志。

第二种方式:

map $request_method $m {
	OPTIONS 0;
	HEAD 0;
	default 1;
}

server
{
	listen 80;
	server_name admin;

	location /
	{
		proxy_pass http://192.168.10.60:10102;
	}
	
	access_log  /usr/local/nginx/logs/admin_access.log combined if=$m;
	error_log   /usr/local/nginx/logs/admin_error.log;
}

server
{
	listen 80;
	server_name api;

	location /
	{
		proxy_pass http://192.168.10.60:10103;
	}
   access_log  /usr/local/nginx/logs/api_access.log combined if=$m;
   error_log   /usr/local/nginx/logs/api_error.log;

}

通过map指令设置自定义变量(map指令由ngx_http_map_module模块提供,默认安装。)
The ngx_http_map_module module creates variables whose values depend on values of other variables.
注意map指令只能在http{}段中出现。对所有虚拟主机都可以直接用。

官方文档中关于access_log的参数:

access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

The if parameter (1.7.0) enables conditional logging. A request will not be logged if the condition evaluates to “0” or an empty string. In the following example, the requests with response codes 2xx and 3xx will not be logged:

map $status $loggable {
    ~^[23]  0;
    default 1;
}

access_log /path/to/access.log combined if=$loggable;

意思是如果用if参数,后面需要跟着一个变量,这个变量如果是0或者是空字符串,则不会记录日志。
上面的第二种方法就是通过map+access_log中if参数实现的。

2020-04-10
发表者 Venus
goaccess配置采集nginx json格式日志已关闭评论

goaccess配置采集nginx json格式日志

之前为了便于python分析nginx日志,将日志格式改为json格式。但是用goaccess分析json格式还需要再下配置。

nginx中格式配置如下:

log_format api escape=json
	'{'
	'"remote_addr":"$remote_addr",'
	'"X-Forwarded-For":"$http_X_Forwarded_For",'
	'"remote_user":"$remote_user",'
	'"time_local":"$time_local",'
	#'"request":"$request",'
	'"method":"$request_method",'
	'"uri":"$uri",'
	'"server_protocol":"$server_protocol",'
	'"request_body":"$request_body",'
	'"status":"$status",'
	'"body_bytes_sent":"$body_bytes_sent",'
	'"http_referer":"$http_referer",'
	'"user_agent":"$http_user_agent",'
	'"upstream_response_time":"$upstream_response_time"'
	'}';

nginx访问日志如下:

{"remote_addr":"115.220.x.x","X-Forwarded-For":"","remote_user":"","time_local":"09/Apr/2020:13:28:09 +0800","method":"POST","uri":"/xxx/xxx","server_protocol":"HTTP/1.1","request_body":"xxxxxxx","status":"200","body_bytes_sent":"468","http_referer":"","user_agent":"Mozilla/5.0 (Linux; Android 10; LIO-AN00 Build/HUAWEILIO-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.64 Mobile Safari/537.36","upstream_response_time":"0.003"}

goaccess 官方配置文档:https://goaccess.io/man#custom-log
goaccess配置文件:

time-format %H:%M:%S # 定义时分秒格式 通过%t调用
date-format %d/%b/%Y # 定义日期格式   通过%d调用
log-format %^:"%h",%^:%^,%^:%^,%^:"%d:%t %^",%^:"%m",%^:"%U",%^:"%H",%^:%^,%^:"%s",%^:%^,%^:"%R",%^:"%u",%^:%^

拼出来要匹配的json格式(等于保留冒号和逗号),还是跟以前一样通过%^忽略某个字段,如:
第一个%^即可忽略{“remote_addr”部分,冒号后面双引号中的%h即可匹配到客户端ip地址,以此来依次匹配出需要的字段。

2020-04-10
发表者 Venus
filebeat配置多行日志合并为一条已关闭评论

filebeat配置多行日志合并为一条

java的错误日志通常有多行表示为一次完成的错误日志。收集的时候需要将其合并为一条。否则每行都会做为一条日志发送。
(logstash也是如此)

如:

13:20:05.491 [http-nio-8080-exec-10] ERROR com.xxx.modules.mall.controller.ApiMallGoodsController - 【商品详情】报错:
java.lang.NullPointerException: null
	at com.xxx.modules.mall.goods.service.MallGoodsService.apiMallGoodsInfo(MallGoodsService.java:279)
	...
	略

官方关于多行匹配参数:https://www.elastic.co/guide/en/beats/filebeat/current/multiline-examples.html

# 配置参数

[root@node3 filebeat]# cat filebeat-java.yml 
filebeat.inputs:
- type: log
  paths:
   - /home/dockermount/api/api*/logs/*-error.log
  fields:
   java: true
  fields_under_root: true
  multiline.pattern: '^[0-9]{2}:[0-9]{2}:[0-9]{2}.* \[http-nio'
  multiline.negate: true
  multiline.match: after

output.redis:
  hosts: ["172.19.34.91:50000"]
  password: "******"
  key: "filebeat-java"
  db: 8
  timeout: 10
multiline.pattern 是匹配一条完整日志开头的正则,如 13:20:05.491 [http-nio 开头
multiline.negate 可配置为true或false,如果为true,则代表 不匹配的行
multiline.match  可配置为before或after,对不匹配的行做什么动作。如果为after,则代表不匹配的行附加到之前匹配行的下面

2020-04-09
发表者 Venus
centos7中利用conda实现多python版本已关闭评论

centos7中利用conda实现多python版本

conda可以用来解决系统中多个python版本共存,也支持其他语言。
这里主要用来解决python3.8下写的脚本在centos7中运行。

conda安装需要 Anaconda 或 Miniconda,推荐安装Anaconda。区别去下面官方看。

下载地址:https://www.anaconda.com/distribution/#download-section
安装文档:https://conda.io/projects/conda/en/latest/user-guide/install/linux.html
Anaconda2 用于系统中python版本为2.x
Anaconda3 用于系统中python版本为3.x
我这里为centos7,下载Anaconda2版本的。

[root@localhost ~]# wget -c https://repo.anaconda.com/archive/Anaconda2-2019.10-Linux-x86_64.sh
[root@localhost ~]# bash Anaconda2-2019.10-Linux-x86_64.sh

最后他会提示是否init,输入yes初始化,重新ssh登录服务器。

(base) [root@localhost ~]# 

会看到前面有个 (base) ,这就是进去了conda环境中了。

# 创建一个python3.8的环境

(base) [root@localhost ~]# conda create --name py3 python=3.8

# 查看已有的环境

(base) [root@localhost ~]# conda info --envs
# conda environments:
#
base                  *  /root/anaconda2
py3                      /root/anaconda2/envs/py3

# 切换版本

(base) [root@localhost ~]# source activate py3
(py3) [root@localhost ~]# python -V
Python 3.8.2

# 退出conda环境

(base) [root@localhost ~]# source deactivate base
[root@localhost ~]# 

# 移除环境

[root@localhost ~]# conda remove -n py3 --all

这样就很方便把py3的脚本在centos中运行,而且不用更改系统python版本。

PS:清华镜像及加速配置:https://mirror.tuna.tsinghua.edu.cn/help/anaconda/

2020-03-21
发表者 Venus
nginx中11个处理阶段已关闭评论

nginx中11个处理阶段

转载自:https://blog.csdn.net/chen213wb/article/details/84728615

对于理解11个阶段有助于在做openresty脚本开发时执行过程的理解,记录一下。

nginx实际把http请求处理流程划分为了11个阶段,这样划分的原因是将请求的执行逻辑细分,以模块为单位进行处理,各个阶段可以包含任意多个http模块并以流水线的方式处理请求。这样做的好处是使处理过程更加灵活、降低耦合度。这11个http阶段如下所示:

1)ngx_http_post_read_phase:

接收到完整的http头部后处理的阶段,它位于uri重写之前,实际上很少有模块会注册在该阶段,默认的情况下,该阶段被跳过。

2)ngx_http_server_rewrite_phase:

uri与location匹配前,修改uri的阶段,用于重定向,也就是该阶段执行处于server块内,location块外的重写指令,在读取请求头的过程中nginx会根据host及端口找到对应的虚拟主机配置。

3)ngx_http_find_config_phase:

根据uri寻找匹配的location块配置项阶段,该阶段使用重写之后的uri来查找对应的location,值得注意的是该阶段可能会被执行多次,因为也可能有location级别的重写指令。

4)ngx_http_rewrite_phase:

上一阶段找到location块后再修改uri,location级别的uri重写阶段,该阶段执行location基本的重写指令,也可能会被执行多次。

5)ngx_http_post_rewrite_phase:

防止重写url后导致的死循环,location级别重写的后一阶段,用来检查上阶段是否有uri重写,并根据结果跳转到合适的阶段。

6)ngx_http_preaccess_phase:

下一阶段之前的准备,访问权限控制的前一阶段,该阶段在权限控制阶段之前,一般也用于访问控制,比如限制访问频率,链接数等。

7)ngx_http_access_phase:

让http模块判断是否允许这个请求进入nginx服务器,访问权限控制阶段,比如基于ip黑白名单的权限控制,基于用户名密码的权限控制等。

8)ngx_http_post_access_phase:

访问权限控制的后一阶段,该阶段根据权限控制阶段的执行结果进行相应处理,向用户发送拒绝服务的错误码,用来响应上一阶段的拒绝。

9)ngx_http_try_files_phase:

为访问静态文件资源而设置,try_files指令的处理阶段,如果没有配置try_files指令,则该阶段被跳过。

10)ngx_http_content_phase:

处理http请求内容的阶段,大部分http模块介入这个阶段,内容生成阶段,该阶段产生响应,并发送到客户端。

11)ngx_http_log_phase:

处理完请求后的日志记录阶段,该阶段记录访问日志。

以上11个阶段中,http无法介入的阶段有4个:

3)ngx_http_find_config_phase

5)ngx_http_post_rewrite_phase

8)ngx_http_post_access_phase

9)ngx_http_try_files_phase

剩余的7个阶段,http模块均能介入,每个阶段可介入模块的个数也是没有限制的,多个http模块可同时介入同一阶段并作用于同一请求。