适用于 CentOSDebianUbuntu 系统进行编译安装与部署

安装

依赖库

  • CentOS 下执行安装
yum install gcc gcc-c++ autoconf automake zlib zlib-devel pcre-devel
  • 如果是 DebianUbuntu 下执行安装
apt install build-essential libpcre3 libpcre3-dev autoconf zlib1g-dev

准备编译源码

当今 **http2.0** 协议正在普及,因此如果使用该模块,用于编译的 **openssl** 源码包版本必须 `>=1.0.2`,**nginx** 推荐使用最新的稳定版本

将准备好的源码包分别解压,进入到 nginx 源码目录下

配置安装,默认下可以直接使用执行,但是很多模块是不包含在内的

./configure

为了减少以后再次配置编译,以下这些配置都是我们常用到的

./configure \
--error-log-path=/var/logs/nginx/error.log \
--http-log-path=/var/logs/nginx/access.log \
--sbin-path=/usr/sbin \
--pid-path=/run/nginx.pid \
--lock-path=/run/nginx.lock \
--http-client-body-temp-path=/var/nginx/client_temp \
--http-proxy-temp-path=/var/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-openssl=/root/openssl-1.1.0i \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-mail \
--with-debug \
--with-mail_ssl_module \
--with-file-aio \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-http_slice_module \
--with-http_v2_module

执行后,配置检测无误就可以编译与安装了

make && make install

环境配置

nginx 新增用户与用户组

groupadd -r nginx
useradd -s /sbin/nologin -g nginx -r nginx

创建运行环境需要的目录

mkdir /var/logs/nginx
mkdir /var/nginx

检测一下配置是否正常

nginx -t

如果提示这些信息,就说明基础的安装配置完成了

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

优化配置

以下是我个人对 nginx 的一些优化与理解,主要针对常用配置合理定义并将虚拟域名分开管理

修改主配置文件 nginx.conf,先将使用用户加入配置

user nginx nginx;

让工作进程自动配置,通常情况下有多少个逻辑处理内核就对应多少个工作进程

worker_processes auto;

关闭惊群 accept_mutex,合理最大并发数设定 worker_connections

events {
	worker_connections 4096;
	accept_mutex off;
}
**accept_mutex** 惊群是一种管理机制,例如在初始状态下少量的进程在保持运转,而并发攀升时其他休眠的进程会逐步被唤醒工作,这样的好处是正常访问下负载相对较低,但是当访问一直处于高位,这种方式反而效率会变低,所以关闭惊群让进程一直待命处理更加高效稳定。

开启文件异步线程池

http {
    aio threads;
}
提高 IO 性能,请求不再因为工作进程被阻塞在读文件,而滞留在事件队列中,等待处理,它们可以被空闲的进程处理掉

开启 sendfile

http {
    sendfile on;
    sendfile_max_chunk 256;
}
**sendfile** 是一种高效的传输模式,对比传统的(read、write/send 方式)能减少拷贝次数,从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,开启后内对文件的解析处理会有很大提升。**sendfile_max_chunk** 可以减少阻塞调用 `sendfile()` 所花费的最长时间,因为 **nginx** 不会尝试一次将整个文件发送出去,而是每次发送大小为 `256KB` 的块数据

开启 tcp_nopushtcp_nodelay

http {
	tcp_nopush on;
	tcp_nodelay on;
}
**tcp_nopush** 是让一个数据包里发送所有头文件,而不一个接一个的发送。
**tcp_nodelay** 是不要缓存数据,而是一段一段的发送,这样有助于解决网络堵塞。

开启 GZIP

http {
	gzip on;
	gzip_disable "MSIE [1-6].(?!.*SV1)";
	gzip_http_version 1.1;
	gzip_vary on;
	gzip_proxied any;
	gzip_min_length 1000;
	gzip_buffers 16 8k;
	gzip_comp_level 5;
	gzip_types text/plain text/css text/xml text/javascript application/json application/x-javascript application/xml application/xml+rss;
}
**GZIP** 的作用是压缩静态请求,提高加载速度

优化反向代理

