nginx基本上所有功能都是通过配置文件实现的,
配置文件的结构是http块下包含server块,server块下包含location块
一、默认配置,作为web服务器
二、七层代理服务器: 在http块里面,用upstream配置后端服务器,并且能够进行调度,调度算法有轮询、加权轮询、最小连接数、加权最小连接数。upstream写在http块之内,server块之外,等于和server平级。
http {
...
upstream clustername {
ip_hash; # 相同客户端访问相同的web服务器
server ip1:port weight=2; # 加权轮询
server ip2:port max_fails=2 fail_timeout=30; # 健康检查,连接两次失败就down,每隔30秒检查一次。
server ip3:port down # 不参与集群业务
}
server {
listen 80;
server_name localhost;
location /{
proxy_pass http://clustername #将请求转发给后端集群
}
}
...
}
三、四层代理服务器(调度器):
编译安装nginx的时候,必须要带--with-stream模块,才能开启四层代理功能。四层代理和七层代理的最大区别是,四层代理的配置,在nginx配置文件中的http模块之外,和http同级别,比七层代理高了一个级别。而七层代理的配置,是写在nginx的配置文件中的http模块之内。四层代理的这个配置主要是写stream块
stream {
upstream clustername {
server ip1:22; # 拿四层服务ssh,端口号22举例
server ip2:22;
}
server {
listen 12345; # 监听12345端口
proxy_pass clustername; # 把访问12345端口的请求转发给clustername这个集群
}
}
http {
...
}
四、用户认证:
装包:httpd-tools
为网站用户创建登录密码:htpasswd -c /path/filename username
配置文件里面,在server块里面加上
auth_basic "认证提示符信息"
auth_basic_user_file "用户认证文件的路径在哪"
重启nginx服务
五、基于域名的虚拟主机:
配置文件http块下,写两个server块,每个server块的server_name 不同,也就是域名不同,不同server_name对应不同的location目录。配置好后,访问不同的域名,得到的不同的数据。两个虚拟主机的域名映射同一个ip地址,写在/etc/hosts文件里面。
六、基于端口的虚拟主机:
修改server块里面的listen 端口号,两个不同的server,对应两个不同的端口号,每个端口号各对应一个location的root(网页文件根目录)
七、基于IP的虚拟主机:
listen的参数改为同样的端口,不同的ip,比如
192.168.88.5:80
192.168.99.5:80
然后对应不同的location块,location块里面一般就包含root“网页文件根目录”和index“默认网页文件”
八、https虚拟主机:
源码编译安装的时候需要加装模块--with-http_ssl-module,启动加密模块。
把配置文件里面的443server模板去掉注释,在里面写上证书文件路径,私钥文件路径
在这个server块里面的location块里面的root的值写上网页文件根目录就行。
私钥生成命令 openssl genrsa > /path/rsafilename
用私钥生成证书文件 openssl reg -x509 -key /path/rsafilename > /path/cafilename
重启nginx服务
九、动静分离
把访问php页面的请求,转发给fastcgi服务器。默认配置文件/etc/nginx/nginx.conf.default,server块里面有一个php$的location块,把这一部分去掉注释,里面设置fastcgi_pass,把请求转发给哪个ip的哪个端口,同时引导请求去读取fastcgi的配置文件,然后在php-fpm的配置文件里面让listen监听nginx服务器里面配置的转发ip和端口。这是两个服务之间用网络转发,也可以用套接字转发。改好两个配置文件之后,重启服务,就可以实现静态页面nginx解析,动态页面转给php-fpm去解析,解析完成之后把结果返回给nginx,nginx再返回给客户端。php和mysql的联动,靠的是php-mysqlnd. 如果访问有问题就看nginx和php-fpm的错误日志。
用套接字的互动方式,就是nginx的配置文件的php$ 的location块里面的fastcgi_pass的值改为unix:/run/php-fpm/www.sock。php-fpm的配置文件里面的listen的值改为/run/php-fpm/www.sock,两个服务就可以通过这个套接字文件进行动态网页解析的通信。这个套接字文件是进程跑起来的时候自动产生的。这个文件用ll看,是s类型的文件,而普通文件是-,普通目录是d,这个s就代表它是一个接口文件,也可以叫套接字文件,是用来进程间通信的。而且这个文件的ll格式是有+acl权限设置的。这个文件在设计的时候给apache用户和nginx用户加了acl权限,可读可写,apche用户是运行httpd服务的,nginx用户是运行nginx服务的。nginx在没有定义用户的情况下,默认的是nobody,nginx的最大权限就在nobody,所以要在php-fpm的配置文件里面,listen.acl_users的值要加上nobody用户。
配置完成后重启服务,就实现了nginx和php-fpm之间的套接字通信,实现了nginx的动静分离解析。
十、地址重写
在nginx的配置文件里面,server块里面,location块之外,写上rewrite /a.html /b.html
地址重定向(地址栏会发生变化)
rewrite ^/a.html$ /b.html redirect
不同网站间的跳转
rewrite /www.abc.com(访问192.168.99.5的请求重定向至www.abc.cn)
捕获组,地址重定向
rewrite /(.*) http://www.abc.cn/$1
访问192.168.99.5/下面子页面,重定向至www.abc.cn/下相同的子页面
根据客户端浏览器类型进行地址重定向。
if ($http_user_agent ~* firefox) {
rewrite (.*) /firefox/$1
}
redirect 临时重定向
permanent 永久重定向
last 不读其他语句,看下一个location
break 不读其他语句,结束请求
十一、自定义报错页面
操作方法:把配置文件里面的error_page对应的图片换一张。
十二、查看服务器状态信息
编译安装nginx时,加装--with-http_stub_status_module,在nginx配置文件里面的http模块里面的server模块里面,写一个与其他location同级别的location
location {
...
}
location /status {
stub_status on; # 开启状态信息, "stub" 票据的存根,在这里意思是网站数据的存根
allow specipaddress; # 允许特定的ip来访问这个页面
deny all; # 其他所有ip不能访问这个页面
}
重启服务,当用户访问这个nginx的web服务器时,在域名尾部加上/status,就可以看到web服务器的状态信息。
这里面可以看到页面的浏览量PV(page view),独立访客数UV(unique visitor)等等。
网站访问量一般时,可以利用日志、zabbix_agent、脚本、zabbix_server来监控PV和UV数据,访问量很大时,可以用用logstash、ELK架构、EFK架构等方式监控网站PV和UV数据及图形化趋势界面。
十三、优化nginx的并发量
优化之前用apache benchmark进行压力测试
~]# ab -n 100 -c 100 http://192.168.1.5/ #-n任务量,-c是连接数
100% #成功
~]# ab -n 2000 -c 2000 http://192.168.1.5/
Benchmarking 192.168.1.5 (be patient)
socket: Too many open files (24) #失败
nginx的配置文件里面有两个参数:
worker_processes 1; 工作进程数,一般优化成和cpu核心数一样,比如8核就写8,用lscpu查看CPU核心数
worker_connections 1024; 每个进程支持的并发量,这个数据可以改大一点,50000或者100000以上
命令行输入ulimit -n # 查询系统默认的最大打开文件数,一般为1024
命令行输入ulimit -n 100000 # 临时修改为100000
vim /etc/security/limits.conf # 永久修改最大打开文件数,重启机器生效
.. ..
* soft nofile 100000 #nofile应该是number of file的意思,软限制可以突破,但是可作为一个监控指标,给监控软件发提示信息
* hard nofile 100000 #nofile应该是number of file的意思,硬限制不能突破,同时打开文件数量只能在100000以内
优化后测试服务器并发量
~]# ab -n 2000 -c 2000 http://192.168.1.5/
# 结果一般就是成功了
十四、修改Nginx配置文件,定义对静态页面的缓存时间
~]# vim /path/nginx.conf
server
{
listen 80;
server_name localhost;
location /
{
root html;
index index.html;
}
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$
{
expires 30d; #定义客户端缓存时间为30天
}
}
十五、和python动静分离
# 安装uWSGI
]# pip3 install uWSGI-2.0.21.tar.gz
]# vim myproject.ini
[uwsgi]
socket=ip:port #与nginx通信的接口
chdir=/root/python/python-project-demo #项目的工作目录
wsgi-file=learning_log/wsgi.py #指定项目中的wsgi.py配置文件
daemonize=/var/log/uwsgi.log #指定日志文件位置
#processes=4 #指定启动进程的数目
#master=true #开启主进程管理模式
# 修改nginx配置文件,和python通信
]# vim /path/nginx.conf
...
location / {
uwsgi_pass ip:port; #动态页面交给uWSGI
include uwsgi_params; #调用uWSGI配置文件
十六、灰度发布
灰度发布,意思是,新版本发布之前,先让部分用户体验,如果反馈比较好,才会正式发布。
在七层代理的基础上,写if条件判断,如果客户机是某个特征的ip,则将其访问请求转发给upstream后端服务器组A(web页面和数据库提供新版本数据),即让新版本服务器来处理访问请求,这一部分客户端就看到的是灰度测试的版本。其他的客户端ip请求的还是原来版本的服务器。当新版本灰度发布测试的效果不错,市场反馈比较积极的话,会讨论在合适的时间进行正式发布新版本。
也可以通过与数据库的交互,来实现符合某些特征的用户ID来访问服务器的时候,用新版本的数据,其他用户还是用原来版本的数据,实现对新版本的灰度发布。
十七、网站限速(比如云盘的普通版下载和会员版下载的速度区别)
限速的主要作用是限制单个客户端的访问速度,来实现对所有用户的访问速度的均衡,如果单个客户的请求处理速度是全速,那么处理高并发访问的时候,服务器的带宽和内存资源是不足以给其他用户提供合理速度的访问处理服务的。另一个点是,如果遭受恶意访问攻击的话,如果不限速,那么服务器将没有资源给其他用户提供服务。所以要限制单个用户访问的速度。然后就是云盘的会员制度,用户办理会员,那么服务商会给用户分配更多的带宽资源,也是一种商业方式。
限速的主要目的,就是为了让服务器给更多用户提供服务,不让少部分访问用户占用了大量的资源
配置方法,修改nginx配置文件,关键字limit_rate
]# vim /path/nginx.conf
http {
...
limit_rate 100k; #全局限速
server {
limit_rate 300k; #虚拟主机限速
listen 80;
location /file_1 {
limit_rate 500k; #目录file_1限速500k
}
location /file_2 {
limit_rate 0k; #目录file_2不限速
}
}
限制单个IP的访问速度,目的是防止单个IP开多个程序来访问服务器,限制之后,无论单个IP开多少访问程序,总速度是被限制的。实现这个功能,nginx需要安装ngx_http_limit_conn_module模块,配置文件修改如下:
http {
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /app {
limit_rate 30k;
limit_conn addr 1 ; # 单个IP只能开一个访问链接,正在访问的链接结束后,才能开启下一个链接
}
十八、跨域访问
默认情况下,浏览器根据同源策略,会拦截非本网站端口、域名、协议的数据,需要通过配置Nginx跨域指令解决。主要配置
location / {
add_header 'Access-Control-Allow-Origin' '*'; #添加允许跨域访问
}
十九、隐藏nginx版本号,防止通过版本漏洞等方式的网站攻击
~]# vim /path/nginx.conf
.. ..
http {
.. ..
server_tokens off;
.. ..
}
二十、防止doss攻击
修改nginx配置文件
~]# vim /path/nginx.conf
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
# 连接共享内存为10M,每秒钟只接收一个请求
server {
.. ..
limit_req zone=one burst=5; # 最多有5个请求排队,其他的拒绝
}
二十一、防止缓冲区溢出
什么是缓冲区溢出,程序企图在预分配的缓冲区之外写数据
~]# vim /path/nginx.conf
http {
client_body_buffer_size 1k;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;