nginx的主要使用场景
- 动静分离
适用于前后端分离的项目,nginx根据请求的内容做区分处理。
如果客户端请求的内容是静态资源,则nginx直接读取资源并返回,也就是说nginx可以作为静态资源的服务器。为了提高响应速度,避免重复的io操作,nginx提供了静态资源的缓存功能(需手动配置)。
如果客户端请求的是后台的服务而非静态资源,则nginx则直接将请求转发给对应的服务。
- 正、反向代理
不管是正向代理还是反向代理,说到底都是代理,区别在于”代理“这个操作是在哪一边做的(服务端还是客户端)。
以客户端的视角来看,当客户端由于某些原因无法访问A服务时(例如被墙),需要通过B服务做一个中转,客户端将请求发送给B,B将请求转发给A,并将响应结果转回客户端。这是正向代理。
如果以服务器端的视角来看问题,服务C接收到客户端发来的请求时不自己处理,将请求转发给其他的服务,其他服务处理完毕后,服务C收到结果并把结果响应给客户端。对于客户端来说,只知道自己和C做了交互,并不知道是C的小伙伴处理了自己请求。这一过程对于客户端来说是完全透明的、无感知的。这是反向代理。
- 负载均衡
在集群环境下,所有的请求打在nginx,nginx根据某些策略将这些请求分发给后台的集群服务,所以目的在于让集群服务的负载更加均衡。
从职能上看,这也是一种反向代理,只不过在实现反向代理的方式上有了更高的要求,即通过”更合理的派发请求“以达到负载均衡的目的。
安装nginx
预备
yum install -y gcc
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
安装
./configure
make
make install
会安装在/usr/local/nginx下
启动
./nginx
./nginx -s stop
./nginx -s quit
./nginx -s reload
关闭防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload
安装成服务
vi /usr/lib/systemd/system/nginx.service
脚本内容
[Unit]
Description=nginx - web server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
ExecQuit=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
启动服务
systemctl daemon-reload
systemctl start nginx.service
## 开启自启动
systemctl enable nginx.service
为了能够全局使用nginx命令,可以配置下全局变量
vim /etc/profile
末尾加上
PATH=$PATH:/usr/local/nginx/sbin
export PATH
保存后刷新配置文件
source /etc/profile
基本命令
启动nginx
nginx
默认使用的是config下的nginx.config文件
控制nginx
启动nginx后,可以通过下面的命令给nginx中的master进程发送信号。
nginx -s <SIGNAL>
SIGNAL可以被替换为下面的参数
- quit
优雅的停止服务,即处理完毕当前的任务后退出。
- reload
重新加载配置文件
- reopen
该指令用于文件切割。
当日志文件比较大的时候,需要将之前的日志文件拷出来,并将日志记录进新的文件。
在不停止nginx的情况下,将旧的日志文件移动至其他目录时,nginx进程依然持有这个文件的句柄,所以会在这个文件上继续写入。
通过 nginx -s reopen命令可以让nginx放弃之前的文件句柄,将日志记录进新的文件,达到文件切割的目的。
- stop
快速停止nginx服务
辅助命令
- nginx -c 配置文件
指定配置文件启动
- nginx -t
检测配置文件是否有语法错误
- nginx -v
查看版本信息
配置文件
基本结构
#user nobody;
# 全局配置
worker_processes 1; #创建多少个worker进程
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid logs/nginx.pid; #master进程id
events {
worker_connections 1024; #一个子进程允许的最大连接是1024
}
# 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"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
#虚拟主机,可以配置多个server
server {
listen 80;
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;
}
# 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;
# }
#}
}
servername匹配规则
servername的匹配分先后顺序,如果前面匹配上就不会走到后面了。
完整匹配
server_name www.baidu.com
通配符
server_name *.baidu.com
正则匹配
server_name ~正则表达式
location匹配规则
符号 | 含义 |
---|---|
= | 开头表示精确匹配 |
^~ | 开头表示 uri 以某个常规字符串开头,理解为匹配 url 路径即可。nginx 不对 url 做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格) |
~ | 开头表示区分大小写的正则匹配 |
~* | 开头表示不区分大小写的正则匹配 |
/ | 通用匹配,任何请求都会匹配到 |
多个 location 配置的情况下匹配顺序为
- 首先匹配
=
- 其次匹配
^~
- 其次是按文件中顺序的正则匹配
- 最后是交给 / 通用匹配
- 当有匹配成功时候,停止匹配,按当前匹配规则处理请求
动静分离
静态资源直接返回,动态请求转发给对应的服务。
server {
listen 80;
server_name 192.168.10.88;
#charset koi8-r;
#access_log logs/host.access.log main;
# 静态化配置,所有静态请求都转发给 nginx 处理,存放目录为 my-project
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|js|css)$ {
root html;
index index.html;
}
location /api {
proxy_pass http://192.168.10.88:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
正向代理
最典型的就是VPN。
正向代理网上可参考的例子比较少,能找到的只有下面这个。
resolver指定dns服务器。
server {
resolver 192.168.1.1; #指定DNS服务器IP地址
listen 8080;
location / {
proxy_pass http://$http_host$request_uri; #设定代理商服务器的协议和地址
}
}
反向代理
其实上面动静分离配置的后台接口转发,就是一种反向代理。
location /api {
proxy_pass http://192.168.10.88:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
负载均衡
在集群环境下,负载均衡可以让反向代理更加的合理。
后台起两个服务,端口为8080和8081
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"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream wms_http{
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8081 weight=1;
}
server {
listen 80;
server_name 192.168.10.88;
#charset koi8-r;
#access_log logs/host.access.log main;
# 静态化配置,所有静态请求都转发给 nginx 处理,存放目录为 my-project
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|js|css)$ {
root html;
index index.html;
}
location /api {
#if ($request_method = 'OPTIONS') {
# add_header Access-Control-Allow-Origin '*';
# add_header Access-Control-Allow-Headers '*';
#add_header Access-Control-Allow-Methods '*';
# add_header Access-Control-Allow-Credentials 'true';
# return 204;
#}
#if ($request_method != 'OPTIONS') {
# add_header Access-Control-Allow-Origin '*' always;
# add_header Access-Control-Allow-Credentials 'true';
#}
proxy_pass http://wms_http;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
nginx将会将请求分发给可用的服务。
负载均衡有如下几种策略
- 配置权重
其实就是上面这种,后面加个weight,权值越大概率越大。
当然,如果哪一台服务挂了,只有还有可用服务存活,对于客户端来说就是无感知的。
upstream wms_http{
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8081 weight=1;
}
- ip_hash
根据客户端的ip觉得,同一ip的转发给同一个服务。
upstream wms_http{
ip_hash;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
- leash_conn
根据连接数来判断,请求优先分发给连接数少的
upstream wms_http{
leash_conn;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}