WEB服务器-Nginx源码安装及相关配置

一、web服务的常用种类

  1. Apache HTTP Server

  • 简介:Apache是一款广泛使用的Web服务器软件,支持多种操作系统,包括Linux。​​​​​​​
  • 特点

                    支持多个虚拟主机。

                     模块化架构,可以根据需要加载不同的模块。

                     强大的安全性配置选项。

  1. Nginx(公司常用)

  • 简介:Nginx是一个高性能的HTTP和反向代理Web服务器,同时也提供了IMAP/POP3/SMTP服务。
  • 特点

                    高并发连接处理能力。

                    反向代理和负载均衡。

                     优秀的稳定性。

对比总结:

  • 性能和资源消耗:Nginx在处理静态文件和高并发连接方面优于Apache,而Apache在处理动态内容方面更加强大。
  • 配置复杂度:Nginx的配置通常比Apache更加简单直观。
  • 功能丰富度:Apache提供了更多的内置功能和模块,而Nginx则更加专注于高性能和轻量级的服务。

二、Nginx 概述

Nginx:engine X ,2002年开发,分为社区版和商业版(nginx plus )

2019年3月11日 F5 Networks 6.7亿美元的价格收购

Nginx是免费的、开源的、高性能的HTTP和反向代理服务器、邮件代理服务器、以及TCP/UDP代理服务 器

解决C10K问题(10K Connections)

Nginx官网:http://nginx.org

nginx的其它的二次发行版:

Tengine:由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加 了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了 很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。从2011年12月开始, Tengine成为一个开源项目官网: http://tengine.taobao.org/
OpenResty:基于 Nginx 与 Lua 语言的高性能 Web 平台, 章亦春团队开发,官网:http://openr esty.org/cn/

 Ng​​​​​​​inx 功能介绍

静态的web资源服务器html,图片,js,css,txt等静态资源 
http/https协议的反向代理
结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
tcp/udp协议的请求转发(反向代理)
imap4/pop3协议的反向代理

基础特性

模块化设计,较好的扩展性
高可靠性
支持热部署:不停机更新配置文件,升级版本,更换日志文件
低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存
event-driven,aio,mmap,sendfile

Web 服务相关的功能

虚拟主机(server)
支持 keep-alive 和管道连接(利用一个连接做多次请求)
访问日志(支持基于日志缓冲提高其性能)
url rewirte
路径别名
基于IP及用户的访问控制
支持速率限制及并发数限制
重新配置和在线升级而无须中断客户的工作进程

三、Nginx源码安装

直接下载压缩包到/home家目录进行操作

3.1 下载所需环境

dnf install gcc pcre-devel zlib-devel openssl-devel -y

源码安装需要提前准备标准的编译器,GCC的全称是(GNU Compiler collection),其有GNU开发,并以GPL即LGPL许可,是自由的类UNIX即苹果电脑Mac OS X操作系统的标准编译器,因为GCC原本只能处理C语言,所以原名为GNU C语言编译器,后来得到快速发展,可以处理C++,Fortran,pascal,objective,java以及Ada等其他语言,此外还需要Automake工具,以完成自动创建Makefile的工作,Nginx的一些模块需要依赖第三方库,比如: pcre(支持rewrite),zlib(支持gzip模块)和openssl(支持ssl模块)等。

3.2 下载官方源码包

tar zxf nginx-1.24.0.tar.gz

解压

tar zxf nginx-1.24.0.tar.gz

解压完成后进入目录

cd nginx-1.24.0

创建Nginx源码安装的用户

useradd  -s /sbin/nologin -M nginx

3.3 源码安装

1.编译

./configure --prefix=/usr/local/nginx --add-module=/root/echo-nginx-module-0.63 --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module

没有erroe错误提示则表示成功,错误多半是上面的环境没有准备

安装完成后nginx-1.24.0目录下会多出Makefile和objs两个文件目录

可以使用./configure --help命令查看命令帮助

参数解释:

./configure --prefix=/usr/local/nginx \

--user=nginx \                                  # 指定nginx运行用户

--group=nginx \                                # 指定nginx运行组

--with-http_ssl_module \                  # 支持https://

--with-http_v2_module \                   # 支持http版本2

--with-http_realip_module \              # 支持ip透传

--with-http_stub_status_module \    # 支持状态页面

--with-http_gzip_static_module \     # 支持压缩

--with-pcre \                                     # 支持正则

--with-stream \                                 # 支持tcp反向代理

--with-stream_ssl_module \             # 支持tcp的ssl加密

--with-stream_realip_module          # 支持tcp的透传ip

 2.安装

make && make install

 make  -j2                 源文件与系统C语言文件开始对接,可以使用-j指定编译时的CUP内核

make install               将objs目录中的东西拷贝到指定的目录/usr/local/nginx/

3 启动Nginx

 进入Nginx配置目录

cd /usr/local/nginx/

找到Nginx的启动程序

sbin/下有一个名叫nginx的可执行程序,这就是nginx的启动程序

cd sbin/

ll

执行/usr/local/nginx/sbin/nginx启动nginx

/usr/local/nginx/sbin/nginx

4.查看nginx是否启动

ps aux |grep nginx                             查看进程

netstat -antlupe | grep nginx                  查看端口号

netstat不存在时安装whatprovides包

dnf whatprovides */netstat  

5.访问

curl 172.25.254.130       #本机的ip地址

第三行看到Welcome to nginx!表示成功

6.nginx相关配置目录

/usr/local/nginx/conf

/usr/local/nginx/conf/nginx.conf 配置文件

7.查看版本

dnf list nginx

curl -I 172.25.254.130

8. 关闭nginx程序

/usr/local/nginx/sbin/nginx   -s   stop 

如果关闭不了

 ps aux |grep nginx查看进程号,然后使用kill -9 进程 杀死进程

9.启动Nginx

nginx     已经写入环境变量文件vim ~/.bash_profile

/usr/local/nginx/sbin/nginx
或者
/usr/local/nginx/sbin/nginx    -s    restart

10. 如果有问题直接卸载

rm  -rf  /usr/local/nginx/                      #相对于取消make && make install

make clean                                        #清除第1步编译./configure --prefix.....产生的配置文件

或者直接删除解压nginx压缩包的目录nginx-1.24.0/

 从第一步开始重新安装,可以是某个地方做错

3.4 Nginx配置调优

1. 关闭debug功能

查看/usr/local/nginx/sbin/nginx的大小,内存比较大,因为有debug模式,可以关掉

[root@localhost sbin]# du -sh nginx
5.5M    nginx

vim nginx-1.24.0/auto/cc/gcc 找到debug将下面一行注释 ,关闭debug

#debug
#CFLAGS="$CFLAGS -g"

2. 添加环境变量

将/usr/local/nginx/sbin写入环境变量文件vim ~/.bash_profile ,这样以后在任何地方直接执行nginx可以启动nginx程序

[root@localhost ~]# vim ~/.bash_profile 
export PATH=$PATH:/usr/local/nginx/sbin
[root@localhost ~]# source ~/.bash_profile 

添加到环境变量中以后,nginx==/usr/local/nginx/sbin/nginx  

 3. 启动脚本编写

vim /lib/systemd/system/nginx.service

[Unit]Description=The NGINX HTTP and reverse proxy serverAfter=syslog.target network-online.target remote-fs.target nss-lookup.targetWants=network-online.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

重启配置并检测生效

[root@localhost sbin]# systemctl daemon-reload 
[root@localhost sbin]# nginx -s stop
[root@localhost sbin]# ps aux | grep nginx
root       21627  0.0  0.0   6408  2296 pts/0    S+   01:53   0:00 grep --color=auto nginx
[root@localhost sbin]# systemctl enable --now nginx.service 
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@localhost sbin]# ps aux | grep nginx
root       21665  0.0  0.0   9920   940 ?        Ss   01:54   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      21666  0.0  0.0  13760  4792 ?        S    01:54   0:00 nginx: worker process
root       21668  0.0  0.0   6408  2300 pts/0    S+   01:54   0:00 grep --color=auto nginx
[root@localhost sbin]# 

4. 在系统中设置nginx的最大链接数

vim /etc/security/limits.conf    在最下面添加以下内容

