nginx

nginx

1 nginx介绍

  Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”,是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器。Nginx是由俄罗斯人 Igor Sysoev为俄罗斯访问量第二的 Rambler.ru站点开发的,它已经在该站点运行超过两年半了。Igor Sysoev在建立的项目时,使用基于BSD许可。

英文主页:http://nginx.net

  到2013年,目前有很多国内网站采用Nginx作为Web服务器,如国内知名的新浪、163、腾讯、Discuz、豆瓣等。据netcraft统计,Nginx排名第3,约占15%的份额(参见:http://news.netcraft.com/archives/category/web-server-survey/ )

  Nginx以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡。其拥有匹配Lighttpd的性能,同时还没有Lighttpd的内存泄漏问题,而且Lighttpd的mod_proxy也有一些问题并且很久没有更新。

  现在,Igor将源代码以类BSD许可证的形式发布。Nginx因为它的稳定性、丰富的模块库、灵活的配置和低系统资源的消耗而闻名.业界一致认为它是Apache2.2+mod_proxy_balancer的轻量级代替者,不仅是因为响应静态页面的速度非常快,而且它的模块数量达到Apache的近2/3。对proxy和rewrite模块的支持很彻底,还支持mod_fcgi、ssl、vhosts ,适合用来做mongrel clusters的前端HTTP响应。

2 ngingx的优点

  • 处理静态文件,索引文件以及自动索引;打开文件描述符缓冲.

  • 无缓存的反向代理加速,简单的负载均衡和容错.

  • FastCGI,简单的负载均衡容错

  • 模块化的结构。包括gzipping, byte ranges, chunked responses,以及 SSI-filter等filter。如果由FastCGI或其它代理服务器处理单页中存在的多个SSI,则这项处理可以并行运行,而不需要相互等待。

  • 支持SSL 和 TLSSNI.

  Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率 。它支持内核Poll模型,能经受高负载的考验,有报告表明能支持高达 50,000个并发连接数。(负载均衡)

  Nginx具有很高的稳定性。其它HTTP服务器,当遇到访问的峰值,或者有人恶意发起慢速连接时,也很可能会导致服务器物理内存耗尽频繁交换,失去响应,只能重启服务器。例如当前apache一旦上到200个以上进程,web响应速度就明显非常缓慢了。而Nginx采取了分阶段资源分配技术,使得它的CPU与内存占用率非常低。nginx官方表示保持10,000个没有活动的连接,它只占2.5M内存,所以类似DOS这样的攻击对nginx来说基本上是毫无用处的。就稳定性而言,nginx比lighthttpd更胜一筹。

  Nginx支持热部署。它的启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够在不间断服务的情况下,对软件版本进行进行升级。

  Nginx采用master-slave模型,能够充分利用SMP的优势,且能够减少工作进程在磁盘I/O的阻塞延迟。当采用select()/poll()调用时,还可以限制每个进程的连接数

  Nginx代码质量非常高,代码很规范,手法成熟, 模块扩展也很容易。特别值得一提的是强大的Upstream与Filter链。Upstream为诸如reverse proxy,与其他服务器通信模块的编写奠定了很好的基础。而Filter链最酷的部分就是各个filter不必等待前一个filter执行完毕。它可以把前一个filter的输出做为当前filter的输入,这有点像Unix的管线。这意味着,一个模块可以开始压缩从后端服务器发送过来的请求,且可以在模块接收完后端服务器的整个请求之前把压缩流转向客户端。

3 ngingx的搭建部署

3.1 nginx的安装

首先把nginx-1.16.0.tar.gz下载下来
其中分为主线版本,稳定版本,旧版本(下载中间的稳定版本就行)

解压文件:

[root@localhost ~]# ls
anaconda-ks.cfg  nginx-1.16.0.tar.gz
[root@localhost ~]# gzip  -d nginx-1.16.0.tar.gz 
[root@localhost ~]# ls
anaconda-ks.cfg  nginx-1.16.0.tar
[root@localhost ~]# tar -zvf nginx-1.16.0.tar
[root@localhost ~]#cd nginx-1.16.0

解压文件详解

3.1.1 编译安装nginx

在linux中编译安装nginx-1.16.0.tar.gz需要先安装好一些依赖

yum install -y gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel

常用的编译选项(先添加Nginx用户和Nginx组,且安装development tools 和 server platform development pcre-devel openssl-devel zlib-devel)

 ./configure --prefix=/usr/local/nginx1.16 --conf-path=/etc/nginx/nginx.conf --user=nginx --group=nginx --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --with-http_ssl_module --with-http_gzip_static_module --with-debug --with-http_stub_status_module

编译安装

 make &&   make    install     

编译安装完成后启动Nginx、已经Nginx的常用命令讲解
(1)(在启动之前,先将命令添加到环境变量里面,再做一个软连接)

ln -sv /usr/local/nginx1.16 /usr/local/nginx

vi /etc/profile.d/nginx.sh 添加

export PATH=/usr/local/nginx/sbin:$PATH

. /etc/profile.d/nginx.sh

(2)启动Nginx

/usr/local/nginx/sbin/nginx

(3)查看nginx客户端程序的帮助

nginx -h

编写Nginx的service脚本文件,让其开机自启

(1)vi /etc/rc.d/init.d/nginx 添加

 #! /bin/bash
 # chkconfig: - 85 15
 PATH=/usr/local/nginx
 DESC="nginx daemon"
 NAME=nginx
 DAEMON=$PATH/sbin/$NAME
  CONFIGFILE=/etc/nginx/nginx.conf
 PIDFILE=/var/run/nginx/nginx.pid
 SCRIPTNAME=/etc/init.d/$NAME
set -e
[ -x "$DAEMON" ] || exit 0
do_start() {
$DAEMON -c $CONFIGFILE || echo -n "nginx already running"
}
do_stop() {
$DAEMON -s stop || echo -n "nginx not running"
}
do_reload() {
$DAEMON -s reload || echo -n "nginx can't reload"
}
case "$1" in
start)
echo -n "Starting $DESC: $NAME"
do_start
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
do_stop
echo "."
;;
reload|graceful)
echo -n "Reloading $DESC configuration..."
do_reload
echo "."
;;
restart)
echo -n "Restarting $DESC: $NAME"
do_stop
do_start
echo "."
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|reload|restart}" >&2
exit 3
;;
esac
exit 0