http {
	proxy_connect_timeout 5;
	proxy_read_timeout 60;
	proxy_send_timeout 5;
	proxy_buffer_size 16k;
	proxy_buffers 4 64k;
	proxy_busy_buffers_size 128k;
	proxy_temp_file_write_size 128k;
	proxy_temp_path /var/nginx/proxy_temp;
}
  • proxy_connect_timeout 给反向代理的服务设置连接的超时时间
  • proxy_read_timeout 连接成功后,等候等待反向代理服务的响应时间
  • proxy_send_timeout 反向代理服务数据回传时间
  • proxy_buffer_size 指令设置缓冲区大小
  • proxy_buffers 指令设置缓冲区的大小和数量
  • proxy_busy_buffers_size 缓冲区满载后写入磁盘的临时文件大小
  • proxy_temp_file_write_size 一次访问能写入的临时文件的大小
  • proxy_temp_path 临时文件目录

设置长连接

http {
    keepalive_timeout 5;
}
设置 **keep-alive** 客户端连接在服务器端保持开启的超时值

最终 nginx.conf 配置是这样的

user nginx nginx;
worker_processes auto;

error_log /var/run/error.log info;
pid /var/run/nginx.pid;
lock_file /var/run/nginx.lock;

events {
	worker_connections 4096;
	accept_mutex off;
}

http {
	include mime.types;
	server_names_hash_bucket_size 64;
	default_type application/octet-stream;
	client_max_body_size 16m;
	access_log off;

	aio threads;
	sendfile on;
	sendfile_max_chunk 256k;

	tcp_nopush on;
	tcp_nodelay on;

	gzip on;
	gzip_disable "MSIE [1-6].(?!.*SV1)";
	gzip_http_version 1.1;
	gzip_vary on;
	gzip_proxied any;
	gzip_min_length 1000;
	gzip_buffers 16 8k;
	gzip_comp_level 5;
	gzip_types text/plain text/css text/xml text/javascript application/json application/x-javascript application/xml application/xml+rss;

	log_format main $remote_addr - $remote_user [$time_local] "$request"  $status $body_bytes_sent "$http_referer"  "$http_user_agent" "$http_x_forwarded_for";

	proxy_connect_timeout 5;
	proxy_read_timeout 60;
	proxy_send_timeout 5;
	proxy_buffer_size 16k;
	proxy_buffers 4 64k;
	proxy_busy_buffers_size 128k;
	proxy_temp_file_write_size 128k;
	proxy_temp_path /var/cache/nginx/proxy_temp;

	keepalive_timeout 5;

	server {
	    listen 80 default;
	    return 404;
	}

	include vhost/**/*.conf;
}

与此同时创建一个 vhost 目录来管理虚拟域名,vhost/**/*.conf; 就是将该目录引入

设置虚拟域名

虚拟域名我通常是放在 vhost 目录下,定义一个虚拟域名创建一个文件夹(可以将文件夹命名为域名), 其内部大概包含 site.conf(子配置)、site.crt(证书)、site.key(签名)

例如:定义子配置

server {
	listen  80;
	server_name <域名>;
	rewrite ^(.*)$  https://<域名>$1 permanent;
}

server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;

	server_name api.yelinvan.cc;
	charset utf-8;

	ssl_certificate <证书的绝对路径>;
	ssl_certificate_key <签名的绝对路径>;
	ssl_session_cache shared:SSL:20m;
	ssl_session_timeout 10m;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	ssl_prefer_server_ciphers on;
	ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

	root <虚拟目录路径>;

	location / {
		aio threads=default;
		index index.html <index.php>;
		# proxy_pass http://127.0.0.1:<port>;
	}

	# location ~ \.php$ {
	# 	fastcgi_pass 127.0.0.1:9000;
	#	<fastcgi_pass unix:php-fpm.sock>;
	# 	fastcgi_index index.php;
	# 	fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
	# 	fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
	# 	include fastcgi_params;
	# }

	error_page 404 403 /404.html;
	error_page 500 502 503 504 /50x.html;
}

加入 Systemctl

创建文件 /etc/systemd/system/nginx.service

[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

启动 nginx

systemctl start nginx

加入开机启动

systemctl enable nginx