Nginx进阶-常见配置(一)

一、nginx Proxy 反向代理

1、代理原理

反向代理产生的背景:

在计算机世界里,由于单个服务器的处理客户端(用户)请求能力有一个极限,当用户的接入请求蜂拥而入时,会造成服务器忙不过来的局面,可以使用多个服务器来共同分担成千上万的用户请求,这些服务器提供相同的服务,对于用户来说,根本感觉不到任何差别。

反向代理服务的实现:

需要有一个负载均衡设备(即反向代理服务器)来分发用户请求,将用户请求分发到后端真正提供服务的服务器上。服务器返回自己的服务到负载均衡设备。负载均衡设备将服务器的服务返回用户。

在反向代理中,Nginx代表服务器端,接收和处理客户端的请求。与正向代理(如代理服务器)不同的是,反向代理是位于服务器端的代理服务器。客户端对其发送请求,并不知道实际处理请求的是后端服务器。

Nginx Proxy反向代理的主要优点包括:

  1. 负载均衡:Nginx可以将请求平均分发给多个后端服务器,以实现负载均衡,提高系统的性能和可扩展性。

  2. 高可用性:当某个后端服务器发生故障或不可用时,Nginx可以自动将请求转发给其他可用的后端服务器,确保服务的高可用性。

  3. 缓存功能:Nginx可以缓存静态资源,如图片、CSS和JavaScript文件等,减轻后端服务器的压力,加快访问速度。

  4. 安全性:Nginx可以作为反向代理服务器,过滤和防护恶意请求,提高系统的安全性。

2、正/反向代理的区别

正向代理

正向代理的过程隐藏了真实的请求客户端,服务器不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替请求。我们常说的代理也就是正向代理,正向代理代理的是请求方,也就是客户端;比如我们要访问youtube,可是不能访问,只能先安装个FQ软件代你去访问,通过FQ软件才能访问,FQ软件就叫作正向代理。

正向代理的作用
  • 为在防火墙内的局域网客户端提供访问Internet的途径
  • 可以使用缓冲特性减少网络使用率
  • 访问受地理位置限制的网络
  • 使用代理后会隐藏真实的IP地址

反向代理

反向代理:(reverse proxy),指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式。客户端不直接与后端服务器进行通信,而是与反向代理服务器进行通信,隐藏了后端服务器的 IP 地址

反向代理的过程隐藏了真实的服务器,客户不知道真正提供服务的人是谁,客户端请求的服务都被代理服务器处理。反向代理代理的是响应方,也就是服务端;我们请求www.baidu.com时这www.baidu.com就是反向代理服务器,真实提供服务的服务器有很多台,反向代理服务器会把我们的请求分转发到真实提供服务的各台服务器。Nginx就是性能非常好的反向代理服务器,用来做负载均衡。

访问www.baidu.com是反向代理的过程

两者的区别在于代理的对象不一样:正向代理中代理的对象是客户端。反向代理中代理的对象是服务端。

 反向代理可实现的功能

反向代理的主要作用是提供负载均衡和高可用性。

  • 负载均衡:Nginx可以将传入的请求分发给多个后端服务器,以平衡服务器的负载,提高系统性能和可靠性。
  • 缓存功能:Nginx可以缓存静态文件或动态页面,减轻服务器的负载,提高响应速度。
  • 动静分离:将动态生成的内容(如 PHP、Python、Node.js 等)和静态资源(如 HTML、CSS、JavaScript、图片、视频等)分别存放在不同的服务器或路径上。
  • 多站点代理: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协议转发至指定服务器处理

3、nginx Proxy 配置

1、代理模块

ngx_http_proxy_module

2、启用 nginx proxy 代理

环境两台nginx真实服务器