(2)chmod +x /etc/rc.d/init.d/nginx


(3)chkconfig --add nginx


(4)chkconfig --level 35 nginx on


(5)chkconfig --list

注意:为了后续准备我们另外下载2个插件模块:nginx_upstream_check_module-0.3.0.tar.gz —— 检查后端服务器的状态,nginx-goodies-nginx-sticky-module-ng-bd312d586752.tar.gz(建议在/usr/local/src下解压后将目录重命名为nginx-sticky-module-ng-1.2.5) —— 后端做负载均衡解决session sticky问题(与upstream_check模块结合使用需要另外打补丁)。

3.1.2 yum安装nginx

yum安装rpm包会比编译安装简单很多,默认会安装许多模块,但缺点是如果你想以后安装第三方模块那就没办法了。

vi /etc/yum.repo.d/nginx.repo

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

剩下的就yum install nginx搞定,也可以yum install nginx-1.6.3安装指定版本(前提是你去packages里看到有对应的版本,默认是最新版稳定版)。

注意:安装完成后,可以用命令netstat -lntup查看一下这个nginx服务是否占用了80端口或者用浏览器登录nginx服务器的IP

3.2 nginx配置文件介绍

(1)全局配置段

1:指明运行worker进程的用户和组
user nginx nginx;
 
2:指明pid文件路径
pid /var/run/nginx.pid;
 
3:指明worker进程所能够打开的最大文件数(可以省略)
worker_rlimit_nofile 1024
 
4:worker的进程数,应该为CPU的核心数或核心数减一,如果是双核CPU,可以给2
worker_processes 2;
 
5:将nginx的worker进程,绑定在不同的CPU上, 如果分别绑定在第一颗和第二颗核心上,可以使用ps axo command,pid,psr 命令查看CPU的绑定情况
worker_cpu_affinity 0001 0010;
 
6:指定进程的nice值,nice值越小优先级越高
worker_priority 0;
 
7:指定以何种方式启动Nginx,默认是以daemon的方式启动
daemon on
 
8:指定是否使用master/worker模型启动nginx进程,默认是
master_process on
 
9:指定错误日志文件路径、日志级别
error_log logs/error.log error;