nginx - nofile 100000

5. 更改nginx配置文件

添加的内容是汉字注释下面的,如:#参数优化1,用户

vim /usr/local/nginx/conf/nginx.conf

#参数优化1,用户
user  nginx;
#参数优化2,内核
worker_processes  auto;
#四核
worker_cpu_affinity 0001 0010 0100 1000;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

#参数优化3,系统支持nginx打开的最大链接数量
events {
    worker_connections  100000;
}


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;
...................................下面不用改,省略

nginx -s reload 重启nginx

查看

ps aux | grep nginx 查看内核数量

sudo -u nginx ulimit -a 下的open files 后的数量

3.5 平滑升级与版本回滚

3.5.1 平滑升级

有时候我们需要对 Nginx 版本进行升级以满足对其功能的需求,例如添加新模块,需要新功能,而此时Nginx有业务无法停掉,这时我们就可以选择平滑升级。

步骤:

  • 将旧 Nginx 二进制文件换成新 Nginx 程序文件(注意先备份 )
  • 向 master 进程发送 USR2 信号
  • master 进程修改 pid 文件名加上后缀 .oldbin, 成为 nginx.pid.oldbin
  • master 进程用新 Nginx 文件启动新 master 进程成为旧 master 的子进程 , 系统中将有新旧两个 Nginx 主
  • 进程共同提供 Web 服务 , 当前新的请求仍然由旧 Nginx 的 worker 进程进行处理 , 将新生成的 master 进程的 PID 存放至新生成的 pid 文件 nginx.pid
  • 向旧的 Nginx 服务进程发送 WINCH 信号,使旧的 Nginx worker 进程平滑停止
  • 向旧 master 进程发送 QUIT 信号,关闭老 master ,并删除 Nginx.pid.oldbin 文件
  • 如果发现升级有问题 , 可以回滚∶向老 master 发送 HUP ,向新 master 发送 QUIT

配置:

1.下载新版本并解压编译

[root@Nginx nginx]# tar zxf nginx-1.26.1.tar.gz
[root@Nginx nginx]# cd nginx-1.26.1/
[root@Nginx nginx-1.26.1]# ./configure --with-http_ssl_module --withhttp_v2_module --with-http_realip_module --with-http_stub_status_module --withhttp_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --
with-stream_realip_module
[root@Nginx nginx-1.26.1]# make           

2.此时可以查看到两个版本

[root@Nginx nginx-1.26.1]# ll objs/nginx /usr/local/nginx/sbin/nginx
-rwxr-xr-x 1 root root 1239416 Jul 18 15:08 objs/nginx
-rwxr-xr-x 1 root root 5671488 Jul 18 11:41 /usr/local/nginx/sbin/nginx

3.将旧版本的nginx命令备份并将新版本的nginx命令复制过去

[root@Nginx ~]# cd /usr/local/nginx/sbin/
[root@Nginx sbin]# cp nginx nginx.24
[root@Nginx sbin]# \cp -f /root/nginx/nginx-1.26.1/objs/nginx  /usr/local/nginx/sbin

USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的nginx,此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80,此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。

[root@Nginx sbin]# ps aux | grep nginx  
[root@Nginx sbin]# kill -USR2 46548

5.回收旧版本

[root@Nginx sbin]# kill -WINCH 46548

6.检测版本信息

[root@Nginx sbin]# curl -I localhost

3.5.2 版本回滚

如果升级的版本有问题可以回滚

1.重新拉起旧版本的worker

[root@Nginx sbin]# cp nginx nginx.26
[root@Nginx sbin]# ls
nginx nginx.24 nginx.26
[root@Nginx sbin]# mv nginx.24 nginx
mv: overwrite 'nginx'? y

2.重新加载旧版本进程

[root@Nginx sbin]# kill -HUP 48732

3.回收新版本进程

[root@Nginx sbin]# kill -WINCH 52075

6.检测版本信息

[root@Nginx sbin]# curl -I localhost

四、Nginx相关实验配置

4.1 Nginx配置文件说明

配置文件位置:

·主配置文件:/usr/local/nginx/conf/nginx.conf

