Nginx的安装

# 1. 查看当前目录
pwd

# 2. 下载nginx包

# 3. 解压缩nginx包
# z:使用 gzip 压缩算法进行压缩和解压缩
# x:解压缩操作,将压缩包中的文件提取出来
# v: 在屏幕上显示详细的操作信息, 即输出解压缩过程中的文件名列表(可省略)
# f: 后面需要紧跟着一个文件名参数,用于指定要操作的压缩包文件
tar zxvf 包名

# 4. 打开文件夹,找到configure文件,打开它。
# 会出现保存,因为打开它需要gcc编译器,所以需要安装gcc编译器
# 4.1. 安装gcc编译器
yum install -y gcc
# 4.2. 打开configure文件,并将其安装在/usr/local/nginx
# --prefix:告诉configure脚本,将nginx安装在哪一个目录下
./configure --prefix=/usr/local/nginx

# 但是会出现报错。为什么?缺失依赖
# pcre库:提供正则表达式匹配操作,这个库被许多软件用于处理文本模式匹配和“搜索与替换”文本操作
# pcre-devil库:包含了开发基于pcre库的应用程序所需的头文件和库文件
# zlib:一个用于数据压缩和解压缩的库,提供了多种压缩算法的实现
# zlib-devil库:zlib 库的开发文件包,包含了头文件和库文件
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel


# 5. 执行make
# make: 编译程序。用于自动构建可执行程序和库,它读取一个名为 Makefile 的文件,该文件描述了如何构建目标程序或库,包括需要编译哪些源文件、如何编译这些文件、以及这些文件之间的依赖关系
# make install: 安装程序
make 
make install

Nginx的启动

打开nginx目录:/usr/local/nginx/sbin

# 启动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

Nginx基本使用

目录结构

  • conf:用来存放配置文件相关的
  • html:用来存放静态资源的默认目录
    • index.html:默认页面
  • sbin:存放Ningx可执行文件
  • src: 存放nginx的源代码的
  • proxy_temp:临时目录
  • logs:存放Nginx的日志文件
    • access.log:记录所有的访问请求
    • error.log:记录错误信息
  • nginx.pid:记录了nginx的进程的id号

基本运行原理

image.png

  1. 运行nginx,将会启动一个master进程
  2. master进程将会读取并校验配置文件
  3. 同时master进程将开启多个worker进程,让woker进程来解析用户请求并返回响应

Nginx基础配置

# 我们知道启动nginx会启动master进程,而master会启动多个worker进程,而到底要启动多少呢?取决于下面的命令。

# 建议:对于多核CPU系统,worker_processes 的值建议设置为等于CPU核心数

# 优缺点:worker进程数量越多,nginx并发处理能力越强,但系统资源(如内存、CPU)的消耗会增加。
worker_processes 1;
# events块:这个块主要用于配置Nginx的工作模式以及连接设置
# worker_connections: 定义了每个worker进程允许的最大并发连接数
# 连接: 指的是网络链接,一个客户端与Nginx服务器建立的TCP连接
# 并发:一次性能够同时处理的数量,而实际连接量= worker_connections * worker_processes

# worker_connections调整建议:应该考虑服务器的硬件配置、预期的并发连接数以及Nginx的工作模式(如是否启用了keep-alive)

events {  
    worker_connections  1024;  
}
# http块:主要用于配置与HTTP协议相关的设置,可以拥有多个server块
# server块:主要用于指定主机和端口,在一个server块中,可以包含多个location块,用于匹配特定的URL路径,并定义如何处理这些请求。
# location块:用于匹配网页位置
http {  
    include       mime.types;  
    default_type  application/octet-stream;  
  
    sendfile        on;  
    keepalive_timeout  65;  
  
    server {  
        listen       80;  
        server_name  localhost;  
  
        location / {  
            root   html;  
            index  index.html index.htm;  
        }  
  
        error_page   500 502 503 504  /50x.html;  
        location = /50x.html {  
            root   html;  
        }  
    }  
}
# include:用于包含另外一个文件的内容的,而mine.types文件的内容位于nginx配置目录(conf)下

