十分钟了解Nginx

nginx 入门、安装、命令、配置、优化

操作系统:CentOS 7
Nginx版本:yum安装1.12.2 、编译安装1.14.2

一、安装

1. yum安装

安装源

[root@localhost ~]# yum list nginx
[root@localhost ~]# rm -rf /etc/yum.repos.d/*
[root@localhost ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
[root@localhost ~]# curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@localhost ~]# yum clean all && yum makecache

启动一个Nginx

[root@localhost ~]# yum install -y nginx
[root@localhost ~]# nginx
[root@localhost ~]# curl localhost

yum安装Nginx的目录结构

[root@localhost ~]# find / -name nginx
/etc/logrotate.d/nginx #滚动日志
/etc/nginx #配置文件
/usr/lib64/perl5/vendor_perl/auto/nginx #http-perl
/usr/lib64/nginx #molules
/usr/sbin/nginx #bin文件
/usr/share/nginx #html/molules
/var/lib/nginx #tmp
/var/log/nginx #log
[root@localhost ~]# yum remove -y nginx
[root@localhost ~]# find / -name nginx

2. 编译安装

准备环境依赖

[root@localhost ~]# rm -rf /etc/yum.repos.d/*
[root@localhost ~]# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
[root@localhost ~]# curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@localhost ~]# yum install -y gcc gcc-c++ make pcre-devel zlib-devel

编译安装Nginx

[root@localhost ~]# curl -o nginx-1.14.2.tar.gz http://nginx.org/download/nginx-1.14.2.tar.gz
[root@localhost ~]# tar -xf nginx-1.14.2.tar.gz
[root@localhost ~]# cd nginx-1.14.2
[root@localhost nginx-1.14.2]# ./configure
[root@localhost nginx-1.14.2]# make && make install
[root@localhost nginx-1.14.2]# find / -name nginx
/root/nginx-1.14.2/objs/nginx #编译文件
/usr/local/nginx #安装目录
/usr/local/nginx/sbin/nginx #bin文件

启动一个Nginx

[root@localhost sbin]# ./nginx
[root@localhost sbin]# curl localhost

3. 编译安装进阶

3.1. 指定编译参数

[root@localhost nginx-1.14.2]# ./configure --prefix=$PWD/nginx

3.2. 安装官方模块

[root@localhost nginx-1.14.2]# ./configure --prefix=$PWD/nginx --with-stream

3.3. 安装自定义模块
3.3.1 编写Nginx自定义模块

[root@localhost nginx-1.14.2]# mkdir -p modules/ngx_http_hello_world_module
[root@localhost nginx-1.14.2]# cd modules/ngx_http_hello_world_module
[root@localhost ngx_http_hello_world_module]# touch ngx_http_hello_world_module.c config

ngx_http_hello_world_module.c

#include "ngx_core.h"
#include "ngx_string.h"
#include "ngx_buf.h"
#include "ngx_module.h"
#include "ngx_conf_file.h"
#include "ngx_http.h"
#include "ngx_http_request.h"
#include "ngx_http_config.h"
#include "ngx_http_core_module.h"
static ngx_int_t ngx_http_hello_world_handler(ngx_http_request_t *r)
{
    if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD)))
        return NGX_HTTP_NOT_ALLOWED;
    ngx_int_t rc = ngx_http_discard_request_body(r);
    if (rc != NGX_OK)
        return rc;
    ngx_str_t type = ngx_string("text/plain");
    ngx_str_t response = ngx_string("Hello World!\n");
    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = response.len;
    r->headers_out.content_type = type;
    rc = ngx_http_send_header(r);
    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only)
        return rc;
    ngx_buf_t *b;
    b = ngx_create_temp_buf(r->pool, response.len);
    if (b == NULL)
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    ngx_memcpy(b->pos, response.data, response.len);
    b->last = b->pos + response.len;
    b->last_buf = 1;
    ngx_chain_t out;
    out.buf = b;
    out.next = NULL;
    return ngx_http_output_filter(r, &out);
}
static char *ngx_http_hello_world(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_core_loc_conf_t *clcf;
    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
    clcf->handler = ngx_http_hello_world_handler;
    return NGX_CONF_OK;
}
static ngx_command_t ngx_http_hello_world_commands[] = {
    {ngx_string("hello_world"), NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF |
        NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, ngx_http_hello_world, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL},
    ngx_null_command
};
static ngx_http_module_t ngx_http_hello_world_module_ctx = {
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
ngx_module_t ngx_http_hello_world_module = {
    NGX_MODULE_V1,
    &ngx_http_hello_world_module_ctx,
    ngx_http_hello_world_commands,
    NGX_HTTP_MODULE,
    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    NGX_MODULE_V1_PADDING
};

config

ngx_addon_name=ngx_http_hello_world_module
HTTP_MODULES="$HTTP_MODULES ngx_http_hello_world_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_world_module.c"

3.3.2 编译自定义模块

[root@localhost nginx-1.14.2]# ./configure --prefix=$PWD/nginx --with-stream --add-module=modules/ngx_http_hello_world_module
[root@localhost nginx-1.14.2]# make && make install
[root@localhost nginx-1.14.2]# vim nginx/conf/nginx.conf
server {
    listen       80;
    server_name  localhost;
    #charset koi8-r;
    #access_log  logs/host.access.log  main;
    location / {
        # root   html;
        # index  index.html index.htm;
        hello_world;
    }
}

3.3.3 启动nginx,测试hello world

[root@localhost nginx-1.14.2]# nginx/sbin/nginx 
[root@localhost nginx-1.14.2]# curl localhost
Hello World!

3.3.4 Nginx开发
​ Tengine http://tengine.taobao.org/
​ Openresty http://openresty.org/cn/

二、Nginx命令

[root@localhost ~]# nginx -h 
nginx version: nginx/1.14.2
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -T            : test configuration, dump it and exit
  -q            : suppress non-error messages during configuration testing
  -s signal     : send signal to a master process: stop, quit, reopen, reload
  -p prefix     : set prefix path (default: /root/nginx-1.14.2/nginx/)
  -c filename   : set configuration file (default: conf/nginx.conf)
  -g directives : set global directives out of configuration file
[root@localhost ~]# nginx -v
nginx version: nginx/1.14.2
[root@localhost ~]# nginx -V
nginx version: nginx/1.14.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) 
configure arguments: --prefix=/root/nginx-1.14.2/nginx --with-stream --add-module=modules/ngx_http_hello_world_module
[root@localhost ~]# nginx -t
nginx: the configuration file /root/nginx-1.14.2/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /root/nginx-1.14.2/nginx/conf/nginx.conf test is successful
[root@localhost ~]# nginx -s quit
[root@localhost ~]# nginx -c /etc/nginx-2.conf
[root@localhost ~]# nginx -g 'worker_processes 4;'

