部分内容来源:

微信公众号:民工哥技术之路:dunwu


1、概述

1.1 什么是nginx?

Nginx (engine x) 是一款轻量级的 Web 服务器 、反向代理服务器及电子邮件(IMAP/POP3)代理服务器。

1.2 什么是反向代理?

反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

2、nginx常用命令

nginx -s stop       快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。
nginx -s quit 平稳关闭Nginx,保存相关信息,有安排的结束web服务。
nginx -s reload 因改变了Nginx相关配置,需要重新加载配置而重载。
nginx -s reopen 重新打开日志文件。
nginx -c filename 为 Nginx 指定一个配置文件,来代替缺省的。
nginx -t 不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。
nginx -v 显示 nginx 的版本。
nginx -V 显示 nginx 的版本,编译器版本和配置参数。

3、ningx配置实践

3.1 nginx.conf基础配置项

# 指定运行nginx的用户名
#user nobody;
# 工作线程数,通常同cpu逻辑核心数一致
worker_processes 1; # 错误日志路径 最小级别 [ debug | info | notice | warn | error | crit ]
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info; # 指定进程的pid记录文件,记录当前运行的nginx的pid
#pid logs/nginx.pid; # 网络连接模块
events {
# 一个工作线程支持的最大并发连接数
worker_connections 1024; # keepalive超时时间,单位:秒
keepalive_timeout 60;
} # 设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
# 设定支持的 mime 类型
include mime.types;
# 默认 mime 类型
default_type application/octet-stream; # 设定日志格式,格式名为main
## $remote_addr:客户端的ip地址(若使用代理服务器,则是代理服务器的ip)
## $remote_user:客户端的用户名(一般为“-”)
## $time_local:访问时间和时区
## $request:请求的url和请求方法
## $status:响应HTTP状态码
## $body_bytes_sent:响应body中的字节数
## $http_referer:客户端是从哪个url来请求的
## $http_user_agent:客户端用户使用的代理(一般为浏览器)
## $http_x_forwarded_for:客户端的ip地址(通过代理服务器记录客户端的ip地址)
#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; # 指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为 on,
# 如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime
sendfile on;
#tcp_nopush on; # keepalive 超时时长,单位:秒
#keepalive_timeout 0;
keepalive_timeout 65; # 打开 gzip
#gzip on; # 以上为 nginx 的全局设置,应用于所有 Web 应用
# 一个Web应用对应一个 server,内部配置仅针对该应用,优先级比全局的高
server {
// 端口号
listen 80;
// 域名,比如 www.test.com
server_name localhost; # 编码格式
#charset koi8-r; # 访问日志文件路径
#access_log logs/host.access.log main; # 一般路由导航到:
location / {
# 根目录为html
root html;
# 默认页为 index.html,如果没有则是 index.htm
index index.html index.htm;
} # 404时的展示页面
#error_page 404 /404.html; # 50X时的展示页面
# 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;
#} # 禁止访问 .htxxx 的文件
# 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 demo beign ##############
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost; # ssl 证书文件位置
# ssl_certificate cert.pem;
# ssl 证书key的位置
# ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# 数字签名 MD5
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on; # location / {
# root html;
# index index.html index.htm;
# }
#}
############### HTTPS demo end ############### ############ 反向代理 demo begin #############
# 设定实际的服务器列表(权重默认都是1)
#upstream myserver{
# server 192.168.0.1:8089 weight=7;
# server 192.168.0.2:8089 weight=3;
#} #server {
# listen 80;
# server_name localhost; #反向代理的路径(和upstream绑定),location 后面设置映射的路径
# location / {
# proxy_pass http://myserver;
# }
#}
############# 反向代理 demo end ############## }

3.2 http 反向代理

nginx.conf 配置文件如下:

注:conf / nginx.conf 是 nginx 的默认配置文件。你也可以使用 nginx -c 指定你的配置文件。

#运行用户
#user somebody; #启动进程,通常设置成和cpu的数量相等
worker_processes 1; #全局错误日志
error_log D:/Tools/nginx-1.10.1/logs/error.log;
error_log D:/Tools/nginx-1.10.1/logs/notice.log notice;
error_log D:/Tools/nginx-1.10.1/logs/info.log info; #PID文件,记录当前启动的nginx的进程ID
pid D:/Tools/nginx-1.10.1/logs/nginx.pid; #工作模式及连接数上限
events {
worker_connections 1024; #单个后台worker process进程的最大并发链接数
} #设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
#设定mime类型(邮件支持类型),类型由mime.types文件定义
include D:/Tools/nginx-1.10.1/conf/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 D:/Tools/nginx-1.10.1/logs/access.log main;
rewrite_log on; #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,
#必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime.
sendfile on;
#tcp_nopush on; #连接超时时间
keepalive_timeout 120;
tcp_nodelay on; #gzip压缩开关
#gzip on; #设定实际的服务器列表
upstream zp_server1{
server 127.0.0.1:8089;
} #HTTP服务器
server {
#监听80端口,80端口是知名端口号,用于HTTP协议
listen 80; #定义使用www.xx.com访问
server_name www.helloworld.com; #首页
index index.html #指向webapp的目录
root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp; #编码格式
charset utf-8; #代理配置参数
proxy_connect_timeout 180;
proxy_send_timeout 180;
proxy_read_timeout 180;
proxy_set_header Host $host;
proxy_set_header X-Forwarder-For $remote_addr; #反向代理的路径(和upstream绑定),location 后面设置映射的路径
location / {
proxy_pass http://zp_server1;
} #静态文件,nginx自己处理
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
root D:\01_Workspace\Project\github\zp\SpringNotes\spring-security\spring-shiro\src\main\webapp\views;
#过期30天,静态文件不怎么更新,过期可以设大一点,如果频繁更新,则可以设置得小一点。
expires 30d;
} #设定查看Nginx状态的地址
location /NginxStatus {
stub_status on;
access_log on;
auth_basic "NginxStatus";
auth_basic_user_file conf/htpasswd;
} #禁止访问 .htxxx 文件
location ~ /\.ht {
deny all;
} #错误处理页面(可选择性配置)
#error_page 404 /404.html;
#error_page 500 502 503 504 /50x.html;
#location = /50x.html {
# root html;
#}
}
}
  1. 启动 webapp,注意启动绑定的端口要和 nginx 中的 upstream 设置的端口保持一致。

  2. 更改 host:在 C:\Windows\System32\drivers\etc 目录下的 host 文件中添加一条 DNS 记录

    127.0.0.1 www.helloworld.com

  3. 启动前文中 startup.bat 的命令

  4. 在浏览器中访问 www.helloworld.com,不出意外,已经可以访问了。