·子配置文件:/usr/local/nginx/conf.d/*.conf

子配置文件格式说明:
  • 配置文件由指令与指令块构成
  • 每条指令以;分号结尾,指令与值之间以空格符号分隔
  • 可以将多条指令放在同一行,用分号分隔即可,但可读性差,不推荐
  • 指令块以{ }大括号将多条指令组织在一起,且可以嵌套指令块
  • include语句允许组合多个配置文件以提升可维护性
  • 使用#符号添加注释,提高可读性
  • 使用$符号使用变量
  • 部分指令的参数支持正则表达式
主配置文件结构:

共四部分

main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
  ...
}
 
#http/https 协议相关配置段
http {
  ...
}
 
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
  ...
}
 
#stream 服务器相关配置段
stream {
  ...
}

主配置文件命令解释
[root@nginx-node1 ~]# vim /usr/local/nginx/conf/nginx.conf
#全局配置或默认配置,设置nginx的启动用户/组,启动的工作进程数量,工作模式,Nginx的PID路径,日志路径等。
#user  nobody;
worker_processes  1;                              #启动工作进程数数量#error_log  logs/error.log;                       
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#pid        logs/nginx.pid;events {                                          #设置块,主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多个网络连接,使用哪种事件驱动模型#处理请求,每个工作进程可以同时支持的最大连接数,是否开启对多工作进程下的网络连接进行序列化等。worker_connections  1024;                     #设置单个nginx工作进程可以接受的最大并发,作为web服务器的时候最大并发数为worker_connections *worker_processes,#作为反向代理的时候为(worker_connections * worker_processes)/2
}http {                                             ##http块是Nginx服务器配置中的重要部分,缓存、代理和日志格式定义等绝大多数功能和第三方模块都可以在这设置,#http块可以包含多个server块,而一个server块中又可以包含多个location块,#server块可以配置文件引入、MIME-Type定义、日志自定义、是否启用sendfile、连接超时时间和单个链接的请求上限等。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;sendfile        on;                             #作为web服务器的时候打开sendfile加快静态文件传输,指定是否使用sendfile系统调用来传输文件#sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作)从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝,#硬盘 >> kernel buffer (快速拷贝到kernelsocketbuffer) >>协议栈。#tcp_nopush     on;#keepalive_timeout  0;keepalive_timeout  65;                          #长连接超时时间,单位是秒#gzip  on;server {                                        #设置一个虚拟机主机,可以包含自己的全局块,同时也可以包含多个location模块##比如本虚拟机监听的端口、本虚拟机的名称和IP配置,多个server可以使用一个端口比如都使用80端口提供web服务listen       80;                            #配置server监听的端口server_name  localhost;                     #本server的名称,当访问此名称的时候nginx会调用当前serevr内部的配置进程匹配。#charset koi8-r;#access_log  logs/host.access.log  main;location / {                               #location其实是server的一个指令,为nginx服务器提供比较多而且灵活的指令都是在location中体现的,#主要是基于nginx接受到的请求字符串对用户请求的UIL进行匹配,并对特定的指令进行处理#包括地址重定向、数据缓存和应答控制等功能都是在这部分实现,另外很多第三方模块的配置也是在location模块中配置。root   html;                           #相当于默认页面的目录名称,默认是安装目录的相对路径,可以使用绝对路径配置。index  index.html index.htm;           #默认的页面文件名称}#error_page  404              /404.html;       #错误页面的文件名称# redirect server error pages to the static page /50x.html#error_page   500 502 503 504  /50x.html;location = /50x.html {                          #location处理对应的不同错误码的页面定义到/50x.html,这个跟对应其server中定义的目录下。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;#}# 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 server##server {#    listen       443 ssl;#    server_name  localhost;#    ssl_certificate      cert.pem;#    ssl_certificate_key  cert.key;#    ssl_session_cache    shared:SSL:1m;#    ssl_session_timeout  5m;#    ssl_ciphers  HIGH:!aNULL:!MD5;#    ssl_prefer_server_ciphers  on;#    location / {#        root   html;#        index  index.html index.htm;#    }#}}#和邮件相关的配置
#mail {
# ...
# } mail 协议相关配置段#tcp代理配置,1.9版本以上支持
#stream {
# ...
# } stream 服务器相关配置段
#导入其他路径的配置文件
#include /apps/nginx/conf.d/*.conf
}

4.2 root和alias

root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location
alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于
location上下文,此指令使用较少。
注意: root, 给定的路径对应于 location 中的 /uri 左侧的 /
           alias , 给定的路径对应于 location 中的 /uri 的完整路径
1.使用epoll事件驱动并将子配置文件目录映射到主配置文件中,重载文件

[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
events {
    worker_connections  100000;
    use epoll;                                #使用epoll事件驱动
}
http  {
    ######
    include "/usr/local/nginx/conf.d/*.conf"; #在响应报文中将指定的文件扩展名映射至MIME对应的类型
    ######
}

nginx -s reload    重启服务
 

2.创建子配置文件并写入规则,重载文件

[root@nginx ~]# mkdir -p /usr/local/nginx/conf.d
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf 
server {
        listen 80;
        server_name www.rhel9.org;
        root /data/web/html;
        index index.html;
}

nginx -s reload                      重启

3.写入测试文字

echo www.rhel9.org > /data/web/html/index.html 

4.测试

记得做本地解析

server {
    listen 80;
    server_name web.rhel9.org;
 
    location /dirtest {                    #必须建立/mnt/dirtest才能访问
        root /mnt;
    }
 
    location /alias {                      #使用alias的时候uri后面如果加了斜杠,则下面的路径配置
必须加斜杠,否则403
        alias /mnt/dirtest;                #当访问alias的时候,会显示alias定义的/mnt/dirtest
里面的内容
}

4.3 location       

在一个 server 中 location 配置段可存在多个,用于实现从 uri到文件系统的路径映射, ngnix 会根据用户请求的 URI 来检查定义的所有 location ,按一定的优先级找出一个最佳匹配, 而后应用其配置在没有使用正则表达式的时候, nginx 会先在 server 中的多个 location 选取匹配度最 高的一个 uri, uri 是用户请求的字符串,即域名后面的 web 文件路径, 然后使用该 location 模块中的正则 url 和字符串,如果匹配成功就结束搜索,并使用此 location 处理 此请求。

匹配优先级: =, ^~, ~ / ~ * , /
location 优先级: (location =) > (location ^~ 路径 ) > (location ~,~* 正则顺序 ) > (location 完整路径 ) > (location 部分起始路径 ) > (/)

匹配符号说明
=用于标准 uri 前,需要请求字串与 uri 精确匹配,大小敏感 , 如果匹配成功就停止向下匹配并立即处理请求
^~用于标准 uri 前,表示包含正则表达式 ,并且匹配以指定的正则表达式开头,对 uri 的最左边部分做匹配检查,不区分字符大小写
~用于标准 uri 前,表示包含正则表达式 , 并且区分大小写
~*用于标准 uri 前,表示包含正则表达式 , 并且不区分大写
不带符号匹配起始于此 uri 的所有的 uri
\用于标准 uri 前,表示包含正则表达式并且转义字符。可以将 . * ? 等转义为普通符号

示例配置:

server {
    listen 80;
    server_name www.rhel9.org;
 
    location / {
        root /data/web/html/ccc;
    }
 
    location ^~ /images {
        root /data/web/html/ccc;
        index index.html;
    }
 
    location /images1 {
        root /data/web/html/ccc;
    }
 
    location ~* \.(gif|jpg|jpeg|bmp|png|tiff|tif|ico|wmf|js)$ {
        root /data/web/html/ccc;
        index index.html;
    }
}

4.4 用户认证功能

1.创建用户,完成后可查看信息

[root@nginx ~]# htpasswd -cm /usr/local/nginx/.htpasswd admin
New password: 
Re-type new password: 
Adding password for user admim
 
[root@nginx ~]# htpasswd -m /usr/local/nginx/.htpasswd ccc
New password: 
Re-type new password: 
Adding password for user ccc
 
[root@nginx ~]# cat /usr/local/nginx/.htpasswd 
admin:$apr1$okMzYJLu$Sk/0N1AUZoDjgpldJUi2a0
ccc:$apr1$DMbv5BB8$HbeB4TMW9UZfAScnzjkq.1

2.创建文件并写入测试文字

[root@nginx ~]# mkdir /data/web/ccc
[root@nginx ~]# echo ccc > /data/web/ccc/index.html 

3.子配置文件中写入规则并重启

[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf 
        location /ccc {
                root /data/web;
                auth_basic "login password !!!";                   #用户在浏览器看到的认证信息提示
                auth_basic_user_file "/usr/local/nginx/.htpasswd"; #http认证文件路径
        }

nginx -s reload         重启服务配置

访问,去Windows浏览器访问,输入创建的用户名和密码

4.5 自定义错误日志

自 定义错误页,同时也可以用指定的响应状态码进行响应

可用位置: http, server, location, if in location

error_page code ... [=[response]] uri;

示例:

listen 80;
server_name www.timinglee.org;
error_page 500 502 503 504 /error.html;
location = /error.html {
root /data/nginx/html;
}

重启 nginx 并访问不存在的页面进行测试

示例:自定义错误页面

[root@nginx ~]# mkdir /webdata/nginx/timinglee/lee/errors -p

[root@nginx ~]# echo error page > /webdata/nginx/timinglee/lee/errors/40x.html

[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf

server {
    listen 80;
    server_name www.timinglee.org;
    error_page 404 /40x.html;
    location = /40x.html {
        root /webdata/nginx/timinglee/lee/errors;
    }
}

测试:

[root@nginx ~]# nginx -s reload
[root@nginx ~]# 

[root@nginx ~]# curl www.timinglee.org/40x.html/
error page

4.6 自定义错误日志

可以自定义错误日志

Syntax: error_log file [level];
Default:
error_log logs/error.log error;
Context: main, http, mail, stream, server, location
level: debug, info, notice, warn, error, crit, alert, emerg

示例:

[root@nginx ~]#  mkdir "/var/log/nginx" -p
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf 

server {
    listen 80;
    server_name www.timinglee.org;
    error_page 404 /40x.html;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    location = /40x.html {
        root /webdata/nginx/timinglee/lee/errors;
    }
}

重启nginx并访问不存在的页面进行测试并验证是在指定目录生成新的日志文件

[root@nginx ~]# nginx -s reload
[root@nginx ~]# curl www.timinglee.org/40x.html/
error page
[root@nginx ~]# cd /var/log/nginx/
[root@nginx nginx]# ls
access.log  error.log

4.7 检测文件是否存在

try_files 会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI 的指向。最后一个参数是回退 URI 且必须存在,否则会出现内部500 错误
语法格式

Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location

示例 : 如果不存在页面 , 就转到 default.html 页面

[root@nginx nginx]# mkdir -p /webdata/nginx/timinglee.org/lee/error/
[root@nginx nginx]# echo "index.html is not exist" > /webdata/nginx/timinglee.org/lee/error/default.html
[root@nginx nginx]# vim /usr/local/nginx/conf.d/vhosts.conf 
server {
    listen 80;
    server_name www.timinglee.org;

    #location /login {
    #    root /webdata/nginx/timinglee.org/lee;
    #    index index.html;
    #    auth_basic "login password";
    #    auth_basic_user_file "/usr/local/nginx/conf/.htpasswd";
    #}
    root /webdata/nginx/timinglee.org/lee;
    error_page 404 /40x.html;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    try_files $uri $uri.html $uri/index.html /error/default.html;
    location = /40x.html {
        root /webdata/nginx/timinglee/lee/errors;
    }
}

测试:

[root@nginx ~]# nginx -s reload

[root@nginx ~]# curl www.timinglee.org/40x.html/
index.html is not exist

4.8 长连接配置

keepalive_timeout timeout [header_timeout];         #设定保持连接超时时长, 0 表示禁止长连接,默认为75s
                                                                        #通常配置在http字段作为站点全局配置
keepalive_requests 数字;                                 #在一次长连接上所允许请求的资源的最大数量
                                                                                #默认为100次,建议适当调大,比如:500

示例:

keepalive_requests 3;
keepalive_timeout 65 60;
# 开启长连接后,返回客户端的会话保持时间为 60s ,单次长连接累计请求达到指定次数请求或 65 秒就会被断
开,第二个数字 60 为发送给客户端应答报文头部中显示的超时时间设置为 60s :如不设置客户端将不显示超时时间。
Keep-Alive:timeout=60                         #浏览器收到的服务器返回的报文
                                                        #如果设置为0表示关闭会话保持功能,将如下显示:
                                                                #Connection:close 浏览器收到的服务器返回的报文
# 使用命令测试:
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
keepalive_timeout  65 60;
keepalive_requests  500;
[root@nginx ~]# telnet www.timinglee.org 80
Trying 192.168.10.140...
Connected to www.timinglee.org.
Escape character is '^]'.
GET / HTTP/1.1                ##输入动作
HOST: www.timinglee.org        ##输入访问HOST

                                                    ##输入回车

HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 20 Aug 2024 14:51:18 GMT
Content-Type: text/html
Content-Length: 24
Last-Modified: Tue, 20 Aug 2024 14:36:54 GMT
Connection: keep-alive
Keep-Alive: timeout=60
ETag: "66c4aa06-18"
Accept-Ranges: bytes

index.html is not exist

Trying 192.168.10.140...
Connected to www.timinglee.org.
Escape character is '^]'.
GET / HTTP/1.1                    #第一次操作     
HOST: www.timinglee.org                #第二次操作

                                                        #第三次操作

HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 20 Aug 2024 14:51:18 GMT
Content-Type: text/html
Content-Length: 24
Last-Modified: Tue, 20 Aug 2024 14:36:54 GMT
Connection: keep-alive
Keep-Alive: timeout=60
ETag: "66c4aa06-18"
Accept-Ranges: bytes

index.html is not exist

Connection closed by foreign host.          # 自动断开链接

4.9 作为下载服务器配置

ngx_http_autoindex_module 模块处理以斜杠字符 "/" 结尾的请求,并生成目录列表 , 可以做为下载服务配置使用

相关指令:

autoindex on | off; # 自动文件索引功能,默为 off
autoindex_exact_size on | off; # 计算文件确切大小(单位 bytes ), off 显示大概大小(单位 K、 M),默认 on
autoindex_localtime on | off ; # 显示本机时间而非 GMT( 格林威治 ) 时间,默认 off
autoindex_format html | xml | json | jsonp; # 显示索引的页面文件风格,默认 html
limit_rate rate; # 限制响应客户端传输速率 ( 除 GET 和 HEAD 以外的所有方法 ) ,单位
B/s,bytes/second , # 默认值 0, 表示无限制 , 此指令由ngx_http_core_module提供
set $limit_rate 4k; # 也可以通变量限速 , 单位 B/s, 同时设置 , 此项优级高 .

示例:实现下载站点

注意 :download 不需要 index.html 文件


    location /download {
        autoindex on;        #自动索引功能
        autoindex_exact_size on;     #计算文件确切大小(单位bytes),此为默认值,off只显示

大概大小(单位 kb 、 mb 、 g[root@nginx ~]#  mkdir -p /webdata/nginx/timinglee.org/lee/download
[root@nginx ~]# cp /root/anaconda-ks.cfg /webdata/nginx/timinglee.org/lee/download
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf 
server {
    listen 80;
    server_name www.timinglee.org;
    root /webdata/nginx/timinglee.org/lee;
    error_page 404 /40x.html;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    try_files $uri $uri.html $uri/index.html /error/default.html;
    location = /40x.html {
        root /webdata/nginx/timinglee/lee/errors;
    }b)

        autoindex_localtime on;        #on表示显示本机时间而非GMT(格林威治)时间,默为为off显示GMT时间

        limit_rate 1024k;        #限速,默认不限速
    }
}

重启 Nginx 并访问测试下载页面

五、高级配置

5.1 状态页

  • 基于nginx 模块 ngx_http_stub_status_module 实现,
  • 在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module
  • 否则配置完成之后监测会是提示法错误

配置:

location /nginx_status {
        stub_status;
        auth_basic "auth login";
        auth_basic_user_file /apps/nginx/conf/.htpasswd;
        allow 192.168.0.0/16;
        allow 127.0.0.1;
        deny all;
}
# 状态页用于输出 nginx 的基本状态信息:
# 输出信息示例:
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
上面三个数字分别对应 accepts,handled,requests 三个值
Reading: 6 Writing: 179 Waiting: 106
Active connections:         #当前处于活动状态的客户端连接数
                                        #包括连接等待空闲连接数=reading+writing+waiting
accepts:                         #统计总值,Nginx 自启动后已经接受的客户端请求连接的总数。
handled:                         #统计总值,Nginx自启动后已经处理完成的客户端请求连接总数
                                        #通常等于accepts,除非有因worker_connections限制等被拒绝的
连接
requests:                         #统计总值,Nginx自启动后客户端发来的总的请求数
Reading:                                 #当前状态,正在读取客户端请求报文首部的连接的连接数
                                                #数值越大,说明排队现象严重,性能不足
Writing:                                 #当前状态,正在向客户端发送响应报文过程中的连接数,数值越大, 说明访问量很大
Waiting:                                 #当前状态,正在等待客户端发出请求的空闲连接数
                                           开启 keep-alive的情况下,这个值等于active –(reading+writing)

5.2 压缩功能

Nginx 支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,样有助于降低出口带宽的利用率,降低企业的IT 支出,不过会占用相应的CPU 资源。
Nginx 对文件的压缩功能是依赖于模块 ngx_http_gzip_module, 默认是内置模

指令说明:

gzip on | off; 启用或禁用 gzip 压缩,默认关闭
gzip_comp_level 4;压缩比由低到高从 1 到 9 ,默认为 1 ,值越高压缩后文件越小,但是消耗 cpu 比较高。基本设定未 4 或者 5
gzip_disable "MSIE [1-6]\."; 禁用 IE6 gzip 功能,早期的 IE6 之前的版本不支持压缩
gzip_min_length 1k;gzip 压缩的最小文件,小于设置值的文件将不会压缩
gzip_http_version 1.0 | 1.1; 启用压缩功能时,协议的最小版本,默认 HTTP/1.1
gzip_buffers number size;指定 Nginx 服务需要向服务器申请的缓存空间的个数和大小 , 平台不同 , 默认 :32 4k 或者 16 8k;
gzip_types mime-type ...;指明仅对哪些类型的资源执行压缩操作 ; 默认为 gzip_types text/html ,不用显示指定,否则出错
gzip_vary on | off;如果启用压缩,是否在响应报文首部插入 “Vary: Accept-Encoding”, 一般建议打开
gzip_static on | off;

 预压缩,即直接从磁盘找到对应文件的 gz 后缀的式的压缩文件返回给用户,无需消耗服务器 CPU

注意 : 来自于 ngx_http_gzip_static_module 模块

配置:

[root@nginx ~]# mkdir /webdata/nginx/timinglee.org/lee/data -p
[root@nginx ~]#  cp /usr/local/nginx/logs/access.log /webdata/nginx/timinglee.org/lee/data/data.txt
[root@nginx ~]# ll /webdata/nginx/timinglee.org/lee/data/data.txt
-rw-r--r-- 1 root root 2494866 Aug 20 23:18 /webdata/nginx/timinglee.org/lee/data/data.txt
[root@nginx ~]# echo test > /webdata/nginx/timinglee.org/lee/data/test.html         #小于1k 的文件测试是否会压缩
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
gzip  on;
gzip_comp_level  5;
gzip_min_length  1k;
gzip_types text/plain application/javascript application/x-javascript text/css
application/xml text/javascript application/x-httpd-php image/gif image/png;
gzip_vary on;
# 重启 Nginx 并访问测试:
[root@nginx ~]# nginx -s reload
[root@nginx ~]# 

[root@nginx ~]# curl --head --compressed www.timinglee.org/data/test.html
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 20 Aug 2024 15:25:51 GMT
Content-Type: text/html
Content-Length: 5
Last-Modified: Tue, 20 Aug 2024 15:18:58 GMT
Connection: keep-alive
Keep-Alive: timeout=60
ETag: "66c4b3e2-5"
Accept-Ranges: bytes

[root@nginx ~]# curl --head --compressed www.timinglee.org/data/data.txt
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Tue, 20 Aug 2024 15:26:08 GMT
Content-Type: text/plain
Last-Modified: Tue, 20 Aug 2024 15:18:05 GMT
Connection: keep-alive
Keep-Alive: timeout=60
Vary: Accept-Encoding
ETag: W/"66c4b3ad-261192"
Content-Encoding: gzip

5.3 变量

  • nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用
  • 变量可以分为内置变量和自定义变量
  • 内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。
5.3.1 内置变量

常用内置变量

$remote_addr;
# 存放了客户端的地址,注意是客户端的公网 IP
$args;
# 变量中存放了 URL 中的所有参数
# 例如 :https://search.jd.com/Search?keyword= 手机 &enc=utf-8
# 返回结果为 : keyword= 手机 &enc=utf-8
$is_args
# 如果有参数为 ? 否则为空
$document_root;
# 保存了针对当前资源的请求的系统根目录 , 例如 :/webdata/nginx/timinglee.org/lee 。
$document_uri;
# 保存了当前请求中不包含参数的 URI ,注意是不包含请求的指令
# 比如 :http://lee.timinglee.org/var?\id=11111 会被定义为 /var
# 返回结果为 :/var
$host;
# 存放了请求的 host 名称
limit_rate 10240;
echo $limit_rate;
# 如果 nginx 服务器使用 limit_rate 配置了显示网络速率,则会显示,如果没有设置, 则显示 0
$remote_port;
# 客户端请求 Nginx 服务器时随机打开的端口,这是每个客户端自己的端口
$remote_user;
# 已经经过 Auth Basic Module 验证的用户名
$request_body_file;
# 做反向代理时发给后端服务器的本地资源的名称
$request_method;
# 请求资源的方式, GET/PUT/DELETE 等
$request_filename;
# 当前请求的资源文件的磁盘路径,由 root 或 alias 指令与 URI 请求生成的文件绝对路径,
# 如 :webdata/nginx/timinglee.org/lee/var/index.html
$request_uri;
# 包含请求参数的原始 URI ,不包含主机名,相当于 :$document_uri?$args,
# 例如: /main/index.do?id=20190221&partner=search
$scheme;
# 请求的协议,例如 :http , https,ftp 等
$server_protocol;
# 保存了客户端请求资源使用的协议的版本,例如 :HTTP/1.0 , HTTP/1.1 , HTTP/2.0 等
$server_addr;
# 保存了服务器的 IP 地址
$server_name;
# 虚拟主机的主机名
$server_port;
# 虚拟主机的端口号
$http_user_agent;
# 客户端浏览器的详细信息
$http_cookie;
# 客户端的所有 cookie 信息
$cookie_<name>
#name 为任意请求报文首部字部 cookie 的 key 名
$http_<name>
#name 为任意请求报文首部字段 , 表示记录请求报文的首部字段, ame 的对应的首部字段名需要为小写,如果有横线需要替换为下划线
# 示例 :
echo $http_user_agent;
echo $http_host;
$sent_http_<name>
#name 为响应报文的首部字段, name 的对应的首部字段名需要为小写,如果有横线需要替换为下划线 , 此变量有问题
echo $sent_http_server;
$arg_<name>
# 此变量存放了 URL 中的指定参数, name 为请求 url 中指定的参数
echo $arg_id;

示例:

[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf 
server {
    listen 80;
    server_name www.timinglee.org;
    root /webdata/nginx/timinglee.org/lee;
    location /var {
        default_type text/html;
        echo $remote_addr;
        echo $args;
        echo $document_root;
        echo $document_uri;
        echo $host;
        echo $http_user_agent;
        echo $request_filename;
        echo $scheme;
        echo $scheme://$host$document_uri?$args;
        echo $http_cookie;
        echo $cookie_key2;
        echo $http_Accept;
    }
}  

测试

[root@nginx ~]# nginx -s reload
[root@nginx ~]# 
[root@nginx ~]# curl -b "title=lee;key1=lee,key2=timinglee" "www.timinglee.org/var?search=lee&&id=666666"

192.168.10.140

search=lee&&id=666666
/webdata/nginx/timinglee.org/lee
/var
lee.timinglee.org
curl/7.29.0
/webdata/nginx/timinglee.org/lee/var
http
http://lee.timinglee.org/var?search=lee&&id=666666
title=lee;key1=lee,key2=timinglee
timinglee
*/*