三、Nginx配置文件

#user  nobody; #worker用户
worker_processes  1; #worker进程数,cat /proc/cpuinfo | grep "processor" | wc -l
#error_log  logs/error.log; #错误日志路径
#error_log  logs/error.log  notice; #错误日志路径notice级别
#error_log  logs/error.log  info; #错误日志路径info级别
#pid        logs/nginx.pid; #pid路径
events { #events块
    worker_connections  1024; #每个worker最大开启连接数,ulimit -n
}
http { #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"';
    # main级别日志输出格式
    #access_log  logs/access.log  main; #访问日志main级别
    sendfile        on; #开启sendfile,作为静态服务器时性能显著提高
    #tcp_nopush     on; #包攒到一定大小再发送,开启sendfile时生效
    #keepalive_timeout  0;
    keepalive_timeout  65; #连接超时(秒)
    #gzip  on; #开启压缩
    server { #server段
        listen       80; #监听80端口
        server_name  localhost; #绑定localhost
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / { #匹配uri
            root   html; #设置root目录
            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;
        }
    }
}

main/events块指令集 http://nginx.org/en/docs/ngx_core_module.html
http块指令集 http://nginx.org/en/docs/http/ngx_http_core_module.html

四、基本用例

1. 静态资源服务器

直接启动Nginx就是个静态资源服务器。
alias和root的区别

location /foo {
    root /a/b;
}
# 当请求的uri为/foo/c.html时,实际请求的文件路径是/a/b/foo/c.html
location /bar {
    alias /x/y;
}
# 当请求的uri为/bar/z.html时,实际请求的文件路径是/x/y/z.html
# alias对末尾的/敏感,alias末尾与uri末尾保持一致

rewrite的用法

location /foo {
    rewrite /foo/(.*) /bar/$1 break;
    root /a/b;
}
# 当请求的uri为/foo/c.html时,将请求改写为/bar/c.html,实际请求的文件路径是/a/b/bar/c.html
location /foo {
    rewrite /foo/(.*) /bar/$1 last;
    root /a/b;
}
# 当请求的uri为/foo/c.html时,将请求改写为/bar/c.html,重新寻找location块匹配,实际请求的文件路径是/x/y/c.html
location /foo {
    rewrite /foo/(.*) /bar/$1 permanent;
}
# 当请求的uri为/foo/c.html时,将请求改写为/bar/c.html,直接返回301跳
location /foo {
    rewrite /foo/(.*) /bar/$1 redirect;
}
# 当请求的uri为/foo/c.html时,将请求改写为/bar/c.html,直接返回302跳

