nginx入门( 基础和原理介绍 重要 )

.
.
.

参考博客

https://blog.csdn.net/khuangliang/article/details/122345060
.
.
.
ngnix官网
https://nginx.org/en/docs/
.
.
在线自动生成nginx配置文件
https://www.digitalocean.com/community/tools/nginx?global.app.lang=zhCN
.
nginx的支持5万的并发量,但是如果你进行优化,甚至能达到百万并发
优化硬件、优化linux内核、优化nginx配置文件参数 一般就这3个方面
.

常见ngnix的命令


./ngnix   # 启动

ngnix -t    # 给master进程发送信号,去检测配置文件,是否有问题

ngnix -s reload    # 重写读取ngnix.conf   worker进程会发生变化,不是原来的了
# master进程根据配置文件ngnix.conf,重新去创建worker进程
# worker进程去接收,响应,处理用户请求

ngnix -s stop   # 停止ngnix


-------------------------------------
也可以用systemctl 来管理ngnix
systemctl status ngnix
systemctl reload ngnix
systemctl restart ngnix

-------------------------------------

.
.
.

小补充


# 客户端(浏览器)向服务器发送报文数据,称为『请求报文』
# 包含(请求首行、请求头、请求空行、请求体)
GET http://localhost:8000/src/api/product/trademark HTTP/1.1   # 请求首行