5.3.2 自定义变量

假如需要自定义变量名称和值,使用指令 set $variable value;
语法格式:
Syntax: set $variable value;
Default: —
Context: server, location, if
示例 :
set $name timinglee;
echo $name;
set $my_port $server_port;
echo $my_port;
echo "$server_name:$server_port";
[root@nginx ~]# mkdir -p /webdata/nginx/timinglee.org/lee/var
[root@nginx ~]# echo xixi > /webdata/nginx/timinglee.org/lee/var/index.html
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf 
server {
    listen 80;
    server_name www.timinglee.org;
    root /webdata/nginx/timinglee.org/lee;
    location /var {
        default_type text/html;
        set $name timinglee;
        echo $name;
        set $web_port $server_port;
        echo $web_port;
    }
}
#测试输出
[root@nginx ~]# nginx -s reload
[root@nginx ~]# 
[root@nginx ~]# curl www.timinglee.org/var
timinglee
80

5.4 模块指令

官方文档 : https://nginx.org/en/docs/http/ngx_http_rewrite_module.html

5.4.1 if 指令

官方文档:
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if
用于条件匹配判断,并根据条件判断结果选择不同的 Nginx 配置,可以配置在 server 或 location 块中进行配置,Nginx 的 if 语法仅能使用 if 做单次判断,不支持使用 if else 或者 if elif 这样的多重判断,用法如下:

