IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Nginx一篇足够 -> 正文阅读

[系统运维]Nginx一篇足够


在这里插入图片描述

nginx官网
tengine官网
tengine是淘宝在nginx的基础上针对大量网站的需求,添加了很多高级功能和特性,目的是打造一个高效,稳定,安全,易用的web平台。


1.nginx介绍

nginx是一款轻量级的web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。

Nginx是由伊戈尔·赛索耶夫开发的,第一个公开版本0.1.0发布于2004年10月4日

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。


2.nginx特性和优点

2.1nginx的特性

  • nginx采用c进行编写,无论是系统资源开销还是cpu使用效率都要比Perlbal(事件驱动性)要好
  • nginx是apache的代替品,高并发连接
  • 使用epoll and kqueue作为开发模型
  • nginx负载均衡服务器,既可以在内部直接支持PHP程序进行服务(集群架构),也可以作为HTTP代理服务对外进行服务(负载均衡)

2.2nginx优点

  • 高并发连接,官方测试支撑5万并发连接,实际生产环境中跑到2-3万并发连接数
  • 内存消耗极少,开启1个nginx进程消耗15MB,10个才150MB
  • 配置文件非常简单,通俗易懂
  • 成本低,nginx为开源软件,免费使用,购买F5 BIG-IP,NetScaler等硬件负载均衡交换,需要几十万费用
  • 支持Rewrite重写规则,根据域名,URL的不同,将HTTP请求分到不同的后端服务器群组
  • 内部有健康检查系统,如果nginx proxy后端的某个web服务器宕机后,不会影响到前端的访问
  • 节省带宽,支持GZIP压缩,可以添加浏览器本地缓存的Header头
  • 稳定性高,用于反向代理,几乎不宕机
  • 模块化设计,模块可动态编译
  • 支持热部署:可以不停机重载配置文件
  • 支持事件驱动,AIO(AsyncIO,异步IO)、mmap(Memory Map,内存映射)等性能优化

3.nginx功能以及扩展

nginx功能

  • 静态资源的web服务器,能缓存打开的文件
  • http,smtp,pop3协议的反向代理服务器
  • 缓存加速,负载均衡
  • 支持FastCGI(fpm,LNMP),uWSGI(python)等
  • 模块化(非DSO机制),过滤器zip,SSI及图像的大小调整
  • 支持SSL

nginx扩展功能

  • 名称和IP虚拟主机
  • 支持keepalive(支持长连接)
  • 支持平滑升级(在不停掉老进程的情况下,启动新进程,保障用户的正常访问)
  • 定制访问日志,支持日志缓存,提高日志缓存性能
  • 支持URL重写
  • 支持路径别名
  • 支持基于ip和用户的访问控制
  • 支持速率限制,支持并发数限制

4.nginx的应用
  • nginx结合FastCGI运行php,jsp,Perl等程序
  • nginx作为反向代理,负载均衡,规则过滤
  • nginx运行静态HTML网页等
  • nginx与其它技术结合应用

5.nginx工作原理

nginx由内核和模块组成,然后通过查找配置文件将客户端请求映射到一个location block中(location是nginx配置中的一个指令,用于URI匹配(URI是标识、定位任何资源的字符串,URL是统一资源定位系统)),location中的配置指令将会启动不同的模块去完成相应的工作。

nginx的模块直接编译进nginx,属于静态编译方式
启动nginx后,nginx的模块会自动加载,(而apache启动是先将模块编译成一个so文件,再在配置文件中指定是否进行加载。)
nginx在解析配置文件时,nginx的每个模块都可能去处理某个请求,但是一个处理请求只能由一个模块完成。

nginx进程结构:
nginx启动后,会产生一个Master进程,该进程不处理任何客户端的请求,用来生成worker线程,一个worker线程可以用来处理n个request请求
在这里插入图片描述

nginx常规处理HTTP的请求和响应的过程图
在这里插入图片描述

客户端进行web请求的流程图:
在这里插入图片描述
图解:
客户端向服务端发送请求连接,其中经过3次握手,接受到了请求后,进行解封装,根据所需要的资源,nginx的master进程会找一个worker子线程去拿到资源,然后返回给主进程master,master进程构建响应报文,通过网络接口发送响应给客户端,其中这个发送响应的过程会被记录事务的过程。


6.nginx模块

nginx官方模块文档
nginx的模块分类
核心模块:
HTTP模块(用来发布http-web服务网站的模块)
EVENT模块(用于处理nginx访问请求,进行回复)
MAIL模块(负责邮箱发布)

基础模块:
HTTP FastCGI模块(用于和php程序进行交互的模块)
HTTP Proxy模块(配置反向代理转发的模块,负责将后端传递参数)
HTTP Rewrite模块(支持Rewrite规则重写,支持域名跳转)
HTTP Access模块(用来进行虚拟主机发布模块,记录访问日志)等
第三方模块:
HTTP Upstream,Request Hash模块(利用hash算法进行负载均衡的模块)
Notice模块
HTTP Access Key模块(http请求访问校验模块)
Limit_req模块:(http请求限制模块)
Upstream check module:检测后端负载转发的模块。

nginx的模块功能

  • Handlers(处理器模块),直接进行处理请求,进行输出内容和修改headers信息等操作,一般一个
  • Filters(过滤器模块),该模块主要对其它处理器输出的内容进行修改操作,最后由nginx输出。
  • Proxies(代理器模块),nginx的HTTP Upstream之类的模块,这些模块主要与后端如FastCGI等操作交互,实现服务代理和负载均衡功能
