前端与Nginx那些事儿

248 阅读7分钟

如何从0搭建一套外网可以访问的web服务呢?基于目前京东的工具大体上分为以下几步:

1.申请服务器资源(行云创建应用及分组)

2.外网VIP申请(反向代理)

3.域名及解析申请



Nginx在这个过程扮演了重要角色,了解总结下

1、初识Nginx



Nginx是一款高性能的Web服务器和反向代理服务器,具有优秀的性能、可靠性和可扩展性,广泛应用于各种Web应用场景。

最重要的几个使用场景:

•反向代理服务,延伸出包括缓存、负载均衡等;

•静态资源服务,通过本地文件系统提供服务;

•请求过滤,可以在代理服务器上设限,过滤掉某些不安全信息

•动静分离

•安全控制

2、常见配置项

先看一个配置示例

# main段配置信息
user  nginx;                        # 运行用户,默认即是nginx,可以不进行设置
worker_processes  auto;             # Nginx 进程数,一般设置为和 CPU 核数一样
error_log  /var/log/nginx/error.log warn;   # Nginx 的错误日志存放目录
pid        /var/run/nginx.pid;      # Nginx 服务启动时的 pid 存放位置

# events段配置信息
events {
    use epoll;     # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
    worker_connections 1024;   # 每个进程允许最大并发数
}