if (条件匹配) {
action
}

使用正则表达式对变量进行匹配,匹配成功时 if 指令认为条件为 true ,否则认为 false ,变量与表达式之间使用以下符号链接:

=         #比较变量和字符串是否相等,相等时 if 指令认为该条件为 true ,反之为 false
!=         #比较变量和字符串是否不相等,不相等时 if 指令认为条件为 true ,反之为 false
~         #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~         #区分大小写字符 , 判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~*         #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~*         #不区分大小字符 , 判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f      #判断请求的文件是否存在和是否不存在
-d 和 !-d         #判断请求的目录是否存在和是否不存在
-x 和 !-x         #判断文件是否可执行和是否不可执行
-e 和 !-e         #判断请求的文件或目录是否存在和是否不存在 ( 包括文件,目录,软链接 )
#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false

示例:

[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf 
    location /test {
        index index.html;
        default_type text/html;
        if ( $scheme = http ){
        echo "if ---------> $scheme";
    }
    if ( $scheme = https ){
        echo "if ---------> $scheme";
     }
    }
    location /test2 {
      if ( !-e $request_filename ){
        echo "$request_filename is not exist";
        return 409;
      } 
    }   

测试:

[root@nginx ~]# curl www.timinglee.org/test/
if ---------> http
[root@nginx ~]# curl www.timinglee.org/test2/test
/webdata/nginx/timinglee.org/lee/test2/test is not exist

5.4.2 set 指令

指定 key 并给其定义一个变量,变量可以调用 Nginx 内置变量赋值给 key
另外 set 定义格式为 set $key value , value 可以是 text, variables 和两者的组合。
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf 

server {
listen 80;
server_name www.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /test3{
set $name lee;
echo $name;
 }
}

#测试:

[root@nginx ~]# curl www.timinglee.org/test3/
lee

5.4.3 break 指令

用于中断当前相同作用域 (location) 中的其他 Nginx 配置
与该指令处于同一作用域的 Nginx 配置中,位于它前面的配置生效
位于后面的 ngx_http_rewrite_module 模块中指令就不再执行
Nginx 服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,、
该指令可以在 server 块和 locationif 块中使用
注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module
模块的指令,其它指令还会执行
使用语法如下:

[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name www.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /break{
default_type text/html;
set $name lee;
echo $name;
break;
set $port $server_port;
echo $port;
 }
}

#测试:

[root@nginx ~]# curl www.timinglee.org/break/        # 当未添加 break 时
lee
80
[root@nginx ~]# curl www.timinglee.org/break/        # 添加 break 后
lee

5.4.4 return 指令

return 用于完成对请求的处理,并直接向客户端返回响应状态码,比如 : 可以指定重定向 URL( 对于特殊重定向状态码,301/302 等 ) 或者是指定提示文本内容 ( 对于特殊状态码 403/500 等 ) ,处于此指令后的所有配置都将不被执行,return 可以在 server 、 if 和 location 块进行配置
语法格式:

return code; # 返回给客户端指定的 HTTP 状态码
return code [text]; # 返回给客户端的状态码及响应报文的实体内容
# 可以调用变量 , 其中 text 如果有空格 , 需要用单或双引号
return code URL; # 返回给客户端的 URL 地址

示例:

server {
listen 80;
server_name www.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /return {
default_type text/html;
if ( !-e $request_filename){
return 301 http://www.baidu.com;
#return 666 "$request_filename is not exist";
}
echo "$request_filename is exist";
 }
}

测试:

[root@client ~]# curl www.timinglee.org/return
/webdata/nginx/timinglee.org/lee/return is exist
[root@client ~]# curl www.timinglee.org/return1
/webdata/nginx/timinglee.org/lee/return1 is not exist
# 测试 return 301 http://www.baidu.com;
可在浏览器直接访问 lee.timinglee.org/return1
return 示例:
location /test {
        default_type application/json;
        return 200 '{"status:"success"}';
}

5.4.5 rewrite 指令

通过正则表达式的匹配来改变 URI ,可以同时存在一个或多个指令,按照顺序依次对 URI 进行匹配,rewrite主要是针对用户请求的 URL 或者是 URI 做具体处理
官方文档:
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite
语法格式 :
rewrite regex replacement [flag];
rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制
如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向301
正则表达式格式

# 匹配除换行符以外的任意字符
\w # 匹配字母或数字或下划线或汉字
\s # 匹配任意的空白符
\d # 匹配数字
\b # 匹配单词的开始或结束
^ # 匹配字付串的开始
$ # 匹配字符串的结束
* # 匹配重复零次或更多次
+ # 匹配重复一次或更多次
? # 匹配重复零次或一次
(n) # 匹配重复 n 次
{n,} # 匹配重复 n 次或更多次
{n,m} # 匹配重复 n 到 m 次
*? # 匹配重复任意次,但尽可能少重复
+? # 匹配重复 1 次或更多次,但尽可能少重复
?? # 匹配重复 0 次或 1 次,但尽可能少重复
{n,m}? # 匹配重复 n 到 m 次,但尽可能少重复
{n,}? # 匹配重复 n 次以上,但尽可能少重复
\W # 匹配任意不是字母,数字,下划线,汉字的字符
\S # 匹配任意不是空白符的字符
\D # 匹配任意非数字的字符
\B # 匹配不是单词开头或结束的位置
[^x] # 匹配除了 x 以外的任意字符
[^lee] # 匹配除了 magedu 这几个字母以外的任意字符

5.4.5.1 rewrite flag 

利用 nginx 的 rewrite 的指令,可以实现 url 的重新跳转, rewrite 有四种不同的 flag ,分别是 redirect( 临时重定向302) 、 permanent( 永久重定向 301) 、 break 和 last 。其中前两种是跳转型的 flag ,后两种是代理型
跳转型指由客户端浏览器重新对新地址进行请求
代理型是在WEB服务器内部实现跳转
rewrite 格式

Syntax: rewrite regex replacement [flag]; # 通过正则表达式处理用户请求并返回替换后的数据包。
Default: —
Context: server, location, if

flag 说明

redirect;
# 临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新 URL 给客户端
# 由客户端重新发起请求 ; 使用相对路径 , 或者 http:// 或 https:// 开头,状态码: 302
permanent;
# 重写完成后以永久重定向方式直接返回重写后生成的新 URL 给客户端
# 由客户端重新发起请求,状态码: 301
break;
# 重写完成后 , 停止对当前 URL 在当前 location 中后续的其它重写操作
# 而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在 location 中使用
# 适用于一个 URL 一次重写
last;
# 重写完成后 , 停止对当前 URI 在当前 location 中后续的其它重写操作,
# 而后对新的 URL 启动新一轮重写检查,不建议在 location 中使用
# 适用于一个 URL 多次重写,要注意避免出现超过十次以及 URL 重写后返回错误的给用户

5.4.5.2 rewrite案例: 域名永久与临时重定向

域名的临时的调整,后期可能会变,之前的域名或者 URL 可能还用、或者跳转的目的域名和 URL 还会跳转,这种情况浏览器不会缓存跳转, 临时重定向不会缓存域名解析记录 (A 记录 ) ,但是永久重定向会缓存。
示例: 因业务需要,将访问源域名 www.timinglee.org 的请求永久重定向到 www.timinglee.com
location / {
        root /data/nginx/html/pc;
        index index.html;
        rewrite / http://www.timinglee.com permanent;
        #rewrite / http://www.timinglee.com redirect;
}
# 重启 Nginx 并访问域名 http://www.timinglee.org 进行测试

永久重定向304

域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到客户端浏览器
永久重定向会缓存DNS解析记录, 浏览器中有 from disk cache 信息,即使nginx服务器无法访问,浏览器也会利用缓存进行重定向
比如: 京东早期的域名 www.360buy.com 由于与360公司类似,于是后期永久重定向到了 www.jd.com
示例
[root@nginx lee]# echo 123456 > /webdata/nginx/timinglee.org/lee/index.html
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
    listen 80;
    server_name lee.timinglee.org;
    root /webdata/nginx/timinglee.org/lee;
    location / {
        #rewrite / http://lee.timinglee.com redirect;
        rewrite / http://lee.timinglee.com permanent;
    }
}   
server {
    listen 80;
    server_name lee.timinglee.com;
    root /webdata/nginx/timinglee.com/lee;
}
#测试:
[root@nginx ~]# nginx -s reload
[root@nginx ~]# 


 临时重定​​​​​​​向301