(2)event配置段

1:指定单个worker进程打开的最大socket连接数,默认为512,但是必须小于worker进程所能够打开的最大文件数
worker_connections 512;
 
2:指明处理并发连接请求时,使用的网络I/O处理方式,无需管理,linux自行判断
use method;
 
3:指明worker进程是否支持轮询响响应的新请求
accept_mutex on;
 
4:指明锁文件路径
lock_file /var/lock/nginx.lock;

(3)http配置段

1:指明mime类型,用于数据传输
default_type text/plain;
或 default_type application/octet-stream;
 
2:指定是否启用sendfile功能,sendfile功能用于读写函数中减少拷贝,也就是linux的0拷贝
sendfile on;
 
3:指定保持连接的超时时长,0表示禁止使用长连接,默认为65秒
keepalive_timeout 65;
 
4:指定长连接上响应客户端请求的最大数量,默认为100
keepalive_requests 100;
 
5:指明向客户端发送响应报文的超时时长,如果客户端没有接受,那么就关闭连接
send_timeout 60s;
 
6:指明客户端请求报文的body部分的数据,设置缓冲区大小,超出16K大小会被存储在硬盘上
client_body_buffer_size 16k;
 
7:指定响应报文的传输速率,默认为0,不做限制
limit_rate 0;
 
8:指明启用AIO
aio off;
 
9:指定配置一个虚拟主机
server { }

(4)server配置段

1:指明socket的监听选项,有下面三种常用情况
  listen address[:port] [default_server] [ssl]   [backlog=number] [rcvbuf=size] [sndbuf=size]
  listen port [default_server] [ssl]
  listen unix:path [default_server] [ssl]
 
port:指明端口
  default_server:指定这个虚拟主机是默认的虚拟主机
  ssl:限制只能通过ssl连接提供服务
  backlog:后援队列的长度
  rcvbuf:接受缓冲大小
  sndbuf:发送缓冲大小
 
 
2:指明当前server的主机名,主机名可以并排写,有四种定义主机名的格式,但是优先级有区别
  server_name www.uplooking.com
    精确定义主机名,例如:www.uplooking.com 优先级第一
    左通配定义主机名:例如:*.uplooking.com 优先级第二
    右通配定义主机名:例如:www.uplooking.* 优先级第三
    使用正则表达式匹配主机名:例如:~^.*/.uplooking/..*$ 优先级第四
 
3:指明站点路径,配置文件默认是相对路径,可以写绝对路径
   /usr/local/nginx/html
   root html;
 
4:在keepalived模式下的连接是否启用TCP_NODELAY选项,TCP有一个默认的delay优化机制,可以在这里将它关闭
   tcp_nodelay on
 
5:指明默认的首页文件
   index index.html index.htm;
 
6:指定错误页面重定向
  error_page 404 =200 /404.html;
  error_page 500 502 503 504 /50x.html;
  location = /50x.html {
  root html;
  }
 
7:指定匹配的URL,通过用户输入的URL来匹配不同的location,匹配到了,就按照location内部的设置进行响应
  location [ = | ~ | ~* | ^~ ] uri {
 
  }
 
= :URI精确匹配 ,优先级第一
^~ :对于URI的左边进行匹配,不区分字符大小写,优先级第二
~ :模式匹配,正则表达式模式匹配,匹配时候区分大小写,优先级第三
~* :模式匹配,正则表达式模式匹配,匹配时候不区分大小写 ,优先级第三
不带以上四种符号的URI的优先级是第四

(5)location配置段

1:指定路径别名(要与root指令区别开来)
   location /i/ {
   alias /data/w3/images/;
   }

请求:http://www.uplooking.com/i/index.html
资源文件:/data/w3/images/index.html
 
 
2:指定访问控制,除了GET方法以外,例如:POST方法,必须是     192.168.10.10主机,才能够被响应
  limit_except GET {
  allow 192.168.10.10;
  deny all;
  }

Nginx缓存指令

 指定缓存开启,且最大的文件缓存为1000,非活动的缓存时长为20秒
  open_file_cache max=1000 inactive=20s;
 
# 指定缓存有效性的,默认是60秒
  open_file_cache_valid 30s;
 
# 缓存对象被访问的次数小于2,则被认为是非活动对象
  open_file_cache_min_uses 2;
 