7.nginx编译安装

nginx包下载

#安装环境工具包
[root@nginx ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++
[root@nginx ~]# yum -y groups mark install 'Development Tools'
#创建系统用户
[root@nginx ~]# useradd -r -M -s /sbin/nologin nginx
#创建日志存放目录
[root@nginx ~]# mkdir -p /var/log/nginx
[root@nginx ~]# chown -R nginx.nginx /var/log/nginx
#下载nginx
[root@nginx ~]# cd /usr/src/
[root@nginx src]# wget https://nginx.org/download/nginx-1.20.1.tar.gz

#编译安装nginx
[root@nginx src]# tar -xf nginx-1.20.1.tar.gz 
[root@nginx src]# cd nginx-1.20.1/
[root@nginx nginx-1.20.1]# ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-debug \
--with-http_ssl_module \					
--with-http_realip_module \					#真实ip
--with-http_image_filter_module \ 			#图片过滤
--with-http_gunzip_module \                 #打包功能
--with-http_gzip_static_module \			#解压功能
--with-http_stub_status_module \			#查看状态功能
--http-log-path=/var/log/nginx/access.log \			
--error-log-path=/var/log/nginx/error.log
[root@nginx nginx-1.20.1]# make -j $(grep 'processor' /proc/cpuinfo |wc -l) && make install

#环境变量配置
[root@nginx ~]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@nginx ~]# source /etc/profile.d/nginx.sh 
[root@nginx ~]# which nginx
/usr/local/nginx/sbin/nginx

#开机自启
[root@nginx ~]# cat /usr/lib/systemd/system/nginxd.service 
[Unit]
Description=Nginx server daemon
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx 
ExecStop=/usr/local/nginx/sbin/nginx -s stop
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process

[Install]
WantedBy=multi-user.target
[root@nginx ~]# systemctl daemon-reload 

#俩种启动方式
[root@nginx ~]# nginx    
[root@nginx ~]# systemctl enable --now nginxd.service
8.nginx常用命令
nginx -t 	//检查语法错误    (默认检查/usr/local/nginx/conf/nginx.conf文件)
nginx -v 	//查看版本
nginx -c	//指定配置文件的路径
nginx -s 	//发送控制信号    {stop/quit关闭|start开启|reload重新加载}

//指定nginx的配置文件(常用)   #直接敲nginx命令会启动默认的配置文件
[root@localhost ~]# cp /usr/local/nginx/conf/nginx.conf /opt/
[root@localhost ~]# cp /usr/local/nginx/conf/mime.types /opt/   //nginx启动依赖这几个文件
[root@localhost ~]# cp /usr/local/nginx/conf/fastcgi_params /opt/
[root@localhost ~]# nginx -s stop;nginx -c /opt/nginx.conf    //停止nginx服务立马启动指定配置文件
[root@localhost ~]# ps -ef|grep nginx
root        4987    2008  0 17:47 ?        00:00:00 nginx: master process nginx -c /opt/nginx.conf
nginx       4988    4987  0 17:47 ?        00:00:00 nginx: worker process
nginx       4989    4987  0 17:47 ?        00:00:00 nginx: worker process
nginx       4991    4987  0 17:47 ?        00:00:00 nginx: worker process
nginx       4993    4987  0 17:47 ?        00:00:00 nginx: worker process
root        5054    2602  0 17:49 pts/0    00:00:00 grep --color=auto nginx

#一般重新修改了nginx配置文件后,一般绝对不会直接重启nginx服务的,如果出现其它错误的因素短时间可能找不到,
服务起不来公司的业务就会中断,所以需要使用发信号的方式,/usr/local/nginx/sbin/nginx -s reload
9.nginx目录结构说明
[root@localhost ~]# tree /usr/local/nginx
/usr/local/nginx
├── client_body_temp
├── conf              //nginx程序所有的文件
│   ├── fastcgi.conf			//Fastcgi参数的配置文件
│   ├── fastcgi.conf.default		
│   ├── fastcgi_params		//fastcgi的参数文件
│   ├── fastcgi_params.default
│   ├── koi-utf
│   ├── koi-win
│   ├── mime.types			//媒体类型
│   ├── mime.types.default
│   ├── nginx.conf			//nginx默认的主配置文件
│   ├── nginx.conf.default
│   ├── scgi_params
│   ├── scgi_params.default
│   ├── uwsgi_params
│   ├── uwsgi_params.default
│   └── win-utf
├── fastcgi_temp       //fastcgi临时数据目录
├── html				//源码编译安装nginx的默认网站发布目录
│   ├── 50x.html				//错误页面
│   ├── index.html		//默认的首页文件
├── logs   //nginx默认的日志路径
│   |── nginx.pid	//nginx进程启动后的进程文件
│   ├── access.log              //用户访问日志,可以利用tail命令进行查看
│   ├── error.log               //错误日志
├── proxy_temp     //临时目录
├── sbin				//nginx命令目录
│   └── nginx				//nginx启动
├── scgi_temp					//临时目录
└── uwsgi_temp				//临时目录

10.nginx配置文件