# mine.types文件,下面会详细讲解

include       mime.types;
# default_type:想象一下,如果nginx接收到一个请求,而该请求指向一个未知扩展名的文件,并且没有其他配置指定该文件的类型,你会怎么做?Nginx将使用 application/octet-stream 作为该文件的MIME类型,这通常会导致浏览器提示用户下载文件,而不是尝试显示或执行它。

# 这样防止了浏览器尝试执行未知文件,从而减少了潜在的安全风险

default_type  application/octet-stream; 
# sendfile: 用于高效数据传输(因为是系统调用)

# sendfile on; 启动sendfile功能,nginx会尽量使用sendfile系统调用来传输静态资源。
# 如:当客户端请求静态文件(图片、视频等)时,Nginx 会使用 sendfile 系统调用将文件数据直接从磁盘传输到客户端的套接字,而不需要先将文件数据读取到用户空间的缓冲区中,然后再写入到套接字的缓冲区中。

# sendfile off; 使用传统的write()和read()来传输数据

sendfile        on;
# keepalive_timeout: 设置长连接的超时时间。
# 什么是长连接?当一个客户端和服务器之间建立了一个长连接后,这个连接可以在指定的超时时间内被多个请求复用,而不是为每个请求都建立一个新的连接。这有助于减少连接建立和关闭的开销,提高性能。

# 单位:秒

# 设置长连接的超时时间为65秒,如果一个客户端在65秒内没有通过已经建立的长连接发送新的请求,那么Nginx将关闭这个连接。
keepalive_timeout  65; 

server块

# 指定服务器监听的端口
# [::]: 表示所有可用的ipv6地址
# 下面的两个确保Nginx在IPv4和IPv6上都可以接受传入的HTTP请求
listen       80;  
listen [::]:80;

# 定义服务器应该响应的域名
server_name  localhost;  

# 当nginx接收一个HTTP请求时,他会根据请求的域名(host头部)和端口号,选择对于的server块来处理该请求。如果请求的域名与某个server块中的server_name指令匹配,并且端口也与listen指令中指定的端口匹配,那么这个服务器块将被选中来处理该请求

# server_name详解:
1. serrve_name可以配置多个域名, 只要请求是这两个的其中一个,都可以响应请求
server_name www.h1.com www.h2.com

2. server_name可以使用 * 匹配,只要请求是 xx.h1.com,都已响应请求,如 a.h1.com, adf.h1.com
server_name *.h1.com

3. 一旦serve_name和端口匹配成功,就不会匹配其他的server块了,从上往下进行匹配

4. server_name可以使用正则进行匹配

# 定义了客户端可以发送到服务器的最大数据量

# 客户端请求主体最大数据为 1024M = 1G
client_max_body_size 1024m;

# 如果超过最大数据,nginx就会报错:413 Request Entity Too Large

# 作用:限制上传文件的大小

location块

# /:匹配所有与 / 开始的URI。会处理网站的所有根路径请求,以及所有子路径请求,因为它是一个前缀匹配
# root:指定请求的资源从哪里获取,html:会去服务器的html目录下查找该文件
# index: 当请求一个目录时,应该尝试返回哪个文件作为默认索引文件

location / {  
    root   html;  
    index  index.html index.htm;  
}
# proxy_pass:将客户端的请求转发到另一个服务器

# 而这里的halo是通过upstream定义,至于upstream是什么?看下文。
proxy_pass http://halo;
# proxy_set_header:用于修改或添加发送到后端服务器的请求头

# HOST: 设置请求头的名称
# $host:这是一个Nginx变量,它包含当前请求的主机名和端口号
# 例如:如果请求是 http://example.com:8080/, 那么 $host 的值将是 example.com:8080
proxy_set_header HOST $host;