a、nginx-1 应用服务器启动
nginx-1的ip:192.168.175.130(作为应用服务器)
已经编译安装好,检查nginx是否启动是否可以访问
b、nginx-2 代理服务器配置
nginx-2的ip:192.168.175.128
编辑nginx的子配置文件: /etc/nginx/conf.d/default.conf 
[root@nginx-server ~]# vim /etc/nginx/conf.d/default.conf
server {server {listen       80;server_name  localhost;location / {proxy_pass http://192.168.175.130:80;proxy_redirect default;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_connect_timeout 30;  proxy_send_timeout 60;proxy_read_timeout 60;}
}
为了不影响访问可以先把主配置文件里的server块注释掉
重新加载nginx配置文件
[root@nginx-server ~]# nginx -s reload
c、nginx proxy 具体配置详解
proxy_pass 指定后端服务器的地址,可以是ip也可以是域名和url地址
proxy_set_header 设置要传递给后端服务器的HTTP请求头。
proxy_set_header X-Real-IP $remote_addr;
记录连接服务器的上一个ip地址信息。(一般为代理服务器的ip地址)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
$proxy_add_x_forwarded_for将客户端的IP地址添加到X-Forwarded-For请求头中,然后传递给后端服务器;X-Forwarded-For的请求头值为客户端的IP地址。实现了IP透传,记录真正客户端机器的ip地址。
proxy_redirect :如果真实服务器使用的是的真实IP:非默认端口。则改成IP:默认端口。
proxy_connect_timeout:指定连接到后端服务器的超时时间,即发起三次握手等候响应超时时间。
proxy_send_timeout:指定向后端服务器发送请求的超时时间,即在规定时间之内后端服务器必须传完所有的数据。
proxy_read_timeout :指定从后端服务器读取响应的超时时间。
nginx接收upstream(上游/真实) server数据超时, 默认60s, 如果连续的60s内没有收到1个字节, 连接关闭,如长连接。

注意:proxy_pass http:// 填写nginx-1实际应用服务器的地址。

使用PC客户端访问nginx-2服务器地址
浏览器中输入http://192.168.175.128 (nginx-2代理服务器的ip)
​成功访问nginx-1应用服务器页面

观察nginx-1服务器的日志

# tail -f /var/log/nginx/access.log
10.0.105.202 - - [27/Jun/2019:15:54:17 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "10.0.105.207"
10.0.105.202  代理服务器地址
10.0.105.207 客户机地址。
访问成功。 记录了客户机的IP和代理服务器的IP

二、Nginx负载均衡

1、upstream配置

upstream指令来配置反向代理的后端服务器池。 upstream 配置:写一组被代理的服务器地址,然后配置负载均衡的算法.(80,443一般在七层,upstream做七层负载)

upstream testapp { server 10.0.105.199:8081;server 10.0.105.202:8081;}server {....location / {         proxy_pass  http://testapp;  #请求转向 testapp 定义的服务器列表         } 

2、负载均衡算法(nginx调度策略)

upstream 负载均衡调度算法
​
1. 轮询算法(Round Robin):每个请求按时间顺序逐一分配到不同的后端服务器;(默认不用写)
2. 加权轮询算法(Weighted Round Robin):根据服务器的处理能力分配权重,按照权重的比例分发请求。
3. IP地址散列算法(IP Hash):每个请求按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器。保证来自同一ip的请求被打到固定的机器上,解决session问题。(没有实现负载均衡)
4. 哈希算法(Hash)(也叫url hash):按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器。根据请求的某一特定属性(如源IP地址或请求URL),通过哈希函数计算后得到一个固定的值,再将该值与服务器列表进行匹配,将请求分发给对应的服务器。(没有实现负载均衡)​
5. fair算法:基于请求处理时间的负载均衡算法。根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持 fair的,如果需要使用这种调度算法,必须下载Nginx的 upstream_fair模块。
实现:通过维护一个请求队列,并记录每个后端服务器的处理时间。当新的请求到达时,Fair算法会选择处理时间最短的服务器来处理该请求,并将该请求加入到该服务器的请求队列中。当服务器的处理时间相差不大时,Fair算法的效果较为明显,可以达到较好的负载均衡效果。

3、配置实例

1、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB.....

upstream myweb { server 172.17.14.2:8080; server 172.17.14.3:8080 backup;  #热备     }

2、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB....

upstream myweb { server 172.17.14.2:8080; server 172.17.14.3:8080;      }

3、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB....

upstream myweb { server 172.17.14.2:8080 weight=1;server 172.17.14.3:8080 weight=2;
}

4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。

upstream myweb { server 172.17.14.2:8080; server 172.17.14.3:8080;ip_hash;}

5、nginx负载均衡配置状态参数

(1)down    
立即将服务器标记为不可用,直到收到 up指令。
(2)backup 
标记为预留的备份机器。当所有其他服务器都不可用时,才会尝试连接到备份服务器。这台机器的压力最轻通常用于处理突发流量。
(3) max_fails
允许请求失败的最大次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
(缺点:请求处理失败后需要重新转发请求,多一次请求转发)
(4)fail_timeout
失败超时时间(在经历了max_fails次失败后的暂停服务时间),单位秒。
max_fails可以和fail_timeout一起使用。
(缺点:请求处理失败后需要重新转发请求,多一次请求转发)
(5)max_conns
指定每个后端服务器的最大连接数。
(6)drain
将服务器标记为排水模式。在排水模式下,服务器不再接收新的请求,但仍在处理现有请求。
通常用于平滑地从负载均衡池中移除服务器。
示例 
upstream myweb { server 172.17.14.2:8080 weight=2 max_fails=2 fail_timeout=2 down;server 172.17.14.3:8080 weight=1 max_fails=2 fail_timeout=1;  server 192.168.1.10 weight=5 max_fails=3 fail_timeout=30s;server 192.168.1.11 weight=2;server 192.168.1.12 down;server 192.168.1.13 backup;server 192.168.1.14 drain;  server localhost:63344 max_conns=3;
}

4、nginx配置7层协议

(1)7层协议

OSI(Open System Interconnection)是一个开放性的通行系统互连参考模型,他是一个定义的非常好的协议规范,共包含七层协议。

(2)协议配置

在nginx做负载均衡,负载多个服务,部分服务是需要7层的,部分服务是需要4层的,也就是说7层和4层配置在同一个配置文件中。

示例

准备三台机器:
代理服务IP:10.0.105. --配置本地host解析域名;
后端服务器IP:
nginx-a :10.0.105.199(编译安装)
nginx-b:10.0.105.202(yum安装)后端服务器将nginx服务启动
配置105代理服务器的nginx配置文件,编辑主配置文件/etc/nginx/nginx.conf的http块
http {...upstream testweb {server 10.0.105.199:80 weight=2 max_fails=2 fail_timeout=2s;server 10.0.105.202:80 weight=2 max_fails=2 fail_timeout=2s;}server {listen       80;server_name  www.test.com;location / {proxy_pass http://testweb;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}​}...
}

配置202应用服务器的配置文件(yum安装)
[root@nginx-server ~]# cd /etc/nginx/conf.d/
[root@nginx-server conf.d]# cp default.conf test.conf
[root@nginx-server conf.d]# cat test.conf 
server {listen       80;server_name  localhost;
​location / {root   /usr/share/nginx/html;index  index.html index.htm;}
}
[root@nginx-server ~]# nginx -s reload
浏览器测试访问:
http://www.test.com/

 三nginx后端健康检查

ngx_http_proxy_module VS nginx_upstream_check_module

nginx自带的针对后端节点健康检查的功能比较简单,通过默认自带的ngx_http_proxy_module 模块和ngx_http_upstream_module模块中的参数来完成,当后端节点出现故障时,自动切换到健康节点来提供访问。但是nginx不能事先知道后端节点状态是否健康,后端即使有不健康节点,负载均衡器依然会先把请求转发给该不健康节点,然后再转发给别的节点,这样就会浪费一次转发,而且自带模块无法做到预警。所以我们可以使用第三方模块 nginx_upstream_check_module模块
​
nginx_upstream_check_module模块由淘宝团队开发 淘宝自己的 tengine 上是自带了该模块的。我们使用原生Nginx,采用添加模块的方式

获取nginx_upstream_check_module模块:从github上面获取

~]# yum install -y unzip
​
下载模块
~]# wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/refs/heads/master.zip
~]# unzip -d /usr/local/ master.zip
安装补丁
注意 check版本和Nginx版本要求有限制 1.12以上版本的nginx,补丁为check_1.20.1+.patch 具体参考github
​# ls nginx_upstream_check_module-master/
# -p0,当前路径   -p1,上一级路径
[root@nginx-server ~]# cd /usr/local/nginx-1.22.1/   #进入nginx的解压目录中
[root@nginx-server nginx-1.22.1]# yum install -y patch
[root@nginx-server nginx-1.22.1]# patch -p1 < ../nginx_upstream_check_module-master/check_1.20.1+.patch
[root@nginx-server nginx-1.22.1]# nginx -V #查看nginx配置路径
[root@nginx-server nginx-1.22.1]# ./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream --add-module=../nginx_upstream_check_module-master/
[root@nginx-server nginx-1.22.1]# make   #如果是添加模块只需要make 第一次安装需要make install
[root@nginx-server nginx-1.22.1]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak  #将原来的nginx二进制命令备份
[root@nginx-server nginx-1.22.1]# ls objs/
[root@nginx-server nginx-1.22.1]# /usr/local/nginx/sbin/nginx
[root@nginx-server nginx-1.22.1]# /usr/local/nginx/sbin/nginx stop
[root@nginx-server nginx-1.22.1]# cp objs/nginx /usr/local/nginx/sbin/ #将新生成的命令cp到nginx的命令目录中。# \cp不提醒,覆盖粘贴复制

配置健康检查

# vim /etc/nginx/nginx.conf
http {
upstream app {server 192.168.209.128 weight=1;server 192.168.209.130 weight=1;check interval=5000 rise=2 fall=3 timeout=4000 type=http port=80;check_http_send "HEAD / HTTP/1.0\r\n\r\n";check_http_expect_alive http_2xx http_3xx;}server {listen       80;server_name  localhost;
​location / {proxy_pass http://app;proxy_redirect default;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}location /status {   #开启监控状态页面,自定义如serverupcheck_status;access_log   off;}}
}
​​
参数解释:
interval:表示每隔多少毫秒向后端发送健康检查包;
rise:表示如果连续成功次数达到2 服务器就被认为是up;
fail:表示如果连续失败次数达到3 服务器就被认为是down;
timeout:表示后端健康请求的超时时间是多少毫秒;
type:表示发送的健康检查包是什么类型的请求;
port: 表示发送检查到后端的服务的端口;
check_http_send:表示http健康检查包发送的请求内容。为了减少传输数据量,推荐采用“head”方法;
check_http_expect_alive:指定HTTP回复的成功状态,默认认为2XX和3XX的状态是健康的;

浏览器查看访问状态

5、层协议方法(扩展)

4层协议

TCP/IP协议

之所以说TCP/IP是一个协议族,是因为TCP/IP协议包括TCP、IP、UDP、ICMP、RIP、SMTP、ARP、TFTP等许多协议,这些协议一起称为TCP/IP协议。

从协议分层模型方面来讲,TCP/IP由四个层次组成:网络接口层、网络层、传输层、应用层。

nginx在1.9.0的时候,增加了一个 stream 模块,用来实现四层协议(网络层和传输层)的转发、代理、负载均衡等。stream模块的用法跟http的用法类似,允许我们配置一组TCP或者UDP等协议的监听.

配置案例:  stream块是与http块同一级别

#4层tcp负载 
stream {upstream ssh_01 {server 192.168.209.129:22;}
​server {listen 6666;proxy_pass ssh_01;proxy_timeout 60s;proxy_connect_timeout 30s;}
}

四、nginx 会话保持

nginx会话保持主要有以下几种实现方式。

1、ip_hash

ip_hash使用源地址哈希算法,将同一客户端的请求总是发往同一个后端服务器,除非该服务器不可用。
ip_hash语法:
upstream backend {ip_hash;server backend1.example.com;server backend2.example.com;server backend3.example.com down;
}
ip_hash简单易用,但有如下问题:
当后端服务器宕机后,session会丢失;
来自同一局域网的客户端会被转发到同一个后端服务器,可能导致负载失衡;

2、sticky_cookie_insert---基于cookie实现

使用sticky_cookie_insert启用会话亲缘关系,让来自同一客户端的请求被传递到一组服务器的同一台服务器。与ip_hash不同之处在于,它不是基于IP来判断客户端的,而是基于cookie来判断。
第三方模块---sticky模块,可以避免上述ip_hash中来自同一局域网的客户端和前段代理导致负载失衡的情况。

过程:

编译安装sticky模块,#给yum安装的nginx添加模块
[root@nginx-server ~]# yum install -y pcre* openssl* gcc gcc-c++ make 安装编译环境
[root@nginx-server ~]# wget  https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip  #下载sticky模块
[root@nginx-server ~]# nginx -v
nginx version: nginx/1.18.0
[root@nginx-server ~]# wget  http://nginx.org/download/nginx-1.18.0.tar.gz #下载yum安装nginx对应版本的源码包
[root@nginx-server ~]# yum install -y unzip #安装解压工具
[root@nginx-server ~]# unzip 08a395c66e42.zip #解压模块包
[root@nginx-server ~]# mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42/ nginx-sticky-module-ng/  #重命名一个简洁的文件名
[root@nginx-server ~]# tar xzvf nginx-1.18.0.tar.gz -C /usr/local/ #解压nginx的源码包
[root@nginx-server ~]# cd /usr/local/nginx-1.18.0/
[root@nginx-server nginx-1.18.0]# nginx -V #查看yum安装nginx所有模块
[root@nginx-server nginx-1.18.0]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/root/nginx-sticky-module-ng
[root@nginx-server nginx-1.18.0]# make && make install
配置基于cookie会话保持
[root@nginx-server conf.d]# vim upstream.conf
upstream web1 {server 192.168.198.143;server 192.168.198.145;sticky;
}
[root@nginx-server conf.d]# vim proxy.conf
server {listen       80;server_name  localhost;
​#charset koi8-r;#access_log  /var/log/nginx/host.access.log  main;
​location / {proxy_pass http://qfedu;}
}
[root@nginx-server conf.d]# nginx -t 
[root@nginx-server conf.d]# nginx -s reload
或者:
upstream web1 {server 192.168.198.143;server 192.168.198.145;sticky expires=1h domain=testpm.com path=/;
}​
说明:
expires:设置浏览器中保持cookie的时间 
domain:定义cookie的域 
path:为cookie定义路径

 浏览器测试访问

# nginx -s reload
# curl -I ip地址

注意:使用后端服务器自身通过相关机制保持session同步,如:使用数据库、redis、memcached 等做session复制

五、nginx 实现动静分离

为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。 简单来说,就是使用正则表达式匹配过滤,然后交个不同的服务器。动态内容通常是由后端应用程序生成的,而静态内容是指不经常变化的文件,如HTML、CSS、JavaScript、图片等。

准备环境

准备一个nginx代理 两个http 分别处理动态和静态。

expires功能说明---(为客户端配置缓存时间)nginx缓存的设置可以提高网站性能,对于网站的图片,尤其是新闻网站,图片一旦发布,改动的可能是非常小的,为了减小对服务器请求的压力,提高用户浏览速度,我们可以通过设置nginx中的expires,让用户访问一次后,将图片缓存在用户的浏览器中,且时间比较长的缓存。
原理:当nginx设置了expires后,例如设置为:expires 10d; 那么用户在10天内请求的时候,都只会访问浏览器中的缓存,而不会去请求nginx。
注:需要注意的是,这种缓存方式只能在用户不对浏览器强制刷新的情况下生效,如果用户通过url来进行访问,是可以访问到缓存的。

1.静态资源配置

server {listen 80;server_name     localhost;
​location ~ \.(html|jpg|png|js|css) {root /home/www/nginx;expires      1d; #为客户端设置静态资源缓存时间,如1h,1m}
}
​# \ 转义
测试:
[root@nginx-yum2 conf.d]# curl -I http://10.0.105.200/test.jpg
HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Mon, 07 Sep 2019 11:35:08 GMT
Content-Type: image/jpeg
Content-Length: 27961
Last-Modified: Mon, 07 Sep 2019 11:31:17 GMT
Connection: keep-alive
ETag: "5f561a05-6d39"
Expires: Tue, 08 Sep 2019 11:35:08 GMT  #缓存到期时间
Cache-Control: max-age=86400 #缓存持续时间(秒)
Accept-Ranges: bytes

2.动态资源配置

yum 安装php7.1
~]# yum install -y epel-release
~]# rpm -ivh  http://rpms.remirepo.net/enterprise/remi-release-7.rpm
~]# cd /etc/yum.repos.d/
~]# ls
remi-php73.repo              remi-php74.repo
remi-php80.repo              nginx.repo
remi-php81.repo              remi-modular.repo
remi-php82.repo              remi-php54.repo
remi-php83.repo              remi-php70.repo
remi.repo                    remi-php71.repo
remi-safe.repo               epel.repo
remi-php72.repo
~]# yum install -y yum-utils
~]# yum-config-manager --enable remi-php71 #启用remi-php71软件仓库
~]# yum install php-xsl php php-ldap php-cli php-common php-devel php-gd php-pdo php-mysql php-mbstring php-bcmath php-mcrypt -y
~]# yum install -y php-fpm
~]# systemctl start php-fpm
~]# systemctl enable php-fpm动态服务器编辑nginx连接php
~]# vim /etc/nginx/conf.d/default.conf  #编辑nginx的配置文件:
server {listen      80;server_name     localhost;location ~ \.php$ {root           usr/share/nginx/html;  #指定网站目录fastcgi_pass   127.0.0.1:9000;    #开启fastcgi连接php地址fastcgi_index  index.php;       #指定默认文件fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name; #站点根目录,取决于root配置项include        fastcgi_params;  #包含fastcgi使用的常量}}
~]# cd /usr/share/nginx/html
html]# vim index.php

