nginx-notes

nginx 可以用于 反向代理、负载均衡、缓存加速、解决跨域 等场景。
详细描述见 官网 http://nginx.org/en/

(1) 下载安装

下载地址 http://nginx.org/en/download.html

(1.1) nginx依赖环境

nginx依赖以下模块:
gzip模块需要 zlib 库 及其开发环境
rewrite模块需要 pcre 库及开发环境
ssl 功能需要openssl库及开发环境以及 yum install -y gcc-c++ 环境。

(1.2) nginx安装环境检查

ZBMAC-C02PGMT0F:nginx-1.18.0 weikeqin1$ ./configure
ZBMAC-C02PGMT0F:nginx-1.18.0 weikeqin1$ make
ZBMAC-C02PGMT0F:nginx-1.18.0 weikeqin1$ make install

./configure 是用来检查安装环境。在configure阶段结束以后,将会出现如下信息:

ZBMAC-C02PGMT0F:nginx-1.18.0 weikeqin1$ ./configure --prefix=/usr/local  --with-openssl=/usr/bin/openssl
checking for OS
 + Darwin 17.7.0 x86_64
checking for C compiler ... found
 + using Clang C compiler
 + clang version: 10.0.0 (clang-1000.10.44.4)
checking for -Wl,-E switch ... not found
checking for gcc builtin atomic operations ... found

...

checking for PCRE library ... found
checking for PCRE JIT support ... found
checking for zlib library ... found
creating objs/Makefile

Configuration summary
  + using system PCRE library
  + using OpenSSL library: /usr/bin/openssl
  + using system zlib library

  nginx path prefix: "/usr/local"
  nginx binary file: "/usr/local/sbin/nginx"
  nginx modules path: "/usr/local/modules"
  nginx configuration prefix: "/usr/local/conf"
  nginx configuration file: "/usr/local/conf/nginx.conf"
  nginx pid file: "/usr/local/logs/nginx.pid"
  nginx error log file: "/usr/local/logs/error.log"
  nginx http access log file: "/usr/local/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

ZBMAC-C02PGMT0F:nginx-1.18.0 weikeqin1$

(1.3) nginx.conf配置文件检查

sudo /usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf

出现以下日志说明配置ok

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

(1.4) 启动

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ZBMAC-C02PGMT0F:~ weikeqin1$ /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.18.0

访问 http://127.0.0.1:8080/ 就可以看到nginx的页面

或者通过 ps -ef | grep nginx 查看nginx是否成功启动

[admin@localhost nginx]$ ps -ef | grep nginx
root          1      0  0 18:23 ?        00:00:00 /bin/sh -c /usr/sbin/sshd && /usr/sbin/crond && bash /home/admin/start_container.sh 1 jdos_data-nginx 1030527 && sleep 9999999d
root        948      1  0 18:31 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
admin       949    948  0 18:31 ?        00:00:00 nginx: worker process
admin       950    948  0 18:31 ?        00:00:00 nginx: worker process
admin      1051    743  0 18:34 pts/0    00:00:00 grep nginx
[admin@localhost nginx]$

(1.5) nginx重启

Command-line parameters http://nginx.org/en/docs/switches.html

# 重新加载配置 新启动一个worker处理
# reload configuration, start the new worker process with a new configuration, gracefully shut down old worker processes. 
/usr/local/nginx/sbin/nginx -s reload   

(2) 不同场景nginx配置


#user  nobody;
worker_processes  2;

error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        logs/nginx.pid;

worker_rlimit_nofile  65535;


events {
    use epoll;
    worker_connections  1024;
}


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

    #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  logs/access.log  main;

                                                       '"$gzip_ratio"';
    #charset                        utf-8;
    server_names_hash_bucket_size   128;
    client_header_buffer_size       32k;
    large_client_header_buffers     4 32k;
    client_max_body_size            300m;
    sendfile                        on;
    tcp_nopush                      on;
    keepalive_timeout               0;
    tcp_nodelay                     on;
    client_body_buffer_size         512k;
    fastcgi_intercept_errors        on;
    proxy_connect_timeout           90;
    proxy_read_timeout              180;
    proxy_send_timeout              180;
    proxy_buffer_size               256k;
    proxy_buffers                   4 256k;
    proxy_busy_buffers_size         256k;
    proxy_temp_file_write_size      256k;
    proxy_intercept_errors          on;
    server_name_in_redirect         off;
    proxy_hide_header       X-Powered-By;

    gzip                            on;
    gzip_min_length                 100;
    gzip_buffers                    4 16k;
    gzip_http_version               1.0;
    gzip_comp_level                 9;
    gzip_types                      text/plain application/x-javascript text/css application/xml;
    gzip_vary                       on;
    gzip_proxied                       any;
    error_page 400 401 402 403 404 405 408 410 412 413 414 415 500 501 502 503 506 = http://weikeqin.com/error.html;


    server {
        listen       8080      proxy_protocol;
        server_name  localhost ;

        #charset koi8-r;

        access_log  logs/host.access.log  main;
        error_log   logs/host.error.log;

        location / {
            root   html;
            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;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      cert.pem;
        ssl_certificate_key  cert.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;
        }
    }

}

(2.1) 负载均衡

跨多个应用程序实例的负载平衡是一种常用的技术,用于优化资源利用率、最大化吞吐量、减少延迟并确保容错配置。