(yum安装)的主配置文件:/etc/nginx/nginx.conf
(编译安装)默认的主配置文件:/usr/local/nginx/conf/nginx.conf
(yum安装)的网站目录:/usr/share/nginx/html
(编译安装)的网站目录:/usr/local/nginx/html

配置作用
nginx.confnginx的基本配置(一般只对该文件进行修改)
mime.typesMIME类型关联的扩展文件
fastcgi.conffastcgi通信接口相关的配置
proxy.conf代理相关的配置
sites.confnginx提供的网站,虚拟主机
10.1nginx.conf文件解析

nginx配置中包含的字段:
main字段:顶格配置,不会出现在某个块中
event{}:定义event模型工作特性
http{}:定义http协议相关的配置,内包含server字段,而server字段内包含location字段

配置指令格式:(配置要以;结尾)

derective value1 [value2…];
指令 参数…

指令如:

user  nobody; #一个参数
error_log  logs/error.log  notice; #俩个参数

支持使用变量:
1.自定义变量(set var_name value)
2.内置变量:模块会提供变量定义

10.2nginx调试与错误定位
daemon {on|off};   //默认为关闭状态,是否以守护进程方式运行nginx,配置在main字段处
error_log 位置 级别;	//配置错误日志,配置在main字段处
master_process {on|off}; 	//默认是开启状态,配置在main字段处,(关闭后,只会有一个进程,不会采用master-worker进程的方式)

error_log中的位置和级别的选项:
级别debug(高)–>emerg(低),级别越高信息越详细

位置详情级别详情
file(常用)指定文件的方式debug记录的信息非常详细,使用debug级别需要编译nginx时使用–with-debug,针对于高效解决错误问题,不常用
stderr屏幕里直接输出错误info
memory:size内存保存方式notice
syslog:server=address[parameter=value] (常用)错误日志记到另一台主机内warn
error(常用)出现网页错误的信息
crit
alert
emerg
10.3nginx使用必备的参数配置
user USERNAME [GROUPNAME];  	//指定运行worker进程的用户和组
pid /path/to/pid_file;			//指定nginx守护进程的pid文件
worker_rlimit_nofile number;	//设置所有worker进程最大可以打开的文件数,默认为1024(可设置10240/655350),配置在main字段处
worker_rlimit_core size; 		//指定所有worker进程能够使用的最大核心文件大小,一般默认即可
10.4nginx优化性能参数
worker_processes  n;	 //启动n个worker进程,设置n时为了避免上下文切换,通常设置cpu总核心数-1或者总核心数。(留一个cpu跑其它的进程,其它cpu均跑nginx)

#手动绑定cpu核心:(一个cpu指定一个进程)
worker_cpu_affinity 0001 0010;   		//2个cpu核心绑定
worker_cpu_affinity 0001 0010 0100;   		//3个cpu核心绑定
worker_cpu_affinity 0001 0010 0100 1000;   //4个cpu核心绑定
(二个cpu指定一个进程)
worker_cpu_affinity 0101 1010; 	//0101也就是第1、3个逻辑CPU上,1010就是第2、4个逻辑CPU上

#自动绑定cpu核心:
worker_cpu_affinity auto;  //自动绑定cpu核心

#减少工作进程中的计时器分辨率
timer_resolution interval;//减少工作进程中的计时器分辨率,从而减少gettimeofday()系统调
用的次数
如:timer_resolution 100ms;

worker_priority number;  //指定worker进程的nice值,范围在[-20,19],-20优先级最高
如:worker_priority -10;

配置流程以及查看

#配置nginx.conf文件
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
user nginx nginx;
worker_processes  3;
worker_cpu_affinity 0001 0010 0100;
worker_rlimit_nofile 10240;
worker_priority -20;

#重启服务
[root@localhost ~]# nginx -s stop ;nginx
#top查看cpu绑定情况
[root@localhost ~]# top
* P       = Last Used Cpu (SMP)    RSfd    = RES File-based (KiB) //输入F,找到此行,空格选中
#q返回输入L搜索nginx查看绑定情况
Locate string nginx
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                             P 
  38054 root      20   0   81632   1112     56 S   0.0   0.1   0:00.00 nginx                               0 
  38055 nginx     20   0  114240   6276   4676 S   0.0   0.3   0:00.00 nginx                               0 
  38056 nginx     20   0  114240   6276   4676 S   0.0   0.3   0:00.00 nginx                               1 
  38057 nginx     20   0  114240   5896   4552 S   0.0   0.3   0:00.00 nginx                               2 
10.4events字段配置
events {
    worker_connections  1024;            //进程连接的最大数
    accept_mutex on|off;    			  //工作进程将依次接受新连接,搭配lock_file字段使用
    use [epoll|rtsig|select|poll];  //指明使用的事件模型,一般默认nginx自行选择即可
}
lock_file logs/nginx.lock; //该字段配置在main字段处,告知锁定文件的路径

生产环境中测试的30000并发数怎么来的呢?

worker_processes  3;
events {
    worker_connections  20480;           
}
#进程数为3个,20480*3/2=30720