域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS 解析记录,这也是临时重定向与永久
重定向最大的本质区别。
即当 nginx 服务器无法访问时 , 浏览器不能利用缓存 , 而导致重定向失败
示例

[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
        listen 80;
        server_name lee.timinglee.org;
        root /webdata/nginx/timinglee.org/lee;
        location / {
        rewrite / http://lee.timinglee.com redirect;
        #rewrite / http://lee.timinglee.com permanent;
        }
}
server {
        listen 80;
        server_name lee.timinglee.com;
        root /webdata/nginx/timinglee.com/lee;
}


5.4.5.3 rewrite 案例: break 与 last

[root@nginx ~]# mkdir /webdata/nginx/timinglee.org/lee/{test1,test2,break}
[root@nginx ~]# echo test1 > /webdata/nginx/timinglee.org/lee/test1/index.html
[root@nginx ~]# echo test2 > /webdata/nginx/timinglee.org/lee/test2/index.html
[root@nginx ~]# echo break > /webdata/nginx/timinglee.org/lee/break/index.html
[root@nginx ~]#vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /break {
root /webdata/nginx/timinglee.org/lee;
rewrite ^/break/(.*) /test1/$1 last;
rewrite ^/test1/(.*) /test2/$1 break;
}
location /last {
root /webdata/nginx/timinglee.org/lee;
rewrite ^/last/(.*) /test1/$1 last;
rewrite ^/test1/(.*) /test2/$1 last;
}
location /test1 {
default_type text/html;
return 666 "new test1";
}
location /test2 {
root /webdata/nginx/timinglee.org/lee;
   }
}
[root@nginx ~]# curl -L lee.timinglee.org/break/index.html
test1
[root@nginx ~]#curl -L lee.timinglee.org/last/index.html
new test1

5.4.5.4 rewrite案例: 自动跳转 https