break/last是同一个连接的内部处理过程,permanent/redirect是两次连接;
break不再执行location匹配,last执行多次location匹配,通常在server中使用last,在location中使用break;
301跳会缓存,302跳不会;

2. 简单文件服务器

server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  _;
    root         /usr/share/nginx/html;
    include /etc/nginx/default.d/*.conf;
    location / {
        autoindex on;
    }
    error_page 404 /404.html;
        location = /40x.html {
    }
    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}

当路径下存在index.html index.htm 时autoindex不生效

3.代理服务器

3.1正向代理

正向代理:代理客户端称为正向代理,如爬虫使用的代理服务器。基本是固定写法。

server {  
    resolver 8.8.8.8;
    listen 8888;
    location / {
        proxy_pass http://$http_host$request_uri;
        proxy_set_header HOST $http_host;
    }
}

3.2 反向代理

正向代理:代理服务端称为反向代理,如通过代理java隐藏端口。基本是固定写法。

server {
    listen       80;
    server_name  _;
    location =/index.html {
        return 200 "index\n";
    }
}
server {
    listen       81;
    server_name  _;
    location /proxy {
        proxy_pass http://localhost/;
    }
}

如果不想改变原地址中的uri,proxy_pass中就不要写uri!

4.负载均衡

利用一定的策略将网络负载分摊到网络集群的各个服务上,从而减轻服务器负载并提高用户体验。

server {
    listen       80 default_server;
    server_name  _;
    location / {
        proxy_pass http://balance;
    }
}
upstream balance {
    server localhost:81;
    server localhost:82;
}
server {
    listen       81;
    server_name  _;
    location / {
        return 200 "1\n";
    }
}
server {
    listen       82;
    server_name  _;
    location / {
        return 200 "2\n";
    }
}

Nginx负载均衡策略:round robin、weight、ip_hash、least_conn、fair(3)、url_hash(3)

5.TCP/UDP代理

TCP/UDP协议的反向代理。

stream{
    upstream mysql{
        server localhost:3306;
    }
    server{
        listen 3307;
        proxy_pass mysql;
    }
}

需要stream模块支持

五、深度优化

1、安全优化

1.1 隐藏Nginx软件名和版本号

[root@localhost /]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Tue, 23 Apr 2019 06:23:27 GMT
Content-Type: application/octet-stream
Content-Length: 2
Connection: keep-alive
  • 方案1:修改nginx.conf添加
server_tokens off;
  • 方案2:修改$NGINX_HOME/src/core/nginx.h(不推荐
#define NGINX_VERSION      "1.14.2"
#define NGINX_VER          "nginx/" NGINX_VERSION
// 随意修改以上两个字段(注意这是C代码,#不是注释的意思)
#define NGINX_VERSION      "7.5.1"
#define NGINX_VER          "IIS/" NGINX_VERSION
  • 方案3:修改$NGINX_HOME/src/core/nginx.h
static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
// 随意修改以上两个字段
static u_char ngx_http_server_string[] = "Server: IIS" CRLF;
static u_char ngx_http_server_full_string[] = "Server: " "IIS/7.5.1" CRLF;
  • 隐藏40x、50x页面的软件名版本号:修改nginx.conf添加
error_page 400 401 402 403 404 405 415 /40x.html;
location = /40x.html {
    return 200 "not found.";
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
    return 200 "error.";
}

1.2 非法域名解析

server {
    listen 80 default_server;
    server_name _;
    rewrite ^(.*) http//:www.example.com/$1 permanent;
}

1.3 黑白名单

location / {
   allow 127.0.0.1;
   deny 192.168.1.1;
}

1.4 DDOS攻击

# 访问频率限制
limit_req_zone $binary_remote_addr zone=perip:100m rate=1r/s;
server {  
    limit_req zone=perip burst=5 nodelay;
}

2、性能优化

2.1 优化进程和连接数

worker_processes    4; #auto=逻辑核数,高io的可以再调大;如果服务器有其他负载按需设置;
worker_cpu_affinity 0001 0010 0100 1000; #cpu亲和性,指定每个线程运行在哪个核上;
events {
    use epoll;  #显式指定采用epoll,如果不知道是什么请让Nginx自己决定最优方案;
    worker_connections  1024;#每个进程最大可打开连接数受制于ulimit -n;
}

2.2 高效文件传输

# 设置传输参数
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
server_names_hash_bucket_size 128;
server_names_hash_max_size 512;
keepalive_timeout 65;
client_header_timeout 15s;
client_body_timeout 15s;
send_timeout 60s;
# 设置压缩参数
gzip on;
gzip_disable "msie6";
gzip_min_length 1k;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 3;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png;
# 为静态资源设置合理的过期时间
expires    -1;

你可能感兴趣的:(十分钟了解Nginx)