#测试并发用ab命令
[root@localhost ~]# yum -y install httpd-tools  #ab命令依赖包
[root@localhost ~]# ab -c 10 -n 30000 http://192.168.136.129/    //模拟10个用户访问30000个请求
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.136.129 (be patient)
Completed 3000 requests
Completed 6000 requests
Completed 9000 requests
Completed 12000 requests
Completed 15000 requests
Completed 18000 requests
Completed 21000 requests
Completed 24000 requests
Completed 27000 requests
Completed 30000 requests
Finished 30000 requests          //30000个请求完成
Percentage of the requests served within a certain time (ms)
  50%      2
  66%      2
  75%      2
  80%      3
  90%      3
  95%      3
  98%      4
  99%      5
 100%     11 (longest request)
10.5nginx网路相关配置
配置字段处:http, server,location
keepalive:长连接
keepalived:高可用
keepalive_timeout number;   //长连接的超时时间,默认为65秒
keepalive_requests number;  //长连接上能够允许请求的最大资源数,默认为1000
keepalive_disable [msie6|safari|none];   //指定UserAgent类型的浏览器禁止连接
tcp_nodelay on|off; 		//默认开启
tcp_nopush on|off;			//默认关闭
client_body_timeout number;  	//读取http请求报文body部分的超时时间
client_header_timeout number;  //读取http请求报文header部分的超时时间
send_timeout number;   //发送响应报文的超时时间
10.6fastcgi配置

LNMP中的交互配置,php要开启fpm模型

        location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;         #php主机的ip地址,反向代理
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/nginx/html/$fastcgi_script_name;  #scripts对应着nginx的html网页目录
            include        fastcgi_params;
        }
10.7http{}字段参数配置

http{…}的配置与http服务相关,由官网的ngx_http_core_module模块处引入,结构如下:

httpd字段中包含upstream和server字段,而server字段中包含location字段

http {				#协议级别
    include       mime.types;
    default_type  application/octet-stream;
        #keepalive_timeout  0;
    keepalive_timeout  65;
    #gzip  on;
    ...
    sendfile        on;
    #upstream{		#负载均衡配置
	#		server 127.0.0.1:81 weight=1;      //交替访问,一个访问81,一个访问80
	#		server 127.0.0.1:80 weight=1;
	#}
	
    server {				#服务器级别,一个server代表一个虚拟主(如httpd的<VirtualHost>)
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {				#请求级别,定义URL和本地系统的映射
            root   html;
            index  index.php index.html index.htm;
        }
    }
}

server{}字段解析

#一个标准的网站
   server {			
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {				
            root   html;
            index  index.php index.html index.htm;
        }
    }
#添加第二个网站
	server {
		listen 81;						#监听端口号
		server_name www.test.com;		#域名

		location / {
			root html/test;					#网站访问的目录
			index index.html;				#寻找资源的格式
		}
	}
}


#监听端口(俩种方式)
listen address:port;
listen port;

#server_name NAME;  (域名)
//当有多个server时,匹配顺序:
1.先精确匹配检查
2.左匹配检查,如*xxx.com
3.右侧匹配检查,如xxx*.com
4.正则表达式检查,如~^.*\xxx\.com$
5.default_server





#访问的目录
root html/test;      //相对路径,设置资源路径映射,用于指明请求URL对应资源文件系统上的起始路径
alias /var/www/html/; //绝对路径,定义路径别名,相对安全
index index.php index.html;  //设置先访问页面的格式,index.php访问不到再访问index.html



