Nginx-基础总结(上)

2022-12-28 20:27:58 浏览数 (1)

常规配置模板

代码语言:javascript复制
#user  www www;
worker_processes auto;
error_log  /home/wwwlogs/nginx_error.log crit;
#pid        /usr/local/nginx/nginx.pid;
#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 655350;
events
  {
    use epoll;
    worker_connections 655350;
  }
http
  {
    include       mime.types;
    default_type  application/octet-stream;
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 50m;
    server_tokens off;
    sendfile on;
    tcp_nopush     on;
    tcp_nodelay on;
    keepalive_timeout 60;
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 256k;
    proxy_connect_timeout 600;
    proxy_read_timeout 600;
    proxy_send_timeout 600;
    proxy_buffer_size 64k;
    proxy_buffers   4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    gzip on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_types    text/plain application/x-javascript text/css application/xml text/xml application/json;
    gzip_vary on;
    log_format  access '$remote_addr - $remote_user [$time_local] $host '
                                   '"$request" $status $body_bytes_sent $request_time '
                                   '"$http_referer" "$http_user_agent" "$http_x_forwarded_for"'
                                   '$upstream_addr $upstream_status $upstream_response_time' ;
 #设置Web缓存区名称为cache_one,内存缓存空间大小为256MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。
    proxy_temp_path   /home/proxy_temp_dir;
    proxy_cache_path  /home/proxy_cache_path levels=1:2 keys_zone=cache_one:256m inactive=1d max_size=30g;
        server {
            listen 80;
            server_name  _;
            return 403;
        }
        include vhost/*.conf;
}
以“exmaple.org”为例,如下为基于 upstream 负载均衡模式的配置:
代码语言:javascript复制
upstream example_backend {
        server   127.0.0.1:9080;
        server   192.168.1.198:9080;
        server 172.16.0.4:80 weight=5 max_fails=3 fail_timeout=10s; # 权重、健康监测
        server 172.16.0.5:8080 backup; # 备份节点,
        ip_hash;  #调度算法
 }
server {
        listen 80;
        server_name www.example.org example.com .example.org;
    location / {
# 如果后端服务器出现502 或504错误代码的话nginx就不会请求某台服务器了,当后端服务器又工作正常了,nginx继续请求,这样一来达到了后端服务器健康状况检测的功能,
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
        proxy_pass http://example_backend;
        proxy_http_version 1.1;
        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   600;
        proxy_read_timeout  600;
        proxy_send_timeout  600;
        proxy_buffer_size   8k;
        proxy_temp_file_write_size  64k;
        # nginx本地cache开启
        proxy_cache cache_one;
        proxy_cache_valid 200 304 30d;
        proxy_cache_valid 301 302 404 1m;
        proxy_cache_valid any 1m;
        proxy_cache_key $host$request_uri;
        # 客户端缓存,在header中增加“Expires”
        expires 30d;
        add_header Cache-Control public;
        add_header X-Proxy-Cache $upstream_cache_status;
        proxy_set_header If-Modified-Since $http_if_modified_since;
        if_modified_since before;
    }
    location ~ .*.(gif|jpg|jpeg|png|bmp|ico|swf|xml|css|js)$ {
        proxy_pass      http://example_backend;
        proxy_set_header        Host    $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        expires 15d;
    }
    location ~ .*.(jhtml)$ {
        proxy_pass      http://example_backend;
        proxy_set_header        Host    $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        expires -1;
    }
    access_log  logs/www.example.org.log;
}
其他的 proxy 配置:

1.proxy_set_header :在将客户端请求发送给后端服务器之前,更改来自客户端的请求头信息。 2.proxy_connect_timeout:配置Nginx与后端代理服务器尝试建立连接的超时时间。 3.proxy_read_timeout : 配置Nginx向后端服务器组发出read请求后,等待相应的超时时间。 4.proxy_send_timeout:配置Nginx向后端服务器组发出write请求后,等待相应的超时时间。 5.proxy_redirect :用于修改后端服务器返回的响应头中的Location和Refresh。

用户认证
代码语言:javascript复制
# htpasswd -bc /usr/local/nginx/auth/passwd admin 123456
vim /usr/local/nginx/conf/vhost/www.conf
server {
        listen   80;
        server_name www.com;
        index  index.html index.htm;
        root /www;
location / {
         auth_basic "test";
         auth_basic_user_file /usr/local/nginx/auth/passwd;
}
#service nginx restart

解决跨域

代码语言:javascript复制
# 提示: add_header 也可以添加到 server 中,这样当前 server 下都允许跨域
server
{
    listen 3002;
    server_name localhost;
    location /ok {
        proxy_pass http://localhost:3000;
        #   指定允许跨域的方法,*代表所有
        add_header Access-Control-Allow-Methods *;
        #   预检命令的缓存,如果不缓存每次会发送两次请求
        add_header Access-Control-Max-Age 3600;
        #   带cookie请求需要加上这个字段,并设置为true
        add_header Access-Control-Allow-Credentials true;
        #   表示允许这个域跨域调用(客户端发送请求的域名和端口)
        #   $http_origin动态获取请求客户端请求的域   不用*的原因是带cookie的请求不支持*号
        add_header Access-Control-Allow-Origin $http_origin;
        #   表示请求头的字段 动态获取
        add_header Access-Control-Allow-Headers $http_access_control_request_headers;
        #   OPTIONS预检命令,预检命令通过时才发送请求
        #   检查请求的类型是不是预检命令
        if ($request_method = OPTIONS){
            return 200;
        }
    }
}

URL 重写 比如说访问某站点的路径为/forum/ , 此时想使用/bbs 来访问此站点需要做 url 重写如下

代码语言:javascript复制
location / {
  rewrite ^/forum/?$ /bbs/ permanent;
}
比如说某站点有个图片服务器(10.0.0.1/p_w_picpaths/ ) 此时访问某站点上/p_w_picpaths/的资源时希望访问到图片服务器上的资源

location / {
  rewrite ^/p_w_picpaths/(.*.jpg)$  /p_w_picpaths2/$1 break;
}

域名跳转

代码语言:javascript复制
server {
    listen 80;
    server_name www.com;
    rewrite ^/ http://www.www.com/;
    # return 301 http://www.andy.com/;
}

域名镜像

代码语言:javascript复制
server {
    listen 80;
    server_name  www.com;
    rewrite ^/(.*)$ http://www.www.com/$1 last;
}

判断表达式

-f 和 !-f 用来判断是否存在文件

-d 和 !-d 用来判断是否存在目录

-e 和 !-e 用来判断是否存在文件或目录

-x 和 !-x 用来判断文件是否可执行

防盗链

代码语言:javascript复制
location ~* .(gif|jpg|png|swf|flv)$ {
  valid_referers none blocked www.com;
  if ($invalid_referer) {
    rewrite ^/ http://www.com/403.html;
  }

会话保持

代码语言:javascript复制
# ip_hash使用源地址哈希算法,将同一客户端的请求只发往同一个后端服务器(除非该服务器不可用)。
# 问题: 当后端服务器宕机后,session会话丢失;同一客户端会被转发到同一个后端服务器,可能导致负载失衡;
upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
}
sticky_cookie_insert

# 使用sticky_cookie_insert 启用会话亲缘关系,会导致来自同一客户端的请求被传递到一组服务器的同一台服务器。与ip_hash不同之处在于,它不是基于IP来判断客户端的,而是基于cookie来判断。因此可以避免上述ip_hash中来自同一客户端导致负载失衡的情况(需要引入第三方模块才能实现)。
upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    sticky_cookie_insert srv_id expires=1h domain=3evip.cn path=/;
}
server {
    listen 80;
    server_name 3evip.cn;
    location / {
      proxy_pass http://backend;
    }
}

expires:设置浏览器中保持 cookie 的时间 domain:定义 cookie 的域 path:为 cookie 定义路径

日志切割 示列一

代码语言:javascript复制
#!/bin/bash
# 适合单个网站日志文件
LOGS_PATH=/home/wwwroot/yunwei/logs
yesterday=`date   "%F" -d  "-1 days"`
mv ${LOGS_PATH}/yunwei.log  ${LOGS_PATH}/yunwei-${yesterday}.log
kill -USR1 $(cat /var/logs/nginx.pid)

示列二

代码语言:javascript复制
#nginx日志切割
# Nginx pid
NGINX_PID=$(cat /var/logs/nginx.pid)
# 多个日志文件
LOGS=(xxx.access.log xxx.access.log)
# Nginx日志路径目录
BASH_PATH="/www/wwwlogs"
# xxxx年xx月
lOG_PATH=$(date -d yesterday  "%Y%m")
# 昨天日期
DAY=$(date -d yesterday  "%d")
# 循环移动
for log in ${LOGS[@]}
do
  # 先判断日志目录是否存在
    [[ ! -d "${BASH_PATH}/${lOG_PATH}" ]] && mkdir -p ${BASH_PATH}/${lOG_PATH}
    # 进入日志目录
    cd ${BASH_PATH}
    mv ${log} ${lOG_PATH}/${DAY}-${log}
    #kill -USR1 `ps axu | grep "nginx: master process" | grep -v grep | awk '{print $2}'`
    kill -USR1 ${NGINX_PID}
    # 删除30天的备份,最好是移动到其他位置,不建议 rm -fr
    #find ${BASH_PATH}/${lOG_PATH} -mtime  30 -name "." -exec rm -fr {} ;
done

示列三

代码语言:javascript复制
#!/bin/bash
#set the path to nginx log files
log_files_path="/usr/local/nginx/logs/"
log_files_dir=${log_files_path}$(date -d "yesterday"  "%Y")/$(date -d "yesterday"  "%m")
#set nginx log files you want to cut
log_files_name=(gw20 gw20-json)
#set the path to nginx.
nginx_sbin="/usr/bin/nginx"
#Set how long you want to save
save_days=10
############################################
#Please do not modify the following script #
############################################
mkdir -p $log_files_dir
log_files_num=${#log_files_name[@]}
#cut nginx log files
for((i=0;i<$log_files_num;i  ));do
mv ${log_files_path}${log_files_name[i]}.log ${log_files_dir}/${log_files_name[i]}_$(date -d "yesterday"  "%Y%m%d").log
done
#delete 30 days ago nginx log files
find $log_files_path -mtime  $save_days -exec rm -rf {} ;
$nginx_sbin -s reload

示列四

代码语言:javascript复制
server{
    if ($time_iso8601 ~ '(d{4}-d{2}-d{2})') {
        set $day $1;
    }
  access_log  /www/wwwlogs/xxx.com-$day.log main;
  error_log  /www/wwwlogs/xxx.com.error.log;
}
动静分离

为加快网站解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。 在动静分离的 tomcat 的时候比较明显,因为 tomcat 解析静态很慢,简单来说,是使用正则表达式匹配过滤,交给不同的服务器。 1、准备环境

代码语言:javascript复制
192.168.62.159 代理服务器
192.168.62.157 动态资源
192.168.62.155 静态资源

2、配置 nginx 反向代理 upstream

代码语言:javascript复制
[root@nginx-server conf.d]# cat upstream.conf
upstream static {
    server 192.168.62.155:80 weight=1 max_fails=1 fail_timeout=60s;
}
upstream phpserver {
    server 192.168.62.157:80 weight=1 max_fails=1 fail_timeout=60s;
}
server {
   listen      80;
   server_name     localhost;
   #动态资源加载
   location ~ .(php|jsp)$ {
       proxy_pass http://phpserver;
       proxy_set_header Host $host:$server_port;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
   #静态资源加载
   location ~ .*.(html|gif|jpg|png|bmp|swf|css|js)$ {
       proxy_pass http://static;
       proxy_set_header Host $host:$server_port;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

3、192.168.62.155 静态资源

代码语言:javascript复制
#静态资源配置
server {
    listen 80;
    server_name     localhost;
    location ~ .(html|jpg|png|js|css|gif|bmp|jpeg) {
        root /home/www/nginx;
        index index.html index.htm;
    }
}

4、192.168.62.157 动态资源

代码语言:javascript复制
server {
    listen      80;
    server_name     localhost;
    location ~ .php$ {
        root           /home/nginx/html;  #指定网站目录
        fastcgi_pass   127.0.0.1:9000;    #指定访问地址
        fastcgi_index  index.php;       #指定默认文件
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name; #站点根目录,取决于root配置项
        include        fastcgi_params;  #包含nginx常量定义
    }
}

location 优先级

代码语言:javascript复制
当有多条 location 规则时,nginx 有一套比较复杂的规则,优先级如下:
`精确匹配=
`前缀匹配^~(立刻停止后续的正则搜索)
`按文件中顺序的正则匹配~或~*
`匹配不带任何修饰的前缀匹配。
这个规则大体的思路是
`先精确匹配,没有则查找带有^~的前缀匹配,没有则进行正则匹配,最后才返回前缀匹配的结果(如果有的话)
HTTPS 使用自颁发证书实现

建立存放https证书的目录

代码语言:javascript复制
mkdir -pv /usr/local/nginx/conf/.sslkey

生成网站私钥文件

代码语言:javascript复制
cd /usr/local/nginx/conf/.sslkey
openssl genrsa -out https.key 1024

生存网站证书文件,需要注意的是在生成的过程中需要输入一些信息根据自己的需要输入,但Common Name 项输入的必须是访问网站的FQDN

代码语言:javascript复制
openssl req -new -x509 -key https.key -out https.crt

为了安全起见,将存放证书的目录权限设置为400

代码语言:javascript复制
chmod -R 400 /usr/local/nginx/conf/.sslkey

vim /usr/local/nginx/conf/vhost/www.conf
server {
        listen   443;
        server_name www.com;
        index  index.html index.htm;
        root /www;
        ssl                 on;
        ssl_protocols       SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
        ssl_certificate     /usr/local/nginx/conf/.sslkey/https.crt;
        ssl_certificate_key /usr/local/nginx/conf/.sslkey/https.key;
        ssl_session_cache   shared:SSL:10m;
        ssl_session_timeout 10m;
}
#重新启动nginx服务
service nginx restar
基于 HTTPS 配置核心配置
upstream example_backend {
    server   127.0.0.1:9080;
    server   192.168.1.198:9080;
 }
server {
        listen 80;
        server_name www.example.org example.org;
        rewrite ^/(.*)$  https://$host/$1 last;
 }
server {
    listen 443;
    server_name www.example.org example.org;
    ssl on;
    ssl_certificate      /usr/local/nginx/conf/ssl/example.crt;
    ssl_certificate_key  /usr/local/nginx/conf/ssl/example.key;
    ssl_session_timeout  5m;
    ssl_protocols  SSLv3 TLSv1 TLSv1.2 TLSv1.1;
    ssl_ciphers HIGH:!aNULL:!MD5:!EXPORT56:!EXP;
    ssl_prefer_server_ciphers   on;
    location / {
        ...
    }
}

根据页面不存在则自定义跳转

代码语言:javascript复制
if (!-f $request_filename) {
      rewrite ^(/.*)$ http://www.com permanent;
}

根据文件类型设置过期时间

代码语言:javascript复制
location ~* .(js|css|jpg|jpeg|gif|png|swf)$ {
    if (-f $request_filename) {
        expires 1h;
        break;
    }
}

0 人点赞