nginx理解与跨域解决方案

Nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。

正向代理与反向代理

正向代理:

正向代理
就像上图所示,由于防火墙存在的原因,我们无法直接访问谷歌,这个时候我们就可通过VPN来绕过防火墙,在这个过程中,客户端是明白自己的请求需要到达的目的地的,只是这个请求会被VPN去代理,所以服务器其实不知道请求实际来自于哪里,正向代理代理的是客户端。

反向代理:

反向代理
反向代理代理的则是服务器,对于客户端来说,他并不知道自己的请求最终去了哪里,被哪一台服务器处理,他只是把请求发送给了代理服务器,反向代理服务器将该请求发送给了内网中的另外一台服务器去处理,这个反向代理的过程对于客户端来说是透明的。

Nginx的模块和工作原理

Nginx由内核和模块组成,其中内核十分简单,仅仅就是通过查找配置文件将客户端请求映射到一个location的block中。

Nginx的模块从结构上分为核心模块,基础模块和第三方模块:
核心模块:HTTP模块,EVENT模块,MAIL模块
基础模块:HTTP Access模块,HTTP FastCGI模块,HTTP Proxy模块和HTTP Rewrite模块
第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。

Nginx的模块从功能上分为如下三类。
Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。
Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。
Proxies (代理类模块)。此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。
nginx

所以其实nginx的本身只是将请求根据配置文件映射到不同的location中去处理,再将处理结果返回。

Nginx进程模型

nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。
但是如果存在多个worker,当一个请求进来时,所有的worker进程都可以监听到该请求,如何选择一个进程去处理该请求呢?
针对这种情况,nginx提供了互斥锁,只有拿到了这把锁才可以去接受请求

热部署原理

修改配置文件nginx.conf后,重新生成新的worker进程,当然会以新的配置进行处理请求,而且新的请求必须都交给新的worker进程,至于老的worker进程,等把那些以前的请求处理完毕后,kill掉即可。

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
main
events {
....
}
http {
....
upstream myproject {
.....
}
server {
....
location {
....
}
}
server {
....
location {
....
}
}
....
}

nginx的配置文件主要分为六个部分,分别为全局配置(main),nginx工作模式(events),http设置(http),主机设置(server),URL匹配(location),负载均衡服务器设置(upstream)

我们经常使用到的是http,server和location

http模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 /usr/local/var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 10;
#gzip on;
upstream myproject {
.....
}
server {
....
}
}

include:用于设定文件的mime类型,类型在配置文件目录下的mime.type中定义,来告诉nginx识别文件的类型
default_type:设定了默认类型为二进制
log_format:设置日志的格式和记录哪些参数
access_log 用来纪录每次的访问日志的文件地址,后面的main是日志的格式样式,对应于log_format的main。
sendfile参数用于开启高效文件传输模式。将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞。
keepalive_timeout设置客户端连接保持活动的超时时间。在超过这个时间之后,服务器会关闭该连接。

server模块

1
2
3
4
5
6
7
8
9
10
11
server {
listen 8080;
server_name localhost 192.168.12.10 www.yangyi.com;
# 全局定义,如果都是这一个目录,这样定义最简单。
root /Users/yangyi/www;
index index.php index.html index.htm;
charset utf-8;
access_log usr/local/var/log/host.access.log main;
aerror_log usr/local/var/log/host.error.log error;
....
}

server标志定义虚拟主机开始。
listen用于指定虚拟主机的服务端口。
server_name用来指定IP地址或者域名,多个域名之间用空格分开。
root 表示在这整个server虚拟主机内,全部的root web根目录。注意要和locate {}下面定义的区分开来。
index 全局定义访问的默认首页地址。注意要和locate {}下面定义的区分开来。
charset用于设置网页的默认编码格式。
access_log用来指定此虚拟主机的访问日志存放路径,最后的main用于指定访问日志的输出格式。

location模块

1
2
3
4
location / {
root /Users/yangyi/www;
index index.php index.html index.htm;
}

location /表示匹配访问根目录。
root指令用于指定访问根目录时,虚拟主机的web目录,这个目录可以是相对路径(相对路径是相对于nginx的安装目录)。也可以是绝对路径。
index用于设定我们只输入域名后访问的默认首页地址,有个先后顺序:index.php index.html index.htm,如果没有开启目录浏览权限,又找不到这些默认首页,就会报403错误。

upstream模块

upstream 模块负债负载均衡模块,通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。

1
2
3
4
5
6
7
upstream iyangyi.com{
ip_hash;
server 192.168.12.1:80;
server 192.168.12.2:80 down;
server 192.168.12.3:8080 max_fails=3 fail_timeout=20s;
server 192.168.12.4:8080;
}

里面是ip_hash这是其中的一种负载均衡调度算法,下面会着重介绍。紧接着就是各种服务器了。用server关键字表识,后面接ip。

Nginx的负载均衡模块目前支持4种调度算法:

  1. weight 轮询(默认)。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。weight。指定轮询权值,weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。
  2. ip_hash。每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。
  3. fair。比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。
  4. url_hash。按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx 的hash软件包。

Nginx解决跨域问题

调试页面是:http://192.168.1.2:8080/

请求的接口是:http://sun668.vip/api/get/info

步骤一:

请求的接口是:http://192.168.1.2/api/get/info

PS:这样就解决了跨域问题。

步骤二:

修改nginx.conf文件:

1
2
3
4
5
6
7
8
9
10
11
12
server{
listen 8088;
server_name 192.168.1.2;

location /{
proxy_pass http://192.168.1.2:8080;
}

location /api{
proxy_pass http://sun668.vip/api;
}
}

参考文件:
https://www.zybuluo.com/phper/note/89391
https://blog.csdn.net/mine_song/article/details/56678736
https://blog.csdn.net/hguisu/article/details/8930668