一、安装Nginx
安装参考文档:https://blog.csdn.net/t8116189520/article/details/81909574
二、运行模式:master-worker工作模式(多进程模式)
master进程:主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程
worker进程:工作进程,用来处理请求
三、热部署(./nginx -s reload)
执行命令时,我们是启动一个新的nginx进程,而新的nginx进程在解析到reload参数后,就知道我们的目的是控制nginx来重新加载配置文件了,它会向master进程发送信号,master进程在接到信号后,向所有老的worker进程发送信号,告诉他们可以光荣退休了。新的worker在启动后,就开始接收新的请求,而老的worker在收到来自master的信号后,就不再接收新的请求,并且在当前进程中的所有未处理完的请求处理完成后,再退出。
案例:修改nginx.conf里面的worker_processes
四、正向代理
客户端非常明确要访问的服务器地址
服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端
正向代理模式隐藏了真实客户端信息
五、反向代理
将请求按照一定的规则分发给后端的业务处理服务器
请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了
反向代理隐藏了服务器的信息
案例:没配置反向代理之前:
配置反向代理:
六、负载均衡规则
weight轮询(默认):接收到的请求按照顺序逐一分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,nginx会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。 这种方式下,可以给不同的后端服务器设置一个权重值(weight),用于调整不同的服务器上请求的分配率;权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的。
ip_hash:每个请求按照发起客户端的ip的hash结果进行匹配,这样的算法下一个固定ip地址的客户端总会访问到同一个后端服务器,这也在一定程度上解决了集群部署环境下session共享的问题。
fair:智能调整调度算法,动态的根据后端服务器的请求处理到响应的时间进行均衡分配,响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少;结合了前两者的优点的一种调度算法。但是需要注意的是nginx默认不支持fair算法,如果要使用这种调度算法,请安装upstream_fair模块
url_hash:按照访问的url的hash结果分配请求,每个请求的url会指向后端固定的某个服务器,可以在nginx作为静态服务器的情况下提高缓存效率。同样要注意nginx默认不支持这种调度算法,要使用的话需要安装nginx的hash软件包
七、Nginx配置
nginx.conf文件:
#全局配置
#user nobody;
worker_processes 2; #nginx要开启的工作进程数量,不超过CPU core个数#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;#pid logs/nginx.pid;
worker_rlimit_nofile 1024; #用于指定一个进程可以打开最多文件数量的描述
##注意:此值不能大于操作系统最大打开文件数,修改/etc/security/limits.conf文件
##注意:设置了这个后,修改worker_connections值时,是不能超过worker_rlimit_nofile的这个值。
# nginx工作模式配置,一般配置Nginx连接的特性
events {
use epoll; #配置指定的线程轮询方法-异步非阻塞
worker_connections 1024; #一个工作进程的最大连接数
}
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压缩配置,可以减少发送数据量
gzip on;
gzip_min_length 1k; #设置对数据启用压缩的最小字节数
gzip_buffers 4 16k; #设置压缩所需要的缓冲区大小
gzip_http_version 1.1; #识别http协议版本,默认1.0协议下不开启压缩
gzip_comp_level 2; #设置gzip压缩级别,级别越底压缩速度越快文件压缩比越小,反之速度越慢文件压缩比越大
gzip_types text/plain application/x-javascript text/css application/xml; #设置需要压缩的数据格式
gzip_vary on; #是否在http header中添加Vary: Accept-Encoding,建议开启
#限制请求速率,TPS
#limit_req_zone $binary_remote_addr zone=myRateLimit:10m rate=10r/s;
#限制IP并发
#limit_conn_zone $binary_remote_addr zone=perip:10m;
#limit_conn_zone $server_name zone=perserver:10m;
upstream tomcats {
#负载均衡策略
#none 轮询(默认策略,权重由weight决定,不设置表示权重一致)
#ip_hash
#fair
#url_hash
server 192.168.137.86:8080;
server 192.168.137.118:8080;
#分配权重,第一台流量占总流量的3/4,第二台流量占总流量1/4
#server 192.168.137.86:8080 weight=3;
#server 192.168.137.118:8080 weight=1;
#max_fails:失败最大次数,超过失败最大次数暂停服务,默认为1
#fail_timeout: 当达到最大失败次数,暂停指定的时间之后重新发起请求
#server 192.168.137.118:8080 weight=2 max_fails=3 fail_timeout=30s;#backup:备份机器,非备份机都挂掉才启用
#server 192.168.137.86:8080 backup;#down:停机标志,不会被访问,用于
#server 192.168.137.86:8080 down;
}#虚拟主机,一个http中可配置多个虚拟主机
server {
listen 80; #监听端口
server_name localhost; #虚拟主机名称,可为IP、域名#charset koi8-r;
#access_log logs/host.access.log main;
#配置反向代理,负载均衡
location / {
#root html;
index index.html index.htm; #web站点主页
#限制请求
#limit_req zone=myRateLimit burst=5 nodelay;
#限制IP并发
#limit_conn perip 10;
#limit_conn perserver 100;
#proxy_pass http://192.168.137.118:8080;
proxy_pass http://tomcats; #配置反向代理,负载均衡
}location /goodsservice {
#root html;
index index.html index.htm; #web站点主页
#限制请求
#limit_req zone=myRateLimit burst=5 nodelay;
#限制IP并发
#limit_conn perip 10;
#limit_conn perserver 100;
#proxy_pass http://192.168.137.118:8080;
proxy_pass http://goodsservice; #配置反向代理,负载均衡
}
#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;
# }
#}}
八、Nginx性能相关参数
https://blog.csdn.net/qq_18298439/article/details/83896777
九、实例
1、限制IP并发
2、限制请求速率
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.1.1 r1855137">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="测试计划" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="用户定义的变量" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="线程组" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="循环控制器" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">1</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">20</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<boolProp name="ThreadGroup.scheduler">true</boolProp>
<stringProp name="ThreadGroup.duration">60</stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
</ThreadGroup>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP请求" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="用户定义的变量" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">192.168.231.128</stringProp>
<stringProp name="HTTPSampler.port">80</stringProp>
<stringProp name="HTTPSampler.protocol">http</stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path"></stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree/>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="察看结果树" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<url>true</url>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
<ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="聚合报告" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<url>true</url>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>