#创建index.html,重启nginx
[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# mkdir test
[root@localhost html]# echo 'test web' > test/index.html
[root@localhost ~]# nginx -s stop ;nginx
[root@localhost ~]# ss -antl             
LISTEN      0           128                     0.0.0.0:80                    0.0.0.0:*                      
LISTEN      0           128                     0.0.0.0:81                    0.0.0.0:*    

80端口访问
在这里插入图片描述
81端口访问
在这里插入图片描述


10.8nginx日志配置

一个网站的访问难免会出现404的情况,所以我们可以根据http响应的状态码来指定我们配置的错误页面,如:
error_page 404 =200 /404.html (访问到错误页面状态码404时,指定返回一个错误的页面)

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
error_page  404      =200        /404.html;      #当访问的页面出现404状态,则返回404,html页面,状态码也会变回200
[root@localhost ~]# vim /usr/local/nginx/html/404.html
<html>
<head>
        <meta charset ="utf-8">
        <title>test page</title>
</head>
<body>
        <a href="https://www.baidu.com">百度</a> 
<body>
</html>
[root@localhost ~]# nginx -s reload

在这里插入图片描述

定义日志格式

此处配置在http{}字段,所有的nginx服务都会受影响

#main代表着后面以;结尾的一段访问格式的变量
    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;     #访问日志 路径  格式变量
#$http_referer 是否是页面跳转
#$remote_user 哪个用户访问 
#$http_x_forwarded_for 从哪里跳转
#访问网站后得到的访问日志内容
[root@localhost logs]# cat access.log 
192.168.136.1  (对应$remote_addr,ip地址) 
- 
-(对应$remote_user,没有找到则显示-)
 [09/Nov/2021:21:18:51 +0800]  【(对应$time_local,时区)
  "GET / HTTP/1.1" (对应$request,GET请求方法)
   200 (对应$status,状态码)
   71774 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" (对应$http_user_agent,浏览器代理)
   "-"

10.9location字段访问资源响应(重要)

location配置是处于http{}字段中,location配置了要访问资源的目录路径以及主页
server有多个,location也可以有多个

location字段语法:

location [修饰符] pattern {
}

修饰符说明:
越精确匹配越应该优先使用

修饰符功能
=精确匹配(优先级最高)
~正则表达式匹配,区分大小写
~*正则表达式匹配,不区分大小写
^~前缀匹配(优先级最低)不支持正则表达式
@定义命名location区段,外部不能访问,只能由内部产生的请求访问

优先级匹配例子:

同样web页面不能出现相同的优先级匹配,比如俩个网页目录都使用 =

[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf
.....
        location = / {
          echo "A"
        }

        location / {
        echo "B"
        }

        location /documents {
        echo "C"
        }

        location ^~ /images {
        echo "D"
        }

        location ~* \.(gif|jpg|jpeg)$ {
        echo "E"
        }
        location ~ ^/Abc$ {
        echo "F"
        }
        
 ....
 
[root@localhost ~]# curl http://192.168.136.129    
A		//精确匹配优先级最高,默认匹配
[root@localhost ~]# curl http://192.168.136.129/abdwadwda
B		//没有修饰的匹配,先匹配有修饰的匹配,均没找到后,再匹配于此
[root@localhost ~]# curl http://192.168.136.129/1dadawdhwaufawo
B


[root@localhost ~]# curl http://192.168.136.129/documents/test
C			//匹配documents目录下的资源	
[root@localhost ~]# curl http://192.168.136.129/images/
D			//匹配前缀为images目录下的资源 

[root@localhost ~]# curl http://192.168.136.129/1.jpg
E			//匹配以gif|jpg|jpeg结尾的资源
[root@localhost ~]# curl http://192.168.136.129/1.gif
E
[root@localhost ~]# curl http://192.168.136.129/1.jpeg
E

[root@localhost ~]# curl http://192.168.136.129/Abc
F				//区分大小写的匹配
[root@localhost ~]# curl http://192.168.136.129/Abc?....
F

location匹配优先级从高到低顺序:

location = 路径 <---- location ^~ 路径 <-------- location ~ 正则表达式 <------ location ~* 路径 <------- location 路径


10.10location用户访问控制
#nginx默认是允许所有网段访问,因此只需要设置黑名单即可
  location = / { 
           deny 192.168.136.0/32;    #拒绝一个网段的ip访问
           #allow all;												//允许所有网段访问
           root   html;
           index  index.php index.html index.htm;
        }  
10.11location用户认证

用户认证是针对于特殊的资源,授予用户和密码,只要输入正确用户和密码才能访问到
认证语法:

location / {
    auth_basic           "closed site";
    auth_basic_user_file .passwd;
}

利用htpasswd生成文件密码

#指定文件密码生成在/usr/local/nginx/conf/内,(htpasswd是由httpd-tools包提供)
[root@localhost ~]# htpasswd -c -m /usr/local/nginx/conf/.pass admin 
New password: 
Re-type new password: 
Adding password for user admin

#查看加密的文件
[root@localhost ~]# cat /usr/local/nginx/conf/.pass 
admin:$apr1$k6eqHSzy$Mn9OeZFYEYvSKYl/ILwnL.

认证配置例子:

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
....
      location = / { 
           auth_basic "欢迎光临";
           auth_basic_user_file .pass;
           root   html;
           index  index.php index.html index.htm;
        } 
        .....
[root@localhost ~]# nginx -s reload

在这里插入图片描述

#curl命令访问的话(-u:输入用户和密码)
[root@localhost ~]# curl http://192.168.136.129 -u admin:admin

用户和密码输入错误的话不会访问到


11.https证书配置

公司内的话是需要购买证书的,相应有证书文件,放在相应位置即可
测试的话,生成私钥,生成证书签署请求获得的证书,配置https证书如下:

配置https证书参考第2段

#nginx.conf文件配置
  server {
126         listen       443 ssl;
127         server_name  clq.com;
128 
129         ssl_certificate      ssl/nginx.crt;          #俩证书文件均放在/usr/local/nginx/conf/ssl目录下
130         ssl_certificate_key  ssl/nginx.key;          #俩证书文件均放在/usr/local/nginx/conf/ssl目录下
131 
132         ssl_session_cache    shared:SSL:1m;
133         ssl_session_timeout  5m;
134 
135         ssl_ciphers  HIGH:!aNULL:!MD5;
136         ssl_prefer_server_ciphers  on;
137 
138         location / {
139             root   html;
140             index  index.html index.htm;
141         }
142     }
143 
144 }

在这里插入图片描述


12.nginx平滑升级

针对于目前使用的nginx版本,想要新的需求新的功能,来进行nginx升级

平滑升级的步骤:
1.获取老版本nginx程序的编译参数  (-V可查看)
2.获取新的软件包或功能包(下载)
3.新的版本包进行编译(./configure make)
4.备份老版本的nginx程序
5.停掉老版本程序开启新版本程序,指定默认的nginx配置文件
6.检查功能无误,替换nginx程序
#现有的nginx编译参数
[root@localhost src]# nginx -V
nginx version: nginx/1.20.1
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-3) (GCC) 
built with OpenSSL 1.1.1k  FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log

#下载新的nginx功能包到/usr/src内,进行解压
[root@localhost src]# ls
echo-nginx-module-master.zip    nginx-1.20.1
[root@localhost src]# unzip echo-nginx-module-master.zip 
[root@localhost src]# ls
echo-nginx-module-master   nginx-1.20.1
[root@localhost src]# cd echo-nginx-module-master/
[root@localhost echo-nginx-module-master]# ls
config  LICENSE  README.markdown  src  t  util  valgrind.suppress