3.3 负载均衡配置

假设这样一个应用场景:将应用部署在 192.168.1.11:80、192.168.1.12:80、192.168.1.13:80 三台 linux 环境的服务器上。网站域名叫 www.helloworld.com,公网 IP 为 192.168.1.11。在公网 IP 所在的服务器上部署 nginx,对所有请求做负载均衡处理。

nginx.conf 配置如下:

http {
#设定mime类型,类型由mime.type文件定义
include /etc/nginx/mime.types;
default_type application/octet-stream;
#设定日志格式
access_log /var/log/nginx/access.log; #设定负载均衡的服务器列表
upstream load_balance_server {
#weigth参数表示权值,权值越高被分配到的几率越大
server 192.168.1.11:80 weight=5;
server 192.168.1.12:80 weight=1;
server 192.168.1.13:80 weight=6;
} #HTTP服务器
server {
#侦听80端口
listen 80; #定义使用www.xx.com访问
server_name www.helloworld.com; #对所有请求进行负载均衡请求
location / {
root /root; #定义服务器的默认网站根目录位置
index index.html index.htm; #定义首页索引文件的名称
proxy_pass http://load_balance_server ;#请求转向load_balance_server 定义的服务器列表 #以下是一些反向代理的配置(可选择性配置)
#proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Forwarded-For $remote_addr;
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数
}
}
}

3.4 网站有多个 webapp 的配置

当一个网站功能越来越丰富时,往往需要将一些功能相对独立的模块剥离出来,独立维护。这样的话,通常,会有多个 webapp。

举个例子:假如 www.helloworld.com 站点有好几个 webapp,finance(金融)、product(产品)、admin(用户中心)。访问这些应用的方式通过上下文(context)来进行区分:

www.helloworld.com/finance/

www.helloworld.com/product/

www.helloworld.com/admin/

我们知道,http 的默认端口号是 80,如果在一台服务器上同时启动这 3 个 webapp 应用,都用 80 端口,肯定是不成的。所以,这三个应用需要分别绑定不同的端口号。

那么,问题来了,用户在实际访问 www.helloworld.com 站点时,访问不同 webapp,总不会还带着对应的端口号去访问吧。所以,你再次需要用到反向代理来做处理。

http {
#此处省略一些基本配置 upstream product_server{
server www.helloworld.com:8081;
} upstream admin_server{
server www.helloworld.com:8082;
} upstream finance_server{
server www.helloworld.com:8083;
} server {
#此处省略一些基本配置
#默认指向product的server
location / {
proxy_pass http://product_server;
} location /product/{
proxy_pass http://product_server;
} location /admin/ {
proxy_pass http://admin_server;
} location /finance/ {
proxy_pass http://finance_server;
}
}
}

3.5 https 反向代理配置

一些对安全性要求比较高的站点,可能会使用 HTTPS(一种使用 ssl 通信标准的安全 HTTP 协议)。