# http段配置信息
# 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
http { 
    # 设置日志模式
    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  /var/log/nginx/access.log  main;   # Nginx访问日志存放位置

    sendfile            on;   # 开启高效传输模式
    tcp_nopush          on;   # 减少网络报文段的数量
    tcp_nodelay         on;
    keepalive_timeout   65;   # 保持连接的时间,也叫超时时间,单位秒
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;      # 文件扩展名与类型映射表
    default_type        application/octet-stream;   # 默认文件类型

    include /etc/nginx/conf.d/*.conf;   # 加载子配置项
    
    # server段配置信息
    server {
    	listen       80;       # 配置监听的端口
    	server_name  bao.jr.jd.com;    # 配置的域名
      
    	# location段配置信息
    	location / {
    		root   /usr/share/nginx/html;  # 网站根目录
    		index  index.html index.htm;   # 默认首页文件
    		deny 172.168.22.11;   # 禁止访问的ip地址,可以为all
    		allow 172.168.33.44;# 允许访问的ip地址,可以为all
    	}
    	### end ###
    	### /service ###
	    location ^~ /service  {
            proxy_pass http://service;
    	    proxy_set_header Host $host;
      	    proxy_set_header X-Real-IP $remote_addr;
      	    proxy_set_header X-Forwarded-For $http_x_forwarded_for;
        }
	    ### end ###
    	
    	error_page 500 502 503 504 /50x.html;  # 默认50x对应的访问页面
    	error_page 400 404 error.html;   # 同上
    }
    # bao.jr.jd.com/service
    upstream service {
  	    server 172.23.187.29:80 max_fails=2 fail_timeout=30s;
        server 10.25.211.176:80 max_fails=2 fail_timeout=30s;

        user_define;
        check interval=3000 rise=2 fall=5 timeout=1000 type=http;
        check_http_send "HEAD / HTTP/1.0\r\n\r\n";
        check_http_expect_alive http_2xx http_3xx http_4xx http_5xx;
    } 
} 

main 全局配置,对全局生效;

events 配置影响 Nginx 服务器与用户的网络连接;

http 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置;

server 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块;

◦server_name 指定虚拟机域名

location 用于配置匹配的 uri ,可以嵌套使用;

◦root 指定静态资源目录位置,root指令实际访问的文件路径是root路径+location路径

◦alias 它也是指定静态资源目录位置,它只能写在 location 中。

upstream 配置后端服务器具体地址,负载均衡配置不可或缺的部分;

location /image1 {
	root /opt/nginx/static;
}
location /image2 {
    # 使用 alias 末尾一定要添加 /
    # alias指令会把location上配置的值去掉,然后把后缀拼接到alias指令后面
	alias /opt/nginx/static/image2/;
}

当用户访问 www.test.com/image1/1.png时,实际在服务器找的路径是 /opt/nginx/static/image1/1.png
当用户访问 www.test.com/image2/1.png时,实际在服务器找的路径是 /opt/nginx/static/image2/1.png,

3、Nginx常用场景

3.1、反向代理

正向代理的是客户端,正向代理中目标服务器并不知道访问它的真实用户是谁,因为和它交互的是代理服务器。

正向代理使用场景:

•突破访问限制,懂的都懂😏

•用作缓存,加速访问速度

•对客户端访问授权,上网进行认证

•代理可以记录用户访问记录,并对外隐藏用户信息

image.png



反向代理的是目标服务器端,用户不知道目标服务器是谁

反向代理使用场景:

•保护内网安全,对客户端隐藏服务器真实ip地址(rip)

•负载均衡,通过nginx将接收到的客户端请求按照指定负载均衡方式分配到这个集群中所有的服务器上,实现服务器压力的负载均衡

•缓存,减少服务器的压力



3.2、负载均衡

负载均衡是反向代理的应用延伸,通过配置Nginx将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器(集群)上,将负载分发到不同的服务器上,来分担服务器压力,即负载均衡。

当有一台服务器宕机时,负载均衡器就分配其他的服务器给用户,极大的增加网站的稳定性。



3.3、动静分离

动静分离是让动态网站里的动态网页根据一定规则将静态资源和动态资源分别放在不同的服务器中,并通过Nginx的反向代理功能将请求转发到相应的服务器

server {
    listen 80;
    server_name www.example.com;
    location /static/ {
        # 静态资源请求转发到静态资源服务器
        proxy_pass http://static.example.com/;
    }
    location / {
        # 动态资源请求转发到动态资源服务器
        proxy_pass http://dynamic.example.com/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

4、location写法

location [ = | ~ | ~* | ^~ ] uri {
	...
}

匹配优先级

1.= 精确匹配;

2.^~ 匹配前缀;

3.~* 正则匹配,不区分大小写;

4.~ 正则匹配,区分大小写;

5.空格 普通前缀

需要注意的是:~*虽然不区分大小写,但是用户访问,还是要与实际文件路径一致的。如果用户请求的URI是大写的,实际文件名是小写的,也不行。Nginx只是帮我们涵盖所有不区分大小写的文件路径,并不是把请求URI和文件路径不区分大小写进行匹配。

4.1、location 中的反斜线

location /test {
	...
}

location /test/ {
	...
}

共同点:Nginx先找是否有 test 目录,如果有则找 test 目录下的 index.html ;

不同点:如果没有 test 目录, 不带反斜线nginx 则会找是否有 test 文件,带了则不会

4.2、return

停止处理请求,直接返回响应码或重定向到其他 URL,后续指令将不会被执行

return code [text];
return code URL;
return URL;

例如:
location / {
	return 404 "pages not found"; # 返回状态码 + 一段文本
}
location / {
	return https://www.baidu.com ; # 返回重定向地址
}

4.3、location @

命名空间,通常在重定向时进行匹配,不提供常规请求匹配

location /index/ {
  error_page 404 @index_error;
}
location @index_error {
  .....
}
#以 /index/ 开头的请求,如果链接的状态为 404。则会匹配到 @index_error 这条规则上。

5、rewrite

根据指定正则表达式匹配规则,重写 URL。

作用域:server、location、if

语法:rewrite 正则表达式 要替换的内容 [flag];

flag枚举:

last 重写后的 URL 发起新请求,再次进入 server 段,重试 location 的中的匹配;

break 直接使用重写后的 URL ,不再匹配其它 location 中语句;

redirect 返回302临时重定向;

permanent 返回301永久重定向;

举个🌰

location /search { 
    rewrite ^/(.*) https://www.baidu.com redirect; 
}  
location /images { 
    rewrite /images/(.*) /pics/$1; 
}

6、try_files

按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜杠/的表示文件夹),若所有的文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。

作用域:server、location

语法:try_files file ... uri 或 try_files file ... = code

# 示例1
location /message {
    alias   /data/www/u-learning-message/develop/dist/;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html =404;
}
# 示例2
location ~ {
    root /export/www/jdos_kj_bfe-insurance-main;
	add_header Cache-Control "max-age=0, s-maxage=300";
    try_files $uri $uri/index.html @rewrite;
}
location @rewrite {
    rewrite ^(.*)/.+ $1/ last;
}

7、upstream

用于定义上游服务器(指的就是后台提供的应用服务器)的相关信息。

作用域:http

语法:
upstream name {
	server address [parameters]
}
示例:
upstream back_end_server{
  server 192.168.100.33:8081
}

8、proxy_pass

配置代理服务器,通常可以配合upstream配置反向代理

语法:proxy_pass URL;
示例:proxy_pass http://localhost:8000/uri/;

•URL必须以http或https开头

•URL中可以携带变量

•域名或者ip和端口号

如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走。

假设下面四种情况分别用 http://127.0.0.1/proxy/test.html 进行访问。

location /proxy/ {
    proxy_pass http://127.0.0.1/;
}
# 代理到URL:http://127.0.0.1/test.html

location /proxy/ {
    proxy_pass http://127.0.0.1;
}
# 代理到URL:http://127.0.0.1/proxy/test.html

location /proxy/ {
    proxy_pass http://127.0.0.1/aaa/;
}
# 代理到URL:http://127.0.0.1/aaa/test.html

location /proxy/ {
    proxy_pass http://127.0.0.1/aaa;
}
# 代理到URL:http://127.0.0.1/aaatest.html

9、反向代理配置

上游服务器配置接收

# 121.42.11.34
# /etc/nginx/conf.d/proxy.conf
server{
  listen 8080;
  server_name localhost;
  
  location /proxy/ {
    root /usr/share/nginx/html/proxy;
    index index.html;
  }
}

代理服务器配置转发

# /etc/nginx/conf.d/proxy.conf
upstream back_end {
  server 121.42.11.34:8080 weight=2 max_conns=1000 fail_timeout=10s max_fails=3;
  keepalive 32;
  keepalive_requests 80;
  keepalive_timeout 20s;
}

server {
  listen 80;
  server_name proxy.test.com;
  location /proxy {
  	proxy_pass http://back_end/proxy;
  }
}

当访问 proxy.test.com/proxy 时通过 upstream 的配置找到上游121.42.11.34:8080资源

一些概念👇👇👇

10、CNAME

•CNAME记录,也叫别名记录,比如www.xx.com的别名是www.yy.com,CNAME记录是一种指向关系,把www.yy.com指向了www.xx.com,一个域名可以有多个别名,存在多对一的关系。

•A记录,即Address记录,我们可以把它理解为一种域名和IP地址的映射关系。

11、CDN(容分发网络)

CDN是一种网络架构,旨在提高用户对互联网上内容的访问速度和性能。CDN通过在全球各地部署大量的服务器节点,将内容缓存到离用户更近的服务器上,从而减少内容传输的距离,提高访问速度和响应时间。当用户请求访问某个网站或应用程序时,CDN会自动选择距离用户最近的服务器节点,从该节点提供内容,而不是直接从原始服务器获取内容。



DNS解析: 浏览器首先会进行DNS解析,将域名解析成对应的IP地址。如果该域名的DNS记录中包含了CDN服务商提供的DNS服务器信息,DNS解析可能会返回一个与用户位置最接近的CDN节点的IP地址。

资源获取:CDN节点服务器接收到用户请求后,会检查是否有缓存该资源的副本。如果有,它会直接从缓存中返回资源;如果没有,它会向源服务器请求资源。

参考资料: juejin.cn/post/694260…

写在末尾:能力一般,水平有限,本文可能存在纰漏或错误,如有问题欢迎指正🙏