#进入旧的nginx的目录下,选择之前的所有编译参数,最后添加一个新的编译板块
[root@localhost src]# cd nginx-1.20.1/
[root@localhost nginx-1.20.1]# nginx -V
nginx version: nginx/1.20.1
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-3) (GCC) 
built with OpenSSL 1.1.1k  FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log
[root@localhost nginx-1.20.1]# ./configure  --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=../echo-nginx-module-master
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"

#进行编译
[root@localhost nginx-1.20.1]# make

#新的nginx程序和老的nginx程序对比
[root@localhost nginx-1.20.1]# ll objs/nginx /usr/local/nginx/sbin/nginx 
-rwxr-xr-x. 1 root root 6831056 119 22:15 objs/nginx
-rwxr-xr-x. 1 root root 6308640 1031 11:42 /usr/local/nginx/sbin/nginx
#备份原来的nginx程序
[root@localhost ~]# cp /usr/local/nginx/sbin/nginx /backup/
#停掉之前的nginx,启动新的nginx程序,指定配置文件不变
[root@localhost ~]# nginx -s stop
[root@localhost ~]# /usr/src/nginx-1.20.1/objs/nginx -c /usr/local/nginx/conf/nginx.conf
[root@localhost ~]# ps -ef|grep nginx
root     1209993       1  0 19:54 ?        00:00:00 nginx: master process /usr/src/nginx-1.20.1/objs/nginx
nginx    1209994 1209993  0 19:54 ?        00:00:00 nginx: worker process
nginx    1209995 1209993  0 19:54 ?        00:00:00 nginx: worker process
nginx    1209996 1209993  0 19:54 ?        00:00:00 nginx: worker process
root     1211389  142727  0 19:55 pts/0    00:00:00 grep --color=auto nginx
#测试新的nginx功能能成功实现后,覆盖老的nginx程序
[root@localhost ~]# cp /usr/src/nginx-1.20.1/objs/nginx /usr/local/nginx/sbin/nginx 
cp:是否覆盖'/usr/local/nginx/sbin/nginx'? yes
#重启新的nginx程序
[root@localhost ~]# /usr/src/nginx-1.20.1/objs/nginx -s stop;nginx

//至此nginx平滑升级成功!!!

13.nginx状态界面

nginx状态配置基于nginx_http_stub_status_module模块
配置语法:

	location /status {
		stub_status;
		allow 192.168.1.0/24;							#拒绝所有访问请求,只让规定ip访问
		deny all;
	}

在这里插入图片描述
状态码页面消息:

状态码意义
Active connection 2当前所有打开状态连接的数量
server accepts处理了多少请求连接
handled成功创建多少次握手
requests处理了多少请求数量
Readingnginx读取客户端的Header信息数,处于接受请求状态的连接数(当一直处于请求状态,则表示已经达到阈值,则需要分流或者加cpu)
writingnginx返回客户端的header信息数,此时请求已经接受完成,处于处理请求或发送响应过程中的连接数
waiting开启长连接(keepalive)的情况下,这个值等于active-(reading+writing)(waiting值越小指明干活越多,值越大证明没怎么干活),说白就是nginx已经处理完了,正在等待下一次请求指定的连接
13.2nginx-重写URL

先说一下URL和URI
URL:统一资源定位符
如:https://www.baidu.com/s?ie=UTF-8&wd=%E7%99%BE%E5%BA%A6

URI:统一资源标识符
格式如下:[protocol] : / /[用户名]:[密码]@[服务器地址]:[服务器端口号]/[路径]?[查询字符串]#[片段ID]

一句话,URI定义资源(也就是网页文件夹的绝对路径,但是人家肯定不会让你看到路径所以会显示乱码加密的格式,通信|文件|等每个格式均不同),而URL不仅定义资源,而且还定义怎么找到资源

当一个网站的某个存放照片的目录空间不够了以后,一般会创建另一个目录挂载到一个空间足够的存储空间中,然后将照片转移过去即可,但是由于更改了路径之后,用户想要访问资源的方式也会变,所以我们就要进行配置,保证用户习惯性的访问路径。

rewrite语法格式:

rewrite regex replacement flag;
#regex:正则表达式
#replacement:可以是某个路径,也可以是URL

flag的几种类型

flag作用
last(常用)当前匹配结束进行下一个匹配,最多匹配10到20个,
break终止rewrite,不再继续匹配, rewrit规则重写后,UserAgent对新的URL重新发起请求,但是不会对当前的location做检查
redirect临时重定向的HTTP状态码302,返回新的URL
permanent永久性重定向的HTTP状态码,301返回新的URL

rewrite重写规则有利于搜索引擎优化(SEO)

nginx语法源于Perl兼容正则表达式(PCRE)库,基本语法如下:

^以^匹配的开头
$以$结尾
.匹配任意字符
[]匹配指定范围内的任意字符
[^]匹配不包括指定范围内的任意字符
|匹配|左右的字符
0分组,与|\协助
^(A|B)$   //$1的值为A,$2的值为B

URL重写的方式

#$1用于引用images内(.*.jpg)的内容,映射到/test/目录下
rewirte ^/images/(.*\.jpg)$ /test/$1 break;

#也可以是URL
rewirte ^/images/(.*\.jpg)$ http://images.baidu.com break;