案例:基于通信安全考虑公司网站要求全站 https ,因此要求将在不影响用户请求的情况下将 http 请求全部自动跳转至 https ,另外也可以实现部分 location 跳转
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
        listen 443 ssl;
        listen 80;
        ssl_certificate /apps/nginx/certs/www.timinglee.org.crt;
        ssl_certificate_key /apps/nginx/certs/www.timinglee.org.key;
        ssl_session_cache shared:sslcache:20m;
        ssl_session_timeout 10m;
        server_name www.timniglee.org;
        location / { #针对全站跳转
        root /data/nginx/html/pc;
                index index.html;
                if ($scheme = http ){ #如果没有加条件判断,会导致死循环
                rewrite / https://$host redirect;
     }
}
                location /login { #针对特定的URL 进行跳转 https
                if ($scheme = http ){ #如果没有加条件判断,会导致死循环
                rewrite / https://$host/login redirect;
         }
   }
}
# 重启 Nginx 并访问测试
[root@nginx ~]#curl -ikL www.timinglee.org
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.18.0
Date: Thu, 08 Oct 2020 15:23:48 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: https://www.magedu.org
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 08 Oct 2020 15:23:48 GMT
Content-Type: text/html
Content-Length: 7
Last-Modified: Sat, 26 Sep 2020 01:18:32 GMT
Connection: keep-alive
ETag: "5f6e96e8-7"
Accept-Ranges: bytes
pc web

2.2.5 rewrite 案例: 判断文件是否存在

案例:当用户访问到公司网站的时输入了一个错误的 URL ,可以将用户重定向至官网首页
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
location / {
        root /data/nginx/html/pc;
        index index.html;
        if (!-e $request_filename) {
                rewrite .* http://www.timinglee.org/index.html; #实现客户端浏览器的302 跳转
                #rewrite .* /index.html; #web服务器内部跳转
    }
}
# 重启 Nginx 并访问测试

5.5 Nginx 防盗链

防盗链基于客户端携带的 referer 实现, referer 是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer 就是之前的那个网站域名,正常的 referer 信息有以下几种:

none : # 请求报文首部没有 referer 首部,
# 比如用户直接在浏览器输入域名访问 web 网站,就没有 referer 信息。
blocked : # 请求报文有 referer 首部,但无有效值,比如为空。
server_names : #referer 首部中包含本主机名及即 nginx 监听的 server_name 。
arbitrary_string : # 自定义指定字符串,但可使用 * 作通配符。示例 : *.timinglee.org
www.timinglee.*
regular expression : # 被指定的正则表达式模式匹配到的字符串 , 要使用 ~ 开头,例如:
~.*\.timinglee\.com
正常通过搜索引擎搜索 web 网站并访问该网站的 referer 信息如下:
172.25.254.1 - - [22/Jul/2024:09:27:36 +0800] "GET /favicon.ico HTTP/1.1" 404 149
"http://lee.timinglee.org/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0)
Gecko/20100101 Firefox/115.0"
2024/07/22 09:27:36 [error] 34596#0: *205 open()
"/webdata/nginx/timinglee.org/lee/favicon.ico" failed (2: No such file or
directory), client: 172.25.254.1, server: lee.timinglee.org, request: "GET
/favicon.ico HTTP/1.1", host: "lee.timinglee.org", referrer:
"http://lee.timinglee.org/"

 5.5.1 实现盗链

在一个 web 站点盗链另一个站点的资源信息,比如 : 图片、视频等
# 新建一个主机 192.168.10.141, 盗取另一台主机 lee.timinglee.org/images/logo.png 的图片
[root@client ~]# yum install httpd -y
[root@client html]# vim /var/www/html/index.html
# 准备盗链 web 页面:
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title> 盗链 </title>
</head>
<body>
<img src="http://lee.timinglee.org/images/logo.png" >
<h1 style="color:red"> 欢迎大家 </h1>
<p><a href=http://lee.timinglee.org> 狂点老李 </a> 出门见喜 </p>
</body>
</html>

# 重启 apache 并访问 http://192.168.10.140  测试
# 验证两个域名的日志,是否会在被盗连的 web 站点的日志中出现以下盗链日志信息:
[root@Nginx ~]# cat /usr/local/nginx/logs/access.log
192.168.10.1 - - [22/Jul/2024:09:50:01 +0800] "GET /images/logo.png HTTP/1.1" 304
0 "http:/192.168.10.140/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
Edg/126.0.0.0"
192.168.10.1 - - [22/Jul/2024:09:50:18 +0800] "GET / HTTP/1.1" 304 0
"http://192.168.10.140/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
Edg/126.0.0.0"

5.5.2 实现防盗链

基于访问安全考虑, nginx 支持通过 ngx_http_referer_module 模块 , 检查访问请求的 referer 信息是否有效实现防盗链功能
官方文档 :
https://nginx.org/en/docs/http/ngx_http_referer_module.html
示例 : 定义防盗链:
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
location /images {
valid_referers none blocked server_names *.timinglee.org ~\.baidu\.;
if ($invalid_referer){
#return 403;
rewrite ^/ http://lee.timinglee.org/daolian.png permanent;
     }
  }
}
# 重启 Nginx 并访问测试
http://192.168.10.140

5.6 反向代理

反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。
Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能

ngx_http_proxy_module: # 将客户端的请求以 http 协议转发至指定服务器进行处理
ngx_http_upstream_module # 用于定义为 proxy_pass,fastcgi_pass,uwsgi_pass
                                                #等指令引用的后端服务器分组
ngx_stream_proxy_module: # 将客户端的请求以 tcp 协议转发至指定服务器处理
ngx_http_fastcgi_module: # 将客户端对 php 的请求以 fastcgi 协议转发至指定服务器助理
ngx_http_uwsgi_module: # 将客户端对 Python 的请求以 uwsgi 协议转发至指定服务器处理

5.6.1 反向代理单台 web 服务器

要求:将用户对域 www.timinglee.org 的请求转发给后端服务器处理

[root@nginx ~]# cat /usr/local/nginx/conf.d/vhosts.conf
server {
        listen 80;
        server_name www.timinglee.org;
        location / {
        proxy_pass http://192.168.10.141;
        }
}
# 重启 Nginx 并访问测试


5.6.2 针对指定的 location

server {
        listen 80;
        server_name www.timinglee.org;
        location / {
        proxy_pass http://192.168.10.141;
        }
        location ~ /static {
                proxy_pass http://192.168.10.140:8080;
        }
}
# 后端 web 服务器必须要有相对于的访问 URL
[root@nginx ~]## mkdir /var/www/html/static
[root@nginx ~]## echo static  192.168.10.140 > /var/www/html/static/index.html
[root@nginx2 ~]#]# echo 192.168.10.141 > /var/www/html/index.html
# 重启 Nginx 并访问测试:
[root@nginx ~]# curl www.timinglee.org/static/
static  192.168.10.140
[root@nginx ~]# curl www.timinglee.org
192.168.10.141

5.6.3 针对特定的资源实现代理

静态分离

[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
        listen 80;
        server_name www.timinglee.org;
        location / {
                proxy_pass http://192.168.10.141;
        }
        location ~ \.(png|jpg|gif) {
                proxy_pass http://192.168.10.140:8080;
        }
}

5.6.4 缓存功能

缓存功能默认关闭状态 , 需要先动配置才能启用

proxy_cache zone_name | off; 默认 off
# 指明调用的缓存,或关闭缓存机制 ;Context:http, server, location
#zone_name 表示缓存的名称 . 需要由 proxy_cache_path 事先定义
proxy_cache_key string;
# 缓存中用于 “ 键 ” 的内容,默认值: proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
# 定义对特定响应码的响应内容的缓存时长,定义在 http{...} 中

示例 :

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_path;
# 定义可用于 proxy 功能的缓存 ;Context:http
proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number]
[manager_sleep=time] [manager_threshold=time] [loader_files=number]
[loader_sleep=time] [loader_threshold=time] [purger=on|off]
[purger_files=number] [purger_sleep=time] [purger_threshold=time];

示例:在 http 配置定义缓存信息

