一、简介
Nginx 是免费的、开源的、高性能的HTTP和反向代理服务器、邮件代理服务器、以及TCP/UDP代理服务器,也是一台IMAP/POP3/SMTP代理服务器
Nginx的版本分为开发版、稳定版和过期版
能够快速的响应静态网页的请求,支持 FastCGI/SSL/Virtual Host/URLRwrite/Gzip/HTTP Basic Auth/http或者TCP的负载均衡(1.9版本以上且开启stream模块)等功能,并且支持第三方的功能扩展
互联网存在用户速度体验的1-3-10原则,即1秒最优,1-3秒较优,3~10秒比较慢,10秒以上用户无法接受
二、应用程序工作模式
2.1 httpd MPM模式
(Multi-Processing Module,多进程处理模块)
(1)prefork:进程模型,两级结构,主进程master负责生成主进程,每个子进程负责响应一个请求
(2)worker:线程模型,三级结构,主进程master负责生成主进程,每个子进程负责生成多个线程,每个线程响应一个请求
(3)event:线程模型,三级结构,主进程master负责生成主进程,每个子进程生成多个线程,每个线程响应一个请求,但是增加了一个监听线程,用于解决在设置了keep-alived场景下线程的空等待问题
2.2 Nginx(Master+Worker)模式
主进程
工作进程 #直接处理客户的请求
三、Nginx的组成与工作原理
Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个命令,用于URL匹配),而在这个location中所配置的每个命令将会启动不同的模块去完成相应的工作
Nginx的模块从结构上分为核心模块、基础模块和第三方模块,其中,
HTTP模块、EVENT模块和MAIL模块等属于核心模块
HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块属于基础模块
而HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块属于第三方模块
用户根据自己的需要开发的模块都属于第三方模块.正是有了这么多模块的支撑,Nginx的功能才会如此强大
核心模块:是 Nginx 服务器正常运行必不可少的模块,提供 错误日志记录、配置文件解析、事件驱动机制、进程管理 等核心功能
标准HTTP模块:提供 HTTP 协议解析相关的功能,比如:端口配置、网页编码设置、HTTP响应头设置 等等
可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如:Flash多媒体传输、解析 GeoIP 请求、网络传输压缩、安全协议SSL支持等
邮件服务模块:主要用于支持Nginx的邮件服务,包括对 POP3协议、IMAP协议和 SMTP协议 的支持
第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如:Json支持、Lua支持 等
四、分支
Nginx有一个著名的分支,淘宝网基于Nginx开发了Tengine,Tengine在使用上和Nginx一致,服务名、配置文件名也是一致的
Tengine和Nginx最大的区别在于,Tengine增加了一些定制化模块,在安全限速方面表现突出
另外,它还支持对JavaScript、css合并
五、openresty源码编译安装
#编译安装
默认安装路径为/usr/local/openresty,nginx安在/usr/local/openresty/nginx目录
[root@nginx openresty-1.19.3.2]# ./configure
[root@nginx openresty-1.19.3.2]# gmake
[root@nginx openresty-1.19.3.2]# gmake install
六、Nginx源码编译安装
6.1 CentOS系统安装
#下载nginx
wget https://nginx.org/download/nginx-1.18.0.tar.gz
#安装编译工具
yum install -y openssl-devel pcre-devel gcc
#创建nginx运行用户
useradd -M -s /sbin/nologin www
#预编译
tar xfv nginx-1.18.0.tar.gz
cd nginx-1.18.0
./configure --prefix=/usr/local/nginx \
--user=www \
--group=www \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
#编译安装
make -j 4 && make install
nginx的 ngx_http_upstream_module 模块是用于nginx反向代理的,默认在安装nginx时已经被安装
--without-xxxx : 编译配置关闭什么指定功能
--with-xxx : 编译设置开启什么指定功能
七、目录结构
编译安装完成之后,nginx位于于/usr/local/nginx目录下,有四个主要的目录
conf:
该目录中保存了nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能的,例如fastcgi功能使用的是fastcgi.conf和fastcgi_params两个文件
html:
该目录中保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web文件是默认的错误页面提示页面
logs:
该目录用来保存nginx服务器的访问日志、错误日志等,logs目录可以放在其他路径,比如/var/logs/nginx
sbin:
该目录用来保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能
八、Ubuntu系统编译安装
#依赖包
build-essential: 该包含一些必要的软件包,如编译器和make工具等,用于编译安装Nginx;
libpcre3: PCRE是Perl兼容正则表达式库,Nginx中默认启用该模块;
libpcre3-dev: PCRE开发库,用于编译Nginx PCRE模块;
zlib1g-dev: Zlib库提供了压缩和解压缩数据的函数,该库被Nginx使用,并且默认启用gzip模块;
libssl-dev: SSL(Secure Sockets Layer)提供了安全的通信渠道,该模块使Nginx能够支持HTTPS协议。
apt install -y build-essential libpcre3 libpcre3-dev zlib1g-dev libssl-dev
九、添加第三方模块方式
9.1 添加第三方静态模块
./configure --add-module=…/ngx_http_proxy_connect_module
9.2 添加第三方动态模块
./configure --add-dynamic-module=…/ngx_http_proxy_connect_module --with-compat
十、Nginx程序命令
-?,-h this help
-v 显示软件版本并退出
-V 显示版本和编译参数
-t 测试配置文件并退出
-T 测试配置文件, 保存全部配置信息并退出
-q 在配置测试时, 抑制正确信息输出,静默模式
-s signal send signal to a master process: stop, quit, reopen, reload
-p prefix 指定 Nginx 目录
-c filename 加载指定配置的文件
-g directives 设置全局指令
十一、Nginx的启动、关闭与重启
Nginx对进程的控制能力非常强大,可以通过信号命令控制进程.常用的信号有:
QUIT 表示处理完当前请求后关闭进程
HUP 表示重新加载配置,即关闭原有的进程并开启新的工作进程.此操作不会中断用户的访问请求,因此,可以通过此信号平滑地重启Nginx
USRl 用于Nginx的日志切换,也就是重新打开一个日志文件,例如,每天要生成一个新的日志文件时,可以使用这个信号来控制
USR2 用于平滑升级可执行程序
WINCH 从容关闭工作进程
十二、systemctl管理nginx
cat >/usr/lib/systemd/system/nginx.service<<EOF
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/bin/rm -f /var/run/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -q
ExecStart=/usr/local/nginx/sbin/nginx -g "pid /var/run/nginx.pid;"
ExecReload=/usr/local/nginx/sbin/nginx -t -q
ExecReload=/usr/local/nginx/sbin/nginx -s reload -g "pid /var/run/nginx.pid;"
ExecStop=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
加载生效:
[root@nginx ~]# systemctl daemon-reload
[root@nginx ~]# systemctl enable nginx.service
[root@nginx ~]# systemctl start nginx.service
十三、反向代理及负载均衡配置
upstream 负载均衡模块,定义可以调度的节点信息
proxy_pass 反向代理模块,将用户请求发送给指定集群
upstream server-enpoint { #server-enpoint是一个定义的web集群组,可以自定义
server 10.0.0.7:80;
server 10.0.0.8:80;
server 10.0.0.9:80;
}
server { #server配置文件放到了主配置文件中
listen 80;
server_name localhost;
location / {
proxy_pass http://server-enpoint; #将用户请求发送给指定server-enpoint集群
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_next_upstream error timeout invalid_header http_404;
}
}
}
十四、正向代理配置
正向代理服务器(192.168.10.10)配置:
server {
resolver 114.114.114.114; #指定DNS服务器IP地址
listen 80;
location / {
proxy_pass http://$host$request_uri; #设定代理服务器的协议和地址
proxy_set_header HOST $host;
proxy_buffers 256 4k;
proxy_max_temp_file_size 0k;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_next_upstream error timeout invalid_header http_502;
}
}
server {
resolver 114.114.114.114; #指定DNS服务器IP地址
listen 443;
location / {
proxy_pass https://$host$request_uri; #设定代理服务器的协议和地址
proxy_buffers 256 4k;
proxy_max_temp_file_size 0k;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_next_upstream error timeout invalid_header http_502;
}
}
客户端访问测试:
[root@localhost ~]# curl -I --proxy 192.168.10.10:80 www.baidu.com
[root@localhost ~]# curl -I --proxy 192.168.10.10:443 www.baidu.com
设置Linux客户端全局代理:
[root@localhost ~]# vim /etc/profile
export http_proxy='192.168.10.10:80'
export http_proxy='192.168.10.10:443'
export ftp_proxy='192.168.10.10:80'
[root@localhost ~]# source /etc/profile
[root@localhost ~]# curl -I www.baidu.com:80
[root@localhost ~]# curl -I www.baidu.com:443
十五、ELK收集nginx日志
15.1 docker安装ELK
[root@docker elk]# cat elk.yaml
version: '2'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.0.1
container_name: elasticsearch701
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
hostname: elasticsearch
restart: always
ports:
- "9200:9200"
- "9300:9300"
kibana:
image: docker.elastic.co/kibana/kibana:7.0.1
container_name: kibana701
hostname: kibana
depends_on:
- elasticsearch
restart: always
ports:
- "5601:5601"
logstash:
image: docker.elastic.co/logstash/logstash:7.0.1
container_name: logstash701
hostname: logstash
restart: always
depends_on:
- elasticsearch
ports:
- "5044:5044"
##启动ELK
[root@docker elk]# docker-compose -f elk.yaml up -d
##数据持久化,创建如下目录
[root@docker apps]# pwd
/opt/data/apps
[root@docker apps]# mkdir -p {elasticsearch/config,elasticsearch/data,elasticsearch/modules,elasticsearch/plugins,kibana/config,logstash/config,logstash/pipeline}
[root@docker apps]# tree
.
├── elasticsearch
│ ├── config
│ ├── data
│ ├── modules
│ └── plugins
├── kibana
│ └── config
└── logstash
├── config
└── pipeline
##复制容器数据到数据存储目录
[root@docker apps]# docker cp elasticsearch701:/usr/share/elasticsearch/data elasticsearch
[root@docker apps]# docker cp elasticsearch701:/usr/share/elasticsearch/config elasticsearch
[root@docker apps]# docker cp elasticsearch701:/usr/share/elasticsearch/modules elasticsearch
[root@docker apps]# docker cp elasticsearch701:/usr/share/elasticsearch/plugins elasticsearch
[root@docker apps]# docker cp logstash701:/usr/share/logstash/config logstash
[root@docker apps]# docker cp logstash701:/usr/share/logstash/pipeline logstash
[root@docker apps]# docker cp kibana701:/usr/share/kibana/config kibana
##logstash配置
[root@docker apps]# cd logstash/pipeline
[root@docker pipeline]# cat logstash.conf
input {
beats {
port => 5044
codec =>"json"
}
}
output {
elasticsearch {
hosts => ["http://172.16.0.66:9200"]
index => "logstash-nginx-%{[@metadata][version]}-%{+YYYY.MM.dd}"
}
}
[root@docker apps]# chown -R 1000:1000 elasticsearch/*
[root@docker apps]# chown -R 1000:1000 logstash/*
##配置docker-compose文件,挂载数据存储目录
[root@docker elk]# cat elk.yaml
version: '2'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.0.1
container_name: elasticsearch701
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- /opt/data/apps/elasticsearch/modules:/usr/share/elasticsearch/modules
- /opt/data/apps/elasticsearch/plugins:/usr/share/elasticsearch/plugins
- /opt/data/apps/elasticsearch/data:/usr/share/elasticsearch/data
- /opt/data/apps/elasticsearch/config:/usr/share/elasticsearch/config
hostname: elasticsearch
restart: always
ports:
- "9200:9200"
- "9300:9300"
kibana:
image: docker.elastic.co/kibana/kibana:7.0.1
container_name: kibana701
hostname: kibana
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- /opt/data/apps/kibana/config:/usr/share/kibana/config
depends_on:
- elasticsearch
restart: always
ports:
- "5601:5601"
logstash:
image: docker.elastic.co/logstash/logstash:7.0.1
container_name: logstash701
hostname: logstash
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- /opt/data/apps/logstash/pipeline:/usr/share/logstash/pipeline
- /opt/data/apps/logstash/config:/usr/share/logstash/config
restart: always
depends_on:
- elasticsearch
ports:
- "5044:5044"
##启动ELK
[root@docker elk]# docker-compose -f elk.yaml up -d
##nginx日志格式改为json格式
[root@docker ~]# cat /usr/local/nginx/conf/nginx.conf
log_format json '{"@timestamp": "$time_iso8601", '
'"connection": "$connection", '
'"remote_addr": "$remote_addr", '
'"remote_user": "$remote_user", '
'"request_method": "$request_method", '
'"request_uri": "$request_uri", '
'"server_protocol": "$server_protocol", '
'"status": "$status", '
'"body_bytes_sent": "$body_bytes_sent", '
'"http_referer": "$http_referer", '
'"http_user_agent": "$http_user_agent", '
'"http_x_forwarded_for": "$http_x_forwarded_for", '
'"request_time": "$request_time"}';
access_log logs/access.log json;
#安装Filebeat
rpm -ivh https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.0.1-x86_64.rpm
#设置输出数据到Logstash及Logstash地址
sed -i "s/#output.logstash:/output.logstash:/g" /etc/filebeat/filebeat.yml
sed -i "s/#hosts: \[\"localhost:5044\"\]/ hosts: \[\"172\.16\.0\.66:5044\"\]/g" /etc/filebeat/filebeat.yml
#关闭直接输出数据到Elasticsearch
sed -i "s/output.elasticsearch/#output.elasticsearch/g" /etc/filebeat/filebeat.yml
sed -i "s/hosts: \[\"localhost:9200\"\]/#hosts: \[\"localhost:9200\"\]/g" /etc/filebeat/filebeat.yml
#安装Filebeat Nginx 模块
filebeat modules enable nginx
#配置Filebeat Nginx 模块
cat >/etc/filebeat/modules.d/nginx.yml<<EOF
- module: nginx
access:
enabled: true
var.paths: ["/usr/local/nginx/logs/*access.log"]
error:
enabled: true
var.paths: ["/usr/local/nginx/logs/*error.log"]
EOF
#检查配置
[root@docker modules.d]# filebeat test config
Config OK
[root@docker modules.d]# filebeat test output
logstash: 172.16.0.66:5044...
connection...
parse host... OK
dns lookup... OK
addresses: 172.16.0.66
dial up... OK
TLS... WARN secure connection disabled
talk to server... OK
#启动filebeat
[root@docker modules.d]# systemctl restart filebeat.service
#设置开机自启动
[root@docker modules.d]# enable restart filebeat.service
#Kibana展示
浏览器输入http://172.16.0.66:5601/进行Kibana后台访问,点击Management->index_patterns->Create index pattern,输入“logstash-ngin-*”,
创建索引然后点击discover,即可查询日志
十六、动静分离配置
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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 /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
upstream dynamic {
server 10.0.0.7:80;
}
upstream static {
server 10.0.0.8:80;
}
upstream default {
server 10.0.0.9:80;
}
server {
listen 80;
server_name localhost;
include proxy_params;
location /dynamic/ {
proxy_pass http://dynamic;
}
location /static/ {
proxy_pass http://static;
}
location / {
proxy_pass http://default;
}
}
}
include proxy_params:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_next_upstream error timeout invalid_header http_404;