RUL重写实例:

[root@localhost images]# pwd
/usr/local/nginx/html/images
[root@localhost images]# ls
1.jpg
[root@localhost images]# mv 1.jpg ../test/
[root@localhost images]# ls     #images目录下没了文件
[root@localhost test]# ls
1.jpg  

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 67         location  /images {
 68                 rewrite ^/images/(.*\.jpg)$ /test/$1 break;
 69         }
[root@localhost ~]# nginx -s reload

在这里插入图片描述
在这里插入图片描述

整个流程:
客户访问请求资源:http://192.168.136.129/images/1.jpg
nginx服务对应的location模块开始工作,进行URL重写
先在/images目录进行查看资源,查找不到再从html目录下进行查找.jpg结尾的文件,最后在test目录下找到
最后返回查找的资源给客户端

13.2nginx-if

nginx-if文档
if指令是用来进行条件判断,根据条件判断的结果选择不同的nginx配置

if(condition){…}
位置server、location

常见的condition:

  • 变量 变量值为空,或以0开头,则为false, 存在以及其它为true
  • 变量作为比较表达式,(=,!=进行测试)
  • 正则表达式匹配:
    ~:区分大小写匹配
    ~*:不区分大小写匹配
    !~ 和!~* :对上面俩种结果取反
  • 测试为文件的可能性(-f, !-f)
  • 测试为目录的可能性(-d,!-d)
  • 测试文件的存在性(-e,!-e)
  • 检查文件是否有执行权限(-x,!-x)
13.3浏览器实现分离案例

语法:

if ($http_user_agent ~* firefox) {
    rewrite ^(.*)$ /firefox/$1 break;
}
if ($http_user_agent ~* msie) {
    rewrite ^(.*)$ /msie/$1 break;
}
if ($http_user_agent ~* chrome) {
    rewrite ^(.*)$ /chrome/$1 break;
}

浏览器分离案访问例:

[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# tree
.
├── 404.html
├── 50x.html
├── chrome
│   └── index.html
├── firefox
│   └── index.html
[root@localhost html]# cat chrome/index.html 
chrome test paage
[root@localhost html]# cat firefox/index.html 
firefox test paage
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
     location  = / {
                if ($http_user_agent ~* chrome) {
                rewrite ^(.*)$ /chrome/$1 break;   
        }   
                if ($http_user_agent ~* firefox) {
                rewrite ^(.*)$ /firefox/$1 break;
        }  
        
        }     
        
        location  /chrome {
                root html; 
                index index.html; 
        }
        location  /firefox { 
                root html;
                index index.html;
        } 
[root@localhost ~]# nginx -s reload

浏览器访问查看
在这里插入图片描述
在这里插入图片描述

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;       //判断是否IE浏览器访问,是则访问/msie目录下的资源
}

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {    #设置变量值
    set $id $1;
}

if ($request_method = POST) {        #请求的资源格式为post则返回405
    return 405;
}

if ($slow) {
    limit_rate 10k;                #限制速度
}

if ($invalid_referer) {					#请求的页面无效则返回403
    return 403;
}
13.4防盗链案例

防盗链:防止别人盗用你的链接资源

location ~* \.(jpg|gif|jpeg|png)$ {
	valid_referers none blocked www.xxx.com;     #有效的连接则直接访问资源
	if ($invalid_referer) {					     #通过特殊手段的访问连接,如别人重写了url访问到你的资源进行请求,则直接丢给它403
		rewrite ^/ http://www.xxx.com/403.html;
	}
}

14.反向代理与负载均衡

nginx如果是获取静态资源的话,直接从nginx配置的路径读取相应资源,而不需要从后台服务器获取。
nginx是通过fastcgi模块进行运作处理动态资源的,常被用作后端服务器的反向代理,这样方便实现动静分离以及负载均衡,从而提高服务器的处理能力。
Http Proxy模块的功能很多,最常用的模块:proxy_pass和proxy_cache

#proxy_pass模块
句法:	proxy_pass URL;
默认:	—
语境:	location, if in location,limit_except

使用proxy_cache模块的话,需要第三方的ngx_cache_purge模块,用来清理指定的URL缓存,安装nginx时安装集成如:

./configure --add-module=../ngx_cache_purge-1.0...

nginx通过upstream模块来实现简单的负载均衡,默认的方式是轮询,针对于同一个用户的请求总是由一个后端服务器处理,可以设置ip_hash,但是客户端的ip可能是动态的,vpn,代理的话,ip随之改变,这时ip_hash设置就无效了,可以通过缓存,session

upstream  xxx.com(自己取的) {
	ip_hash;
	server 127.0.0.1:9090 weight=5;
	server 127.0.0.1:8080 weight=3;
	server 127.0.0.1:1111;
}

#upstream设置后,server段添加内容
server {
	location / {
	proxy_pass http://xxx.com;
	}
}
15.nginx负载均衡实战-静态分离
系统ip主机名服务
centos8192.168.136.239RS1-lnmplnmp
centos8192.168.136.230DR-nginx(调度器)nginx
centos7192.168.136.135RS2-httpdhttpd

RS1-lnmp上:lnmp搭建

DR-nginx搭建nginx(编译安装方式)

