nginx二三事
过去的项目一直使用windows,加上后台使用的是PHP,自然而然使用Wamp集成本地服务器开发环境。新公司项目用node写中间层,需要使用nginx搭建本地环境,之前对nginx的了解仅限于反向代理,现搭环境基本都是现查资料现学,因此简单整理,以做备忘。
开发环境是Mac OS 10.12.6,参考:
安装
通过brew安装
brew install nginx
由于遇见了一个很蛋疼的问题
Error: Cannot link pcre Another version is already linked: /usr/local/Cellar/pcre/8.41
貌似是brew权限的问题,参考解决方案。
sudo chown -R $USER /usr/local
然后重新安装即可
基本使用
安装完成后使用nginx -h
查看对应指令。
# 启动服务
sudo nginx
启动完成后可以通过下面语法进行控制
sudo nginx -s signal
其中signal
有下面四个选项
- stop,快速关闭
- quit,平滑关闭
- reload,重新加载配置文件,这个命令在修改配置文件后经常使用
- reopen,重新打开log文件
可以通过ps查看nginx进程状态
# 输出格式化的表格
ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
可以发现有一个master process
和多个worker process
的情形 ,这跟nginx的进程管理模型有关,在Master 模型下
- master 进程主要负责对外揽活(即接收客户端的请求),并将活儿合理的分配给多个worker,
- 每个worker 进程主要负责干活(处理请求)。
也可以通过kill
杀掉master process
的进程,实现nginx -s quit
的功能。
配置
文档里提到,nginx配置文件通过指令Directives
来实现
- 简单指令,以分号结尾
- 块级指令,包含数条简单指令,以
{}
包围 - 如果一个块级指令内部包含其他指令,就称为
context
,常见的如events, http, server, and location等
下面是安装后的nginx的配置文件的一部分
# /usr/local/etc/nginx/nginx.conf
user root staff;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
}
}
include /usr/local/etc/nginx/conf.d/*.conf
这个是nginx的主要配置文件,还可以通过include
指令引入其他的子配置模块文件。
指令
指令和指令之间是有层级和继承关系的,现在暂时只关注http和server等web相关的东西。
server server就是一个web服务器,可以简单理解为部署的一个网站。一个server常见的配置有
- 端口号,web服务器默认端口号均为80,通过listen指定
- 站点根目录,通过root指定
- 站点根文件,通过index指定
- 域名,通过server_name指定
那么下面就是一个server指令的配置,跟Apache的XML配置相比,nginx的配置要简洁很多
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
}
location 如果要访问server根目录下其他文件,可以通过location指令进行定位
location \ {
index index.html index.php;
}
location ~ \.php {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
inclue fastcgi_params;
}
下面是location的匹配规则
location [=|~|~*|^~] /uri/ { ... }
- = 开头表示精确匹配
- ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。
- ~ 开头表示区分大小写的正则匹配
- ~* 开头表示不区分大小写的正则匹配
- !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则
- / 通用匹配,任何请求都会匹配到。
关于location更详细的配置,可以参考这里;
代理服务器
考虑下面一个场景:用户A需要访问C服务器,但是由于某种原因限制,A只能访问B服务器而不能访问C服务器,一种解决办法是通过B访问C服务器,然后将请求结果返回给A服务器。这种处理方式被称做正向代理,正向代理一般由客户端设置,B作为代理服务器,其主要作用是转发请求
反向代理与正向代理相反,其中,由C提供真正的服务,A不知道也不需要知道C的存在,只需要访问B即可,B会作为C的代理服务器向用户提供服务。与正向区别的代理在于,客户端不需要手动设置代理服务器地址。
工作项目中,node开启的本地服务器运行在一个指定的端口上,而http默认端口号为80,因此需要将其他端口上的服务器通过nginx进行反向代理`
server {
listen 80;
server_name api.test.com;
location / {
proxy_pass http://127.0.0.1:3015;
}
}
如果还需要转发请求信息,可以添加
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
gzip
开启gzip后会显著降低静态资源的尺寸,提高传输效率,当然这需要消耗一定的CPU资源用于压缩。
下面是关于gzip的配置
http {
gzip on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
server {
listen 80;
server_name static.test.com;
location ~ ^/static/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
}
}
常见问题
下面是在开发过程中遇见的一些问题
检测配置文件格式
如果nginx.conf
文件语法错误,则会导致reload失败,可以通过
nginx -t
对配置文件进行校验
nginx.pid丢失
某次电脑重启导致nginx退出异常,使用nginx -s reload
nginx: [error] open() "/usr/local/var/run/nginx.pid" failed (2: No such file or directory)
错误原因是nginx.pid丢失。正常情况下,启动nginx后,会在/usr/local/var/run
目录下生成nginx.pid
文件,而nginx -s stop
则会删除该文件。
遇见上面这种情况,则需要重新启动nginx,生成nginx.pid
文件
sudo nginx
同理,在已启动nginx的情况下,再次启动nginx则会出现下面错误
nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)
这种情况下,只需要使用nginx -s reload
即可。
nginx 静态资源403
本地有个静态资源服务器,配置站点root后访问,出现403错误。
参考解决办法,配置nginx.conf
的user选项
- 先查看目录的权限
ls -la
获取用户和所在分组 - 然后配置
user username [usergroup];
小结
现在在工作中需要用node写中间层,以后接触到nginx的场景也比较多,因此还需要多多学习。不得不说,nginx确实比Apache更简洁一些。
你要请我喝一杯奶茶?
版权声明:自由转载-非商用-保持署名和原文链接。
本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。