使用nginx作为一个非常有效的HTTP负载均衡器,可以将流量分配到多个应用服务器,并使用nginx提高web应用程序的性能、可伸缩性和可靠性。

nginx支持以下负载平衡机制(或方法):
轮询 - 对应用程序服务器的请求以循环方式分发,
最少连接 - 下一个请求被分配给活动连接数最少的服务器,
ip哈希 - 哈希函数用于确定下一个请求应选择的服务器(基于客户端的ip地址)。

参考 nginx官网 http://nginx.org/en/docs/http/load_balancing.html

# 服务器列表
http {
    upstream 127.0.0.1 {
        server 127.0.0.1:8081;
        server 127.0.0.1:8082;
        server 127.0.0.1:8083;
    }

    server {
        listen 8080;

        location / {
            proxy_pass http://127.0.0.1;
        }
    }
}

http://127.0.0.1:8080 的流量转发到 三台服务器上( 127.0.0.1:8081 127.0.0.1:8082 127.0.0.1:8081 )
实际使用时,可以把一个域名下的流量转发到多个域名/ip上


(2.2) 跨域请求转发

http://127.0.0.1:8080/demo/ 的请求转发到 http://127.0.0.1:11011/demo/

实际应用时会把域名 http://weikeqin.com/demo/ 的请求转发到 后台服务 http://10.x.x.x:11011/demo/

server {
    listen       8080;
    server_name  localhost;

    #charset koi8-r;

    access_log  logs/host.access.log  main;

    location / {
        root   html;
        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;
    }

    location = /demo/ {
        proxy_pass         http://localhost:11011;
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    }

}

注意 listen 对应的是 转发前的端口,server_name 对应转发前的域名/ip
location对应转发后的url,proxy_pass 对应转发后的域名/ip 注意不要多加/

(3) 遇到的问题

安装 启动 及 配置 的过程中遇到的问题。

(3.1) 缺少PCRE库

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.

解决办法
pcre官网 https://www.pcre.org/
pcre下载地址 https://ftp.pcre.org/pub/pcre/

cd pcre-8.44/
sudo ./configure --prefix=/usr/local
sudo make
sudo make install

(3.2) 目录没有写权限

ZBMAC-C02PGMT0F:pcre-8.44 weikeqin1$ brew install pcre
Updating Homebrew...
Error: The following directories are not writable by your user:
/usr/local/lib/pkgconfig
/usr/local/share/info
/usr/local/share/man/man3
/usr/local/share/man/man5

You should change the ownership of these directories to your user.
  sudo chown -R $(whoami) /usr/local/lib/pkgconfig /usr/local/share/info /usr/local/share/man/man3 /usr/local/share/man/man5

And make sure that your user has write permission.
  chmod u+w /usr/local/lib/pkgconfig /usr/local/share/info /usr/local/share/man/man3 /usr/local/share/man/man5
ZBMAC-C02PGMT0F:pcre-8.44 weikeqin1$

对应目录授权
sudo chown -R weikeqin1 /usr/local/lib/pkgconfig /usr/local/share/info /usr/local/share/man/man3 /usr/local/share/man/man5

(3.3) nginx: [warn] the “user” directive makes sense only if the master process runs with super-user privileges, ignored in /usr/local/nginx/conf/nginx.conf:2

nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /usr/local/nginx/conf/nginx.conf:2

用户没有权限

  1. 注释掉用户,使用默认用户
  2. 给用户设置权限
  3. 手动启动

(3.4) nginx: [emerg] mkdir() “/dev/shm/nginx_temp/client_body” failed (2: No such file or directory)

nginx: [emerg] mkdir() "/dev/shm/nginx_temp/client_body" failed (2: No such file or directory)

缺少文件或目录,穿件对应的文件或目录
sudo mkdir -p /dev/shm/nginx_temp/client_body

(3.5) nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)

Linux只有root用户可以使用1024以下的端口

  1. 使用root用户启动
  2. 换一个端口

(3.6) nginx: [emerg] “server” directive is not allowed here in /usr/log/nginx/conf/domains/weikeqin_nginx.conf:1

nginx: [emerg] "server" directive is not allowed here in /usr/local/nginx/conf/domains/weikeqin_nginx.conf:1
  1. 检查 /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/domains/weikeqin_nginx.conf 两个文件有无配置错误
  2. 手动启动
  3. 把两个文件合并到一个 /usr/local/nginx/conf/nginx.conf

(3.7) 容器里配置nginx自动启动

# 如果使用到nginx需要启动nginx,不要reload,因为nginx默认是不启动的,需要使用sudo执行
# 注:首先创建client_body文件
mkdir -p /dev/shm/nginx_temp/client_body
sudo /export/servers/nginx/sbin/nginx -c /export/servers/nginx/conf/nginx.conf

(3.8) the page you are looking for is currently unavailable.

An error occurred.

Sorry, the page you are looking for is currently unavailable.
Please try again later.

If you are the system administrator of this resource then you should check the error log for details.

Faithfully yours, nginx.

请求页面不存在,后端服务关掉了,启动就好了

References

[1] nginx documentation
[2] Nginx 简易教程
[3] 十分钟-Nginx入门到上线
[4] 解决Mac下安装nginx出现的问题
[5] Nginx install on Mac OS X Lion. Cannot find PCRE
[6] brew 无法安装提示不能在根目录下使用
[7] 在mac os x 10.9.2上安装nginx
[8] nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)