# 是否缓存错误信息
  open_file_cache_errors on;

http段 访问控制模块 ngx_http_access_module
  location / {
  deny 192.168.1.1;
  allow 192.168.1.0/24;
  allow 10.1.1.0/16;
  allow 2001:0db8::/32;
  deny all;
  }

http段 访问认证模块 ngx_http_auth_basic_module
创建basic认证文件
  htpasswd -c /etc/nginx/.uplooking_password uplooking
 
  location /uplooking/ {
  auth_basic "uplooking Place;"
  auth_basic_user_file /etc/nginx/.uplooking_password;
  }

http段 基本状态模块 ngx_http_stub_status_module
# 请用统计功能
  stub_status;

3.2.1 几个常用的模块

ngx_http_ssl_module(https)

1:指明是否启用的虚拟主机的ssl功能
ssl on | off;
  
2:指明虚拟主机使用的证书文件
ssl_certificate /usr/local/nginx/conf/cert.pem;
  
3:指明虚拟主机使用的私钥文件
ssl_certificate_key /usr/local/nginx/conf/cert.key;
  
4:指明SSL的协议版本
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  
5:指明ssl会话的缓存机制
ssl_session_cache shared:SSL:10m;
shared:表明是worker共享的缓存
name:缓存的名称
size:缓存大小的单位是字节,每1MB内存空间可以缓存4000个会话
  
6:指明ssl会话超时时长
ssl_session_timeout 10m;
  

ngx_ http_ log_ module(日志)

1:访问日志路径,记录类型,是否压缩,多长时间刷新一次缓冲
access_log /path/to/log.gz combined gzip flush=5m;
  
2:指定日志记录类型
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
  
3:指定日志缓冲的信息,也就是指定文件描述符
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;
  

Nginx使用proxy_ pass和fastcgi_pass实现单台主机的动静分离(PHP以httpd模块方式运行)

location ~* \.html$ {
  
proxy_pass http://192.168.23.11:8080;
  
}
  
location ~* \.php$ {
  
proxy_pass http://192.168.23.12;
  
}

  

ngx_ http_ headers_module模块详解(这个模块可以给响应报文添加自定义首部)

可以在location段中添加
# 添加一个响应头,指明响应请求的服务器的主机名
add_header X-Server $server_name;
  
# 指明缓存的超时时长,超过这段时间缓存服务器就会向后端真实服务器请求,并更新缓存
expires 24h;
  
# 告知客户端,响应客户端请求的报文是缓存中加载的,还是后端服务器响应的
add_header X-cache $uptream_cache_status;

4 nginx的正向代理和方反向代理的配置

什么是正向代理和反向代理:

正向代理:客户端给服务器发送的请求,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。(俗语:明确知道要访问哪个网站)

反向代理:客户端给服务器发送的请求,nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。此时~请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,nginx扮演的就是一个反向代理角色(俗语:收到的请求不明确)

  通常情况下,我们在实际项目操作时,正向代理和反向代理很有可能会存在在一个应用场景中,正向代理代理客户端的请求去访问目标服务器,目标服务器是一个反向代理服务器,反向代理了多台真实的业务处理服务器。
配置文件之前需要使用OpenSSL生成证书

openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout /home/data/ssl/nginx.key -out /home/data/ssl/nginx.crt

4.1nginx的正向代理与方向代理配置

user   root owner;
worker_processes  4;

#error_log  /usr/local/etc/nginx/logs/error.log;
#error_log  /usr/local/etc/nginx/logs/info.log info;

pid/Users/martin/nginx.pid;

events {
worker_connections  256;
}

