Nginx学习
一、Nginx
- Nginx:轻量级、高性能的HTTP 和反向代理服务器,也是IMAP/POP3/SMTP代理服务器
- 官方测试支持5万并发
- 特点:cpu、内存消耗小,并发能力强
Nginx 可以解决的问题
- 高并发
- 负载均衡
- 高可用
- 虚拟主机
- 伪静态
- 动静分离
二、对比Nginx 和Apache
Apache:同步多进程模型,一个连接对应一个进程,一个进程对应一个线程;
Nginx:异步,多个连接(万级别)对应一个进程,一个进程对应多个线程。
Nginx优点
- 轻量级,同样起web服务,比apache占用更少的内存及资源
- 抗并发,Nginx处理请求时异步非阻塞(I/O)的,而apache是阻塞的,高并发下nginx拥有低消耗高性能
- 高度模块化设计,编写模块相对简单
- 社区活跃,各种高性能模块产出迅速
- 配置简洁
Apache优点
* 相比Nginx,rewrite更加强大
* 模块多,功能完善,基本想要的功能都有
* bug较少
rewrite :即url重写,如将http://xxx/index.html?p=123 改写为http://xxx/index.html/p/123.html,使其对浏览器更友好
Nginx与Apache进程调度
前提:cpu同时内核数为4,只能同时处理四个进程
nginx:异步处理
当有四个用户发起请求时,每个进程处理一个用户请求;
当第五个用户接入时,没有空闲进程,选择一个进程,开启新的线程交由操作系统内核去处理(磁盘I/O、网络I/O),进程只负责监控状态,进行转发,从而减少了cpu进程调度的时间
Apache:同步处理
当有四个用户发起请求时,每个进程处理一个用户请求;
当第五个用户接入时,没有空闲进程,选择一个进程,抢占cpu资源,cpu通过进程调度来处理请求
三、相关资源文档
- Tengine下载和文档
http://tengine.taobao.org/
- Nginx官网和文档
http://nginx.org
- Tengne :对Nginx进行了封装与扩展,基本配置相同
四、安装Tengine
注意:安装前需要安装系统依赖组件
gcc openssl-devel pcre-devel zlib-devel
安装:
yum install gcc openssl-devel pcre-devel zlib-devel -y
- 将下载好的安装包(tengine-2.3.1.tar.gz)上传服务器,并解压
tar -zxvf tengine-2.3.1.tar.gz
-
文件目录中的可执行文件configure:用来配置tengine相关参数
[root@VM-16-11-centos tengine-2.3.1]# ./configure --prefix=/usr/local/tengine #配置成功,显示相关配置 Configuration summary + using system PCRE library + using system OpenSSL library + using system zlib library + jemalloc library is disabled nginx path prefix: "/usr/local/tengine" nginx binary file: "/usr/local/tengine/sbin/nginx" nginx modules path: "/usr/local/tengine/modules" nginx configuration prefix: "/usr/local/tengine/conf" nginx configuration file: "/usr/local/tengine/conf/nginx.conf" nginx pid file: "/usr/local/tengine/logs/nginx.pid" nginx error log file: "/usr/local/tengine/logs/error.log" nginx http access log file: "/usr/local/tengine/logs/access.log" nginx http client request body temporary files: "client_body_temp" nginx http proxy temporary files: "proxy_temp" nginx http fastcgi temporary files: "fastcgi_temp" nginx http uwsgi temporary files: "uwsgi_temp" nginx http scgi temporary files: "scgi_temp"
-
编译并安装
make && make install
-
安装完成可以在/usr/local/中找到tengine目录
使用/usr/local/tengine/sbin目录中的nginx命令启动tengine
[root@VM-16-11-centos sbin]# ./nginx [root@VM-16-11-centos sbin]# #不报错,即启动成功
在浏览器使用IP访问:http://xx.xx.xx.xx/,出现如下页面,表示安装成功
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-44TCqhZJ-1617118860756)(.\image\nginx默认页面.png)]
-
停止nginx
nginx没有停止命令,只能直接杀掉进程
[root@VM-16-11-centos sbin]# ps -ef | grep nginx root 15432 1 0 20:31 ? 00:00:00 nginx: master process ./nginx #主进程 nobody 15433 15432 0 20:31 ? 00:00:00 nginx: worker process #工作线程 root 16697 32742 0 20:40 pts/1 00:00:00 grep --color=auto nginx [root@VM-16-11-centos sbin]# kill -9 15432 15433 #主进程与 工作线程都要杀掉 [root@VM-16-11-centos sbin]# ps -ef | grep nginx root 16794 32742 0 20:41 pts/1 00:00:00 grep --color=auto nginx [root@VM-16-11-centos sbin]#
开机启动
chkconfig --list
chkconfig --add nginx
chkconfig nginx on
#时间同步
service ntpd status
配置nginx启动脚本
- 在/etc/init.d/nginx文件中编写启动脚本,脚本内容如下,文件不存在则创建,文件路径不能修改
- 赋予可执行权限 :
chmod 777 ./nginx
- 启动命令
service Nginx start #启动服务
service Nginx stop #停止服务
service Nginx status #查看状态
service Nginx reload #动态重载配置文件
#centos7 中可以使用下面命令
systemctl start nginx
systemctl stop nginx
systemctl status nginx
systemctl daemon-reload #重新加载启动脚本
#nginx启动脚本内容,需要针对自己的安装目录进行修改
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /etc/sysconfig/nginx
# pidfile: /var/run/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/tengine/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/usr/local/tengine/conf/nginx.conf"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/subsys/nginx
make_dirs() {
# make required directories
user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
options=`$nginx -V 2>&1 | grep 'configure arguments:'`
for opt in $options; do
if [ `echo $opt | grep '.*-temp-path'` ]; then
value=`echo $opt | cut -d "=" -f 2`
if [ ! -d "$value" ]; then
# echo "creating" $value
mkdir -p $value && chown -R $user $value
fi
fi
done
}
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
make_dirs
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
sleep 1
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac
五、相关配置
/usr/local/tengine/conf/nginx.conf nginx配置文件
#如果不配置,默认当前登录的用户,尽量不要使用root用户运行,
user nobody;
user www www; #指定nginx运行的用户和用户组
#允许nginx同时处理的最大进程数,建议设置为等于cpu的总核心数,最大化利用资源,避免cpu频繁切换进行
worker_processes 8;
#一个进程能处理的最大连接数,并发量即为:进程数*连接数,官方号称可以处理5万并发,实际需要考虑系统磁盘I/O和网络I/O。
#events表示基于事件,异步网络I/O是基于事件的
events {
worker_connections 1024;
}
#linux内核能打开的文件句柄个数,总连接数要小于这个数字
[root@VM-16-11-centos conf]# cat /proc/sys/fs/file-max
177079
#当前使用句柄数
cat /proc/sys/fs/file-nr
#修改句柄数
ulimit -SHn 65535
#查看系统资源限制
ulimit -a
#并发总数是 worker_processes 和 worker_connections 的乘积
#即 max_clients = worker_processes * worker_connections
#在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4
#为什么上面反向代理要除以4,应该说是一个经验值
#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log info;
#进程文件
pid /var/run/nginx.pid;
#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。
worker_rlimit_nofile 65535;
http
#文件扩展名与文件类型映射表,include 可以引入其他配置
#通过配置文件类型,可以指定页面加载方式:下载或直接打开
include mime.types;
default_type application/octet-stream; #默认文件类型
charset utf-8; #默认编码
client_header_buffer_size 32k; #上传文件大小限制
#sendfile指令:文件传输模式,指定nginx是否调用sendfile函数来输出文件
#sendfile on; 开启高效文件传输模式,对普通应用设为on
#如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载
#如果图片显示不正常改为off。
#操作本地磁盘文件时
sendfile on 相当于 ctrl+x
sendfile off 相当于 ctrl+c
#操作网络文件时
sendfile on:app向内核发送一个指令,由内核去磁盘读取文件,并发送给网卡
sendfile off:app从磁盘读取文件,发送给内核,内核再发送给网卡,多一层I/O
tcp_nopush
在linux/Unix系统中优化tcp数据传输,批处理,仅在sendfile开启时有效
autoindex on;
#开启目录列表访问,合适下载服务器,默认关闭。
keepalive_timeout 120;
#长连接超时时间,单位是秒
gzip
`gzip on;` 开启gzip压缩输出
`gzip_min_length 1k;` 设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是0,不管页面多大都压缩。建议设置成大于2k的字节数,小于2k可能会越压越大。
`gzip_buffers 4 16k;` 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。 例如 4 4k 代表以4k为单位,按照原始数据大小以4k为单位的4倍申请内存。 4 8k 代表以8k为单位,按照原始数据大小以8k为单位的4倍申请内存。 如果没有设置,默认值是申请跟原始数据相同大小的内存空间去存储gzip压缩结果。
`gzip_http_version 1.0; `压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
`gzip_comp_level 2;` 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间
`gzip_types text/plain application/x-javascript text/css application/xml;`
#压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。
默认值: gzip_types text/html (默认不对js/css文件进行压缩)
压缩类型,匹配MIME类型进行压缩
设置哪压缩种文本文件可参考 conf/mime.types
`gzip_disable "MSIE [1-6]\."; `E6及以下禁止压缩
`gzip_vary on; `给CDN和代理服务器使用,针对相同url,可以根据头信息返回压缩和非压缩副本
server
http{
server{
#表示一个虚拟主机
}
}
#虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务,每个虚拟主机之间是独立的,互不影响的
通过nginx可以实现虚拟主机的配置,nginx支持三种类型的虚拟主机配置
- 基于ip的虚拟主机, (一块主机绑定多个ip地址)
- 基于域名的虚拟主机(servername)
- 基于端口的虚拟主机(listen如果不写ip端口模式)
#监听端口
listen 80;
#服务名,域名可以有多个,用空格隔开
server_name www.mashibing.com mashibing.com;
#编码集
charset koi8-r;
日志相关
access_log "pipe:rollback logs/host.access_log interval=1d baknum=7 maxsize=2G" main;
location
location / {#匹配规则
root html; #根目录
index index.html index.htm; #默认页面,依次查找,当访问路径中没有指定页面时返回
}
匹配规则:普通匹配 < 长路径匹配 < 正则匹配 < 短路匹配 < 精确匹配
当存在多个同类配置时
正则匹配:与编辑顺序有关,匹配到第一个规则就停止后面的匹配
其他匹配:与顺序无关,按
最大前缀规则
匹配
* /xxx #普通匹配,匹配当前路径及子路径
* /xxx/xxx #长路径匹配,即比普通匹配较长的路径,匹配当前路径及子路径
-
~/xxx #正则匹配,区分大小写
~*/xxx #正则匹配,不区分大小写
-
^~/xxx/ooo #短路匹配
-
=/xxx #精确匹配,只匹配当前路径
注意事项
-
root
配置只能有一个,即所有location中的root配置必须相同,如果需要指定其他根目录,使用alias
(虚拟目录) -
root与alias区别
-
都是指定用来指定文件根目录,但是配置段不同,
root配置段:http、server、 location、if
alias配置段:location
-
nginx解析路径区别
root:root路径 + location路径
alias:使用alias 路径替换location路径
-
-
location路径配置时需要注意,当配置路径与静态页面名称相同时,会有坑,如下
location / { #配置一
root html;
index index.html index.htm;
}
location /doc {#配置二
root html;
index doc.html index.htm;
}
http://xx.xx.xx.xx/doc.html;http://xx.xx.xx.xx/doc/doc.html #使用这两个连接访问时,nginx都会匹配到 配置二,
#IP访问控制
location {
deny IP /IP段
deny 192.168.1.109;
allow 192.168.1.0/24;192.168.0.0/16;192.0.0.0/8
}
#用户认证访问,模块ngx_http_auth_basic_module 允许使用“HTTP基本认证”协议验证用户名和密码来限制对资源的访问。
location ~ (.*)\.avi$ {
auth_basic "closed site";
auth_basic_user_file users;#默认在conf/目录下加载
}
#安装httpd-tools
yum install httpd
#生成用户文件,将文件复制到conf目录下
htpasswd -c -d /usr/local/users zhangyang
#nginx访问状态监控
location /basic_status {
stub_status on;
}
#动态代理服务器配置
location /test {
Proxy_pass https://www.baidu.com/;
}
代理服务器:用户访问服务器时,不是直接访问而是通过一个中间服务器转发,这个服务器就叫代理服务器,从用户角度来看,叫做
正向代理服务器
,从服务器角度看叫反向代理服务器
动态代理转发请求的两种方式:
* 用户发送请求给代理服务器,代理服务器将请求发送给服务器,并且将服务器返回的数据发送给用户,---请求转发
* 用户发送请求给代理服务器,代理服务器将服务器地址发给用户,由用户直接请求服务器,---请求重定向(301,302)
负载均衡
#url要与proxy_pass相对应
upstream tomcat{
url_hash; #负载均衡算法,默认轮询
server 192.168.2.52:8080 weight=1 max_conns=800 dwon;
server 192.168.2.53:8080 weight=10 backup;
}
http{
server{
location /tomcat {
proxy_pass http://tomcat/;
}
}
}
#weight 权重,越大访问越多
#down:表示当前的server暂时不参与负载
#backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。
#max_conns: 最大连接数,防止服务器过载
#max_fails=3 fail_timeout=30s :30秒内请求失败连续3次,认为该应用宕机,不会再向该服务发起请求,30秒后,再次发起请求,若失败(仅一次)则继续等待30秒,循环,直到恢复。
负载算法:
-
轮询+weight:
-
ip_hash:容易造成访问量偏移
-
url_hash :方便定向存储数据缓存
-
least_conn:
-
least_time
健康检查
upstream tomcat{
server 192.168.2.52:8080 weight=1 max_conns=800;
server 192.168.2.53:8080 weight=1;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD / HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
location /status {
check_status;
}
#查看负载服务器状态
自动索引
location /art {
alias /var/data/www1/;#虚拟目录
autoindex on;
}
#可以查看目录下的所有文件
动静分离
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|html|htm|css|js)$ {
root /var/data/www1/;
}
相关异常
启动脚本配置配置报错
#centos7报错,6不确定有没有
#错误信息
[root@VM-16-11-centos conf]# systemctl status nginx.service
● nginx.service - SYSV: Nginx is an HTTP(S) server, HTTP(S) reverse proxy and IMAP/POP3 proxy server
Loaded: loaded (/etc/rc.d/init.d/nginx; bad; vendor preset: disabled)
Active: failed (Result: timeout) since Sat 2021-03-13 21:41:58 CST; 11s ago
Docs: man:systemd-sysv-generator(8)
Process: 25154 ExecStart=/etc/rc.d/init.d/nginx start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/nginx.service
├─25184 nginx: master process /usr/local/tengine/sbin/nginx -c /usr/local/tengine/conf/nginx.conf
└─25186 nginx: worker process
Mar 13 21:36:58 VM-16-11-centos systemd[1]: Starting SYSV: Nginx is an HTTP(S) server, HTTP(S) reverse proxy and IMAP/POP3 proxy server...
Mar 13 21:36:58 VM-16-11-centos nginx[25154]: /etc/rc.d/init.d/nginx: line 12: pidfile:: command not found
Mar 13 21:36:58 VM-16-11-centos nginx[25154]: Starting nginx: [ OK ]
Mar 13 21:36:58 VM-16-11-centos systemd[1]: Can't open PID file /var/run/nginx.pid (yet?) after start: No such file or directory
Mar 13 21:41:58 VM-16-11-centos systemd[1]: nginx.service start operation timed out. Terminating.
Mar 13 21:41:58 VM-16-11-centos systemd[1]: Failed to start SYSV: Nginx is an HTTP(S) server, HTTP(S) reverse proxy and IMAP/POP3 proxy server.
Mar 13 21:41:58 VM-16-11-centos systemd[1]: Unit nginx.service entered failed state.
Mar 13 21:41:58 VM-16-11-centos systemd[1]: nginx.service failed.
原因:如上PID文件位置不对,修改PID文件路径即可解决
解决:
方法一:
修改/etc/init.d/nginx 配置的PID文件路径和nginx.conf文件中的PID路径一致,配置完不一定好使,建议多试几次
方式一:
PIDFILE=/usr/local/nginx/logs/nginx.pid
方式二:
pidfile: /usr/local/nginx/logs/nginx.pid
方法二:
1.修改/usr/local/nginx/conf/nginx.conf配置文件
拷贝一行代码 #pid logs/nginx.pid; ,修改为报错提示的路径,即:pid /var/run/nginx.pid
nginx请求转发异常
异常:413 Request Entity Too Large
原因:nginx默认请求体大小为1m,数据超过1m就会报错
解决:
# 指定请求体大小,默认1m,必须修改
client_max_body_size 50m;
# 指定请求处理时间,时间过小会报502 Bad Gateway,根据需求设置
client_header_timeout 1m;
client_body_timeout 1m;
proxy_connect_timeout 60s;
proxy_read_timeout 1m;
proxy_send_timeout 1m;
异常:504 Gateway Time-out
原因
nginx访问出现504 Gateway Time-out,一般是由于程序执行时间过长导致响应超时,例如程序需要执行90秒,而nginx最大响应等待时间为30秒,这样就会出现超时。
通常有以下几种情况导致:
1.程序在处理大量数据,导致等待超时。
2.程序中调用外部请求,而外部请求响应超时。
3.连接数据库失败而没有停止,死循环重新连。
解决:在nginx.config中配置如下参数
fastcgi_connect_timeout
#fastcgi连接超时时间,默认60秒
fastcgi_send_timeout
#nginx 进程向 fastcgi 进程发送请求过程的超时时间,默认值60秒
fastcgi_read_timeout
#fastcgi 进程向 nginx 进程发送输出过程的超时时间,默认值60秒
异常:502 Bad Gateway
原因:nginx反向代理,如果header过大,超出了默认的1k,就会引发upstream sent too big header异常
解决:nginx.config中添加/修改参数
http {
...
#分配8*16k的空间来缓存请求数据,超出空间则会放进 临时文件:fastcgi_temp 中存储
fastcgi_buffers 8 16k;
#读取响应头需要的缓存空间
fastcgi_buffer_size 32k;
...
}
问题: proxy_temp文件中没有报文
原因:nginx.conf中没有配置
user user
,新建的临时文件owner就是nobody了,就导致没有权限写进去这些临时文件
解决:nginx.conf中配置
user user
,删除proxy_temp下的文件,重新reload一下nginx就可以了,注意要使用管理员权限