proxy_cache_path /var/cache/nginx/proxy_cache # 定义缓存保存路径, proxy_cache 会自动创建
levels=1:2:2 # 定义缓存目录结构层次
#1:2:2 可以生成
2^4x2^8x2^8=2^20=1048576 个目录
keys_zone=proxycache:20m # 指内存中缓存的大小,主要用于存放 key 和 metadata
(如:使用次数)
# 一般 1M 可存放 8000 个左右的 key
inactive=120s # 缓存有效时间
max_size=10g; # 最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
# 调用缓存功能,需要定义在相应的配置段,如 server{...}; 或者 location 等
proxy_cache proxycache;
proxy_cache_key $request_uri; # 对指定的数据进行 MD5 的运算做为缓存的 key
proxy_cache_valid 200 302 301 10m; # 指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 1m; # 除指定的状态码返回的数据以外的缓存多长时间 , 必须设置 ,
否则不会缓存
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 |
http_502 | http_503 | http_504 | http_403 | http_404 | off ; # 默认是 off

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/411183.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多态(虚构的整体,具体的个体)(多态的基本概念/多态的原理剖析/纯虚函数和抽象类/虚析构和纯虚析构)

多态的基本概念 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; // 多态的基本概念 // 多态分为静态多态和动态多态 // 静态多态&#xff1a; 函数重载还运算符重载属于静态多态&#xff0c;服用函数名 // 动态多态&#xff1a; 派生派和虚函…

VUE使用websocket

在之前搭建好的项目的基础上新版security demo&#xff08;二&#xff09;前端-CSDN博客 目录 一、代码改造 1、后端改造 2、VUE使用websocket 3、测试 二、按用户推送 1、完整代码如下 1.1、前端 1.2、后端&#xff1a; 2、测试 一、代码改造 1、后端改造 &#x…

逆波兰表达式

简介 介绍逆波兰表达式之前&#xff0c;先介绍一下运算种类。 中缀运算与后缀运算 中缀运算是一种常用的算术和逻辑公式表示方法&#xff0c;其中操作符位于两个运算数之间。例如&#xff0c;在表达式 “3 2” 中&#xff0c;加号&#xff08;&#xff09;是操作符&#xf…

算法设计:实验一分治与递归

【实验目的】 深入理解分治法的算法思想&#xff0c;应用分治法解决实际的算法问题。 【实验内容与要求】 设有n2k个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表&#xff1a; 1.每个选手必须与其他n-1个选手各赛一次&#xff1b;2.每个选手一天只能赛一…

Mysql 集群技术

目录 一 Mysql 在服务器中的部署方法 1.1 在Linux下部署mysql 1.1.1 安装依赖性并解压源码包&#xff0c;源码编译安装mysql&#xff1a; 1.1.2 部署mysql 二 mysql的组从复制 2.1 配置mastesr和salve 测试结果 2.2 当有数据时添加slave2 2.3 延迟复制 2.4 慢查询日志…

【C++ | 设计模式】简单工厂模式的详解与实现

1.简单工厂模式概述 简单工厂模式&#xff08;Simple Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它定义了一个工厂类&#xff0c;由这个类根据提供的参数决定创建哪种具体的产品对象。简单工厂模式将对象的创建逻辑集中到一个工厂类中&#xff0c;从而将对…

Python-进阶-Excel基本操作

文章目录 Excel 基本操作1. 概述2. 写入2.1 使用 xlwt2.2 使用 XlsxWriter 3. 读取4. 修改 Excel 基本操作 1. 概述 在数据处理方面&#xff0c;Python 一直扮演着重要的角色&#xff0c;对于 Excel 操作&#xff0c;它有着完整且成熟的第三方库&#xff0c;使用也较为简单。…

视频结构化从入门到精通——认识视频结构化

认识视频结构化 1. 视频结构化与非结构化 1. 非结构化数据 非结构化数据指的是未经处理、以原始形式存在的数据。这类数据是直接采集、记录的&#xff0c;包含了音频、视频等多维信息&#xff0c;且没有任何标签、注释或分类来表示其中的内容。非结构化数据需要进一步处理和…

AI视频平台精选:国内外对比与推荐

原文&#xff1a;AI视频平台精选&#xff1a;国内外对比与推荐 国内外有多个平台可以生成AI视频&#xff0c;这些平台各有其独特的优点和缺点。以下是对一些主要平台的详细介绍&#xff0c;包括它们的优缺点&#xff0c;以及针对个人和自媒体用户的推荐。 国内平台 1. 快手可…

Android 架构模式之 MVVM

Android 架构 Android 架构模式之 MVCAndroid 架构模式之 MVPAndroid 架构模式之 MVVM 目录 Android 架构架构设计的目的对 MVVM 的理解代码ModelViewViewModel Android 中 MVVM 的问题试吃个小李子BeanModelViewViewModel效果展示 大家好&#xff01; 作为 Android 程序猿&a…

代码随想录算法训练营第13天 |二叉树的学习

目录 二叉树 理论基础 二叉树的分类 1. 满二叉树 (Full Binary Tree) 2. 完全二叉树 (Complete Binary Tree) 3. 平衡二叉树 (Balanced Binary Tree) 5. 二叉搜索树 (Binary Search Tree, BST) 二叉树的存储 1. 链式存储 (Linked Representation) 2. 顺序存储 (Sequent…

Golang | Leetcode Golang题解之第363题矩形区域不超过K的最大数值和

题目&#xff1a; 题解&#xff1a; import "math/rand"type node struct {ch [2]*nodepriority intval int }func (o *node) cmp(b int) int {switch {case b < o.val:return 0case b > o.val:return 1default:return -1} }func (o *node) rotate…

pyro 教程 时间序列 单变量,重尾,python pytorch,教程和实例 Forecasting预测,布朗运动项、偏差项和协变量项

预测I:单变量&#xff0c;重尾 本教程介绍了预测模块&#xff0c;用Pyro模型进行预测的框架。本教程只涵盖单变量模型和简单的可能性。本教程假设读者已经熟悉慢病毒感染和张量形状. 另请参见: 预测II:状态空间模型 预测三:层次模型 摘要 要创建预测模型: 创建预测模型班级…

算法笔试-编程练习-H-02-24

w这套题&#xff0c;侧重模拟和题目理解&#xff0c;只要按照题目描述正常复现整体分数应该不错 一、数据重删 数据重删是一种节约存储空间的技术&#xff0c;通常情况下&#xff0c;在数据存储池内是有很多重复的数据库。重删则是将这些重复的数据块找出并处理的技术。简单地…

Java:jdk8之后新增的时间API

文章目录 为什么要使用新增的API新增了哪些&#xff1f;Local常用方法代码一样的用法 黑马学习笔记 使用新增的 为什么要使用新增的API 新增了哪些&#xff1f; Local 常用方法 代码 package NewTime;import java.time.LocalDate;/*** Author: ggdpzhk* CreateTime: 2024-08-…

竞猜足球核心算法源码

需要实现的功能如下&#xff1a; 仅用于学习 竞猜足球核心算法源码 package com.lotterysource.portsadmin.service; import com.aliyun.oss.common.utils.DateUtil; import com.fasterxml.jackson.core.type.TypeReference; import com.lotterysource.portsadmin.dbprovid…

@ohos.systemParameterEnhance系统参数接口调用:控制设备硬件(执行shell命令方式)

本文介绍如何使用应用ohos.systemParameterEnhance (系统参数)(系统接口)来控制设备硬件&#xff0c;可以通过它在系统中执行一段shell命令&#xff0c;从而实现控制设备的效果。接下来以一个实际的样例来演示如何通过它来控制设备以太网接口 开源地址&#xff1a;https://git…

链表OJ题——环形链表2

文章目录 一、题目链接二、解题思路三、解题代码 一、题目链接 环形链表2 题目描述&#xff1a;在链表有环的基础上&#xff0c;找出环的入口点。 二、解题思路 三、解题代码

超实用的8个无版权、免费、高清图片素材网站整理

不管是设计、文章配图&#xff0c;还是视频制作&#xff0c;图片都至关重要。但是图片版权一直都是困扰很多设计、自媒体以及企业的大问题。现在&#xff0c;因为图片侵权被告的案例已经是司空见惯了&#xff0c;有的公众号甚至因为图片版权问题遭受致命打击。 1. Pexels Pexe…

(经验)SVN降版本,保留版本信息和用户信息。

背景&#xff1a;由于开始公司人数规模小&#xff0c;没有关心SVN最新版本免费对于用户数量限制要求不敏感&#xff0c;随着人数越来越多&#xff0c;公司来了新员工已经添加不了SVN需要注册码了&#xff0c;不利于SVN文件管理的在公司内部的推广。看了好多资料&#xff0c;都没…