实战nginx笔记

96
hopevow
2016.09.28 09:57* 字数 2650

使用理由

配置文件简单
支持Rewrite重写规则
内置健康检查功能
节省带宽
稳定性高
支持热部署```
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/3079704-6b2ce4b4b940b7d7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

>平滑重启

``` kill -HUP \`/usr/local/nginx/logs/nginx.pid\` ```

当Nginx接收到hup信号时,它会尝试先解析配置文件,如果 成功就应用新的配置谁的,之后,Nginx运行新的工作进程并从容关闭旧的工作进程 ,通知工作进程 关闭监听大套接字,但是继续为新的客户提供服务 ,所有客户端的服务完成后旧的工作进程 被关闭。如果 新的配置文件应用失败,Nginx继续使用旧的配置进行工作。

>Nginx支持以下几种信号

- TERM, INT 快速关闭;
- QUIT 从容关闭;
-  HUP 一滑重启,重新加载配置文件;
- USR1 重新的打开日志文件,在切割日志时用途较大;
- USR2 平滑升级可执行程序 ;
- WINCH  从容关闭工作进程。

>nginx配置

```#使用的用户和组
user www www;
#指定工作衍生进程数(一般等于CUP的总或总的两倍,例如两个 四核CUP,则总核数为8)
worker_processes 8;
#指定错误日志存放的路径,错误日志记录级别可选项为:【debug | info | notice | warn | error | crit 】
error_log /data1/logs/nginx_error.log crit;
#指定PID存放的路径
pid /usr/local/nginx/nginx.pid;
#指定文件描述符数量 
worker_rlimit_nofile 51200;

events {
 #使用的网络I/O模型,Linux系统推荐采用epoll模型,FreeBSD系统采用kqueue模型
use epoll;
#允许的连接数
worker_connections 51200;
}

http {
include mime types;
default_type application/octet-stream;
#设置使用的字符集,如果 一个网站 有多种字符集,请不要随便设置,就让程序 员在html代码中通过meta标签设置
#charset gb2312;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
#设置客户端能够上传文件的大小
client_max_body_size 8m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fasgcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
#开启gzip压缩
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m;
server {
#监听的IP和端口
 listen 80;
#主机名称
 server_name www.yourdomain.com yourdomain.com;
#默认首页文件,顺序从左到右,如果 找不到index.html文件,则查找 index.htm文件作为首页文件
index index.html index.htm index.php;
root /data0/htdocs;
#limit_conn crawler 20;
location ~  .*\.(gif|jpg|jpeg|png|bmp|swf)${
 expires 30d;
} 
location ~ .*\.(js|css)?${
 expires 1h;
}

log_format access '$remote_addr - $remote_user [$time_local] "$request" ' ' $status $body_bytes_sent "$http_referer" ' '$http_user_agent" $http_x_forwarded_for';
access_log /data1/logs/access.log access;
}
}

虚拟主机

虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机,每台虚拟主机都可以是一个独立的网站,可以具有独立的域名,具有完整的Internet服务器功能(www、FTP、Email等),同一台主机上的虚拟主机之间是完全独立的。从网站访问者来看,每一台虚拟主机和一台独立的主机完全一样。

利用虚拟主机,不用为每个要运行的网站 提供一台单独的Nginx服务 器或单独运行一级nginx进程 。虚拟主机提供了在同一台服务器、同一级Nginx进程 上运行多个网站 的功能。

跟apache一样,Nginx也可以配置多种类型的虚拟主机;一是基于ip的虚拟主机,二是基于域名的虚拟主机,三是基于端口的虚拟主机。

一段server{......}就是一个虚拟该机,如果要配置多个虚拟主机,建立多段server{}配置即可,非常方便,监听的IP商品也可以不写IP地址,只写端口,把它配置成“listen 80",则表示监听 该服务器所有IP的80端口,可通过 server_name区分不同的虚拟主机。

反向代理后客户端IP问题

由于在客户端和web服务器之间增加了蹭层,因此 web服务器无法直接拿到客户端的IP,通过 $remote_addr变量拿到的是反向代理服务器的ip地址,但是,反射代理服务器在转发请求的HTTP头信息中,可以增加X-Forwarded-For信息,用以记录原有的客户端IP地址和原来客户端请求的服务器地址

日志切割

#!/bin/bash
logs_path = "/data1/logs/"
mkdir -p ${logs_path}$(date -d "yesterday" + "%Y")/$(date -d "yesterday" + "%m")/
mv ${logs_path}access.log ${logs_path}$(date -d "yesterday" + "%Y")/$(date -d "yesterday" + "%m")/access_$(date -d "yesterday" + "%Y%m%d").log
kill -USR1 `cat /usr/local/nginx/nginx.pid`

配置crontab每天凌晨00:00定时执行这个脚本:
crontab -e

Nginx的压缩输出配置

gizp(GNU-ZIP)是一种压缩技术。经过gzip压缩后页面的大小可以变为原来的30%甚至更小。这样,用户浏览页面时候会快很多。gzip的压缩页面需要浏览器和服务器双方都支持,实际上就是服务器端压缩,浏览器端解压并解析。大多数浏览器都支持解析gzip过的页面。
配置在http{}段中:

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/palin application/x-javascript text/css application/xml;
gzip_vary on;

自动目录配置

前提:当前目录下不存在index指令设置的默认首页文件。

location / {
  autoindex on;
}
相关指令
#设定索引时文件大小的单位【B、KB、GB】
autoindex_exact_xize [on|off]
#开户本地时间来显示 文件时间的功能。默认为关(GMT时间)

Nginx的浏览器本地缓存设置(Browser Cacging)

浏览器缓存是为了加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示 文档,这样就可以加速页面的浏览。缓存 的方式节约了网络的资源,提高网络的效率。

fastcgi

FastCG是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能,众所周知,CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器保持在内存中并接受FastCGI进程 管理器调度,则可以提供良好的性能,伸缩性、Fail-Over特性等。

fastcgi 原理和优点

Paste_Image.png

mysql管理shell脚本

vi /data0/mysql/3306/mysql

#!/bin/sh
mysql_port=3306
mysql_username="admin"
mysql_password="123456"

function_start_mysql() {
      printf "starting mysql...\n"
      /bin/sh/usr/local/mysql/bin/mysqld_safe --defaults-file=/data0/mysql/${mysql_port}/my.cnf 2>&1>/dev/null &
}

function_stop_mysql() {
      printf "stoping mysql...\n"
      /usr/local/mysql/bin/mysqladmin -u ${mysql_username} -p ${mysql_password} -S /tmp/mysql.sock shutdown
}

function_restart_mysql(){
      printf "restarting mysql...\n"
      function_stop_mysql
      sleep 5
      function_start_mysql
}

function_kill_mysql(){
       kill -9 $(ps -ef | grep 'bin/mysqld_safe' | grep ${mysql_port} | awk '{printf $2}')
        kill -9 $(ps -ef | grep 'libexec/mysqld' | grep ${mysql_port} | awk '{printf $2}')
}

if [ "$1" = "start"]; then
      function_start_mysql
elif [ "$1" = "stop" ]; then
      function_stop_mysql
elif ["$1" = "restart" ]; then
      function_restart_mysql
elif [ "$1" = "kill" ]; then
       function_kill_mysql
else
       printf "Usage:/data0/mysql/${mysql_prot}/mysql {start|stop|restart|kill}\n"
fi

chmod +x /data0/mysql/3306/mysql

启动mysql:

/data0/mysql/3306/mysql start

/usr/local/mysql/bin/mysql -u -root -p -S /tmp/mysql.sock

创建一个具有root权限的用户和密码

GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'127.0.01' IDENTIFIED BY '123456';

为什么使用负载 均衡

随着网站 访问量的快速增长,单台服务器已经无法承担大量用户的并发访问,必须采用多台服务器协同工作,以提高计算机系统的处理能力和计算强度,满足当前业务量的需求。而如何 在完成同样功能的多个网络设备之间实现合理的业务量分配,使之不会出现一台设备过忙,而其它设备却没有充分使用的情况。要解决这一问题,可以采用负载 均衡的方法

负载均衡

负载均衡是由多台服务器以对称的方式组成 一个服务器集合,每台服务器具有等价的地位,都可以单独对提供服务而无须其他服务器的辅助。通过某种负载分担技术,将外部送来请求均匀分配到对称的某一台服务器上,而接收到请求的服务器独立 地回应客户的请求。均衡负载 能够平均分配 客户请求到服务器阵列,藉此快速获取重要数据,解决大量并发访问服务问题。这种集群技术可以用最少 的投资获得接近于大型主机的性能 。

反向代理

反向代理是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。


Paste_Image.png

负载均衡实现方式

  • 用户手动选择
  • DNS轮询方式(可靠性低,负载分配 不均衡)
Nginx反向代理负载均衡动静分离系统架构图

upstream 中的ip_hash

会使相同的用户访问后端同一个服务器
但是会影响负载均衡

如果后端有时候要从Nginx负载均衡(已使用ip_hash)中摘除一段时间,你必须将其标记为"down",而不是直接从配置文件中删掉或注释掉该后端服务器信息

upstream bakcend{
        ip_hash;
        server backend1.example.com;
        server backend2.example.com;
        server bakcend3.example.com down;
        server backend4.example.com;
}

rewrite规则的用处

通过Rewrite规则,可以实现规范的URL,根据变量来做URL转向及选择配置。例如,一些使用MVC框架的程序只有一个入口,可以通过 Rewrite来实现 ,一些动态URL地址需要伪装成静态HTML,全球搜索引擎攫取,也需要Rwrite来处理,一些由于目录结构、域名变化的旧URL需要跳转到新的URL上,也可以通过 Rwrite来处理

if 中的条件


if 中的条件

rewrite

该指令根据表达试来重定向URI,或者修改字符串,指令根据配置文件中的顺序来执行。重写表达式只对相对路径有效,如果你想配对主机名,需要使用if语句:

if ($host ~* www\.(.*)) {
  set $host_without_www $1;
  rewrite ^(.*)$ http://$host_without_www$1 permanent;
}

如果字符串以http://开头,将会采用301或302跳转进行URL重定向。

rewrite指命的flag

rewrite指命的flag

last 和break 标记的实现功能类似 ,但二者之间有细微的差别,使用alias指令时必须用last标记,使用proxy_pass指令时要使用break标记,lat标记在本条rewrite规则执行完毕后,终止匹配,不再匹配后面的规则。
一般在根location中(即location / {})或直接在server标签中编写rewrite规则,推荐使用last标记,在非根location中 (例如location /cms/ {}),则使用break标记。

如果被替换的URI中含有参数(妈类似/app/test.php?id=5之类的URI),默认情况下参数 会被自动加到替换串上,可以在末尾加上?来解决这个问题。如
rewrite ^/users/(.*)$ /show?user=$1? last;

对花括号来说,它们既能用在重定向的正规表达式里,也能用在配置文件里分割代码块,为了避免冲突,正则表达式里如果 带花括号,应该用双引号或单引号包围如:/photos/123456 => /path/to/photos/12/1234/123456.png

rewrite "/photos/([0-9]{2})([0-9]{2})([0-9]{2})" /path/to/photos/$1/$1$2/$1$2$3.png;

Nginx的Rwrite规则编写实例

if (!-e $request_filename) {
     rewrite ^/(.*)$ /index.php last;
}
多目录转成参数 abc.domain.com/sort/2 => abc.domain.com/index.php?act=sort&name=abc&id=2;

if ($host ~* (.*)\.domain\.com) {
    set $sub_name $1;
    rewrite ^/sort\/(\d)\/?$ /index.php?act=sort&name=$sub_name&id=$1 last;
}
目录对换/123456/xxxx => /xxxx?id=1234565:
rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;
如果 客户端 使用IE浏览器,则重定向到/nginx-ie目录下

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /nginx-ie/$1 break;
}

禁止访问多个目录:
location ~ ^/(cron|templates)/ {
      deny all;
      break;
}

禁止访问以/data/开头的文件:
location ~ ^/data {
        deny all;
}

设置某些类型文件的浏览器缓存时间:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
        expires 30d;
}
location ~ .*\.(js|css)$ {
        expires 1h;
}

将多级目录下的文件转换成一个文件/job-123-456-789.html 指向/job/123/456/789.html
rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$  /job/$1/$2/jobshow_$3.html last;

禁止访问以.sh、.flv、.mp4为文件后缀的URL地址:
location ~ .*\.(sh|flv|mp4)?$ {
        return 403;
}

适用于Zend Framework重写规则:
if ($request_uri ~* "^/pay(.*)") {
        set $var_pay_public '1';
}

if ($request_uri ~* "."\.(js|ico|gif|jpg|png|css)$") {
        set $var_pay_public '0';
}

if ($request_pay_public ~ '1') {
        rewirte ^(.*)$  /pay/index.php last;
}

Bo-blog开源PHP博客系统伪静态重写规则
if (! -x $request_filename) {
        rewrite ^/post/([0-9]+)/?([0-9+])/?([0-9]?/?$) /read.php/entryid=$1&page=$2&part=$3 last
rewrite ^/page/([0-9]+)/([0-9]+)?/?$ /index.php?mode=$1&page=$2 last;
rewrite ^/started/([0-9]+)/?([0-9]+)?/?$  /star.php?mode=$1&page=$2 last;
rewrite ^/category/([^/]+)/?([0-9]+)?/?([0-9]+)?/?$  /index.php?go=category_$1&mode=$2&page=$3 last
rewrite ^/archiver/([0-9]+)/([0-9]+)/?([0-9]+)?/?([0-9]+)?/?$  /index.php?go=archive&cm=$1&cy=$2&mode=$3&page=$4 last;
rewrite ^/date/([0-9]+)/([0-9]+)/([0-9]+)/?([0-9]+)?([0-9]+)?/?([0-9]+)?/?$  /index.php?go=showday_$1-$2-$3&mode=$4&page=$5 last;
rewrite ^/user/([0-9]+)/?$ /view.php?go=user_$1 last;
rewrite ^/tags/([^/]+)/?([0-9]+)?/?([0-9]+)?/?$  /tag.php?tag=$1&mode=$2&page=$3 last;
rewrite ^/compnent/id/([0-9]+)/?$  /page.php?pageid=$1 last;
rewrite ^/component/([^/]+)/?$  /page.php?pagealias=$1 last;
rewrite  ^/read\.php/([0-9]+)/([0-9]+)\.htm$  http://$host/post/$1/ permanent;
rewrite  ^/post/([0-9]+)\_([0-9]+)\.htm$  http://$host/post/$1/$2/ permanent;
rewrite  ^/post/([0-9]+)\_([0-9]+)\_([0-9])\.htm$  http://$host/post/$1/$2/$3/ permanent;
rewrite  ^/index\_([0-9]+)\_([0-9]+)\.htm$  http://$host/page/$1/$2/ permanent;
rewrite ^/star\_([0-9]+)\_([0-9]+)\.htm$  http://$host/starred/$1/$2/ permanent;
rewrite  ^/category\_([0-9]+)\.htm$  http://$host/category/$1/  permanent;
rewrite ^/category\_([0-9]+)\_([0-9]+)\.htm$  http://$host/category/$1/$2/$3/   permanent;
rewrite  ^archive\_([0-9]+)\_([0-9]+)\.htm$  http://$host/archiver/$1/$2/ permanent;
rewrite  ^/archive\_([0-9]+)\_([0-9]+)\_([0-9]+)\_([0-9]+)\.htm$  http://$host/archiver/$1/$2/$3/$4/ permanent;
rewrite  ^/showday\_([0-9]+)\_([0-9]+)\_([0-9]+)\.htm$   http://$host/date/$1/$2/$3/ permanent;
rewrite ^/showday\_([0-9]+)\_([0-9]+)\_([0-9]+)\_([0-9]+)\_([0-9])\.htm  http://$host/date/$1/$2/$3/$4/$5 permanent;
}
rewrite ^/([a-zA-Z0-9_-]+)/?([0-9]+)?/?$  /read.php?biogalias=$1&page=$2&part=$3 last;

根据referer信息防盗链

location ~* \.(gif|jpg|jpeg|png|swf|flv)$ {
        valid_referers none blocked www.youdomain.com *.youdomain.com;
        if ($invalid_referer) {
               rewrite ^/(.*)  http://www.yourdomain.com/blocked.html;
         }
}

Nginx与Apache的Rewrite规则

Apache:

RewriteRule ^/(mianshi|xianjing)/$  /z1/index.php?name=$1 [L]

Apache的RewriteRule指令换成Ngnix的rewrite指令,Apache的[L]标记换成 Nginx的last标记,中间的内容不变。

Nginx与apache的各种区别

区别详解

nginx模块

要编写一个Nginx模块,你要熟悉Nginx的配置文件。Nginx配置文件主要分成4部分:main(全局配置)、server(虚拟主机配置)、upstream(主要为反向代理、负载均衡相关配置)和location(目录匹配配置),每部分包含若干个指令。main部分的指令将影响其他所有部分;server部分的指令主要用于指定虚拟主机域名、IP端口;upstream的指令用于设置反向代理及后端服务器的负载均衡;location部分用于匹配网页位置(例如,根目录“/"、"/images",等等)。location部分会继承server部分的指令,而server会继承main部分的指令:upstream既不会继承指令也不会影响其他 部分。它有自己的特殊指令,不需要在其他地方应用。

Nginx的模块不能够像Apache那样动态添加,所有的模块要预先编译进Nginx二进制可执行文件中。

Nginx模块的三种角色

  • Handlers(处理模块) 用于处理HTTP请求并输出内容
  • Filters(过滤模块) 用于过滤Handler输出的内容
  • Load-balancers (负载均衡模块)当有多于一台的后端服务器供选择时,选择一台后端服务器并将HTTP请求转发到该服务器。

Nginx模块的处理流程

客户端改善HTTP请求到Nginx服务器->Nginx基于配置文件中的位置选择一个合适的处理模块->负载均衡模块选择一台后端服务器(反向代理情况下)->处理模块进行处理并把输出缓冲放到第一个过滤模块上->第一个过滤模块处理后输出 给第二个过滤模块->第n个过滤模块->最后把处理结果发送给客户端 。


模块相当于钩子
web编程之路