3.配置nginx反向代理upstream,并实现客户端缓存时间

# vim /etc/nginx/conf.d/upstream.conf
upstream static {server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=60s;}
upstream php {server 10.0.105.200:80 weight=1 max_fails=1 fail_timeout=60s;}
​server {listen      80;server_name     localhost#动态资源加载location ~ \.(php|jsp)$ {proxy_pass http://php;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}#静态资源加载location ~ .*\.(html|jpg|png|css|js)$ {proxy_pass http://static;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}
当访问静态页面的时候location 匹配到 (html|jpg|png|js|css) 通过转发到静态服务器,
静态服务通过location的正则匹配来处理请求。
当访问动态页面时location匹配到 .\php 结尾的文件转发到后端php服务处理请求。

六、nginx的localtion指令详解

nginx中的location指令用于指定请求的处理位置。它可以根据请求的URI进行匹配,并且根据匹配结果执行相应的操作。

location指令的语法如下:location [修饰符] 匹配规则 { ...操作内容... }

Nginx 的 HTTP 配置主要包括三个区块,结构如下:

http {                      # 这个是协议级别include mime.types;default_type application/octet-stream;keepalive_timeout 65;gzip on;server {             # 这个是服务器级别listen 80;server_name localhost;location / {  # 这个是请求级别root html;index index.html index.htm;}}
}

1、location 区段

- location 是在 server 块中配置,根据不同的 URI 使用不同的配置,来处理不同的请求。
- location 是有顺序的,会根据不同请求配置的优先级来匹配的location 处理。
基本语法如下:
location [=|~|~*|^~|@] pattern{……}

2、location 前缀含义

=    表示精确匹配,优先级最高,只有请求的URI与匹配规则完全一致时才会执行操作 
^~   普通字符串前缀匹配,表示uri以某个常规字符串开头
~    区分大小写的正则匹配  
~*   不区分大小写的正则匹配
!~   表示区分大小写不匹配的正则
!~*  表示不区分大小写不匹配的正则
/    通用匹配,任何请求都会匹配到,优先级最低查找顺序和优先级
= 大于 ^~  大于 ~|~*|!~|!~* 大于 /
多个location配置的情况下匹配顺序为:
首先匹配 =,其次匹配^~, 其次是按正则匹配,最后是交给 / 通用匹配。
当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

3、location 配置示例

1、没有修饰符 表示:必须以指定模式开始

# mkdir -p /data/www/abc
# echo abc >> /data/www/abc/1.html
# vim vim /etc/nginx/conf.d/app.conf
server {listen       80;server_name  localhost;
​location  /abc {root    /data/www;index   1.html;}# nginx -t
# systemctl restart nginx
​
访问测试
http://192.168.1.9/abc

2、=表示:必须与指定的模式精确匹配

# vim /etc/nginx/conf.d/app.conf
server {listen       80;server_name  localhost;access_log  /var/log/nginx/http_access.log  main;​    location  /abc {root    /data/www;index   1.html;} location / {return https://www.baidu.com;}location = / {return https://www.jd.com;}
}
# nginx -s reload测试:访问192.168.1.9/abc(注意浏览器无缓存)
可以看的直接跳转到京东

3、~ 表示:指定的正则表达式要区分大小写

# mkdir /data/www/nginx
# ls /data/www/
# 
server {
server_name localhost;location ~ /abc {root /data/www/nginx;index 2.html index.html;}
}
测试访问:
http://192.168.1.9/abc
不正确的
http://192.168.1.9/ABC
========================================
如果将配置文件修改为location ~ /ABC {root /home/www/nginx;index 2.html index.html;}
创建目录和文件:
[root@ansible-server html]# cd /home/www/nginx/
[root@ansible-server nginx]# mkdir ABC
[root@ansible-server nginx]# vim ABC/2.html访问:http://192.168.1.9/ABC/结论:~ 需要区分大小写。而且目录需要根据大小写定义。
404原因:访问路径是否正确;访问目录是否存在;路径大小写是否正确;

4、^~和~*匹配案例

~*:表示不区分大小写的正则匹配
[root@localhost conf.d]# vim /etc/nginx/conf.d/default.conf 
server {listen       80;server_name  localhost;
​#access_log  /var/log/nginx/host.access.log  main;
​location / {root   /usr/share/nginx/html;index  index.html index.htm;}
​location ~* /a/b/ {return 888;}
​
}
​
测试:
[root@localhost ~]# curl -I http://192.168.209.200/a/b/
HTTP/1.1 888 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:14:09 GMT
Content-Length: 0
Connection: keep-alive
​
[root@localhost ~]# curl -I http://192.168.209.200/A/B/
HTTP/1.1 888 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:16:52 GMT
Content-Length: 0
Connection: keep-alive
​
​
​^~:表示uri以某个常规字符串开头,理解为匹配url路径即可
例如:下面配置文件有两条规则,分别匹配url以字母a开头,但是长度不同,首先将长的规则先注释掉,如下:
# vim /etc/nginx/conf.d/default.conf 
server {listen       80;server_name  localhost;
​#access_log  /var/log/nginx/host.access.log  main;
​location / {root   /usr/share/nginx/html;index  index.html index.htm;}
​location ^~ /a/ {return 123;}
​#location ^~ /a/b/ {    #注释掉/a/b#return 12345;#}
​
}
测试:
# curl -I http://192.168.209.200/a/
HTTP/1.1 678 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:28:03 GMT
Content-Length: 0
Connection: keep-alive
[root@localhost ~]# curl -I http://192.168.209.200/a/b/
HTTP/1.1 678 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:28:07 GMT
Content-Length: 0
Connection: keep-alive
[root@localhost ~]# curl -I http://192.168.209.200/a/b/dsdfsdf
HTTP/1.1 678 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:28:10 GMT
Content-Length: 0
Connection: keep-alive
结论:
当前只有一个规则开启,因此当匹配url以/a/开头的任何url时,都会返回状态码678
​
# vim /etc/nginx/conf.d/default.conf  
server {listen       80;server_name  localhost;​#access_log  /var/log/nginx/host.access.log  main;location ^~ /a/ {return 678;}
​location ^~ /a/b/ {             # 取消注释return 876;}
}​
​
测试:
# curl -I http://192.168.209.200/a/
HTTP/1.1 678 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:44:52 GMT
Content-Length: 0
Connection: keep-alive
​
# curl -I http://192.168.209.200/a/b/
HTTP/1.1 876 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:44:56 GMT
Content-Length: 0
Connection: keep-alive
​
# curl -I http://192.168.209.200/a/b/sdgsdgdg
HTTP/1.1 876 
Server: nginx/1.24.0
Date: Fri, 24 Nov 2023 08:44:58 GMT
Content-Length: 0
Connection: keep-alive
​
结论:
两条规则同时被匹配成功,但是第二条规则比较长,因此第二条规则优先被匹配。(最长匹配)

七、nginx 地址重写 rewrite

1、什么是Rewrite

Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程

  • 从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客利用,对你的系统造成一定的破坏,所以静态化的URL地址可以给我们带来更高的安全性。

  • 实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问tianyun.com的80端口时,将其跳转到443端口。

2、Rewrite 相关指令

  • Nginx Rewrite 相关指令有 if、rewrite、set、return

  • 语法

rewrite regex replacement [flag];regex是用来匹配请求URI的正则表达式,
replacement是用来替换匹配到的部分的字符串。
flag是可选的标志,用于指定重写规则的行为。

2.1、if 语句

  • 应用环境

    作用域:
    server块
    location块

    语法:

    if (condition) { … }
    if 可以支持如下条件判断匹配符号
    ~                   正则匹配 (区分大小写)
    ~*                  正则匹配 (不区分大小写)
    !~                  正则不匹配 (区分大小写)
    !~*                 正则不匹配  (不区分大小写)
    -f 和!-f             用来判断是否存在文件
    -d 和!-d             用来判断是否存在目录
    -e 和!-e             用来判断是否存在文件或目录
    -x 和!-x             用来判断文件是否可执行
    ​
    在匹配过程中可以引用一些Nginx的全局变量
    $args               请求中的参数;
    $document_root      针对当前请求的根路径设置值;
    $host               请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
    $limit_rate         对连接速率的限制;
    $request_method     请求的方法,比如"GET"、"POST"等;
    $remote_addr        客户端地址;
    $remote_port        客户端端口号;
    $remote_user        客户端用户名,认证用;
    $request_filename   当前请求的文件路径名(带网站的主目录/usr/local/nginx/html/images/a.jpg)
    $request_uri        当前请求的文件路径名(不带网站的主目录/images/a.jpg)
    $query_string       与$args相同;
    $scheme             用的协议,比如http或者是https
    $server_protocol    请求的协议版本,"HTTP/1.0"或"HTTP/1.1";
    $server_addr        服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费);
    $server_name        请求到达的服务器名;
    $document_uri       与$uri一样,URI地址;
    $server_port        请求到达的服务器端口号;

    2.2、Rewrite flag

    rewrite 指令根据表达式来重定向URI,或者修改字符串。可以应用于server,location, if环境下每行rewrite指令最后跟一个flag标记,支持的flag标记有:

    last                表示完成rewrite。默认为last。
    break               本条规则匹配完成后,终止匹配,不再匹配后面的规则
    redirect            返回302临时重定向,浏览器地址会显示跳转后的URL地址
    permanent           返回301永久重定向,浏览器地址会显示跳转后URL地址

    redirect 和 permanent区别则是返回的不同方式的重定向:

    对于客户端来说一般状态下是没有区别的。而对于搜索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。

    使用302重定向时,搜索引擎(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,也许地址栏不会更改。

1、Rewrite匹配参考示例

本地解析host文件--wind
# http://www.testpm.com/a/1.html ==> http://www.testpm.com/b/2.htmllocation /a {root    /html;             #可不写index   1.html index.htm;  #可不写rewrite .* /b/2.html permanent;}location /b {root    /html;index   2.html index.htm;}
例2:(二级目录跳转,(.*)捕获了所有/2019/二级目录后面的路径和查询参数)
# http://www.testpm.com/2019/a/1.html ==> http://www.testpm.com/2018/a/1.htmllocation /2019/a {root    /var/www/html;index   1.html index.hml;rewrite ^/2019/(.*)$ /2018/$1 permanent; }location /2018/a {root    /var/www/html;index   1.html index.htl;}
​
例3:
# http://www.qf.com/a/1.html ==> http://jd.com
location /a {root    /html;if ($host ~* www.baidu.com ) {rewrite .* http://jd.com permanent;}
}
​
例4:
# http://www.qf.com/a/1.html ==> http://jd.com/a/1.html
location /a {root /html;if ( $host ~* baidu.com ){rewrite .* http://jd.com$request_uri permanent;}
}
​
例5:
# http://www.tianyun.com/login/tianyun.html ==> http://www.tianyun.com/reg/login.html?user=tianyunlocation /login {root   /usr/share/nginx/html;rewrite ^/login/(.*)\.html$ http://$host/reg/login.html?user=$1;}location /reg {root /usr/share/nginx/html;index login.html;}
​
例6:
#http://www.tianyun.com/qf/11-22-33/1.html  ==>  http://www.tianyun.com/qf/11/22/33/1.html
location /qf {rewrite ^/qf/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /qf/$1/$2/$3$4 permanent;}
​location /qf/11/22/33 {root /html;index   1.html;}

2、set 指令

set 指令是用于定义一个变量,并且赋值

应用环境:

server,location,if

应用示例

例8:
#http://alice.testpm.com ==> http://www.testpm.com/alice
#http://jack.testpm.com ==> http://www.testpm.com/jack
​
[root@nginx-server conf.d]# cd /usr/share/nginx/html/
[root@nginx-server html]# mkdir jack alice
[root@nginx-server html]# echo "jack.." >> jack/index.html
[root@nginx-server html]# echo "alice.." >> alice/index.html
​
本地解析域名host文件
打开windows本地文件:C:\Windows\System32\drivers\etc\hosts
10.0.105.202 www.testpm.com
10.0.105.202 alice.testpm.com
10.0.105.202 jack.testpm.com# echo alice >> /usr/share/nginx/html/alice/index.html
# echo jack >> /usr/share/nginx/html/jack/index.html
# vim /etc/nginx/conf.d/app.conf  
#编辑配置文件,不同配置文件需要区别域名或者端口,如下端口设置为81
server {listen       81;   server_name  www.testpm.com;
​location / {root   /usr/share/nginx/html;index  index.html index.htm;if ( $host ~* ^www.testpm.com$) {break;}if ( $host ~* "^(.*)\.testpm\.com$" ) {set $user $1;rewrite .* http://www.testpm.com/$user permanent;}}location /jack {root /usr/share/nginx/html;index  index.html;}location /alice {root /usr/share/nginx/html;index index.html;}
}

3、return 指令

return 指令用于返回状态码给客户端

server,location,if

应用示例:

例9:如果访问的.sh结尾的文件则返回403操作拒绝错误
server {listen       80;server_name  www.testpm.cn;#access_log  /var/log/nginx/http_access.log  main;
​location / {root   /usr/share/nginx/html;index  index.html index.htm;}
​location ~* \.sh$ {return 403;}
}
​
例10:80 ======> 443 :80转443端口
server {listen       80;server_name  www.testpm.cn;access_log  /var/log/nginx/http_access.log  main;return 301 https://www.testpm.cn$request_uri;
}
​
server {listen 443 ssl;server_name www.testpm.cn;access_log  /var/log/nginx/https_access.log  main;
​#ssl on;ssl_certificate   /etc/nginx/cert/2447549_www.testpm.cn.pem;ssl_certificate_key  /etc/nginx/cert/2447549_www.testpm.cn.key;ssl_session_timeout 5m;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;ssl_prefer_server_ciphers on;
​location / {root  /usr/share/nginx/html;index index.html index.htm;}
}
​
[root@nginx-server ~]# curl -I http://www.testpm.cn
HTTP/1.1 301 Moved Permanently
Server: nginx/1.16.0
Date: Wed, 03 Jul 2019 13:52:30 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://www.testpm.cn/

4、last,break详解

last指令:当使用last指令时,Nginx会重新开始处理匹配的location块。它会重新解析URI,并在重新匹配的location块中继续处理请求。

break指令:当使用break指令时,Nginx会停止在当前的location块中处理请求,并直接返回对应的内容。这个指令在重写URI时特别有用,它会停止后续的location匹配过程。

[root@localhost test]# cat /etc/nginx/conf.d/last_break.conf 
server {listen       80;server_name  localhost;access_log  /var/log/nginx/last.access.log  main;
​location / {root   /usr/share/nginx/html;index  index.html index.htm;}location /break/ {root /usr/share/nginx/html;rewrite .* /test/break.html break;}location /last/ {root /usr/share/nginx/html;rewrite .* /test/last.html last;}location ~ /test/ {                     #二级目录test后要加/,因为要进入test匹配内容root /usr/share/nginx/html;rewrite .* /test/test.html break;}
​
}
[root@localhost conf.d]# cd /usr/share/nginx/html/
[root@localhost html]# mkdir test       #最终跳转路径需要有对应目录和文件内容
[root@localhost html]# echo "last" > test/last.html
[root@localhost html]# echo "break" > test/break.html
[root@localhost html]# echo "test" > test/test.html
​
http://10.0.105.196/break/break.html
http://10.0.105.196/last/last.html

注意:

- last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求;

- break 标记则在本条规则匹配完成后,停止匹配,不再做后续的匹配;

- 使用 proxy_pass 指令时,则必须使用break。

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

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

相关文章

2024年8月2日(安装MySQL,以及各种操作)

一、安装并配置MySQL 1、下载mysql软件包 [rootmysql ~]# wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar 2、解压 [rootmysql ~]# tar -xf mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar 3、检查是否具有mariadb/mysql&…

港湾周评|俞敏洪是否理解投资者?

《港湾商业观察》李镭 围绕着东方甄选&#xff08;01797.HK&#xff09;、俞敏洪及董宇辉的是非仍然在坊间流传。这笔人情生意的交易也无疑引发了众多投资者&#xff0c;尤其是中小股东的愤慨。 在其后的解释中&#xff0c;俞敏洪表示&#xff1a;“大家也都知道最近三个月我…

计算机毕业设计选题推荐-校内跑腿业务系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

springboot专家门诊预约管理平台-计算机毕业设计源码79775

摘要 随着互联网技术的快速发展&#xff0c;医疗健康领域数字化需求日益增长&#xff0c;专家门诊预约管理平台应运而生。本研究基于Spring Boot框架开发了一款专家门诊预约管理平台。该平台涵盖了患者用户、专家用户和管理员三个角色&#xff0c;实现了患者的预约、评价、信息…

模型 ESBI(财富四象限)

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。财富自由之路的4个阶段。 1 ESBI模型的应用 1.1 一名工程师的财富自由之路 有一个名叫张伟的软件工程师&#xff0c;他在一家大型科技公司工作&#xff08;E象限&#xff09;。随着时间的推移&#…

CTF-web基础 TCP/UDP协议

传输层协议由TCP/UDP协议组成&#xff0c;来控制信息的传输&#xff0c;二者有什么区别呢&#xff0c;TCP比较靠谱&#xff0c;但是UDP速度比较快一点。 TCP协议 Transmission Control protocol&#xff0c; 三次握手&#xff1a;先给服务器传输询问要发消息&#xff0c;然后…

二百五十四、OceanBase——Linux上安装OceanBase数据库(四):登录ocp-express,配置租户管理等信息

一、目的 在部署OceanBase成功后&#xff0c;接下来就是登录ocp-express&#xff0c;配置租户管理等信息&#xff01; 二、ocp-express网址以及账密信息 三、实施步骤 1 登录ocp-express 2 集群总览 3 租户管理 3.1 新建租户 3.2 配置新租户信息 剩下的几个模块了解即可&am…

springboot餐饮管理系统-计算机毕业设计源码73168

摘要 随着科技的不断进步和互联网时代的深入发展&#xff0c;餐饮行业正面临着一场由传统向智能化、信息化转变的革命。传统的餐饮管理方式&#xff0c;如手工点餐、纸质菜单、人工结算等&#xff0c;已经无法满足现代餐饮企业对于效率、准确性和用户体验的高要求。因此&#x…

快速将网站从HTTP升级为HTTPS

在当今数字化的世界中&#xff0c;网络安全变的越来越重要&#xff0c;HTTPS&#xff08;超文本传输安全协议&#xff09;不仅能够提供加密的数据传输&#xff0c;还能增强用户信任度&#xff0c;提升搜索引擎排名&#xff0c;为网站带来多重益处。所以将网站从HTTP升级到HTTPS…

服务器 Linux 的文件系统初探

好久没更新文章了&#xff0c;最近心血来潮&#xff0c;重新开始知识的累计&#xff0c;做出知识的沉淀~ 万事万物皆文件 文件系统&#xff1a;操作系统如何管理文件&#xff0c;内部定义了一些规则或者定义所以在 Linux 中所有的东西都是以文件的方式进行操作在 Linux 中&am…

JVM: 方法调用

文章目录 一、介绍二、方法调用的原理1、静态绑定2、动态绑定&#xff08;1&#xff09;介绍&#xff08;2&#xff09;原理 一、介绍 在JVM中&#xff0c;一共有五个字节码指令可以执行方法调用&#xff1a; invokestatic: 调用静态方法。invokespecial&#xff1a;调用对象…

Antd - Table 父子表格Checkbox联动

Antd - Table 父子表格Checkbox联动 前言一. 勾选父子组件联动二. 效果 前言 由于Antd中的父子组件之间&#xff0c;如果有多选功能&#xff0c;那么不会有联动的关系&#xff0c;需要自己实现。 一. 勾选父子组件联动 代码如下&#xff1a; import React, { useState } fr…

【靶场实操】sql-labs通关详解----第二节:前端页面相关(Less-11-Less-17)

SQL注入攻击是一种针对Web应用程序的安全漏洞&#xff0c;那么自然&#xff0c;SQL注入攻击也和前端页面息息相关&#xff0c;用户输入未被正确处理、动态查询的构建、前端JavaScript代码错误&#xff0c;等等我问题都可能造成安全威胁。 在上一节&#xff0c;我们了解了基础的…

springboot书店销售管理系统-计算机毕业设计源码09304

摘要 随着互联网的普及和发展&#xff0c;线上书店越来越受到人们的欢迎。为了更好地管理书店的销售活动&#xff0c;提高用户体验&#xff0c;开发一个基于Springboot的书店销售管理系统是至关重要的。这种系统可以帮助书店管理员更高效地管理书籍、订单和用户信息&#xff0c…

维修雅萌五代射频仪

维修雅萌五代射频仪&#xff0c;主板进水&#xff0c;看起来有点严重&#xff0c;看看这回能不能把它修好

力扣SQL50 2016年的投资 窗口函数

Problem: 585. 2016年的投资 &#x1f468;‍&#x1f3eb; 参考题解 Code SELECT ROUND(SUM(tiv_2016), 2) AS tiv_2016 -- 对符合条件的记录计算 tiv_2016 的总和&#xff0c;并保留两位小数 FROM (SELECTtiv_2016, -- 选取 tiv_2016 …

参数包 emplace_back lambda

参数包 下面的参数args前面有省略号&#xff0c;所以它就是一个可变模版参数&#xff0c;我们把带省略号的参数称为“参数包”&#xff0c;它里面包含了0到N&#xff08;N>0&#xff09;个模版参数。 // Args是一个模板参数包&#xff0c;args是一个函数形参参数包 // 声明一…

【动态规划-最大子段和】力扣1191. K 次串联后最大子数组之和

给定一个整数数组 arr 和一个整数 k &#xff0c;通过重复 k 次来修改数组。 例如&#xff0c;如果 arr [1, 2] &#xff0c; k 3 &#xff0c;那么修改后的数组将是 [1, 2, 1, 2, 1, 2] 。 返回修改后的数组中的最大的子数组之和。注意&#xff0c;子数组长度可以是 0&…

【论文阅读visual grounding】QRNet论文解读与关键代码实现

Shifting More Attention to Visual Backbone: Query-modulated Refinement Networks for End-to-End Visual Grounding 论文链接&#xff1a;https://arxiv.org/abs/2203.15442 代码链接&#xff1a;https://github.com/z-w-wang/QRNet Motivation 视觉定位&#xff08;visua…

2023-2024年 Java开发岗面试题经验分享

在各行各业中&#xff0c;面试前我们总会思索一个问题&#xff1a;究竟什么样的求职者能获得面试官的青睐&#xff1f;作为求职者&#xff0c;我们又该如何准备&#xff0c;以应对各种面试官的挑战&#xff1f;在这激烈的竞争里&#xff0c;如何才能让自己从众多应聘者中脱颖而…