# X-Forwarded-Proto:这是一个自定义的请求头
# $scheme:这是一个Nginx变量,代表原始请求的协议。如果请求是通过 HTTP 发起的,$scheme 的值就是 http;如果请求是通过 HTTPS 发起的,$scheme 的值就是 https

# 这句话的意思是:如果客户端通过 HTTPS (https://example.com) 访问 Nginx,然后 Nginx 将请求代理到后端服务器,那么 Nginx 会在请求头中添加 X-Forwarded-Proto: https。这样,后端服务器就能知道原始请求是通过 HTTPS 进行的,即使它实际接收到的请求是一个普通的 HTTP 请求。
proxy_set_header X-Forwarded-Proto $scheme;

# $remote_addr:客户端的 IP 地址。请求到达 Nginx 时,这个变量会被自动填充为发起请求的客户端的 IP 地址
proxy_set_header X-Real-IP $remote_addr;

# X-Forwarded-For:表示 HTTP 请求的来源 IP 地址
# $proxy_add_x_forwarded_for:含原始客户端的 IP 地址以及任何之前代理服务器添加的 X-Forwarded-For 头信息。如果 Nginx 不是第一个代理服务器,那么通常 X-Forwarded-For 头信息已经存在,并且 $proxy_add_x_forwarded_for 会将原始客户端的 IP 地址添加到现有的头信息中,而不是替换它
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

upstream块

# 定义一个服务器组

# 其中的每一个server定义了一个后端服务器的地址和端口

# 一旦定义了 upstream 块,您就可以在Nginx配置的其他位置通过 proxy_pass 指令引用这个服务器组,从而将请求代理到这个组中的一个或多个服务器上

# upstream可以定义多个server,至于代理哪一个服务,取决于负载均衡算法。默认情况下是一人一下。

upstream halo {  
  server 127.0.0.1:8090;  
  server 127.0.0.1:163;
}

# 而至于到底代理哪个?取决于权重weight
# 当请求8次,访问127.0.0.1:8090,再请求2次,访问127.0.0.1:163
upstream halo {  
  server 127.0.0.1:8090 weight=8;  
  server 127.0.0.1:163 weight=2;
}

# 如果不想要参与反向代理使用down
upstream halo {  
  server 127.0.0.1:8090 weight=8 down;  
  server 127.0.0.1:163 weight=2;
}

DNS域名解析

image-hami.png

  1. 当用户在浏览器中访问域名时,会先进行本地查询。先去找hosts,再去找本地缓存。若本地查询命中,则直接返回;未命中,则需要访问线上的 DNS 服务器进行解析
  2. 线上 DNS 解析主要包含:Local DNS 服务器、根域 DNS 服务器、顶级域 DNS 服务器、权威域 DNS 服务器。Local DNS 服务器不在客户端本地,一般为运营商提供的线上 DNS 服务器;权威 DNS 是特定域名记录在域名注册商处所设置的 DNS 服务器,用于特定域名本身的管理。
  3. 线上查询主要分为递归查询和迭代查询:递归查询是浏览器把任务交给 Local DNS ,然后等待 Local DNS 返回结果;迭代查询是 Local DNS 分别向各级 DNS 服务器发送查询请求,直到获取 DNS 解析结果为止。
  4. 总的来说,客户端向 Local DNS 服务器进行查询,如果命中 Local DNS 服务器的缓存,直接返回 IP;没有命中,Local DNS 服务器会向各级域名服务器进行查询,直到最终解析出 IP 为止

反向代理和负载均衡

image-tjol.png

小明访问百度,代理服务器可能会给小明分配服务器资源1。

小红访问百度,代理服务器可能会给小红分配服务器资源2。

这样子就可以让服务器资源更加的轻松。

举一个简单的例子:小王是一名餐厅的服务员,他每天的工作就是洗碗。顾客越多,他洗的碗就越多,他就越累。此时,又来了一位服务员小李,他可以分担小王洗碗的一部分工作,这样子,小王就不会那么累。而且工作效率也很高。这就是负载均衡。而小王、小李洗多少碗,取决于负载均衡算法。

负载均衡算法