http {
include   mime.types;
default_type  application/octet-stream;

#日志的格式
#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  /usr/local/etc/nginx/logs/access_log_pipe  main;

#sendfileon;
#tcp_nopush on;

keepalive_timeout  65;

gzip  on;

#反向代理配置

server {
listen   443 ssl;  #监听443端口
server_name  app.doodl6.com;   #服务域名

ssl  on;   #是否开启SSL加密
ssl_certificate /home/data/ssl/nginx.crt;
ssl_certificate_key /home/data/ssl/nginx.key;
ssl_session_cache    shared:SSL:1m;
ssl_session_timeout  5m;

Documents/ssl/doodl6.crt; # SSL加密证书
Documents/ssl/doodl6.key; # SSL加密秘钥

charset UTF-8;   #编码指定

location ~* ^.+\.(xls|woff2|log|jpg|jpeg|gif|png|ico|html|cfm|cfc|afp|asp|lasso|pl|py|txt|fla|swf|zip|js|css|less)$ {   #代理指定后缀的请求,这里配的是常见的前端资源
proxy_pass https://127.0.0.1:80;  #转向提供内容的真实服务器地址,也可以配置本地目录(见HTTP代理配置)
#禁止在header中出现服务器版本,防止黑客利用版本漏洞攻击
server_tokens off;
#如果是全站 HTTPS 并且不考虑 HTTP 的话,可以加入 HSTS 告诉你的浏览器本网站全站加密,并且强制用 HTTPS 访问
fastcgi_param   HTTPS               on;
fastcgi_param   HTTP_SCHEME         https;
#proxy_set_header Host $http_host;  #写入Header值,
#proxy_set_header referer "$http_referer";
}  

location = / {#代理域名请求,也就只有域名的请求,如:https://app.doodl6.com
proxy_pass https://127.0.0.1:8080;
proxy_set_header Host $http_host;
} 

location ~ / {   #代理所有请求,不符合上面两种配置的请求都会走这个代理配置
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $http_host;
}
}


server {
listen   80;
server_name  app.doodl6.com;
charset UTF-8; 

location ~* ^.+\.(xls|woff2|log|jpg|jpeg|gif|png|ico|html|cfm|cfc|afp|asp|lasso|pl|py|txt|fla|swf|zip|js|css|less|ico)$ {
expires 30s;   #内容缓存30秒
root /Users/martin/project/app/front;  #指定文件根目录
} 

location ~ / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $http_host;
}
}

#正向代理配置

server{
listen 82;   #监听端口 
server_name   proxy.doodl6.com;

resolver 8.8.8.8;   #DNS
resolver_timeout 10s;  # DNS解析超时时间
location / {
proxy_pass http://$http_host$request_uri;
#proxy_set_header Host $http_host;
#proxy_buffers 256 4k;
#proxy_max_temp_file_size 0;
#proxy_connect_timeout 30;
#proxy_cache_valid 200 302 10m;
#proxy_cache_valid 301 1h;
#proxy_cache_valid any 1m;
}
error_page   500 502 503 504  /index.html;
location = /index.html {
     root   /home/data/forwordproxy;
     }
}
#本地反向转正向代理

server {
listen   80;
server_name  proxy.doodl6.com;
charset UTF-8; 

location ~ / {
proxy_pass http://127.0.0.1:82;  #转到本地正向代理
proxy_set_header Host $http_host;
}
}

}

简单的反向代理配置:

 server {
    listen 443 ssl;
    server_name proxy.test.com;
    root  /home/data/proxy;

    ssl_certificate /home/data/ssl/nginx.crt;
    ssl_certificate_key /home/data/ssl/nginx.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    #禁止在header中出现服务器版本,防止黑客利用版本漏洞攻击
    server_tokens off;
    #如果是全站 HTTPS 并且不考虑 HTTP 的话,可以加入 HSTS 告诉你的浏览器本网站全站加密,并且强制用 HTTPS 访问
    fastcgi_param   HTTPS               on;
    fastcgi_param   HTTP_SCHEME         https;

    location /api/
    {
        rewrite ^/api/(.*) /$1 break;
        proxy_pass http://192.168.10.191:8080;
    }      
}

使用wget进行测试

验证证书

wget --ca-certificate=/home/data/ssl/nginx.crt -e "http_proxy=http://www.forwordproxy.com" "https://proxy.test.com/interface/test"

使用上面生成的nging.crt证书,通过正向代理,访问反向代理服务接口。

不验证证书

wget --no-check-certificate  -e "http_proxy=http://www.forwordproxy.com" "https://proxy.test.com/interface/test"

注意:域名都需要配置/etc/hosts

若是配置过程中,遇到问题,就是通过配置的代理访问页面都报404,后来我发现需要改下proxy_pass:
proxy_pass $scheme://$host$request_uri;
改成:
proxy_pass $scheme://$http_host$request_uri;

  

posted @ 2019-08-05 13:11  ~小学生~  阅读(579)  评论(0编辑  收藏  举报