# 请求头示例
Host: localhost:8000
Connection: keep-alive   # 保持长链接
Content-Length: 40
sec-ch-ua: "Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"
Accept: application/json, text/plain, */*
Content-Type: application/json            # 请求体参数类型
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36     # 浏览器信息
Referer: http://localhost:8000/login?redirect=/home
Cookie: xxxxxxxx

# 请求空行
就是一个换行,用来隔开请求头和请求体

# 请求体
{"username":"admin","password":"111111"}   请求体数据

--------------------------------------------------------

# 服务器向客户端(浏览器)返回报文数据,称为『响应报文』
# 包含( 响应首行、响应头、响应空行、响应体  )

HTTP/1.1 200 OK   # 响应首行

# 响应头示例
access-control-allow-origin: http://localhost:8000
server: Tengine
content-type: application/json;charset=UTF-8
connection: close
vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
access-control-allow-credentials: true
date: Fri, 03 Mar 2023 01:19:01 GMT
ali-swift-global-savetime: 1677806341
via: cache78.l2cn2647[69,68,200-0,M], cache78.l2cn2647[70,0], kunlun4.cn5045[97,96,200-0,M], kunlun4.cn5045[98,0]
timing-allow-origin: *
Content-Length: 264
Cache-Control: no-cache
Etag: W/"79d-t/WosM2JJmSsn2caT8m0wBrbTnA"

----------------------------------------------
access-control-allow-origin cors允许跨域
content-type 响应体数据类型
Cache-Control 强制缓存控制
Etag / Last-Modifined 协商缓存控制
----------------------------------------------

# 空行
就是一个换行,用来隔开响应头和响应体

# 响应体
{"success":true,"code":20000,"message":"成功","data":null}


.
.
.

ngnix 处理请求的流程


# 1  ngnix 接收到浏览器的的请求报文后,解析请求首行、请求头、请求体(如有的话)
# 2  处理请求     匹配配置文件里的server    location匹配路径   记录日志等
# 3  拿到数据后   整合为响应报文后,发送给客户端

image

.
.
.
.
.
.
.
.

ngnix包里面 conf文件夹里各文件的作用


fastcgi_params   # 翻译ngnix变量为php可识别的变量
uwsgi_params     # 翻译ngnix变量为python可识别的变量
mime.types       # 支持的媒体文件类型
ngnix.conf       # ngnix主配置文件

.
.
.
.
.
.
.
.
.

ngnix主配置文件里个参数详解 巨重要!!!


#user  nobody;   # 设置运行用户
worker_processes  1;
#error_log  logs/error.log  info;

events {
    worker_connections  1024;
}


http {
    include       mime.types;      # 支持导入外部配置文件,用于配置优化
    # include     C:/nginx-1.21.4/conf_children/*.conf
    # 导入conf_children目录下的所有以 .conf结尾的文件
    # 一般情况下如果有多个server的情况下,就可以这样做,
    # 但是建议该行的include代码,放在http {} 括号里面的最下面

    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;
        #charset utf-8;

        location / {
            root   html;
            index  index.html index.htm;
        }
        # 浏览器 输入 localhost:80/111.txt  就能拿到 html文件夹下的111.txt文件数据
        # 浏览器 输入 localhost:80/  就默认拿 html文件夹下的index.html文件


        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }


    server {
        listen       8080;
        listen       [::]:8080;
        server_name  port8080;
        root d:;
        index index.html;
		# 浏览器输入 localhost:8080/222.txt 就能拿到 D盘下的222.txt
		# 浏览器输入 localhost:8080/  就默认拿D盘下的index.html文件

        location / {
            try_files $uri $uri/ /index.html;
        }
        location ^~ /api/dtw/ {
            proxy_pass http://localhost:5001/;
        }
        location ^~ /api/ps/ {
            proxy_pass http://192.168.11.60:5000/;
        }
    }

}


---------------------------------------

# 全局块      没写在花括号里面的 就是全局配置
	设置ngnix的运行用户、worker数量、日志的参数设置等

# event块
	ngnix的性能设置,已经tcp的连接数

# http块
	ngnix核心的网站HTTP部署功能都在这个 http {}  括号里面了
	写在花括号里面,但是没写在server{}里面的,是一些关于http请求与响应的优化参数
	如压缩、缓冲等

# server块
	ngnix实现网站部署的,服务配置
	http {} 括号里面,有几个server{}, 就是ngnix里面就有几个服务监听当前主机对应的端口了


# location块
	ngnix实现七层负载均衡转发

-------------------------------------------

# ngnix核心配置语法

http {}里面允许嵌套多个server{}
server{}里面允许嵌套多个location{}


http {} 用于解决用户请求与响应整体功能
server{} 用于响应具体某一个网站( 就是针对 具体的ip与端口 的请求与响应 )

location{} 用于匹配网站具体的URL路径(根据用户请求url的不同,完成不同的动作,)


-------------------------------------------

# ngnix 最简单直接的功能就是,在一个具有公网ip的主机上,跑ngnix
# 假设 公网ip为 193.169.111.111
# 具有公网ip的主机,它的局域网里面有多台主机跑着多个网站项目
# 外面人访问不到这些在内网里面跑的项目,这个时候就可以用ngnix来做请求转发了
# 在ngnix的http{}里面 写一个server 对应一个内网主机跑的网站项目
# 每个server里面只要用 端口去区分,就可以让互联网上的用户统一访问 该公网ip及对应的端口
# ngnix就能对应的转发到对应的内网主机运行的服务端了,拿到数据后,再返回给互联网上的用户了

--------------------------------------------

    server {
        listen       8080;     # 当前ngnix进程的服务,所监听的端口
        listen       [::]:8080;
        server_name  www.teng.com;    # 要匹配的域名 www.teng.com
        # 没有域名的话,就写localhost就行了

        root d:;
        index index.html;
		# 浏览器输入 localhost:8080/222.txt 就能拿到 D盘下的222.txt
		# 浏览器输入 localhost:8080/  就默认拿D盘下的index.html文件

        location / {
            try_files $uri $uri/ /index.html;
        }
        location ^~ /api/dtw/ {
            proxy_pass http://localhost:5001/;
        }
        location ^~ /api/ps/ {
            proxy_pass http://192.168.11.60:5000/;
        }


        location / {
        # 根据root参数,填写网页根目录信息
            root   html;  # 表示当访问localhost:8080 ,会自动到html目录下找数据
            # root   C:/nginx-1.21.4/haha;  # 当访问ip:port 会自动到haha目录下找数据
            # localhost:8080/111.txt  就会到html目录下找111.txt数据

            # localhost:80/111.xlsx  其他格式的文件,
            # ngnix默认不解析该文件数据,而是直接下载,因为ngnix不能识别这些类型的数据
            # mime.types配置文件里面,写明了ngnix能识别的文件类型
            index  index.html index.htm;
        }


    }


------------------------------------

listen       [::]:8080;
# 这句话的意思是   [::]表示监听所有可用的IPv6地址,相当于IPv6的通配符。
# 这样配置后,Nginx服务器将会监听本机所有可用的IPv6地址上的8080端口,
# 以便接收到该端口的请求。这个配置可以用于支持IPv6网络环境下的访问。

-------------------------------------------------------

try_files $uri $uri/ /index.html;
# 这句话的意思是
$uri 表示当前请求的URI路径(不包含主机和查询参数)。
$uri/ 表示当前请求的URI路径加上斜杠(表示请求的是一个目录)。
/index.html 是指定的默认文件路径。
try_files指令的作用是按照给定的顺序尝试查找文件,直到找到存在的文件为止。这在处理静态文件服务时非常有用。

在这个例子中,Nginx服务器会按照以下顺序尝试处理请求:
首先,它会尝试查找与当前请求URI路径完全匹配的文件。
如果找不到匹配的文件,它会尝试查找一个与当前请求URI路径加上斜杠的目录。
如果还是找不到,最后它会返回 /index.html 文件。
这种配置通常用于单页应用程序(如Vue.js或React应用)的路由处理。
如果请求的文件不存在,它会将请求转发到默认的 index.html 文件,以便应用程序能够处理路由。

------------------------------------------------------

location ^~ /api/dtw/ {
    proxy_pass http://localhost:5001/;
}
这段配置的作用是将以 /api/dtw/ 开头的请求转发(代理)到指定的后端服务器。


具体解释如下:

location ^~ /api/dtw/ 表示匹配以 /api/dtw/ 开头的请求路径。
^~ 修饰符表示前缀匹配,意味着只要请求路径以 /api/dtw/ 开头,就会应用这个配置。
proxy_pass http://localhost:5001/ 指定了反向代理的目标地址。
它将请求转发到位于本地主机(localhost)的端口号为 5001 的后端服务器。
因此,当收到以 /api/dtw/ 开头的请求时,Nginx会将请求转发给 http://localhost:5001/,
以便由后端服务器处理该请求。这种配置常用于实现前端与后端分离的架构,
其中 Nginx 作为反向代理服务器,将请求转发给后端服务器处理业务逻辑。

假设ngnix收到 localhost:8080/api/dtw/login 请求时,
就会转发到http://localhost:5001/login 上去


------------------------------------------------------

# 同理
proxy_pass http://192.168.11.60:5000/ 指定了反向代理的目标地址。
它将请求转发到位于 IP 地址为 192.168.11.60,端口号为 5000 的后端服务器。

------------------------------------------------------
------------------------------------------------------

location ^~ /api/ps/ws/pixel_streaming {
    proxy_pass http://192.168.11.60:5000/ws/pixel_streaming;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
}


这段配置的作用是将以 /api/ps/ws/pixel_streaming 开头的 WebSocket 请求
转发(代理)到指定的后端服务器。

具体解释如下:

location ^~ /api/ps/ws/pixel_streaming
表示匹配以 /api/ps/ws/pixel_streaming 开头的请求路径。
^~ 修饰符表示前缀匹配,意味着只要请求路径以 /api/ps/ws/pixel_streaming 开头,
就会应用这个配置。

proxy_pass http://192.168.11.60:5000/ws/pixel_streaming 指定了反向代理的目标地址。
它将 WebSocket 请求转发到位于 IP 地址为 192.168.11.60,端口号为 5000,
路径为 /ws/pixel_streaming 的后端服务器。

proxy_http_version 1.1; 指定使用 HTTP 1.1 协议。
proxy_set_header Upgrade $http_upgrade;
设置请求头中的 Upgrade 字段,用于支持 WebSocket 协议升级。
proxy_set_header Connection "Upgrade";
设置请求头中的 Connection 字段为 "Upgrade",表明连接需要升级为 WebSocket 连接。

因此,当收到以 /api/ps/ws/pixel_streaming 开头的 WebSocket 请求时,
Nginx会将请求转发给 http://192.168.11.60:5000/ws/pixel_streaming,
以便由后端服务器处理该请求,并且在转发过程中保持 WebSocket 连接的正确协议和头部信息。


# ngnix怎么知道 收到的以 /api/ps/ws/pixel_streaming开头的请求,是websocket请求的
因为如果是websocket请求 一定是ws:// 开头的
比如:本机的公网ip为193.199.199.199,那么当收到如下请求后
ws://193.199.199.199:8765/api/ps/ws/pixel_streaming
就会触发上面的location了!!!!

------------------------------------------------------
------------------------------------------------------

.
image
.
.
.
.
.
.

补充


    server {
        listen       80;
		# 如果监听的不是本机的127.0.0.1 ip地址的话,一个网卡可以绑定多个内网ip
		# 所以如果要监听本机网卡绑定的内网ip加端口的话要写全 192.168.11.12:80
        server_name  www.teng.com;

        location / {
            root   C:/nginx-1.21.4/haha;
            index  index.html index.htm;
        }
    }

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }


# 假设我们在本地的host文件里面都配置了
# localhost对应127.0.0.1       www.teng.com也对应127.0.0.1
# 无论浏览器里输入localhost还是www.teng.com 最终都是被解析为127.0.0.1
# 但是有一个地方不一样,请求头中host主机信息不一样,
# ngnix就是根据该信息区分,要去匹配哪个server

localhost:80/111.txt   # 拿的就是html文件夹下的111.txt
www.teng.com:80      # 拿的就是haha文件夹下的 index.html

-------------------------------------------------

# 总结
# 也就是说虽然域名对应的ip地址都是一个ip地址,只要域名不一样,在ngnix配置文件里面
# 只要server{}里面 server_name 对应好,ngnix也能区分开来

------------------------------------------------

# 还有种情况就是
# hosts文件里面某域名对应了比如127.0.0.1,但是ngnix里面没有对应server_name
# 那么浏览器里输入该域名,ngnix怎么处理
localhost:80    # 到html文件夹下拿数据

127.0.0.1:80    # 由于配置文件的加载顺序,127.0.0.1:80符合第一个server的条件
# 所以到haha文件夹下拿数据了

www.teng.com:80   # 到haha文件夹下拿数据
www.nihao.ccc:80   # 由于没有一个server_name符合,
# 所以就找到了第一个符合ip加端口的server,到haha文件夹下拿数据

但是如果你配了一个server,还是会优先去符合自己的server_name的server里面对应文件夹拿数据
	server {
        listen       80;
        server_name  www.nihao.ccc;

        location / {
            root   html;
            index  index.html index.htm;
        }
	}
------------------------------------------------

.
.
.
.

ngnix 的日志功能


ngnix的功能都是基于模块来实现的

# 访客日志、错误日志、错误页面优化日志

# 官网指南
https://nginx.org/en/docs/http/ngx_http_log_module.html

# 日志功能是默认开启的,但是有些情况需要关闭掉日志功能

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;

}


# log_format   main
设置日志具体格式,需要提取哪些信息,给这个日志的格式起个名字叫main
log_format 的参数只能写在http{}括号里面,不能写在server{}括号里面,官网有说明


# access_log
设置日志的存储路径,以及格式
access_log  logs/a1.access.log  main;  这行代码可以写到server{}括号里
这样就实现每个server里面可以定义一个记录日志的路径


remote_addr   # 记录客户端ip地址
remote_user   # 客户端用户名称
time_local    # 什么时间发来的
request       # 请求首行信息
status        # 服务端响应状态码
body_bytes_sent      # 记录服务器发送给客户端的响应数据的 字节数
http_referer    # 记录请求是从哪一个连接访问过来的
http_user_agent     # 记录客户端的信息浏览器或手机信息
http_x_forwarded_for    # 获取客户端真实的ip地址

根据日志,可以判断用户是否是爬虫、并禁止该用户ip、图片资源是否被盗用、服务器的运行情况等
如果日志中404状态码较多,可能是服务端网站有问题了
如果日志中50x系列状态码较多,表示ngnix和后端的代理出了问题,需要排查接口是否故障了
如果日志中20x系列状态码较多,说明技术架构没问题,但是如果客户反馈卡,可能是带宽小了
或者是硬件配置太低了,连接数太多了,内存与cpu压力较高导致的

--------------------------------------------------------

# 开启与关闭日志

ngnix  默认日志就是开启的

# access_log  logs/access.log  main;
注释掉了其实就是使用nginx设置的默认值,并不是禁用。所以没有用,还是会继续记日志

access_log  off;     # 只有这样就访客日志才能关闭
error_log off;   # 只有这样就错误日志才能关闭


--------------------------------------------------------

# 具体的其他变量的使用,参考
https://nginx.org/en/docs/varindex.html



.
.
.
.
.
.
.
.
.
.
.

正反向代理


# 正向代理:
由客户端向代理服务器指定它要访问哪个原始的服务器,
然后由代理服务器将请求转发给对应的原始服务器。比如vpn就是正向代理


# 反向代理:
客户端指定访问代理服务器,
它并不知道它访问的原始服务器是谁,由代理服务器根据配置规则转发给相应的原始服务器。
反向代理访问的实际是一个虚拟的ip,不是最终实际的ip地址。
比如nginx就是反向代理

image
.
image
.
.
.
.
.

负载均衡


单个web应用服务器不能承受日益增长的并发请求量,
因此我们需要不断的扩张web应用服务器来支持更高的并发请求量。
需要均匀的将请求分配到各个应用服务器上就是负载均衡,常用的策略有轮询策略。


nginx提供的负载均衡策略有2种:内置策略和扩展策略。
内置策略为轮询,加权轮询,Ip hash。
扩展策略,就天马行空,只有你想不到的没有他做不到的啦

----------------------------------------------------

# 负载均衡的五种算法

# 1 round robin 轮询 (默认)
按时间顺序依次将请求分配到各个后台服务器中,挂掉的服务器自动从列表中剔除
upstream bakend {
   server 192.168.0.1 down;
   server 192.168.0.2;
}

# 2 weight 轮询权重
weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下,
或在主从的情况下设置不同的权值,达到合理有效的地利用主机资源。
upstream bakend {
    server 192.168.0.1 weight=10;
    server 192.168.0.2 weight=10;
}

# 3 ip_hash
每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,
并且可以有效解决动态网页存在的session共享问题。
upstream bakend {
    ip_hash;
    server 192.168.0.1:88;
    server 192.168.0.2:80;
}


# 4 url_hash
按访问的URL的哈希结果来分配请求,使每个URL定向到同一台后端服务器,
可以进一步提高后端服务器缓存的效率。Nginx本身不支持url_hash,需要安装Nginx的hash软件包。
upstream backend {
     server 192.168.0.1:88;     //使用hash语句时,不能在使用weight等其他参数
     server 192.168.0.2:80;
     hash $request_uri;
     hash_method crc32;    //使用hash算法
 }


# fair算法
fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,
根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身不支持fair,
要安装upstream_fair模块才能使用。
upstream backend {
      server 192.168.0.1:88;
      server 192.168.0.2:80;
      fair;
  }


Ip hash算法,对客户端请求的ip进行hash操作,然后根据hash结果,
将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题。
image
.
image
.
.
.
.

动静分离


为了加快网站的解析速度,将动态页面和静态页面由不同的服务器来解析,
加快解析速度,降低原来单个服务器的压力。
将静态文件放在一个单独的web服务器上。


Nginx是静态资源的服务器,
访问http://localhost 会默认访问/root目录下面的index.html静态网页,
所以静态资源可以直接放在Nginx上,动态请求由相应的后端服务器处理,实现动静分离。


//静态网页
server {

        listen       80;              //端口
        server_name  localhost;       //主机域名
        client_max_body_size 1024M;   //设置允许客户端请求的最大的单个文件字节数
        location / {
               root   /root;    //网站根目录
               index  index.html;	 //默认发布页面
        }
}



image
.
.
.
.
.
.

nginx原理


1、工作流程
(1)用户通过域名发出访问Web服务器的请求,该域名被DNS服务器解析为反向代理服务器的IP地址;

(2)反向代理服务器接受用户的请求;

(3)反向代理服务器在本地缓存中查找请求的内容,找到后直接把内容发送给用户;

(4)如果本地缓存里没有用户所请求的信息内容,反向代理服务器会代替用户向源服务器请求同样的信息内容,并把信息内容发给用户,如果信息内容是缓存的还会把它保存到缓存中。

2、master-workers机制
Nginx在启动时会以daemon形式在后台运行,采用多进程+异步非阻塞IO事件模型来处理各种连接请求。多进程模型包括一个master进程,多个worker进程,一般worker进程个数是根据服务器CPU核数来决定的。master进程负责管理Nginx本身和其他worker进程。


image
.
image
.


从上图中可以很明显地看到,4个worker进程的父进程都是master进程,表明worker进程都是从父进程fork出来的,并且父进程的ppid为1,表示其为daemon进程。

需要说明的是,在nginx多进程中,每个worker都是平等的,因此每个进程处理外部请求的机会权重都是一致的。

Master进程的作用是?

读取并验证配置文件nginx.conf;管理worker进程;

Worker进程的作用是?

每一个Worker进程都维护一个线程(避免线程切换),处理连接和请求;注意Worker进程的个数由配置文件决定,一般和CPU个数相关(有利于进程切换),配置几个就有几个Worker进程。

连接数worker_aconnection和并发数关系?

表示每个worker进程所能建立的连接的最大值,如果nginx作为反向代理,最大并发数量 = work_connections * worker_process / 4 , 客户端和服务端都要占用两个连接。

Nginx如何做到热部署?

所谓热部署,就是配置文件nginx.conf修改后,不需要stop Nginx,不需要中断请求,就能让配置文件生效!(nginx -s reload 重新加载/nginx -t检查配置/nginx -s stop)

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

.
请求处理流程
image
.


Nginx真正处理请求业务的是Worker之下的线程。worker进程中有一个ngx_worker_process_cycle()函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个Nginx服务被停止。

worker 进程中,ngx_worker_process_cycle()函数就是这个无限循环的处理函数。在这个函数中,一个请求的简单处理流程如下:

(1)操作系统提供的机制(例如 epoll, kqueue 等)产生相关的事件。

(2)接收和处理这些事件,如是接收到数据,则产生更高层的 request 对象。

(3)处理 request 的 header 和 body。

(4)产生响应,并发送回客户端。

(5)完成 request 的处理。

(6)重新初始化定时器及其他事件。

.
.
.
.
.
.
.
.
.
.

nginx配置文件介绍




...              #全局块

events {         #events块
   ...
}

http      #http块
{
    ...   #http全局块
    server        #server块
    {
        ...       #server全局块
        location [PATTERN]   #location块
        {
            ...
        }
        location [PATTERN]
        {
            ...
        }
    }
    server
    {
      ...
    }

}


# 全局块:
配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,
日志存放路径,配置文件引入,允许生成worker process数等。


# events块:
配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,
选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。


# http块:
可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。
如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,
单连接请求数等。


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


# location块:
配置请求的路由,以及各种页面的处理情况。


# events块、http块、location块 这3个块很重要
端口号的主要作用是表示一台计算机中的特定进程所提供的服务。
网络中的计算机是通过IP地址来代表其身份的,它只能表示某台特定的计算机,
但是一台计算机上可以同时提供很多个服务,
我们就通过端口号来区别相同计算机所提供的这些不同的服务,

nginx是一个进程,这个进程里面可以同时提供多个服务,每个服务都要使用一个端口号,
也就是每个服务都监听了一个独自的端口
现在假设本机启动nginx,配置文件里面
    server {
        listen       8080;
        listen       [::]:8080;
        server_name  port8080;
        root d:;
        index index.html;
        location / {
            try_files $uri $uri/ /index.html;
        }
        location ^~ /api/dtw/ {
            proxy_pass http://localhost:5001/;
        }
        location ^~ /api/ps/ {
            proxy_pass http://192.168.11.60:5000/;
        }
    }

-------------------------------

# 那么别人访问,我的本机的ip地址加端口时,假设为 192.168.11.18:8080 时
# 就会被nginx进程监听到,该server就会把该请求接收到,根据路由规则,去做对应的事
# 比如当别人访问的网址为192.168.11.18:8080/api/dtw/auth/
# nginx监听到后根据路由规则,转给了http://localhost:5001/
# 并将auth/ 拼到了要转发的ip与端口后面 变成了http://localhost:5001/auth/
# 这样就触发了本地我起的项目的服务了!!!
# 最终我本地项目的数据,
# 就展示到了别人访问的网址192.168.11.18:8080/api/dtw/auth/页面上了
-------------------------------

# 当别人访问 192.168.11.18:8080/1.png  就能拿到我本机的D盘下的1.png图片了
-------------------------------


-------------------------------

.
.
.
.
.

配置实例


########### 每个指令必须有分号结束。#################

# user administrator administrators;       # 配置用户或者组,默认为nobody nobody。
worker_processes 2;  # 允许生成的进程数,默认为1
# pid /nginx/pid/nginx.pid;                # 指定nginx进程运行文件存放地址
# 制定日志路径,级别。这个设置可以放入全局块,http块,server块,
# 级别以此为:debug|info|notice|warn|error|crit|alert|emerg

error_log log/error.log debug;

events {
    accept_mutex on;   # 设置网路连接序列化,防止惊群现象发生,默认为on
    multi_accept on;  # 设置一个进程是否同时接受多个网络连接,默认为off
    #use epoll;      # 事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
    worker_connections  1024;    # 最大连接数,默认为512
}


http {
    include       mime.types;   # 文件扩展名与文件类型映射表
    default_type  application/octet-stream; # 默认文件类型,默认为text/plain
    # access_log off;    # 取消服务日志

    log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
    access_log log/access.log myFormat;  # combined为日志格式的默认值

    sendfile on;   # 允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
    sendfile_max_chunk 100k;  # 每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
    keepalive_timeout 65;  # 连接超时时间,默认为75s,可以在http,server,location块。

    upstream mysvr {
      server 127.0.0.1:7878;
      server 192.168.10.121:3333 backup;  # 热备
    }
    error_page 404 https://www.baidu.com; # 错误页

    server {
        keepalive_requests 120; # 单连接请求上限次数。
        listen       4545;   # 监听端口
        server_name  127.0.0.1;   # 监听地址
        location  ~*^.+$ {
               # 请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
               # 一般直接 / 就行了
           # root path;     # 根目录
           # index vv.txt;   # 设置默认页
           proxy_pass  http://mysvr;  # 请求转向mysvr 定义的服务器列表
           deny 127.0.0.1;     # 拒绝的ip
           allow 172.18.5.54;   # 允许的ip
        }
    }
}


.
.

简单配置


error_log log/error.log debug;
sendfile on;

events {
    accept_mutex on;
    multi_accept on;
    worker_connections  1024;
}

http {
    keepalive_timeout 65;

    upstream mysvr {
      server 127.0.0.1:7878;
      server 192.168.10.121:3333 backup;
    }

    error_page 404 https://www.baidu.com;

	server {
        keepalive_requests 120;
        listen       80;
        server_name  127.0.0.1;
        location / {
           proxy_pass  http://mysvr;
        }
    }
}


.
.

实现不同url路由到不同端口


error_log log/error.log debug;
sendfile on;

events {
    accept_mutex on;
    multi_accept on;
    worker_connections  1024;
}

http {
    keepalive_timeout 65;

    error_page 404 https://www.baidu.com;

	server {
        keepalive_requests 120;
        listen       80;
        server_name  127.0.0.1;
        location ~ /edu/ {
           proxy_pass  http://127.0.0.1:8080;
        }
		location ~ /vod/ {
           proxy_pass  http://127.0.0.1:8081;
        }
    }
}


.
.
.

location匹配表达式


= 开头表示精确匹配如 A 中只匹配根目录结尾的请求,后面不能带任何字符串。

^~ 开头表示uri以某个常规字符串开头,不是正则匹配
开头表示区分大小写的正则匹配;
~* 开头表示不区分大小写的正则匹配

/ 通用匹配, 如果没有其它匹配,任何请求都会匹配到


.
.
.

nginx配置负载均衡


upstream myServer {
    server 192.168.72.49:9090 down;
    server 192.168.72.49:8080 weight=2;
    server 192.168.72.49:6060;
    server 192.168.72.49:7070 backup;
}


1)down
表示单前的server暂时不参与负载


2)Weight
默认为1,weight越大,负载的权重就越大。


3)max_fails
允许请求失败的次数默认为1,当超过最大次数时,返回proxy_next_upstream 模块定义的错误


4)fail_timeout
max_fails 次失败后,暂停的时间。


5)Backup
其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。


-----------------------------------------

.
.
.

nginx配置动静分离


动静分离:

所谓动静分离指的是当访问静态资源时,路由到一台静态资源服务器,
当访问是非静态资源时,路由到另外一台服务器


worker_processes  1;
events {
    worker_connections  1024;
}
http {
   server {
       listen       10000;
       server_name  localhost;

      #拦截后台请求
      location / {
        proxy_pass http://localhost:8888;
        proxy_set_header X-Real-IP $remote_addr;
      }

      #拦截静态资源
      location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|js|css)$ {
        root /Users/dalaoyang/Downloads/static;
        autoindex on;
       }
    }
}



.
.
.

nginx配置高可用集群 (暂时可以先不看)


需要借助keepalived实现

【1】keepalived介绍
Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP (Virtual Router Redundancy Protocol ,虚拟路由器冗余协议)功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件

【2】故障转移机制
Keepalived高可用服务之间的故障切换转移,是通过VRRP 来实现的。
在 Keepalived服务正常工作时,主 Master节点会不断地向备节点发送(多播的方式)心跳消息,用以告诉备Backup节点自己还活着,当主 Master节点发生故障时,就无法发送心跳消息,备节点也就因此无法继续检测到来自主 Master节点的心跳了,于是调用自身的接管程序,接管主Master节点的 IP资源及服务。而当主 Master节点恢复时,备Backup节点又会释放主节点故障时自身接管的IP资源及服务,恢复到原来的备用角色。

【3】keepalived主配置
在nginx主节点机器上安装keepalived;修改keepalived配置如下


Copyvi keepalived.conf
keepalived.conf:
Copy#检测脚本
vrrp_script chk_http_port {
    script "/usr/local/src/check_nginx_pid.sh" #心跳执行的脚本,检测nginx是否启动
    interval 2                          #(检测脚本执行的间隔,单位是秒)
    weight 2                            #权重
}
#vrrp 实例定义部分
vrrp_instance VI_1 {
    state MASTER            # 指定keepalived的角色,MASTER为主,BACKUP为备
    interface ens33         # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) 用ifconfig查看你具体的网卡
    virtual_router_id 66    # 虚拟路由编号,主从要一直
    priority 100            # 优先级,数值越大,获取处理请求的优先级越高
    advert_int 1            # 检查间隔,默认为1s(vrrp组播周期秒数)
    #授权访问
    authentication {
        auth_type PASS #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
        auth_pass 1111
    }
    track_script {
        chk_http_port            #(调用检测脚本)
    }
    virtual_ipaddress {
        192.168.16.130            # 定义虚拟ip(VIP),可多设,每行一个
    }
}


----------------------------------------

keepalived从节点配置
在nginx从节点上安装keepalived;修改配置如下

keepalived.conf:
Copy#检测脚本
vrrp_script chk_http_port {
    script "/usr/local/src/check_nginx_pid.sh" #心跳执行的脚本,检测nginx是否启动
    interval 2                          #(检测脚本执行的间隔)
    weight 2                            #权重
}
#vrrp 实例定义部分
vrrp_instance VI_1 {
    state BACKUP                        # 指定keepalived的角色,MASTER为主,BACKUP为备
    interface ens33                      # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) 用ifconfig查看你具体的网卡
    virtual_router_id 66                # 虚拟路由编号,主从要一直
    priority 99                         # 优先级,数值越大,获取处理请求的优先级越高
    advert_int 1                        # 检查间隔,默认为1s(vrrp组播周期秒数)
    #授权访问
    authentication {
        auth_type PASS #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
        auth_pass 1111
    }
    track_script {
        chk_http_port                   #(调用检测脚本)
    }
    virtual_ipaddress {
        192.168.16.130                   # 定义虚拟ip(VIP),可多设,每行一个
    }
}


----------------------------------------

设置添加检测脚本
Copy#!/bin/bash
#检测nginx是否启动了
A=`ps -C nginx --no-header |wc -l`

if [ $A -eq 0 ];then    #如果nginx没有启动就启动nginx
      systemctl start nginx                #重启nginx
      if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then    #nginx重启失败,则停掉keepalived服务,进行VIP转移
              killall keepalived
      fi
fi


---------------------------------------------

脚本授权:chmod 775 check_nginx_pid.sh

说明:脚本必须通过授权,不然没权限访问啊,在这里我们两条服务器执行、VIP(virtual_ipaddress:192.168.16.130),我们在生产环境是直接通过vip来访问服务。


架构
image
.
.
.
.

内部进程模型


Nginx是以多进程的方式来工作的,当然Nginx也是支持多线程的方式的,
只是我们主流的方式还是多进程的方式,也是Nginx的默认方式。
Nginx采用多进程的方式有诸多好处。


Nginx在启动后,会有一个master进程和多个worker进程。
master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,
监控 worker进程的运行状态,当worker进程退出后(异常情况下),
会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了。
多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。
一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。
worker进程的个数是可以设置的,一般我们会设置与机器CPU核数一致,
这里面的原因与Nginx的进程模型以及事件处理模型是分不开的。

.
.
.

处理请求


首先,Nginx在启动时,会解析配置文件,得到需要监听的端口与IP地址,
然后在Nginx的master进程里面,先初始化好这个监控的socket(创建socket,设置addrreuse
等选项,绑定到指定的IP地址端口,再listen),

然后再fork(一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程 )
出多个子进程出来,然后子进程会竞争accept新的连接。

此时,客户端就可以向Nginx发起连接了。当客户端与Nginx进行三次握手,
与Nginx建立好一个连接后,某一个子进程会accept成功,
得到这个建立好的连接的socket,然后创建Nginx对连接的封装,即ngx_connection_t结构体。


接着,设置读写事件处理函数并添加读写事件来与客户端进行数据的交换。最后,Nginx或客户端来主动关掉连接,到此,一个连接就寿终正寝了。

image

.
.
.
.

windows系统上安装ngnix


# 有个nssm.exe的服务封装程序,它可以将普通exe程序封装成服务,实现开机自启动
# 使用:管理员权限打开命令行工具,切换到nssm.exe所在路径,
# 运行 nssm install,打开程序配置界面即可

配置项说明:
Path:要做成服务的应用程序
Startup directory:应用程序所在的目录
Arguments:应用运行的参数
Service name:生成服务的名称
最后点击install service 完成windows服务安装,在windows服务列表就能看到创建的服务了。

.
image
.
也可以 nssm install teng-ngnix 服务的名称就会自动在弹出框里生成了
image
.
最后点击install service 就完成了
image
.
最后再到计算机管理里面把服务启动一下,就行了
image
.
.

可以看到,当当输入localhost:80 后 只要html文件夹里有index.html文件 就会展示了

image
.

只要是html下的文件,只要在地址栏里端口后面拼上对应的文件名称,就能拿到

image
.
.
.
.

单独给一个server设置日志


.
.
.
.
.

错误页面优化


.
.
.
.
.

posted @   tengyifan  阅读(31)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示