服务器概述
常见的Web服务器
Apache:http://httpd.apache.org,它是世界上用的最多的web服务器,市场占有率达60%左右,模块非常丰富,系统非常稳定,可移植性好,但是比较消耗资源。
Lighttpd:http://www.lighttpd.net,它是德国人开发的一个开源软件,目标是提供一个高性能的网站,它具有内存开销低,cpu占用低,效能好及模块丰富,Nginx的重要竞争对手之一。
Tomcat:http://tomcat.apache.org,是一个开源的软件,运行servlet+jsp的web应用软件,对静态文件,高并发的处理能力弱。
IBM websphere:它功能完善,开放的Web应用程序服务器,是IBM电子商务计划的核心部分,它是基于java的应用环境,范围从简单到高级到企业级应用,相于对其它web服务器来说应该比较少。
Microsoft IIS:Microsoft的Web服务器产品为Internet information Server (IIS),IIS提供了图形界面管理工具,IIS是一种web服务器组件,其中有 web服务器,FTP服务器,nntp服务器,smtp服务器,因为有window2008和2012的支持,所以IIS也有一定的市场。
各web服务器市场占有率
查询网址:https://news.netcraft.com/。
Nginx概述
什么是Nginx
Nginx(engine x)是一个高性能的HTTP和反向代理Web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的,第一个公开版本0.1.0发布于2004年10月4日。官方测试nginx能够支支撑5万并发链接,并且cpu、内存等资源消耗却非常低,运行非常稳定。
其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx作用
在传统的Web项目中,并发量小,用户使用的少。所以在低并发的情况下,用户可以直接访问Tomcat服务器,然后Tomcat服务器返回消息给用户。比如,我们上传图片:
当然我们知道,为了解决并发,可以使用负载均衡:也就是我们多增加几个Tomcat服务器。当用户访问的时候,请求可以提交到空闲的Tomcat服务器上。
但是这种情况下可能会有一种这样的问题:上传图片操作。我们把图片上传到了Tomcat1上了,当我们要访问这个图片的时候,Tomcat1正好在工作,所以访问的请求就交给其他的Tomcat操作,而Tomcat之间的数据没有进行同步,所以就发生了我们要请求的图片找不到。
为了解决这种情况,我们就想出了分布式。我们专门建立一个图片服务器,用来存储图片。这样当我们都把图片上传的时候,不管是哪个服务器接收到图片,都把图片上传到图片服务器。
图片服务器上需要安装一个http服务器,可以使用Tomcat、Apache、Nginx。
既然我们要选择的是http服务器,为什么不继续使用Tomcat,而要使用Nginx?
原因如下:Nginx常用做静态内容服务和代理服务器(不是你FQ那个代理),直面外来请求转发给后面的应用服务(Tomcat,Django什么的),Tomcat更多用来做一个应用容器,让Java Web App跑在里面,对应同级别的有Jboss、Jetty等服务器。
Nginx的应用场景
1、 http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。
2、 虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。
-
基于端口的,不同的端口。
-
基于域名的,不同域名。
3、 反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。
在CentOS7下安装Nginx
Nginx下载
官网:http://nginx.org/en/download.html 。
Nginx的安装
1、安装Nginx依赖的包
Nginx是C语言开发,建议在Linux上运行,所以我们选择在Linux上安装Nginx。
-
gcc:安装Nginx需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gcc。
-
PCRE:PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库。Nginx的http模块使用pcre来解析正则表达式,所以需要在Linux上安装pcre库。注:pcre-devel是使用pcre开发的一个二次开发库。Nginx也需要此库。
-
zlib:zlib库提供了很多种压缩和解压缩的方式,Nginx使用zlib对http包的内容进行gzip,所以需要在Linux上安装zlib库。
-
openssl:OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。 Nginx不仅支持http协议,还支持https(即在ssl协议上传输http),所以需要在Linux安装openssl库。
yum install gcc-c++
yum install -y pcre pcre-devel
yum install -y zlib zlib-devel
yum install -y openssl openssl-devel
2、上传nginx并解压
# 切换目录
cd /usr/local/src
# 解压上传的Nginx
tar -zxvf nginx-1.18.0.tar.gz -C /usr/local/src
# 重命名
mv nginx-1.18.0/ nginx
上面的步骤操作完成后,在/usr/local/src里面会有一个nginx的文件夹,进入后运行configure。
#在/usr下创建nginx目录
mkdir /usr/nginx
cd /usr/local/src/nginx
[root@localhost nginx]# ./configure --prefix=/usr/nginx
[root@localhost nginx]# make make编译
[root@localhost nginx]# make install 编译安装
Nginx的目录结构
conf:配置文件。
html:静态页面【可以做CDN加速】。
logs:日志。
sbin:可执行文件。
Nginx的启动、停止
[root@localhost nginx]# cd /usr/nginx/sbin/
# 运行
[root@localhost sbin]# ./nginx
# 停止
./nginx -s stop
#刷新,当修改了conf文件夹下的配置文件后要进行刷新
./nginx -s reload
访问
在浏览器中输入ip地址即可访问
Nginx的配置
在/usr/nginx/conf目录下nginx.conf文件是Nginx的配置文件。
main # 全局信息的配置
# user nobody nobody; #user用来指定nginx worker进程运行用户以及用户组,默认nobody账号运行
worker_processes 2; #指定nginx要开启的子进程数量,运行过程中监控每个进程消耗内存(一般几M~几十M不等)根据实际情况进行调整,通常数量是CPU内核数量的整数倍
# error_log logs/error.log #定义错误日志文件的位置及输出级别【debug、info、notice、warn、error、crit】
# error_log logs/error.log notice
# error_log logs/error.log info
# pid logs/nginx.pid #用来指定进程id的存储文件的位置
worker_rlimit_nofile 1024; #用于指定一个进程可以打开最多文件数量的描述
events { # nginx工作模式配置
worker_connections 1024;#指定最大可以同时接收的连接数量,最大连接数量是和worker processes共同决定的。
multi_accept on;#指定nginx在收到一个新连接通知后尽可能多的接受更多的连接
use epoll;#指定了线程轮询的方法,如果是linux2.6+,使用epoll,如果是BSD如Mac请使用Kqueue
}
http { # http设置
....
server { # 服务器主机配置
....
location { # 路由配置
....
}
location path {
....
}
location otherpath {
....
}
}
server {
....
location {
....
}
}
upstream name { # 负载均衡配置
....
}
}
http模块
http{
##
# 基础配置
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL证书配置
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# 日志配置
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip 压缩配置
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript
text/xml application/xml application/xml+rss text/javascript;
##
# 虚拟主机配置
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
1、基础配置
sendfile on:配置on让sendfile发挥作用,将文件的回写过程交给数据缓冲去去完成,而不是放在应用中完成,这样的话在性能提升有有好处
tc_nopush on:让nginx在一个数据包中发送所有的头文件,而不是一个一个单独发
tcp_nodelay on:让nginx不要缓存数据,而是一段一段发送,如果数据的传输有实时性的要求的话可以配置它,发送完一小段数据就立刻能得到返回值,但是不要滥用哦
keepalive_timeout 10:给客户端分配连接超时时间,服务器会在这个时间过后关闭连接。一般设置时间较短,可以让nginx工作持续性更好
client_header_timeout 10:设置请求头的超时时间
client_body_timeout 10:设置请求体的超时时间
send_timeout 10:指定客户端响应超时时间,如果客户端两次操作间隔超过这个时间,服务器就会关闭这个链接
limit_conn_zone $binary_remote_addr zone=addr:5m :设置用于保存各种key的共享内存的参数,
limit_conn addr 100: 给定的key设置最大连接数
server_tokens:虽然不会让nginx执行速度更快,但是可以在错误页面关闭nginx版本提示,对于网站安全性的提升有好处哦
include /etc/nginx/mime.types:指定在当前文件中包含另一个文件的指令
default_type application/octet-stream:指定默认处理的文件类型可以是二进制
type_hash_max_size 2048:混淆数据,影响三列冲突率,值越大消耗内存越多,散列key冲突率会降低,检索速度更快;值越小key,占用内存较少,冲突率越高,检索速度变慢
2、日志配置
access_log logs/access.log:设置存储访问记录的日志
error_log logs/error.log:设置存储记录错误发生的日志
3、SSL证书加密
ssl_protocols:指令用于启动特定的加密协议,nginx在1.1.13和1.0.12版本后默认是ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2,TLSv1.1与TLSv1.2要确保OpenSSL >= 1.0.1 ,SSLv3 现在还有很多地方在用但有不少被攻击的漏洞。
ssl prefer server ciphers:设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件
4、压缩配置
gzip 是告诉nginx采用gzip压缩的形式发送数据。这将会减少我们发送的数据量。
gzip_disable 为指定的客户端禁用gzip功能。我们设置成IE6或者更低版本以使我们的方案能够广泛兼容。
gzip_static 告诉nginx在压缩资源之前,先查找是否有预先gzip处理过的资源。这要求你预先压缩你的文件(在这个例子中被注释掉了),从而允许你使用最高压缩比,这样nginx就不用再压缩这些文件了(想要更详尽的gzip_static的信息,请点击这里)。
gzip_proxied 允许或者禁止压缩基于请求和响应的响应流。我们设置为any,意味着将会压缩所有的请求。
gzip_min_length 设置对数据启用压缩的最少字节数。如果一个请求小于1000字节,我们最好不要压缩它,因为压缩这些小的数据会降低处理此请求的所有进程的速度。
gzip_comp_level 设置数据的压缩等级。这个等级可以是1-9之间的任意数值,9是最慢但是压缩比最大的。我们设置为4,这是一个比较折中的设置。
gzip_type 设置需要压缩的数据格式。上面例子中已经有一些了,你也可以再添加更多的格式。
5、文件缓存配置
open_file_cache 打开缓存的同时也指定了缓存最大数目,以及缓存的时间。我们可以设置一个相对高的最大时间,这样我们可以在它们不活动超过20秒后清除掉。
open_file_cache_valid 在open_file_cache中指定检测正确信息的间隔时间。
open_file_cache_min_uses 定义了open_file_cache中指令参数不活动时间期间里最小的文件数。
open_file_cache_errors 指定了当搜索一个文件时是否缓存错误信息,也包括再次给配置中添加文件。我们也包括了服务器模块,这些是在不同文件中定义的。如果你的服务器模块不在这些位置,你就得修改这一行来指定正确的位置。
server模块
srever模块配置是http模块中的一个子模块,用来定义一个虚拟访问主机,也就是一个虚拟服务器的配置信息。
server {
listen 80;
server_name localhost 192.168.1.100;
root /nginx/www;
index index.php index.html index.html;
charset utf-8;
access_log logs/access.log;
error_log logs/error.log;
......
}
核心配置信息如下:
-
server:一个虚拟主机的配置,一个http中可以配置多个server。
-
server_name:用力啊指定ip地址或者域名,多个配置之间用空格分隔。
-
root:表示整个server虚拟主机内的根目录,所有当前主机中web项目的根目录。
-
index:用户访问web网站时的全局首页。
-
charset:用于设置www/路径中配置的网页的默认编码格式。
-
access_log:用于指定该虚拟主机服务器中的访问记录日志存放路径。
-
error_log:用于指定该虚拟主机服务器中访问错误日志的存放路径。
location模块
location模块是Nginx配置中出现最多的一个配置,主要用于配置路由访问信息。
在路由访问信息配置中关联到反向代理、负载均衡等等各项功能,所以location模块也是一个非常重要的配置模块。
基本配置
location / {
root /nginx/www;
index index.php index.html index.htm;
}
location /:表示匹配访问根目录。
root:用于指定访问根目录时,访问虚拟主机的web目录。
index:在不指定访问具体资源时,默认展示的资源文件列表。
反向代理配置方式
通过反向代理代理服务器访问模式,通过proxy_set配置让客户端访问透明化
location / {
proxy_pass http://localhost:8888;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header Host $http_host;
}
uwsgi配置
wsgi模式下的服务器配置访问方式
location / {
include uwsgi_params;
uwsgi_pass localhost:8888
}
upstream模块
upstream模块主要负责负载均衡的配置,通过默认的轮询调度方式来分发请求到后端服务器。
简单的配置方式如下:
upstream name {
ip_hash;
server 192.168.1.100:8000;
server 192.168.1.100:8001 down;
server 192.168.1.100:8002 max_fails=3;
server 192.168.1.100:8003 fail_timeout=20s;
server 192.168.1.100:8004 max_fails=3 fail_timeout=20s;
}
核心配置信息如下:
-
ip_hash
:指定请求调度算法,默认是weight权重轮询调度,可以指定。 -
server host:port
:分发服务器的列表配置。 -
-- down
:表示该主机暂停服务。 -
-- max_fails
:表示失败最大次数,超过失败最大次数暂停服务。 -
-- fail_timeout
:表示如果请求受理失败,暂停指定的时间之后重新发起请求。
端口和目录的配置
在nginx.conf文件中添加一个server节点,修改端口号就可以【自行添加,不影响原来的】,也就是一个nginx里面可以跑多个端口的项目,这个是tomcat是有本质的区别的。一个tomcat只能对应一个端口的多个项目服务,一个nginx可以对应多个端口下面的多个项目服务。
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
}
反向代理、负载均衡
正向代理与反向代理
1、正向代理
拿借钱打个比方,A想向C借钱,但是C不认识A所以不借给他,然后A就通过B向C借钱,B借到钱之后再转交给A,在这个过程中B就扮演了一个正向代理的角色,这个过程中,真正借钱的人是谁,C是不知道的。
我们常说的代理也就是指正向代理,正向代理的过程,它隐藏了真实的请求客户端,服务端不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替来请求,科学上网工具Shadowsocks扮演的就是典型的正向代理角色。
比如我想访问谷歌,要想翻越这堵墙,你可以在国外用Shadowsocks来搭建一台代理服务器,代理帮我们请求谷歌,代理再把请求响应结果再返回给我。
2、反向代理
还用借钱的例子,A想向C借钱,然后C借给他了,但是实际上这个钱可能C向B借的,至于钱到底是谁的,A是不知道的。这里的C扮演着一个反向代理的角色,客户不知道真正提供服务的人是谁。
反向代理隐藏了真实的服务端,当我们访问百度的时候,背后可能有成千上万台服务器为我们服务,但具体是哪一台,你不知道,也不需要知道,你只需要知道反向代理服务器是谁就好了。www.baidu.com
就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到提供真实服务的服务器那里去。Nginx就是性能非常好的反向代理服务器,它可以用来做负载均衡。
负载均衡
网站的访问量越来越大,服务器的服务模式也得进行相应的升级,比如分离出数据库服务器、分离出图片作为单独服务,这些是简单的数据的负载均衡,将压力分散到不同的机器上。有时候来自web前端的压力,也能让人十分头痛。怎样将同一个域名的访问分散到两台或更多的机器上呢?这其实就是另一种负载均衡了,nginx自身就可以做到,只需要做个简单的配置就行。
nginx不单可以作为强大的web服务器,也可以作为一个反向代理服务器,而且nginx还可以按照调度规则实现动态、静态页面的分离,可以按照轮询、ip哈希、URL哈希、权重等多种方式对后端服务器做负载均衡,同时还支持后端服务器的健康检查。
Nginx负载均衡一些基础知识:
Nginx 的 upstream 目前支持 4 种方式的分配 :
-
轮询(默认) :每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
-
weight(权重):指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
-
ip_hash:每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
-
fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。
-
url_hash(第三方)
反向代理+负载均衡的配置
架构思想
配置
#编辑里面的nginx.conf
vi nginx.conf
#在server节点上加入以下配置
upstream www.erp.com {
server 192.168.15.131:8080;
server 192.168.15.131:8090;
server 192.168.15.131:8100;
#ip_hash;这是是用来解决登陆的session的问题
}
#修改location的配置
server {
listen 80;
server_name www.erp.com;#配置访问的域名
location / {
# root html;
# index index.html index.htm;
proxy_pass http://www.erp.com; #指向上面配置的server的节点
}
}
解决请求过慢的问题
#在nginx.conf文件的location里面加入如下配置
proxy_redirect off ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 50m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 256k;#缓冲区代理缓冲用户端请求的最大字节数,
proxy_connect_timeout 1; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 30; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 60; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 256k;#设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 256k; #proxy_buffers缓冲区,网页平均在256k下,这样设置
proxy_busy_buffers_size 256k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 256k; #设定缓存文件夹大小
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
权重配置
upstream www.erp.com {
server 192.169.15.131:8080 weight=5;
server 192.168.15.131:8090 weight=3;
server 192.168.15.131:8100 weight=1;
#ip_hash;这是是用来解决登陆的session的问题
}
#以下的配置是权重 最大请求失败次数 失败超时时间
#server 192.168.15.131:8080 weight=5 max_fails=2 fail_timeout=30s
登陆session的配置问题
1、不使用session,换用cookie
session是存放在服务器端的,cookie是存放在客户端的,我们可以把用户访问页面产生的session放到cookie里面,就是以cookie为中转站。你访问web服务器A,产生了session然后把它放到cookie里面,当你的请求被分配到B服务器时,服务器B先判断服务器有没有这个session,如果没有,再去看看客户端的cookie里面有没有这个session,如果也没有,说明session真的不存在,如果cookie里面有,就把cookie里面的sessoin同步到服务器B,这样就可以实现session的同步了。
说明:这种方法实现起来简单,方便,也不会加大数据库的负担,但是如果客户端把cookie禁掉了的话,那么session就无从同步了,这样会给网站带来损失;cookie的安全性不高,虽然它已经加了密,但是还是可以伪造的。
2、session存在数据库(MySQL等)中
可以配置将session保存在数据库中,这种方法是把存放session的表和其他数据库表放在一起,如果mysql也做了集群了话,每个mysql节点都要有这张表,并且这张session表的数据表要实时同步。
说明:用数据库来同步session,会加大数据库的IO,增加数据库的负担。而且数据库读写速度较慢,不利于session的适时同步。
3、session存在memcache或者redis中
memcache可以做分布式,php配置文件中设置存储方式为memcache,这样php自己会建立一个session集群,将session数据存储在memcache中。
说明:以这种方式来同步session,不会加大数据库的负担,并且安全性比用cookie大大的提高,把session放到内存里面,比从文件中读取要快很多。但是memcache把内存分成很多种规格的存储块,有块就有大小,这种方式也就决定了,memcache不能完全利用内存,会产生内存碎片,如果存储块不足,还会产生内存溢出。
4、ip_hash
upstream www.erp.com {
server 192.168.15.131:8080;
server 192.168.15.131:8090;
server 192.168.15.131:8100;
ip_hash;#一种IP的算法,只要用户使用同一个IP请求,nginx会分流到之前请求的服务器
}
Nginx中的ip_hash技术能够将某个ip的请求定向到同一台后端应用服务器,这样一来这个ip下的某个客户端和某个后端就能建立起稳固的session,ip_hash是在upstream配置中定义的。
说明:因为这种方式只能用IP来分配后端,所以要求nginx一定要是最前端的服务器,否则nginx会取不到真实的客户端ip,那ip_hash就失效了。例如在服务器架构中使用squid做前端高速缓存,那么nginx取到的就是squid服务器的ip,用这个ip来做ip_hash肯定是不对的。再有,如果nginx的后端还有其他的负载均衡,将请求又分流了,那么对于某个客户端的请求,肯定不能定位到同一台应用服务器(例如php的fast-cgi服务器等),这样也不能做到session共享,如果在nginx后面再做负载均衡,我们可以再搭一台squid,然后再直接到应用服务器,或者用 location作一次分流,将需要session的部分请求通过ip_hash分流,剩下的走其它后端。
动静分离
静动分离,就是将css、js、jpg等静态资源和jsp等动态资源分开处理,以此提高服务器响应速度,提高性能。
配置:修改conf/nginx.conf的server里面的配置。
#动态分离的配置
location ~* \.(css|js|html)$ {
root resources;#可以使用相对路径和绝对路径 /usr/resources就是绝对路径
expires 7d;#有效天数
}
location ~* \.(avi|txt|png|gif|jpg|mp3|mp4|rmvb)$ {
root resources;
expires 20d;
}
动静分离的配置正则说明
http.server.localtion语法
基本语法: location [=|~|~*|^~]/uri/{...}
= 严格匹配, 如果这个查询匹配,将停止搜索并立即处理此请求
~ 区分大小写匹配(可用正则表达式)
~* 不区分大小写匹配(可用正则表达式)
!~ 区分大小写匹配
!~* 不区分大小写匹配
^~ 如果把这个前缀用于一个常规字符串,那么告诉nginx如果路径匹配那么不测试正则表达式
location = /{
#只匹配/查询
}
location /{
#匹配任何查询,因为所有请求都以/开头。但是正则表达式和长的块规则将被优先查询匹配
}
location ^~ /images/{
#匹配任何以/images/开头的查询并停止搜索。任何正则表达式将不会被测试。
}
location ~*.(gif|jpg|jpeg)${
#匹配任何以gif|jpg|jpeg结尾的请求
}
评论区