[root@DR-nginx~]# systemctl stop firewalld
[root@DR-nginx ~]# setenforce 0
[root@DR-nginx ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++
[root@DR-nginx ~]# yum -y groups mark install 'Development Tools'
[root@DR-nginx ~]# useradd -r -M -s /sbin/nologin nginx
[root@DR-nginx~]# cd /usr/local/src/
[root@DR-nginx src]#  wget https://nginx.org/download/nginx-1.20.1.tar.gz
--2021-11-17 23:09:22--  https://nginx.org/download/nginx-1.20.1.tar.gz
[root@DR-nginxsrc]# tar -xf nginx-1.20.1.tar.gz
[root@DR-nginx src]# cd nginx-1.20.1/
[root@DR-nginxnginx-1.20.1]# ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-debug \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log
[root@DR-nginx nginx-1.20.1]# make -j $(grep 'processor' /proc/cpuinfo |wc -l) && make install
[root@DR-nginx ~]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@DR-nginx ~]# source /etc/profile.d/nginx.sh 
[root@DR-nginx ~]#  cat /usr/lib/systemd/system/nginxd.service
[Unit]
Description=Nginx server daemon
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx 
ExecStop=/usr/local/nginx/sbin/nginx -s stop
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process

[Install]
WantedBy=multi-user.target
[root@DR-nginx ~]# systemctl daemon-reload 
[root@DR-nginx ~]# systemctl enable --now nginxd.service 

RS2-httpd搭建httpd网站(这里采用yum方式)

[root@RS2-httpd ~]# systemctl stop firewalld
[root@RS2-httpd~]# setenforce 0
setenforce: SELinux is disabled
[root@RS2-httpd ~]# yum -y install httpd
[root@RS2-httpd~]# cd /var/www/html/
[root@RS2-httpd html]# echo 'test httpd server' > index.html
[root@RS2-httpd ~]# systemctl enable --now httpd

DR-nginx主机上配置负载均衡

[root@DR-nginx ~]# vim /usr/local/nginx/conf/nginx.conf
#负载均衡
    upstream webservers {
        server 192.168.136.239 weight=3;
        server 192.168.136.135 weight=1;
    }

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
#反向代理
        location / {
            proxy_pass http://webservers;
        }

通过调度器的ip访问httpd的静态资源和lnmp的动态资源
在这里插入图片描述
在这里插入图片描述
以上是负载均衡的一个测试,现在配置动静分离:

[root@DR-nginx ~]# vim /usr/local/nginx/conf/nginx.conf
#负载均衡
    upstream static {          #静态资源
        server 192.168.136.135;
    }
    upstream dynamic {     #动态资源
        server 192.168.136.239;
    }
 server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

#反向代理
        location / {
            proxy_pass http://static;    
        }
        #....
   location ~ \.php$ {
            proxy_pass   http://dynamic;
        }
[root@DR-nginx ~]# nginx -s reload

在这里插入图片描述
在这里插入图片描述


15.zabbix监控nginx状态
系统ip主机名服务
centos8192.168.136.239nginxnginx,zabbix_agent(被监控端)
centos8192.168.136.233zabbixzabbix(监控端)

相应的服务均已部署

第一步:确保nginx服务有http_stub_status_module模块

[root@nginx ~]# nginx -V
nginx version: nginx/1.20.1
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-3) (GCC) 
built with OpenSSL 1.1.1k  FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log

第二步:配置nginx配置文件开启状态界面

[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;
  
        #access_log  logs/host.access.log  main;

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

#nginx-状态页面
        location /status{
                stub_status;
                allow 127.0.0.1;
                access_log off;

        }

第三步:配置监控脚本,主要监控waiting字段,值越小证明完成工作越多,值越大则证明没完成相应的进程工作,则认为失败了进行报警通知

[root@nginx ~]# mkdir /scripts
[root@nginx ~]# cd /scripts/
[root@nginx scripts]# vim check_nginx_status.sh
[root@nginx scripts]# cat check_nginx_status.sh 
#!/bin/bash
count=$(curl -s  http://192.168.136.239/status|awk 'NR==4{print $6}')
if [ $count -ge 3 ];then          #当监控的waiting值大于等于3时(大于30720并发情况下)则认为发生故障了(以实际情况为主)
        echo '1'
else
        echo '0'
fi

第四步:配置 /usr/local/etc/zabbix_agentd.conf文件

[root@nginx scripts]# vim /usr/local/etc/zabbix_agentd.conf
UnsafeUserParameters=1
UserParameter=check_nginx_status,/scripts/check_nginx_status.sh
#重启zabbix_agent
[root@nginx scripts]# killall zabbix_agentd 
[root@nginx scripts]# zabbix_agentd

第五步:zabbix服务端检查语法

[root@zabbix ~]# zabbix_get -s 192.168.136.239 -k check_nginx_status
0						#检测成功

第六步:zabbix-web添加相应的监控项,触发器,用户媒介,动作,告知方式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第七步:模拟超过30720请求数进行测试

[root@zabbix ~]#  ab -c 100 -n 31000 http://192.168.136.239/
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.136.239 (be patient)
Completed 3000 requests
Completed 6000 requests
Completed 9000 requests
Completed 12000 requests
Completed 15000 requests
Completed 18000 requests
Completed 21000 requests
Completed 24000 requests
Completed 27000 requests
Completed 30000 requests
Completed 30000 requests
Finished 31000 requests

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-11-24 08:22:22  更:2021-11-24 08:22:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 3:41:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计