轻量级web服务器,用作代理服务器
优点:占有内存少,并发能力强
以事件驱动方式编写
- 支持热部署,启动速度特别快,不需要重启,只需重载操作;
- 具有很高的可靠性;
- 处理静态文件响应速度很快;
在微服务的体系之下,Nginx正在被越来越多的项目采用作为网关来使用,配合Lua做限流、熔断等控制。
集群(分布式)
服务器架构集群
多台服务器组成的响应大并发、高数据量访问的架构体系。
特点
- 成本高,需要多台服务器;
- 能够降低单台服务器的压力,使流量平均分配到多台服务器;
- 使网站服务架构更加安全稳定;
服务器
提供某种或者多种服务(功能)的机器
- 硬件——性能比较好的电脑主机
- 软件——实现各种服务支持特定协议的软件
web服务软件
LAMP架构——apache
LNMP架构——nginx
nginx 安装简单小巧、并发量高、web服务器、代理服务器、邮箱服务器
fast-cgi 网络接口服务
资源服务器
存储静态资源
代理服务器
代理:自己做不到,让别人帮忙做
需求:a访问c,但不能直接访问。a可以访问b,b可以访问c。
Varnish——Varnish是一款高性能的开源HTTP加速器
缓存服务器
memcache
redis
CDN——内容分发网络
反向代理
- 正向代理——客户端配置代理服务器
- 反向代理——不需要配置代理服务器,直接访问反向代理服务器地址,由代理服务器选择合适的服务器,将访问转发。可将代理服务器与服务器视为一个整体。
负载均衡
存在多个目标服务器,由nginx选择负载小的服务器来响应我们的请求。
将请求分发到服务器集群中不同的服务器上,使流量平均分配。
硬件级别
F5 性能好,价格高
软件级别
nginx upstream 性价比高
lvs —— Linux Virtual Server,Linux虚拟服务器
高可用
高可用服务器,用来监控负载均衡服务器,一旦负载均衡宕机,会接替负载均衡服务器的工作,继续进行网络的分发工作。
动静分离
以前:单服部署所有资源
现在:动静分离,nginx配置分别指向静态资源、动态资源
Nginx 安装
Linux 检测是否已安装某个程序
1、rpm包安装的,可以用 rpm -qa 看到,如果要查找某软件包是否安装,用 rpm -qa | grep “软件或者包的名字”
2、以deb包安装的,可以用 dpkg -l 看到。如果是查找指定软件包,用 dpkg -l | grep “软件或者包的名字”
3、yum方法安装的,可以用 yum list installed 查找,如果是查找指定包,用 yum list installed | grep “软件名或者包名”
举例:查看是否安装了gcc
yum list installed | grep "gcc"
yum -y install gcc
yum安装
yum安装rpm包会比编译安装简单很多,默认会安装许多模块,但缺点是如果你想以后安装第三方模块那就没办法了。 参考官网:https://nginx.org/en/linux_packages.html#RHEL-CentOS
- 创建一个“/etc/yum.repos.d/nginx.repo”的文件,新增一个yum源
vim /etc/yum.repos.d/nginx.repo
新增内容
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
检查配置是否正常
yum list | grep nginx
- 安装nginx
yum -y install nginx
- 安装目录
[root@CentOS nginx]# pwd
/etc/nginx
源码安装
linux版本:CentOS7 64位
在安装nginx前首先要确认系统中安装了gcc、pcre-devel、zlib-devel、openssl-devel。
Linux下检查是否安装过某软件包:http://www.cnblogs.com/xxoome/p/5866553.html
安装命令:
yum -y install gcc pcre-devel zlib-devel openssl openssl-devel
安装patch包
yum -y install patch
下载 nginx_upstream_check_module 模块
在通过nginx搭建负载均衡服务器时,我们无法实时监测各个负载节点的运行情况,当某个节点崩溃后这个时候再有请求到来的话只能等待超时时间后转发到其他节点,这样就会造成响应延迟性能降低的问题。 而nginx自带的两个节点健康检查模块功能有限。 nginx_upstream_check_module是一个更专业的第三方的负载均衡节点健康检查模块,这个模块是由淘宝技术团队姚伟斌大神开发的,github地址:https://github.com/yaoweibin/nginx_upstream_check_module/releases
cd /usr/local/src
wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master
unzip master
ll -d nginx_upstream_check_module-master
下载 nginx-sticky-module 模块
目前的项目网站架构中使用了F5和nginx,F5用来做负载均衡,nginx只用作反向代理服务器。 nginx抗并发能力强,又可以做负载均衡。 但nginx在会话保持这方面比较弱,用ip_hash做会话保持有很大的缺陷,它是通过客户端ip来实现,根据访问ip的hash结果分配请求到后端的app服务器,负载不会很均匀。 nginx-sticky-module这个第三方模块可以基于cookie实现会话保持。 https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/master.tar.gz
cd /usr/local/src
wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/master.tar.gz
tar -zxvf master.tar.gz
mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42 nginx-sticky
移动到/usr/local/src
下,下载“nginx-1.16.1.tar.gz”。
nginx下载地址:https://nginx.org/download/
cd /usr/local/src
wget https://nginx.org/download/nginx-1.16.1.tar.gz
# 解压
tar -zxvf nginx-1.16.1.tar.gz
# 进入nginx目录
cd nginx-1.16.1
# 打补丁
patch -p1 < ../nginx_upstream_check_module-master/check_1.16.1+.patch
# 配置
# ./configure --prefix=/usr/local/nginx
# 另一种配置
./configure \
--user=www \
--group=www \
--with-pcre \
--prefix=/usr/local/nginx \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-http_realip_module \
--add-module=/usr/local/src/nginx_upstream_check_module-master/ \
--add-module=/usr/local/src/nginx-sticky/
# --with-http_geoip_module \
# --http-client-body-temp-path=/usr/local/nginx/client \
# --http-proxy-temp-path=/usr/local/nginx/proxy \
# --http-fastcgi-temp-path=/usr/local/nginx/fcgi \
# --http-scgi-temp-path=/usr/local/nginx/scgi \
# --http-uwsgi-temp-path=/usr/local/nginx/uwsgi
# make && make install
make
make install
nginx的configure命令支持以下参数:
--prefix=
path` 定义一个目录,存放服务器上的文件 ,也就是nginx的安装目录。默认使用
/usr/local/nginx`--sbin-path=
path设置nginx的可执行文件的路径,默认为
prefix/sbin/nginx
--conf-path=
path设置在nginx.conf配置文件的路径。nginx允许使用不同的配置文件启动,通过命令行中的-c选项。默认为
prefix/conf/nginx.conf
--pid-path=path
设置nginx.pid文件,将存储的主进程的进程号。安装完成后,可以随时改变的文件名 , 在nginx.conf配置文件中使用 PID指令。默认情况下,文件名 为`_prefix_
/logs/nginx.pid`--error-log-path=
path设置主错误,警告,和诊断文件的名称。安装完成后,可以随时改变的文件名 ,在nginx.conf配置文件中 使用 的error_log指令。默认情况下,文件名 为
prefix/logs/error.log
--http-log-path=
path设置主请求的HTTP服务器的日志文件的名称。安装完成后,可以随时改变的文件名 ,在nginx.conf配置文件中 使用 的access_log指令。默认情况下,文件名为
prefix/logs/access.log
--user=
name`` 设置nginx工作进程的用户。安装完成后,可以随时更改的名称在nginx.conf配置文件中使用的 user指令。默认的用户名是nobody--group=
name`` 设置nginx工作进程的用户组。安装完成后,可以随时更改的名称在nginx.conf配置文件中 使用的 user指令。默认的为非特权用户--with-select_module
--without-select_module
启用或禁用构建一个模块来允许服务器使用select()方法。该模块将自动建立,如果平台不支持的kqueue,epoll,rtsig或/dev/poll--with-poll_module
--without-poll_module
启用或禁用构建一个模块来允许服务器使用poll()方法。该模块将自动建立,如果平台不支持的kqueue,epoll,rtsig或/dev/poll--without-http_gzip_module
不编译压缩的HTTP服务器的响应模块。编译并运行此模块需要zlib库--without-http_rewrite_module
不编译重写模块。编译并运行此模块需要PCRE库支持--without-http_proxy_module
不编译http_proxy模块--with-http_ssl_module
使用https协议模块。默认情况下,该模块没有被构建。建立并运行此模块的OpenSSL库是必需的--with-pcre=
path`` 设置PCRE库的源码路径。PCRE库的源码(版本4.4 - 8.30)需要从PCRE网站下载并解压。其余的工作是Nginx的./ configure和make来完成。正则表达式使用在location指令和 ngx_http_rewrite_module 模块中--with-pcre-jit
编译PCRE包含“just-in-time compilation”(1.1.12中, pcre_jit指令)--with-zlib=
path`` 设置的zlib库的源码路径。要下载从 zlib(版本1.1.3 - 1.2.5)的并解压。其余的工作是Nginx的./configure和make完成。ngx_http_gzip_module模块需要使用zlib--with-cc-opt=
parameters` 设置额外的参数将被添加到CFLAGS变量。例如,当你在FreeBSD上使用PCRE库时需要使用:
—with-cc-opt=”-I /usr/local/include如需要需要增加 select()支持的文件数量:
—with-cc-opt=”-D FD_SETSIZE=2048”`--with-ld-opt=
parameters` 设置附加的参数,将用于在链接期间。例如,当在FreeBSD下使用该系统的PCRE库,应指定:
—with-ld-opt=”-L /usr/local/lib”`--with-http_stub_status_module
用来监控 Nginx 的当前状态--with-http_stub_realip_module
通过这个模块允许我们改变客户端请求头中客户端 IP 地址值(例如:X-Real-IP
或X-Forwarded-For
),意义在于能够使得后台服务器记录原始客户端的 IP 地址--add-module=PATH
添加第三方外部模块,如:nginx-sticky-module-ng
或缓存模块。每次添加新的模块都要重新编译
注意:如果后期新增module,只需make,不用make install,
接下来备份一下nginx命令cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx-xxx.bak
接下来就是把新编译的nginx命令替换过来
# 如果nginx服务正在运行,需要先停服务
./nginx -s stop
# objs中的nginx会在make后生成
cp ./objs/nginx /usr/local/nginx/sbin/
# 检查配置文件是否有问题
/usr/local/nginx/sbin/nginx -t
# 启动nginx
./nginx
脚本安装
#!/bin/bash
groupadd www
useradd -g www -s /usr/sbin/nologin www
cd /root/amp
#pcre
tar zxvf pcre-8.39.tar.gz
tar zxvf nginx-1.11.3.tar.gz
cd nginx-1.11.3/
./configure \
--user=www \
--group=www \
--prefix=/usr/local/nginx \
--with-http_stub_status_module \
--with-http_ssl_module \
# --with-pcre=/root/data/pcre-8.39 \
# --with-openssl=/root/data/openssl-1.0.lt
make && make install
测试是否安装成功
# cd到刚才配置的安装目录/usr/loca/nginx/
./sbin/nginx -t
启动nginx
cd /usr/local/nginx/sbin
# 启动nginx
./nginx
正常情况下,此时在浏览器输入本机ip就可以显示 ‘Welcome to nginx!’
如果打不开链接,可以如下排查:
# 查看目标ip
ifconfig
# 如遇命令未找到,可能是功能包未安装,可通过使用 yum provides ifconfig 来查看哪个包提供ifconfig,
# 并通过 yum install net-tools 安装一下。
# ping目标ip,是否通
ping 192.168.1.12
# 看端口是否通,可连接
telnet 192.168.1.12 80
# 如出现在 【端口80:连接失败】,说明服务器的80端口是打不开的
# CentOS7可以在服务器中执行如下命令来验证端口是否开放:
firewall-cmd --query-port=80/tcp
# 开启80端口
firewall-cmd --add-service=http --permanent
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --list-all
# 重启防火墙
systemctl restart firewalld
# 或
firewall-cmd --reload
# --permanent #永久生效,没有此参数重启后失效
附:centos最小化安装后ifconfig不能使用,问题排查:首先我们了解是不是没有开启网卡导致的?我们可以通过一下3种方法来排查:
通过
ping www.baidu.com
了解网卡是否启用能ping通的话,说明网卡有启用,并能获取IP地址来上网。
通过输入
ip addr
查看是否能获取IP地址来确定网卡是否启用能通ip addr 查到获取的IP地址,证明网卡是启用。
- 如果获取不了请修改网络配置文件。注:修改完后需要重启网卡(命令:service network restart)通过
cat /etc/sysconfig/network-scripts/ifcfg-enp0s3
(ifcfg-enp0s3是网卡名,不同的机器是不一样的)下的ONBOOT是否开启(意思就是网卡是否开启)通过
cat /etc/sysconfig/network-scripts/ifcfg-enp0s3
查看网卡是否启用,如果没有使用vi /etc/sysconfig/network-scripts/ifcfg-enp0s3
修改网络配置文件。
nginx 命令行参数
./nginx -c </path/to/config>
为 Nginx 指定一个配置文件,来代替缺省的。
./nginx -t
-t 不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。养成良好习惯,更改配置都记得要使用该命令检测一下!
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
./nginx -v
-v 显示 nginx 的版本。
./nginx -V
-V 显示 nginx 的版本,编译器版本和配置参数。
nginx version: nginx/1.16.1 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) configure arguments:xxx
nginx 控制信号
可以使用信号系统来控制主进程。
默认,nginx 将其主进程的 pid 写入到 /usr/local/nginx/nginx.pid
文件中。
通过传递参数给 ./configure
或使用 pid 指令,来改变该文件的位置。
主进程可处理信号:
TERM/INT | 快速关闭服务 |
---|---|
QUIT | 从容关闭 |
HUP | 重载配置,用新的配置开始新的工作进程,从容关闭旧的工作进程 |
USR1 | 重新打开日志文件,写入新的日志 |
USR2 | 平滑升级 |
WINCH | 从容关闭工作进程 |
工作进程可处理信号:
TERM/INT | 快速关闭 |
---|---|
QUIT | 从容关闭 |
USR1 | 重新打开日志文件,写入新的日志 |
常用命令
ps -ef | grep nginx
root 18668 1 0 Jan27 ? 00:00:00 nginx: master process ./nginx
root 22643 25226 0 23:00 pts/0 00:00:00 grep --color=auto nginx
nobody 26414 18668 0 17:51 ? 00:00:00 nginx: worker process
# nginx从容停止命令,等所有请求结束后关闭服务
kill -QUIT [nginx PID]主进程18668
# 立刻关闭nginx进程
kill -TERM [nginx PID]
# 强制停止
kill -9 [nginx PID]
# 不查看进程号直接操作,nginx.pid没有找到
kill -信号类型(HUP|TERM|QUIT) `cat /usr/local/nginx/nginx.pid`
./nginx
./nginx -s stop
./nginx -s reload
平滑改变 nginx 配置
请注意,在重载前,要先测试一下配置文件 当 nginx 接收到
HUP
信号,它会尝试先解析配置文件(如果指定配置文件,就使用指定的,否则使用默认的),成功的话,就应用新的配置文件(例如:重新打开日志文件或监听的套接 字)。 之后,nginx 运行新的工作进程并从容关闭旧的工作进程。 通知工作进程关闭监听套接字但是继续为当前连接的客户提供服务。 所有客户端的服务完成后,旧的工作进程被关闭。 如果新的配置文件应用失败,nginx 将继续使用旧的配置进行工作。
# -c </path/to/config> 为 Nginx 指定一个配置文件,来代替缺省的。
# -t 不运行,而仅仅测试配置文件。
nginx -t -c ./nginx/nginx.conf
ps aux | egrep '(PID|nginx)'
kill -HUP [PID]
平滑升级
首先,使用新的可执行程序替换旧的(最好做好备份),
然后,发送 USR2 (kill -USR2 pid)信号给主进程。
主进程将重命名它的 .pid 文件为 .oldbin (比如:/usr/local/nginx/logs/nginx.pid.oldbin),
然后执行新的可执行程序,依次启动新的主进程和新的工作进程
两个 nginx 实例会同时运行,一起处理输入的请求。
要逐步停止旧的实例,你必须发送 WINCH 信号给旧的主进程,
然后,它的工作进程就将开始从容关闭。
一段时间后,旧的工作进程处理了所有已连接的请求后退出,就仅由新的工作进程来处理输入的请求了。
如果尝试升级成功,而你也希望保留新的服务器时,发送 QUIT 信号给旧的主进程使其退出而只留下新的服务器运行。
如果升级失败或不想升级,这时,因为旧的服务器还尚未关闭它监听的套接字,所以,通过下面的几步,你仍可以恢复旧的服务器:
- 发送 HUP 信号给旧的主进程 - 它将在不重载配置文件的情况下启动它的工作进程
- 发送 QUIT 信号给新的主进程,要求其从容关闭其工作进程
- 发送 TERM 信号给新的主进程,迫使其退出
- 如果因为某些原因新的工作进程不能退出,向其发送 KILL 信号
新的主进程退出后,旧的主进程会由移除 .oldbin 前缀,恢复为它的 .pid 文件,这样,一切就都恢复到升级之前了。
配置文件
位置
/usr/local/nginx/conf/nginx.conf
组成
- 全局块——影响整体运行的配置
- events块——nginx服务器与用户的网络连接
- http块
- http全局块
- server块
nginx 配置文件主要分成四部分:main(全局设置)、server(主机设置)、upstream(上游服务器设置,主要为反向代理、负载均衡相关配置)和 location (url匹配特定位置后的设置),每部分包括若干个指令。
- main 部分设置的指令将影响其他所有部分的设置;
- server 部分的指令主要用于指定虚拟主机域名、IP 和端口;
- upstream 的指令用语设置一系列的后端服务器,设置反向代理及后端服务器的负载均衡;
- location 部分用语匹配网页位置(比如,根目录“/”,“/images”,等等)。
他们之间的关系式:server 继承 main,location 继承 server;upstream 既不会继承指令,也不会被继承,它有自己的特殊指令,不需要在其他地方的应用。
#运行用户,即运行的身份
#user nobody;
#启动进程,通常设置成和cpu的数量相等
worker_processes 1;
#在高并发情况下,通过设置cpu粘性来降低由于多CPU核切换造成的寄存器等现场重建带来的性能损耗。如四核CPU
worker_cpu_affinity 0001 0010 0100 1000;
#默认是没有设置,可以限制为操作系统最大的限制65535
worker_rlimit_nofile 10240;
#全局错误日志及PID文件
error_log logs/error.log warn;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid logs/nginx.pid;
#工作模式及连接数上限
events {
#epoll是多路复用IO(I/O Multiplexing)中的一种方式,
#仅用于linux2.6以上内核,可以大大提高nginx的性能
use epoll;
#单个后台worker process进程的最大并发连接数
#nginx作为反向代理服务器,计算公式 最大连接数 = worker_processes * worker_connections/4
#当nginx作为http服务器时,计算公式里面是除以2。
worker_connections 1024;
# 并发总数是 worker_processes 和 worker_connections 的乘积
# 即 max_clients = worker_processes * worker_connections
# 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4
# 为什么?
# 每个成功的请求会建立4个链接:
# 1.browser->nginx
# 2.nginx-upstream
# 3.upstream->nginx
# 4.nginx->browser
# 为什么上面反向代理要除以4,应该说是一个经验值
# 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
# worker_connections 值的设置跟物理内存大小有关
# 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
# 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
# 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
# $ cat /proc/sys/fs/file-max
# 输出 34336
# 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
# 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
# 使得并发总数小于操作系统可以打开的最大文件数目
# 其实质也就是根据主机的物理CPU和内存进行配置
# 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
# ulimit -SHn 65535
}
# 一个http多个server
# 一个server多个location
http {
#设定mime类型,类型由mime.types文件定义
include mime.types;
default_type application/octet-stream;
#引入其他配置文件
#include /etc/nginx/conf.d/*.conf;
#设定日志格式
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 logs/access.log main;
#sendfile指令指定nginx是否调用sendfile函数(zero copy方式)来输出文件,减少用户空间到内核空间的上下文切换。
#对于普通应用,必须设为on,开启高效文件传输模式
#如果用来进行下载等应用磁盘IO重负载应用,可设置为off,
#以平衡磁盘与网络IO处理速度,降低系统负载。
sendfile on;
#tcp_nopush on;
#长连接超时时间,单位是秒,这个参数很敏感,涉及浏览器的种类、后端服务器的超时设置、操作系统的设置等等。
#长连接请求大量小文件的时候,可以减少重建连接的开销,但假如有大文件上传,65s内没上传完成会导致失败。
#如果设置时间过长,用户又多,长时间保持连接会占用大量资源。
#keepalive_timeout 0;
keepalive_timeout 65;
#用于指定响应客户端的超时时间。
#这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。
send_timeout 30;
#设定请求缓冲
client_header_buffer_size 128k;
large_client_header_buffers 4 128k;
#允许客户端请求的最大单文件字节数。如果有上传较大文件,请设置它的限制值
client_max_body_size 10m;
#缓冲区代理缓冲用户端请求的最大字节数
client_body_buffer_size 128k;
#开启gzip压缩输出,减少网络传输。
gzip on;
#IE6及以前版本禁用压缩,不支持gzip
gzip_disable "MSIE [1-6].";
#设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。
#默认值是20。建议设置成大于1k的字节数,小于1k可能会越压越大。
gzip_min_length 1k;
#设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。
#4 16k代表以16k为单位,安装原始数据大小以16k为单位的4倍申请内存。
gzip_buffers 4 16k;
#用于识别 http 协议的版本,早期的浏览器不支持 Gzip 压缩,用户就会看到乱码,
#所以为了支持前期版本加上了这个选项,如果你用了 Nginx 的反向代理并期望也启用 Gzip 压缩的话,
#由于末端通信是 http/1.0,故请设置为 1.0。
gzip_http_version 1.0;
#gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu)
gzip_comp_level 6;
#匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的。
gzip_types text/html text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml;
#和http头有关系,会在响应头加个 Vary: Accept-Encoding ,可以让前端的缓存服务器缓存经过gzip压缩的页面,例如,用Squid缓存经过Nginx压缩的数据。
gzip_vary on;
#Nginx作为反向代理的时候启用,决定开启或者关闭后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含”Via”的 header头。
gzip_proxied any;
#http_proxy 设置,这个模块实现的是nginx作为反向代理服务器的功能,包括缓存功能
#nginx跟后端服务器连接超时时间(代理连接超时)
proxy_connect_timeout 75;
proxy_send_timeout 75;
#连接成功后,与后端服务器两个成功的响应操作之间超时时间(代理接收超时)
proxy_read_timeout 75;
#设置代理服务器(nginx)从后端realserver读取并保存用户头信息的缓冲区大小,
#默认与proxy_buffers大小相同,其实可以将这个指令值设的小一点
proxy_buffer_size 4k;
#缓冲区,nginx针对单个连接缓存来自后端realserver的响应,网页平均在32k以下的话,这样设置
proxy_buffers 4 32k;
#高负荷下缓冲大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;
#当缓存被代理的服务器响应到临时文件时,这个选项限制每次写临时文件的大小
proxy_temp_file_write_size 64k;
#(可以在编译的时候)指定写到哪那个目录
proxy_temp_path /usr/local/nginx/proxy_temp 1 2;
#设定负载均衡后台服务器列表
upstream backend {
ip_hash;
server 192.168.50.100:8080 max_fails=2 fail_timeout=30s;
server 192.168.50.101:8080 max_fails=2 fail_timeout=30s;
}
#设定虚拟主机配置
server {
#侦听80端口
listen 80;
#定义使用localhost访问,提供服务的域名或主机名
server_name localhost;
#server_name www.nginx.com
#charset koi8-r;
#设定本虚拟主机的访问日志
#access_log logs/host.access.log main;
#配置默认访问页
location / {
#定义服务器的默认网站根目录位置
root html;
#定义首页索引文件的名称
index index.html index.htm;
#请求转向backend定义的服务器列表,即反向代理
proxy_pass http://backend;
proxy_redirect off;
#后端的Web服务器可以通过 X-Forwared-For 获取用户真实 IP
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
# 静态文件,nginx 自己处理,不去 backend 请求 tomcat
location ~* /download/ {
root /apps/oa/fs;
}
location ~ .*.(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
root /apps/oaapp;
expires 7d;
}
# 状态检测,
location /nginx_status {
stub_status on;
access_log off;
# 限定ip
allow 192.168.10.0/24
deny all;
}
location ~ ^/(WEB-INF)/ {
denny all;
}
#定义错误提示页面
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
#静态文件,nginx自己处理
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
#过期30天,静态文件不怎么更新,过期可以设大一点,
#如果频繁更新,则可以设置得小一点。
expires 30d;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
#PHP 脚本请求全部转发到 FastCGI处理,使用FastCGI默认配置
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
#禁止访问 .htxxx 文件
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
location匹配规则
location匹配命令
= 进行普通字符精确匹配
^~ 表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
~ 波浪线表示执行一个正则匹配,区分大小写
~* 表示执行一个正则匹配,不区分大小写
@ 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files
location 优先级官方文档
- =前缀的指令严格匹配这个查询。如果找到,停止搜索。
- 所有剩下的常规字符串,最长的匹配。如果这个匹配使用^〜前缀,搜索停止。
- 正则表达式,在配置文件中定义的顺序。
- 如果第3条规则产生匹配的话,结果被使用。否则,使用第2条规则的结果。
Location处理逻辑
- 用uri测试所有的prefix string;
- uri精确匹配到=定义的location,使用这个location,停止搜索;
- 匹配最长prefix string,如果这个最长prefix string带有^~修饰符,使用这个location,停止搜索,否则:
- 存储这个最长匹配;
- 然后匹配正则表达式;
- 匹配到第一条正则表达式,使用这个location,停止搜索;
- 没有匹配到正则表达式,使用#4步存储的prefix string的location。
location = / {
# 只匹配"/".
[ configuration A ]
}
location / {
# 匹配任何请求,因为所有请求都是以"/"开始
# 但是更长字符匹配或者正则表达式匹配会优先匹配
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开始的请求,并停止匹配 其它location
[ configuration C ]
}
location ~* .(gif|jpg|jpeg)$ {
# 匹配以 gif, jpg, or jpeg结尾的请求.
# 但是所有 /images/ 目录的请求将由 [Configuration C]处理.
[ configuration D ]
}
upstream
定义一组服务器,这些服务器可以监听不同的端口
http {
...
# 默认情况下,nginx按加权轮转的方式将请求分发到各服务器。
upstream backend {
# 这种方法可以确保从同一个客户端过来的请求,会被传给同一台服务器。
# 指定服务器组的负载均衡方法,请求基于客户端的IP地址在服务器间进行分发。 IPv4地址的前三个字节或者IPv6的整个地址,会被用来作为一个散列key。
# 除了当服务器被认为不可用的时候,这些客户端的请求会被传给其他服务器,而且很有可能也是同一台服务器。
ip_hash;
# 每7个请求会通过以下方式分发: 5个请求分到backend1.example.com, 一个请求分到第二个服务器,一个请求分到第三个服务器。
# 定义服务器的地址address和其他参数parameters
server backend1.example.com weight=5;
server backend2.example.com:8080 max_fails=3 fail_timeout=30s;;
server backend3.example.com down;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
# 指定服务器组的负载均衡方法,根据其权重值,将请求发送到活跃连接数最少的那台服务器。 如果这样的服务器有多台,那就采取有权重的轮转法进行尝试。
least_conn;
}
upstream memcached_backend {
server 127.0.0.1:11211;
server 10.0.0.2:11211;
# 激活对上游服务器的连接进行缓存。
# connections参数设置每个worker进程与后端服务器保持连接的最大数量。这些保持的连接会被放入缓存。 如果连接数大于这个值时,最久未使用的连接会被关闭。
# keepalive指令不会限制Nginx进程与上游服务器的连接总数。 新的连接总会按需被创建。 connections参数应该稍微设低一点,以便上游服务器也能处理额外新进来的连接。
keepalive 32;
}
upstream http_backend {
server 127.0.0.1:8080;
keepalive 16;
}
upstream fastcgi_backend {
server 127.0.0.1:9000;
keepalive 8;
}
server {
location / {
proxy_pass http://backend;
}
location /memcached/ {
set $memcached_key $uri;
memcached_pass memcached_backend;
}
location /http/ {
proxy_pass http://http_backend;
# 对于HTTP代理,proxy_http_version指令应该设置为“1.1”,同时“Connection”头的值也应被清空。
proxy_http_version 1.1;
proxy_set_header Connection "";
...
}
location /fastcgi/ {
fastcgi_pass fastcgi_backend;
# 设置 fastcgi_keep_conn 指令来让连接keepalive工作
fastcgi_keep_conn on;
...
}
}
}
参数:weight
=*number*
设定服务器的权重,默认是1。max_fails
=*number*
设定Nginx与服务器通信的尝试失败的次数。
在fail_timeout
参数定义的时间段内,如果失败的次数达到此值,Nginx就认为服务器不可用。在下一个fail_timeout
时间段,服务器不会再被尝试。 失败的尝试次数默认是1。设为0就会停止统计尝试次数,认为服务器是一直可用的。 你可以通过指令proxy_next_upstream、 fastcgi_next_upstream和memcached_next_upstream来配置什么是失败的尝试。 默认配置时,http_404
状态不被认为是失败的尝试。fail_timeout
=*time*
设定,默认情况下,该超时时间是10秒。
- 统计失败尝试次数的时间段。在这段时间中,服务器失败次数达到指定的尝试次数,服务器就被认为不可用。
- 服务器被认为不可用的时间段。
backup
标记为备用服务器。当主服务器不可用以后,请求会被传给这些服务器。down
标记服务器不可用,可以跟ip_hash指令一起使用。如果其中一个服务器想暂时移除,应该加上down
参数。这样可以保留当前客户端IP地址散列分布。
当使用的负载均衡方法不是默认的轮转法时,必须在keepalive
指令之前配置。
反向代理
不清楚的话上翻查看location配置
- 环境准备,tomcat安装,配置多台tomcat,不同端口并开放访问
- host文件添加映射 192.168.1.104 www.abc.com
nginx.conf 文件里的http块添加
server {
listen 8001;
server_name 192.168.1.104;
location / {
...
proxy_pass http://127.0.0.1:8080;
...
}
location ~ /edu/ {
...
proxy_pass http://127.0.0.1:8081;
...
}
location ~ /vod/ {
...
proxy_pass http://127.0.0.1:8082;
...
}
}
负载均衡
不清楚的话上翻查看upstream配置
http {
upstream myserver {
# 配置同一个用户访问同一台服务器,避免session丢失
ip_hash;
server ip:port weight=1 max_fails=3 fail_timeout=20s;
server ip:port weight=1 max_fails=3 fail_timeout=20s;
# 在nginx.conf配置文件里面的upstream加入健康检查
check interval=3000 rise=2 fall=5 timeout=1000;
}
server {
location / {
proxy_pass http://myserver;
proxy_connect_timeout 10;
}
}
}
session丢失
- 用户状态无法判断用户是否登录
- 验证码无法验证
解决方案:
- 入库redis、mysql
- 磁盘共享
- ip hash一致性
状态监控
需要安装第三方模块:http_stub_status_module
/usr/local/nginx/sbin/nginx -V 执行后可以查看到有http_stub_status_module模块说明已经安装
配置
location /nginx_status {
stub_status on;
access_log off;
}
执行命令
nginx -t
nginx -s reload
# 查看日志
tail -f /var/log/nginx/access.log
页面的参数介绍
# ip:port/nginx_status
# 当前活动的连接数
Active connections: 1
server accepts handled requests
2 2 12
2 总连接数connection
2 成功的连接数connection 失败连接=(总连接数-成功连接数)
12 总共处理的请求数requests
Reading: 0 Writing: 1 Waiting: 0
Reading: 0 读取客户端Header的信息数 请求头
Writing: 1 返回给客户端的header的信息数 响应头
Waiting: 0 等待的请求数,开启了keepalive
后端节点健康检查
借助nginx_upstream_check_module
#服务器的集群
upstream ERP{
server 192.168.1.104:8001;
server 192.168.1.105:8001;
#tcp检测对于网络故障比如断网、端口号被禁、等问题时无法自动剔除,导致请求还是被分发给网络有问题的节点导致降低了性能
#check interval=3000 rise=2 fall=5 timeout=1000 type=tcp;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD /ERP HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
upstream JWB{
server 192.168.1.104:8002;
server 192.168.1.105:8002;
#check interval=3000 rise=2 fall=5 timeout=1000 type=tcp;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD /JWB HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
#当前的Nginx的配置
server {
listen 80;
server_name 127.0.0.1;
#charset koi8-r;
#access_log logs/host.access.log main;
location /ERP/ {
proxy_pass http://ERP/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 5;
proxy_send_timeout 1;
proxy_read_timeout 10;
proxy_ignore_client_abort on;
}
location /JWB/ {
proxy_pass http://JWB/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 5;
proxy_send_timeout 1;
proxy_read_timeout 10;
proxy_ignore_client_abort on;
}
#通过访问 http://ip:port/n_status 看到nginx负载中各个节点的动态状态
location /n_status {
check_status;
access_log off;
}
}
下载站点模块
conf添加如下配置:
location /down {
#可实现限定仅开启二级目录浏览
root /soft/src; #实际访问路径/soft/src/down
#alias /tmp/share/down; #使用别名省去路径拼接,不需要root
autoindex on;
autoindex_localtime on; #默认off显示文件的GMT时间,on显示服务器时间
autoindex_exact_size off; #显示文件的大概大小。如为on,显示确切大小,单位bytes
charset utf-8,gbk; #默认中文目录乱码,添加上解决乱码
}
在Nginx.conf指定的路径中放入文件
- 配置完成,检测Nginx配置是否正确:
nginx -t
- 重新加载Nginx配置文件(修改配置文件后一定要重新加载)
nginx -s reload
expires缓存功能
nginx缓存功能概述
nginx通过配置,可以告诉浏览器返回数据的有效时间,浏览器就可以根据数据的有效时间确定是否应该到服务器请求,如果数据没有超过有效期,就使用浏览器缓存的数据。
缓存:快速响应用户请求,减少服务器请求,降低带宽压力;
# 缓存图片文件
location ~ \.(jpeg|jpg|png)$ {
# 缓存时间为30天
expires 30d;
}
验证步骤:
- 上传图片;
- 测试正常访问;
- 测试配置;
- 重载配置;
- 浏览器访问,打开控制台,查看Cache-Control及响应码是否304,是否仍会发送请求;
- chrome控制台会算作一次请求,但会显示为
from cache
nginx访问限制
连接频率限制 limit_conn_module 请求频率限制 limit_req_module
http协议与请求
HTTP是建立在TCP,在完成HTTP请求需要先建立TCP三次握手,在连接的基础上进行HTTP请求。
HTTP请求建立在一次TCP连接基础上;一次TCP请求至少产生一次HTTP请求;
limit_req_zone && limit_conn_zone
#$binary_remote_addr较$remote_addr节省空间
#1m——大小1M
#1r/s——每秒1次请求
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
server {
...
location / {
root /usr/share/nginx/html;
index index.html index.htm;
#多余直接处理
limit_req zone=req_zone;
#剩下的将被延迟处理,请求数超过burst定义的数量,多余的请求返回503
#limit_req zone=req_zone burst=3 nodelay;
#同一时刻只允许一个客户端IP连接
limit_conn conn_zone 1;
}
}
ab压测工具
安装 yum install -y httpd-tools
使用ab
#50次 并发20
ab -n 50 -c 20 http://192.168.56.11/index.html
nginx访问控制
基于IP的访问控制 http_access_module 基于用户登陆认证 http_auth_basic_module
context: location
allow [ip]/all;
deny [ip]/all;
- x-forwarded-for 在这里就体现作用了,记录下客户端IP及代理服务器IP,才能做好访问控制;
- 结合geo模块;
- 通过http自动以变量传递;
nginx用户认证模块
http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
location / {
auth_basic "input password";
auth_basic_user_file /etc/nginx/auth_conf;
}
安装依赖组件
yum install -y httpd-tools
htpasswd -c /etc/nginx/auth_conf abc
password: 123456
Re-type new password: 123456
局限性
- 用户信息依赖文件方式
- 操作管理机械,效率低下
解决方法
- nginx结合Lua实现高效验证
- 结合LDAP,利用
nginx-auth-ldap
模块
其他
查看占用的端口
$ netstat -anop
$ netstat -tunlp | grep [port]
$ kill -9 [pid]
$ pkill -9 --help
查看nginx进程号
$ ps aux | grep nginx
$ ps -ef | grep nginx
linux更改hosts
vim /etc/hosts
# 做IP地址映射,由访问地址决定
查看日志
curl -v www.test.com
# log_format 配置,使用内置常量
linux 下查看文件属性的命令
- ls
- ls -a 查看所有文件
- ls -l 查看详细的属性
lsattr
查看文件的扩展属性, 如果文件被
chattr + i
添加了写保护, 用lsattr
可以看到添加的属性file
查看文件的类型
- stat
查看文件的状态