使用 nginx 配置 https 需要知道几点:

  • HTTPS 的固定端口号是 443,不同于 HTTP 的 80 端口
  • SSL 标准需要引入安全证书,所以在 nginx.conf 中你需要指定证书和它对应的 key

其他和 http 反向代理基本一样,只是在 Server 部分配置有些不同。

  #HTTP服务器
server {
#监听443端口。443为知名端口号,主要用于HTTPS协议
listen 443 ssl; #定义使用www.xx.com访问
server_name www.helloworld.com; #ssl证书文件位置(常见证书文件格式为:crt/pem)
ssl_certificate cert.pem;
#ssl证书key位置
ssl_certificate_key cert.key; #ssl配置参数(选择性配置)
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
#数字签名,此处使用MD5
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on; location / {
root /root;
index index.html index.htm;
}
}

3.6 静态站点配置

配置静态站点(即 html 文件和一堆静态资源)。

举例来说:如果所有的静态资源都放在了 /app/dist 目录下,我们只需要在 nginx.conf 中指定首页以及这个站点的 host 即可。

配置如下:

worker_processes  1;

events {
worker_connections 1024;
} http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65; gzip on;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript image/jpeg image/gif image/png;
gzip_vary on; server {
listen 80;
server_name static.zp.cn; location / {
root /app/dist;
index index.html;
#转发任何请求到 index.html
}
}
}

然后,添加 HOST:

127.0.0.1 static.zp.cn

此时,在本地浏览器访问 static.zp.cn ,就可以访问静态站点了。

3.7 搭建文件服务器

使用 Nginx 可以非常快速便捷的搭建一个简易的文件服务。

Nginx 中的配置要点:

  • 将 autoindex 开启可以显示目录,默认不开启。
  • 将 autoindex_exact_size 开启可以显示文件的大小。
  • 将 autoindex_localtime 开启可以显示文件的修改时间。
  • root 用来设置开放为文件服务的根路径。
  • charset 设置为 charset utf-8,gbk;,可以避免中文乱码问题(windows 服务器下设置后,依然乱码,本人暂时没有找到解决方法)。

一个最简化的配置如下:

autoindex on;# 显示目录
autoindex_exact_size on;# 显示文件大小
autoindex_localtime on;# 显示文件时间 server {
charset utf-8,gbk; # windows 服务器下设置后,依然乱码,暂时无解
listen 9050 default_server;
listen [::]:9050 default_server;
server_name _;
root /share/fs;
}

3.8 跨域解决方案

web 领域开发中,经常采用前后端分离模式。这种模式下,前端和后端分别是独立的 web 应用程序,例如:后端是 Java 程序,前端是 React 或 Vue 应用。

各自独立的 web app 在互相访问时,势必存在跨域问题。解决跨域问题一般有两种思路:

3.8,1 CORS

在后端服务器设置 HTTP 响应头,把你需要运行访问的域名加入加入 Access-Control-Allow-Origin中。

3.8.2 jsonp

把后端根据请求,构造 json 数据,并返回,前端用 jsonp 跨域。

nginx 根据第一种思路,也提供了一种解决跨域的解决方案。

举例:www.helloworld.com 网站是由一个前端 app ,一个后端 app 组成的。前端端口号为 9000, 后端端口号为 8080。

前端和后端如果使用 http 进行交互时,请求会被拒绝,因为存在跨域问题。来看看,nginx 是怎么解决的吧:

首先,在 enable-cors.conf 文件中设置 cors :

# allow origin list
set $ACAO '*'; # set single origin
if ($http_origin ~* (www.helloworld.com)$) {
set $ACAO $http_origin;
} if ($cors = "trueget") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
} if ($request_method = 'OPTIONS') {
set $cors "${cors}options";
} if ($request_method = 'GET') {
set $cors "${cors}get";
} if ($request_method = 'POST') {
set $cors "${cors}post";
}

接下来,在你的服务器中 include enable-cors.conf 来引入跨域配置:

# ----------------------------------------------------
# 此文件为项目 nginx 配置片段
# 可以直接在 nginx config 中 include(推荐)
# 或者 copy 到现有 nginx 中,自行配置
# www.helloworld.com 域名需配合 dns hosts 进行配置
# 其中,api 开启了 cors,需配合本目录下另一份配置文件
# ----------------------------------------------------
upstream front_server{
server www.helloworld.com:9000;
}
upstream api_server{
server www.helloworld.com:8080;
} server {
listen 80;
server_name www.helloworld.com; location ~ ^/api/ {
include enable-cors.conf;
proxy_pass http://api_server;
rewrite "^/api/(.*)$" /$1 break;
} location ~ ^/ {
proxy_pass http://front_server;
}
}

