Nginx 简介
- nginx 是一个高性能的Web和反向代理服务器,它具有非常优越的特性
- nginx 能支持高达50000个并发连接数的响应,用于高连接并发情况 使用epol and kqueue作为开发模型
- nginx 作为负载均衡服务器:nginx 即可在内部直接支持和PHP程序对外进行服务,也可支持作为HTTP代理服务器对外进行服务
- nginx采用C进行编写,不论系统资源开销还是CPU使用效率都比Perlbal要好
Nginx 的优点
-
高并发连接:官方测试能够支撑5万并发连接,在实际的生产环境中跑到2~3万的并发连接数
-
内存消耗少:在三万并发连接下,开启的10个nginx进程才消耗150M的内存
-
配置文件简单、成本低廉、支持Rewrite重写规则(能够根据域名、URL的不同 ,将HTTP请求分到不同的后端服务器群组
Nginx的基本功能
- 静态资源的Web服务器,能缓存打开的文件描述符
- http、smtp、pop3协议的反向代理服务器
- 缓存加速、负载均衡 支持FastCGI (fpm,LNMP),uWSGI (Python)等 模块化
- (非DSO机制),过滤器zip、SSI及图像的大小调整 支持SSL
Nginx 的扩展功能
- 基于名称和IP的虚拟主机
- 支持keepalive
- 支持平滑升级
- 定制访问日志,支持使用日志缓冲区提高日志存储性能
- 支持URL重写
- 支持路径别名
- 支持基于IP及用户的访问控制
- 支持速率限制,支持并发数限制
Nginx 的应用类别
- 使用nginx结合FastCGI运行的PHP、 JSP 、Perl等程序
- 使用nginx作反向代理、负载均衡、过滤规则
- 使用nginx运行静态HTML网页、图片
- nginx与其他新技术的结合应用
nginx的模块分类
nginx的模块从结构上分为核心模块、基础模块和第三方模块
HTTP模块、EVENT模块和MAIL模块等属于核心模块
HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块属于基本模块
HTTP Upstream模块、Request Hash模块、Notice模块和HTTP Access Key模块属于第三方模块
访问控制
用于loaction 段
allow:设定允许哪台主机或哪些主机访问,多个参数间用空格隔开
deny: 设定禁止哪台或者哪些主机访问,多个参数间用空格隔开
allow 192.168.169.1/32 172.16.0.0/16;
deny all;
基于用户认证
auth_basic "欢迎信息";
auth_basic_user_file "/path/to/user_auth_file"
user_auth_file内容格式为:
username:password
这里的密码为加密后的密码串,建议用htpasswd来创建此文件:
htpasswd -c -m /path/to/.user_auth_file USERNAME
httpds 配置
生成私钥,生成证书签署请求并获得证书,然后在nginx.conf中配置如下内容:
server {
listen 443 ssl;
server_name www.idfsoft.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.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;
}
}
用户认证实验
实验环境:关闭防火墙,关闭selinux
安装Nginx,配置yum源
[root@localhost ~]# cd /usr/local/nginx/
创建一个目录
[root@localhost nginx]# mkdir auth
安装生成密码的命令
[root@localhost nginx]# yum provides *bin/htpasswd
[root@localhost nginx]# yum install httpd-tools
创建登录nginx 的用户和密码
[root@localhost nginx]# htpasswd -c -m /usr/local/nginx/auth/.user_auth_file tom
New password:
Re-type new password:
Adding password for user tom
修改配置文件
[root@localhost nginx]# vi /usr/local/nginx/conf/nginx.conf
location / {
root html;
index index.html index.htm;
auth_basic "welcome there"; //添加此行
auth_basic_user_file ../auth/.user_auth_file;
}
在浏览器上验证
开启状态界面
开启status:
location /status {
stub_status {on | off};
allow 172.16.0.0/16;
deny all;
}
访问状态页面的方式:http://server_ip/status
状态页面信息详解:
状态码 | 表示的意义 |
---|---|
Active connections 2 | 当前所有处于打开状态的连接数 |
accepts | 总共处理的多少个连接 |
handled | 成功创建多少握手 |
requests | 总共处理了多少个请求 |
Reading | nginx读取到客户端的Header信息数,表示正处于接收请求状态的连接数 |
Writing | nginx返回给客户端的Header信息数,表示请求已经接收完成,且正处于处理请求或发送响应的过程的连接数 |
Waiting | 开启keep-alive的情况下,这个值等于active -(reading+writing),意思就是Nginx以处理完正在等候下一次请求指令的驻留连接 |
rewrite
语法: rewrite regex replacement flag;如
rewrite ^/images/(.*.jpg)$ /imgs/$1 break;
此处的$1用于引用(.*.jpg)匹配到的内容,如:
rewrite ^/bbs/(.*)$ http://www.idfsoft.com/index.html redirext
如上例所示,replacement可以是某个路径,也可以是某个URL
实验效果如下
在 /usr/local/nginx/html 创建一个目录,并上传一张图片
[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# mkdir chen
[root@localhost chen]# ls // 上传一张图片,改名叫1.png
1.png
修改nginx 的主配置文件
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
....... 此处省略
server {
listen 80;
server_name localhost;
access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /chen { //添加以下内容
root html;
index index.html;
}
......... 此处省略
访问IP及URL,能否找到这个图片
修改 html/chen 改为 html/chens,在用原来的位置访问
[root@localhost html]# mv chen chens
[root@localhost html]# ls
50x.html cd chens index.html
修改nginx的主配置文件
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
............. 此处省略
server {
listen 80;
server_name localhost;
access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /chen {
root html;
index index.html;
rewrite ^/chen/(.*\.png)$ /chens/$1 break; //添加此行
}
.........此处省略
// rewrite ^/chen/(.*.png)$ /chens/$1 break; 意思为将前面访问请求的结果,转交到后面(chens)这个目录去处理
检查语法,重新加载配置文件
[root@localhost nginx]# nginx -t
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
[root@localhost nginx]# nginx -s reload
再次访问IP以及原来的URL来验证结果
修改nginx 的主配置文件,让其访问html 下的请求时,把访问的结果转交给 www.baidu.com
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /chen { //从此处开始添加
root html;
index index.html;
rewrite ^/chen/(.*\.png)$ http://www.baidu.com break;
}
[root@localhost nginx]# nginx -t
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
[root@localhost nginx]# nginx -s reload
rewrite ^/chen/(.*.png)$ http://www.baidu.com break; 将前面请求的结果,转交给www.baidu.com
用浏览器,访问原来的IP和URL,查看结果
自动将请求结果转到交到百度
实验思路
实验环境与上面的一样
客户端发出的请求改变后的URL(chen)———>改变后的URL(chen)——>现以存在的URL(chens)——>www.baidu.com
1.修改nginx的主配置文件
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /chens { //这里必须先定义一个chens
rewrite ^/chens/(.*)$ http://www.baidu.com redirect;
}
location /chen {
root html;
index index.html;
rewrite ^/chen/(.*)$ /chens/$1 last; //当客户端发起请求是,把请求转交给chens
}
浏览器访问IP,显示结果为www.baidu.com
常见的flag
flag | 作用 |
---|---|
last | 基本上都用这个flag,表示当前的匹配结束,继续下一个匹配,最多匹配10个到20个,一旦此rewrite规则重写完成后,就不再被后面其他的rewrite规则进行处理,而由UserAgent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程 |
break | 终止Rewrite,不再继续匹配,一旦rewrite规则重写完成后,由UserAgent对新的URL重新发起请求,且不在会被当前location内的任何rewrite 规则所检查 |
redirect | 以临时重定向的HTTP状态302返回新的URL |
permanent | 以永久重定向的HTTP状态301返回新的URl |
rewrite 模块的作用是来执行URL重定向。这个机制有利于去掉恶意访问的url,也有利于搜索引擎优化(SEO)
捕获表达式,可以捕获放在()之间的任何文本,比如
^(hellolsir)$ //字符串为“hi sir”捕获的结果:$1=hi $2=sir
// 这些被捕获的数据 ,在后面就可以当变量一样使用
openssl 实现私有CA
实验环境:
server-ip | 192.168.169.10 |
---|---|
运行的服务 | nginx |
//这里只用一台服务器演示,所以服务器,和客户端都是192.168.169.10
CA生成一对密钥
[root@nginx-server ]# cd /etc/pki/CA/
[root@nginx-server CA]# (umask 077;openssl genrsa -out private/cakey.pem 2048) //生成密钥括号必须要
[root@nginx-server CA]# openssl rsa -in private/cakey.pem -pubout //提取公钥
CA 生成自签署证书
[root@nginx-server CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365 //生成自签署证书
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:ch
State or Province Name (full name) []:hb
Locality Name (eg, city) [Default City]:wh
Organization Name (eg, company) [Default Company Ltd]:cs
Organizational Unit Name (eg, section) []:yw
Common Name (eg, your name or your server's hostname) []:cs
Email Address []:1@2.com
[root@nginx-server CA]# openssl x509 -text -in cacert.pem 读出cacert.pem证书
[root@nginx-server CA]# mkdir certs newcerts crl
[root@nginx-server CA]# touch index.txt && echo 01 > serial
客户端如(nginx)服务器生成密钥
[root@nginx-server CA]# cd /usr/local/nginx/ && mkdir ssl && cd ssl
[root@nginx-server ssl]# (umask 077;openssl genrsa -out httpd.key 2048)
客户端生成证书签署请求
[root@nginx-server ssl]# openssl req -new -key httpd.key -days 365 -out httpd.csr
//注意这里于服务器端签署证书的信息一致
客户端把证书签署请求文件发送给CA
scp httpd.csr root@CA端IP:/root
CA签署客户端提交上来的证书
openssl ca -in /usr/local/nginx/ssl/httpd.csr -out httpd.crt -days 365
if
语法: if (condition)
应用场景:
server段
location 段
常见的condition
变量名 (变量值为空串 ,或者以 "0“开始,则为false,其它的均为true)
以变量为操作数构成的比较表达式(可使用=,!=类似的比较操作符进行测试)
正则表达式的模式匹配操作
.~:区分大小写的模式匹配检查
.~:不区分大小写的模式匹配检查
.!和!:对上面两种测试取反
测试指定路径为文件的可能性(-f,!-f)
测试指定路径为目录的可能性(-d,!-d)
测试文件的存在性(-e,!-e)
检查文件是否有执行权限(-x,!-x)
基于浏览器实现分离案例
if ($http_user_agent ~ firefox) {
rewrite ^()$ /firefox/$1 break;
}
if ($http_user_agent ~MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($http_user_agent ~ (hrome) {
rewrite ^(.*)$ /chrome/$1 break;
}
防盗链案例
location ~* \.(jpg|gif|jpeg|png)$ {
valid_referer none clocked www.idfsoft.com;
if($invalid_referer) {
rewrite ^/ http://www.idfsoft.com/403.html;
}
}
反向代理与负载均衡
nginx 通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离以及负载均衡,从而大大提高服务器的处理能力
nginx 实现动静分离,其实就是在反向代理的时候,如果是静态资源,就直接从发布的路径去读取,而不需要从后台服务器获取了
但是需要注意,这种情况下需要保证后端更前端的程序保持一致,可以使用Rsync做服务端自动同步或者使用NFS、MFS分布式共享存储
Http Proxy模块,功能很多,最常用的是 proxy_pass 和 proxy_cache
如果使用proxy_cache,需要集成第三方的nginx_cache_purge模块,用来清除指定的URL缓存。这个集成需要在安装 nginx 的时候去做,如: ./configure --add-module=…/ngx_cache_purge-1.0 …
nginx 通过 upstream 段内,定义一个服务器列表,默认的方式是轮询,如果要确定同一个访问者发出的请求总是由同一个后端服务器来处理,可以设置ip_hash,如:
upstream idfsoft.com {
ip_hash;
server 192.168.169.10:8090 weight=5; //weight 为权重,权值越大,被分配的几率就越大
server 192.168.169.20:8080 weight=5;
}
注意:这个方法本质还是轮询,而且由于客户端的IP可能是不断变化的比如动态的ip 、代理、翻墙等,因此ip_hash并不能完全保证同一个客户端是由同一个服务器来处理
定义好 upstream 后,需要在server 段内添加如下内容
server {
location / {
proxy_pass http://idfsoft.com;
}
}
同过客户端访一台主服务器,主服务器把结果交给其他两台服务器处理,并且把结果返回给主服务器在返回到客户端
实验环境
服务器 | IP地址 |
---|---|
nginx-server | 192.168.169.10 |
apache | 192.168.169.20 |
nginx | 192.168.169.30 |
nginx-server 为主服务器运行nginx
其他两台上运行apache 、和 nginx
安装nginx 步骤略,修改nginx配置文件
[root@nginx-server ~]# vim /usr/local/nginx/conf/nginx.conf
# gzip on;
upstream web { 在此处添加
server 192.168.169.30:8090;
server 192.168.169.20:8080;
}
server {
listen 80;
server_name localhost;
access_log logs/host.access.log main;
location / {
proxy_pass http://web; 添加此行
root html;
index index.html index.htm;
}
在apache这台服务器上,修改端口号,添加网页测试
[root@localhost html]# vi /etc/httpd/conf/httpd.conf
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 8080
[root@localhost ~]# echo 'chen'>>/var/www/html/index.html
修改nginx 这台服务器上的端口,添加网页测试
[root@nginx ~]# mkdir /usr/local/nginx/html/chen
[root@nginx ~]# echo 'this is jeck' << /usr/local/nginx/html/chen/index.html
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
#gzip on;
server {
listen 8090;
server_name localhost;
access_log logs/host.access.log main;
location / {
root html/chen; //修改此处
index index.html index.htm;
}
#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;
}
验证结果
第一次访问主服务器
再次访问主服务器
用yum 安装nginx 时出现如下错误
[root@nginx-server ~]# yum install -y nginx
From : http://mirrors.163.com/centos/RPM-GPG-KEY-CentOS-7
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
GPG key retrieval failed: [Errno 14] curl#37 - "Couldn't open file /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7"
解决方法
[root@nginx-server rpm-gpg]# cd /etc/pki/rpm-gpg/
[root@nginx-server rpm-gpg]# wget https://archive.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7