爬梯:Nginx全解析
学习整理自:B站尚硅谷
系统平台:centos 7
Nginx
1、基本概念
百科:
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强。
正向代理
客户端通过配置代理服务器的信息,访问国外的网站。
对于客户端来说他访问的是代理服务器,而代理服务器再访问国外的网站
反向代理
客户端不需要配置代理服务器直接访问访问代理服务器,而代理服务器将请求引导至真实的应用服务器。
反向的意思是,代理服务器代理了应用服务器,而非常理中的客户端。
图解:
负载均衡
将大量的请求分发到各台服务器上,将访问负担均衡开来
图解:
动静分离
为了加快网站的解析速度,把动态页面和静态页面由不同的服务器来解析,加快客户端的解析速度
图解:
2、安装、常用命令及配置文件
安装
Nginx需要PCRE运行环境
- 安装PCRE
PCRE官方下载地址:https://sourceforge.net/projects/pcre/files/pcre/8.44/pcre-8.44.tar.gz/download
[root@mq1 opt]# wget http://downloads.sourceforge.net/project/pcre/pcre/8.44/pcre-8.44.tar.gz
# ...
[root@mq1 opt]# tar zxvf pcre-8.44.tar.gz
# ...
[root@mq1 pcre-8.44]# ./configure
# ...
[root@mq1 pcre-8.44]# make && make install
# ...
[root@mq1 opt]# pcre-config --version
8.44
如果configure失败的话可以尝试以下命令:
yum install gcc gcc-c++ autoconf automake
- 安装Nginx
我从win下载了压缩包拖进去的
[root@mq1 opt]# tar zxvf nginx-1.18.0.tar.gz
# ...
[root@mq1 nginx-1.18.0]# ./configure
# ...
[root@mq1 nginx-1.18.0]# make && make install
# ...
[root@mq1 nginx-1.18.0]# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.18.0
如果configure失败的话可以尝试以下命令:
yum install -y zlib-devel
安装完成~
启动并访问:
[root@mq1 nginx-1.18.0]# /usr/local/nginx/sbin/nginx
[root@mq1 nginx-1.18.0]# ps -ef|grep nginx
root 38148 1 0 05:07 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody 38149 38148 0 05:07 ? 00:00:00 nginx: worker process
root 38162 3793 0 05:09 pts/0 00:00:00 grep --color=auto nginx
[root@mq1 nginx-1.18.0]#
nginx默认监听80端口
常用命令
# 查看版本
[root@mq1 ~]# /usr/local/nginx/sbin/nginx -v
nginx version: nginx/1.18.0# 启动
[root@mq1 ~]# /usr/local/nginx/sbin/nginx# 关闭
[root@mq1 ~]# /usr/local/nginx/sbin/nginx -s stop# 重新加载,平滑重启
[root@mq1 ~]# /usr/local/nginx/sbin/nginx -s reload# 测试配置文件是否正确
[root@mq1 ~]# /usr/local/nginx/sbin/nginx -t [config name]
配置文件
/usr/local/nginx/cinf/nginx.conf
全局块
从配置文件开始到events块之间的内容,主要是设置nginx服务器整体运行,主要包括:
- 配置运行Nginx服务器的用户(组)
- 允许生成的worker process数
- 进程PID存放路径
- 日志存放路径、类型以及配置文件的引入等
Nginx.cof
#user nobody; # 配置运行Nginx服务器的用户(组)
worker_processes 1; # 进程数,并发量#error_log logs/error.log; # 日志存放路径
#error_log logs/error.log notice; # 日志类型
#error_log logs/error.log info; # 日志类型#pid logs/nginx.pid; # 进程PID存放路径
events{ }
主要配置Nginx服务器与用户的网络连接,常用设置包括:
- 是否开启对多work process下的网络连接进行序列化
- 是否允许同事接收多个网络连接
- 选取事件驱动模型来处理连接请求
- 每个word process可以同时支持的最大连接数等
这部分配置对Nginx的性能影响较大,在实际中应灵活配置
Nginx.cof
events {# 表示每个work process支持的最大连接数为 1024个worker_connections 1024;
}
http{ }
可以配置Nginx的代理、缓存和日志定义等大多数功能和第三方模块
包括两部分:http全局快、server块
- http 全局块
http全局快配置的指令包括文件引入、MIME-TYPE定义、日志自定义、链接超时时间、单链接请求数上限等
nginx.conf
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;sendfile on;#tcp_nopush on;#keepalive_timeout 0;keepalive_timeout 65;#gzip on;}
- server 块
这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机完全相同,该技术的产生是为了节省互联网服务器硬件成本。
每个http块可以包含多个server块,而每个server块就相当于一个虚拟主机。
而每个server块也分为全局server块,及同时包含多个location块
- 全局server块
最常见的配置是本虚拟机的监听配置和本虚拟机的名称或IP配置
- location块
一个server块可以配置多个location块。
这块的主要作用是基于Nginx服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(IP别名)之外的字符串(如:/uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存或应答控制等功能,还有许多第三方模块的配置也在这里配置。
location [ = | ~ | ~* | ^~ ] uri {
}
- = :全值严格匹配,如果匹配成功则停止继续向下搜索并立即处理该请求;
- ~ : 用于匹配uri中正则表达式,区分大小写;
- ~* :用于匹配uri中正则表达式,不区分大小写;
- ^~ :用匹配uri中不包含的正则表达式,nginx服务器找到匹配度最高的location后,才会使用对应的规则来处理此请求。(也就是可能要全部location都匹配一遍才处理的意思)
nginx.conf
http{server {listen 80; #监听端口server_name localhost;#charset koi8-r;#access_log logs/host.access.log main;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 {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;# }#}}
3、反向代理
准备工作
安装启动Tomcat
# ...检查jdk
[root@mq1 logs]# java -version
# ...解压tomcat
[root@mq1 opt]# tar -vxf apache-tomcat-8.5.58.tar.gz
# ...启动tomcat
[root@mq1 opt]# /opt/apache-tomcat-8.5.58/bin/startup.sh
# ...查看tomcat日志
[root@mq1 opt]# tail -f /opt/apache-tomcat-8.5.58/log/catalina.out
启动防火墙,添加80端口和8080端口协议
[root@mq1 opt]# systemctl enable firewalld.service
Created symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service.
Created symlink from /etc/systemd/system/basic.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service.
[root@mq1 opt]# systemctl start firewalld.service
[root@mq1 opt]# firewall-cmd --state
running
[root@mq1 opt]# firewall-cmd --zone=public --permanent --add-port=8080/tcp
success
[root@mq1 opt]# firewall-cmd --zone=public --permanent --add-port=80/tcp
success
[root@mq1 opt]# systemctl-cmd --reload
success
[root@mq1 opt]# firewall-cmd --list-all
public (default, active)interfaces: eno16777736sources: services: dhcpv6-client sshports: 15672/tcp 80/tcp 6379/tcp 5672/tcp 8080/tcpmasquerade: noforward-ports: icmp-blocks: rich rules:
[root@mq1 opt]#
反向代理实例(一)
简单IP转发
修改Nginx.conf
到这一步,已经完成了对8080的转发配置
反向代理实例(二)
使用正则判断更精细的uri进行分发
准备工作
启动两个tomcat,分别监听8080、8081
# ...创建两个文件夹
[root@mq1 opt]# mkdir tomcat8080
[root@mq1 opt]# mkdir tomcat8081# ...先停止tomcat
[root@mq1 opt]# /opt/apache-tomcat-8.5.58/bin/shutdown.sh# ...拷贝两份tomcat
[root@mq1 opt]# cp -r apache-tomcat-8.5.58/. tomcat8080
[root@mq1 opt]# cp -r apache-tomcat-8.5.58/. tomcat8081# ...修改tomcat8081端口
[root@mq1 opt]# vi tomcat8081/conf/server.xml<Server port="8006" shutdown="SHUTDOWN">
<Connector port="8081" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443" /># ...启动
[root@mq1 opt]# tomcat8080/bin/startup.sh
[root@mq1 opt]# tomcat8081/bin/startup.sh # ...防火墙
[root@mq1 opt]# firewall-cmd --zone=public --permanent --add-port=8081/tcp
success
[root@mq1 opt]# systemctl-cmd --reload
success
加入静态页面到 webapps/
8080
8081
正式修改nginx.conf
# 在http块中加入
# 监听9001端口,转发到location。“~”表示正则匹配
# 当连接中含有hello则转发到8080
# 如:http://192.168.0.106:9001/hello/a.html
# 转发到:http://127.0.0.1:8080/hello/a.htmlserver {listen 9001; server_name 192.168.0.106;location ~ /hello/ {proxy_pass http://127.0.0.1:8080;}location ~ /hi/ {proxy_pass http://127.0.0.1:8081;}}# ...测试配置文件是否编写正确
[root@mq1 opt]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
# ...平滑重启,重新加载配置文件信息
[root@mq1 opt]# /usr/local/nginx/sbin/nginx -s reload
# ...防火墙
[root@mq1 opt]# firewall-cmd --zone=public --permanent --add-port=9001/tcp
success
[root@mq1 opt]# firewall-cmd --reload
success
开放9001端口后测试:
hello
hi
4、负载均衡
将请求按一定规则分发到不同的应用服务器,实现负载的均衡
准备工作
准备两台tomcat,分别监听8080、8081,并放入一个路径相同的静态页面
…/webapps/ssx/stone.html
正式配置 nginx.conf
在http块中,加入upstream块,并将server块代理到这个upstream块
upstream mystream{server 127.0.0.1:8080; # 负载的服务器1地址server 127.0.0.1:8081; # 负载的服务器2地址}server {listen 80;server_name 192.168.1.106;#charset koi8-r;#access_log logs/host.access.log main;location / {root html;proxy_pass http://mystream; # 使用多个server处理请求index index.html index.htm;}......}# 测试 重启
[root@mq1 ssx]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@mq1 ssx]# /usr/local/nginx/sbin/nginx -s reload
测试
将会在8080、8081间选择
负载规则
负载均衡既是将负载分摊到不同的服务单元,既保证服务器的可用性,有保证用户体验。
- 轮询(默认)
每个请求按先后顺序逐一分配到不同的应用服务器上,如果应用服务器宕机,能自动剔除。
- weight
weight代表权重,默认为1,权重越高被分配请求的几率就越大。
upstream server_pool{server 192.168.0.106 weight=2;server 192.168.0.107 weight=3;server 192.168.0.108 weight=5;
}
- ip_hash
每个请求按照访问ip(即Nginx的前置服务器或者客户端IP)的hash结果分配,即某个访客的后续的请求都访问这一个server,从而解决应用session不一致的问题。
upstream server_pool{ip_hash;server 192.168.0.106;server 192.168.0.107;server 192.168.0.108;
}
- fair(第三方)
按后端服务器的响应时间来分配请求,相应时间短的优先分配
upstream server_pool{server 192.168.0.106;server 192.168.0.107;server 192.168.0.108;fair;
}
5、动静分离
基本概念
动静分离指的是,匹配判断动态请求和静态请求,然后区别对待,分开处理,目的还是为了提高服务的响应速度、用户的体验。
现在比较主流的分离方式是,将动态请求放在一台服务器上,静态请求放在另一台服务器上。
- location 指定不同的后缀名实现请求类型的判断,转发请求;
- expires 设置浏览器缓存过期时间。使用浏览器缓存可以加快响应速度,降低请求流量。这个过期时间,无需到应用服务端验证,浏览器自身确认是否过期。
准备工作
在服务器放一张图
/opt/images/sailboat.png
正式配置 nginx.conf
没有匹配到png的请求正常访问tomcat
匹配到 .png的请求访问目录
测试
6、高可用集群
基础概念
应用服务器可能会宕机,所以配置了多台,那么nginx也可能会宕机,所以也有一定的需要配置高可用集群。
集群结构图:
集群配置
- 两台nginx服务器 192.168.0.106、192.168.0.107
- keepalived软件
# 安装keepalived
[root@mq2 opt]# yum install keepalived -y
[root@mq2 opt]# rpm -q -a keepalived
keepalived-1.3.5-16.el7.x86_64
keepalived配置文件
[root@mq2 opt]# ls /etc/keepalived/
keepalived.conf
! Configuration File for keepalivedglobal_defs { # 全局配置notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.0.106 smtp_connect_timeout 30router_id LVS_DEVEL # 路由ID,服务器名。/etc/hosts
}# 脚本
vrrp_script chk_http_port {script "/usr/local/src/nginx_check.sh"interval 2 # 检测脚本执行的间隔 weight 2 # 权重。意思是当脚本执行成立,则此服务的权重 +2 。若配置的是负数,则减2
}# 虚拟机配置
vrrp_instance VI_1 {state MASTER # MASTER:主服务器 BACKUP:备用服务器interface eno16777736 # 网卡 ifconfig查看virtual_router_id 51 #主、备机的virtual_router_id必须相同priority 100 # 主、备机取不同的优先级,主机取较大值,备机取较小值。一般主机配置100advert_int 1 # 时间间隔、心跳。每隔1s发送一个心跳包,检测服务器是否存活authentication { # 校验权限的方式auth_type PASS # 密码方式auth_pass 1111 # 密码是 1111}virtual_ipaddress {192.168.0.110 # VRRP H虚拟地址。可绑定多个。}
}
检测脚本
检测nginx是否存活,如果死掉则关闭keepalived。目的是让另一台keepalived检测到。
#!/bin/bash
A='ps -C nginx -no-header |wc -1'
if [ $A -eq 0 ];then/usr/local/nginx/sbin/nginxsleep 2if [ 'ps -C nginx --no-header |wc -1' -eq 0 ];thenkillall keepalivedfi
fi
两台机器都要修改keepalived.conf、添加脚本文件。
脚本文件不用改,配置文件需要修改网卡和priority。
启动和测试
1. 启动
[root@mq2 src]# /usr/local/nginx/sbin/nginx
[root@mq2 src]# systemctl start keepalived.service
[root@mq2 src]# ps -ef|grep keepalived
root 18055 1 0 10:06 ? 00:00:00 /usr/sbin/keepalived -D
root 18057 18055 0 10:06 ? 00:00:00 /usr/sbin/keepalived -D
root 18058 18055 0 10:06 ? 00:00:00 /usr/sbin/keepalived -D
root 18148 2665 0 10:06 pts/0 00:00:00 grep --color=auto keepalived
2. 测试-访问虚拟主机 192.168.0.110
成功进入主Nginx配置的tomcat!
3. 测试-停掉主Nginx,再访问110
请求正常访问,进入了备机nginx,没有配置转发端口,所以不跳tomcat
此时备机上的绑定了虚拟ip 192.168.0.110
至此,Nginx的集群已经全部完成。
撒花~~
7、Nginx工作原理(性能调优)
Master&Worker
[root@mq1 src]# ps -ef|grep nginx
root 18485 1 0 10:35 ? 00:00:00 nginx: master process /usr/local/nginx/sbin//nginx
nobody 18486 18485 0 10:35 ? 00:00:00 nginx: worker process
root 18488 14574 0 10:35 pts/0 00:00:00 grep --color=auto nginx
Nginx启动之后,可以看到是有两个进程的。
Marster:分配任务;
Worker:接收命令,具体执行任务,可以有多个。每个woker是一个独立的进程!
工作原理图:
当有新的请求到来时,Master得到新任务,由多个Woker进行争抢执行新任务。
Nginx热部署原理:
修改nginx配置文件平滑加载的命令:
./nginx -s reload
原理是:比如此时有个四个woker存活,而worker1正在执行请求任务,另外三个woker空闲,执行了 reload之后,三个空闲的woker去加载了新的nginx.conf,当有新的任务进来时,三个空闲的woker使用的是新nginx.conf去执行任务。而当woker1执行完任务后,会自行去加载新配置文件,再参与争抢下一个任务。
性能调优
因为每个woker是一个独立的进程,所以当一个woker进程销往并不会对nginx的服务造成影响!
同redis类似都采用io多路复用机制,每个woker进程都只有一个主线程,通过异步非阻塞的方式来处理请求,即使成千上万个请求也可支持。所以关键点在于设置多少个woker进程数,才能充分发挥cpu资源。
1. worker_processes
通常cpu有多少核就配置多少个进程
2. worker_cpu_affinity
开启cpu多核配置:
2核cpu,开启两个进程
worker_processes 2; worker_cpu_affinity 01 10;
解释:01表示启用第一个cpu内核、10表示启用第二个cpu内核。意思是第一个进程对应第一个cpu内核,第二个进程表示第二个内核。
2核cpu,开启四个进程
worker_processes 4; worker_cpu_affinity 01 10 01 10;
4核cpu,开启两个进程
worker_processes 2; worker_cpu_affinity 0101 1010;
解释:0101表示开启第一个和第三个内核,1010表示开启第二个和第四个内核。
4核cpu,开启四个进程
worker_processes 4; worker_cpu_affinity 0001 0010 0100 1000;
8核cpu,开启8个进程
worker_processes 8; worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
worker_processes最多开启8个,8个以上性能提升不会再提升了,而且稳定性变得更低,所以8个进程够用了。
规律:2核是 01,四核是0001,8核是00000001,有多少个核,就有几位数,1表示该内核开启,0表示该内核关闭。
配置完之后可以重启nginx,用ab工具或者wrk工具,可以进行性能测试,在服务器上执行top
,然后按1,就可以看到cpu工作情况,如果多个cpu内核的利用率差不多,就证明nginx已经成功利用了多核cpu,测试结束后,cpu内核的负载都同时降低。
3. worker_connection
连接数考题:客户端发送一条请求,占用了worker的几个连接数?
答案:2或4个;
解释:1:客户端链接到nginx服务器的请求;2、nginx返回客户端的请求;3:nginx服务器访问tomcat服务器的请求;4、tomcat服务器返回nginx服务器的请求;当访问的内容在nginx服务器上则答案是2条,当访问的内容在外部服务器上则答案是4条;
并发数考题:当前Nginx有一个Master,有四个Worker,每个Worker支持最大连接数是1024,那么当前Nginx支持的最大并发数是多少?
答案:2048或1024个;
解释:当前最大请求数:4个woker * 1024连接数 / ( 2|4 ) = 2048 | 1024
至此可以按照实际情况,计算调试出最合适的连接数配置。
爬梯:Nginx全解析相关推荐
- php文件名解析漏洞 nginx,nginx服务器解析漏洞(一)
Nginx解析漏洞: 影响版本:全版本 影响说明:命令执行,获取服务器web权限 环境说明:Nginx 1.13.0 环境搭建: 此次环境使用docker环境搭建,环境采用地址>Vulhub 遇 ...
- 2020年 Java 最常见200+ 面试题全解析:面试必备
Java 最常见200+ 面试题全解析:面试必备 如想了解更多更全面的Java必备内容可以阅读:所有JAVA必备知识点面试题文章目录: JAVA必备知识点面试题 序 言 在本篇文章开始之前,我想先来回 ...
- Go modules基础精进,六大核心概念全解析(下)
Go 语言做开发时,路径是如何定义的?Go Mudules又为此带来了哪些改变?本文将会全面介绍Go Modules六大核心概念,包括了设计理念与兼容性原则等,掌握这些技术点对于管理和维护Go 模块有 ...
- 第四章:Spring项目文件上传两种方式(全解析)
欢迎查看Java开发之上帝之眼系列教程,如果您正在为Java后端庞大的体系所困扰,如果您正在为各种繁出不穷的技术和各种框架所迷茫,那么本系列文章将带您窥探Java庞大的体系.本系列教程希望您能站在上帝 ...
- 阿里秋招面试全解析(含内推岗)
每个技术人都有个大厂梦,我觉得这很正常,并不是饭后的谈资而是每个技术人的追求.像阿里.腾讯.美团.字节跳动.京东等等的技术氛围与技术规范度还是要明显优于一些创业型公司/小公司,如果说能够在这样的公司锻 ...
- Apache Web服务器访问控制机制全解析
Apache Web服务器访问控制机制全解析 原文请见: http://netsecurity.51cto.com/art/201102/245666.htm Linux下的Aapche服务器提供了强 ...
- 6.15 Unity引擎渲染效率全解析
UWA新晋主播赵福恺从Unity渲染模块中的各种渲染效果性能.PBR渲染性能以及阴影的渲染性能三个角度分别进行了详细的分析总结.为响应各大听众的需求,小编奉上完整视频回顾,同时也向看完直播才下班的五好 ...
- python读取txt文件写入-Python读写txt文本文件的操作方法全解析
一.文件的打开和创建 >>> f = open('/tmp/test.txt') >>> f.read() 'hello python! hello world! ...
- jQuery Ajax 实例 全解析(转)
jQuery Ajax 实例 全解析 jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 废话少说,直接进入正题,我 ...
最新文章
- Payara基金会发布全面支持MicroProfile 2.0的5.183版Payara Server和Payara Micro
- python连接redis有中文_Python连接Redis并操作
- jeesite在eclipse中部署
- python中如何打印阶梯_字符阶梯(python)
- Python基础---OS模块 (二)
- 用XAML做网页!!—广告展示区
- easypoi的学习笔记
- [bbk4995] 第99集 -第12章 -数据移植 05
- *ST东方A:山重水复疑无路 强烈推荐评级
- 如何选择APP内测分发平台?五年开发者亲述
- Python挑战游戏( PythonChallenge)闯关之路Level- 6
- 基于python 的电影票房可视化系统
- 安徽计算机在职研究生学校,安徽在职研究生招生学校2020
- 笔记本添加固态硬盘记
- 游戏安全反汇编分析开启取消自动攻击call
- 模仿国内知名B2C网站,实现的一个分布式B2C商城
- java设计文档怎么写,斩获offer
- 改进YOLOv5系列:首发结合最新efficient Layer Aggregation Networks结构,高效的聚合网络设计,提升性能
- 电脑开机安装流氓软件、弹广告处理办法
- .net framework 转为 .net core
热门文章
- java输入单个字符
- html 999是什么颜色,迪奥口红999是什么颜色 迪奥口红999的价格
- Docker部署Redis单机版
- CAD的琐琐碎碎记录
- html按钮设置动作,ppt设置动作按钮在哪 PPT中怎么添加动作按钮?
- Python面试:迭代器和生成器
- 鸿蒙之隙活动可以参加几次,语文小学选择题
- SQL数据库连接失败---错误18456
- linux svn怎么更新文件,linux安装SVN以及同步更新到项目上
- 辽宁初级药师职称计算机考试时间,一文get!2020年药士\药师\主管药师考试安排详情!...