沧海一粟

天下事有难易乎?为之,则难者亦易矣;不为,则易者亦难矣。

0%

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安装环境检查

1
2
3
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阶段结束以后,将会出现如下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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配置文件检查

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

出现以下日志说明配置ok

1
2
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) 启动

1
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
1
2
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是否成功启动

1
2
3
4
5
6
7
[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

1
2
3
# 重新加载配置 新启动一个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配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 服务器列表
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/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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库

1
2
3
4
./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/

1
2
3
4
cd pcre-8.44/
sudo ./configure --prefix=/usr/local
sudo make
sudo make install

(3.2) 目录没有写权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

1
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)

1
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)

1
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

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自动启动

1
2
3
4
# 如果使用到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.

1
2
3
4
5
6
7
8
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)