nginx及其常用实践方案的更多相关文章

  1. 【实战分享】又拍云 OpenResty / Nginx 服务优化实践

    2018 年 11 月 17 日,由 OpenResty 主办的 OpenResty Con 2018 在杭州举行.本次 OpenResty Con 的主题涉及 OpenResty 的新开源特性.业界 ...

  2. window下nginx的常用命令

    window nginx 启动 常用命令 2016-05-04 11:11 214人阅读 评论(0) 收藏 举报 分类: nginx(5) 版权声明:本文为博主原创文章,未经博主允许不得转载. 启动 ...

  3. java多线程中最佳的实践方案是什么?

    java多线程中最佳的实践方案是什么? 给你的线程起个有意义的名字.这样可以方便找bug或追踪.OrderProcessor, QuoteProcessor or TradeProcessor 这种名 ...

  4. 基于OVS的VLAN虚拟化简易实践方案

    基于OVS的VLAN虚拟化简易实践方案 前言 本实验基于ovs的vlan流表匹配,根据端口进行vlan标签插入.手工配置ovs,使其具有vlan虚拟化方案. 实验拓扑 ---- ---- | h1 | ...

  5. Upsync:微博开源基于Nginx容器动态流量管理方案

    Upsync:微博开源基于Nginx容器动态流量管理方案 https://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=404151075& ...

  6. Nginx配置try_files实践二

    本文内容承接<Nginx配置try_files实践一> 1. 环境: OS:Ubuntu 15.10 nginx:nginx/1.9.3 (Ubuntu) 假设有三台虚拟机db1(IP:1 ...

  7. Nginx配置try_files实践一

    参考资料: http://linuxplayer.org/2013/06/nginx-try-files-on-multiple-named-location-or-serverhttp://stac ...

  8. CentOS + Nginx 的常用操作指令总结

    CentOS + Nginx 的常用操作指令总结 一. 关于CentOS 查看 yum 源是否存在 yum list | grep nginx 如果不存在 或者 不是自己想要的版本 可以自己设置Ngi ...

  9. nginx 的常用模块

    nginx的常用模块 ngx_http_index_module Syntax: index file ...; Default: index index.html; Context: http, s ...

随机推荐

  1. web攻防环境--一句话木马

    任务一.基于centos7搭建dvwa web服务靶机 1.在centos7安装LAMP并启动,访问phpinfo页面 也即安装httpd.php.mysql服务. 直接进行yum安装即可,完成后检查 ...

  2. 【分布式锁】Redis实现可重入的分布式锁

    一.前言 之前写的一篇文章<细说分布式锁>介绍了分布式锁的三种实现方式,但是Redis实现分布式锁关于Lua脚本实现.自定义分布式锁注解以及需要注意的问题都没描述.本文就是详细说明如何利用 ...

  3. (class: org/apache/jasper/runtime/PageContextImpl, method: getELResolver signature: ()Ljavax/el/ELResolver;) Incompatible argument to

    网上大多都说是jsp版本原因: 引用: .............................................. ................................. ...

  4. 大数据量查询容易OOM?试试MySQL流式查询

    一.前言 程序访问 MySQL 数据库时,当查询出来的数据量特别大时,数据库驱动把加载到的数据全部加载到内存里,就有可能会导致内存溢出(OOM). 其实在 MySQL 数据库中提供了流式查询,允许把符 ...

  5. 【并发编程】- ThreadPoolExecutor篇

    Executor框架 Executor框架的两级调度模型(基于HotSpot) 在上层,Java多线程程序通常把应用分解为若干个任务,然后使用用户级的调度器(Executor框架)将这些任务映射为固定 ...

  6. Socket粘包问题的3种解决方案,最后一种最完美!

    在 Java 语言中,传统的 Socket 编程分为两种实现方式,这两种实现方式也对应着两种不同的传输层协议:TCP 协议和 UDP 协议,但作为互联网中最常用的传输层协议 TCP,在使用时却会导致粘 ...

  7. Thread线程控制之sleep、join、setDaemon方法的用处

    Thread线程控制之sleep.join.setDaemon方法的用处 1. sleep方法 public static void sleep(long millis) throws Interru ...

  8. 【Flutter】容器类组件之剪裁

    前言 Flutter中提供了一些剪裁函数,用于对组件进行剪裁. 剪裁Widget 作用 ClipOval 子组件为正方形时剪裁为内贴圆形,为矩形时,剪裁为内贴椭圆 ClipRRect 将子组件剪裁为圆 ...

  9. Flutter 应用入门:包管理

    pubspec.yaml name: flutter_combat description: A Flutter combat application. # The following defines ...

  10. wpf 中 Ellipse 对象对动画性能的影响

    vs2019 .NetFramework 4.8 win10-64 1909 接手一个wpf项目,某窗口中包含大量的 Shape 对象(线,矩形,圆形等). 这些内容要匀速的向左平移,类似于游戏&qu ...