• Nginx动静分离、缓存配置、性能调优、集群配置


    一. Nginx动静分离

    1. 准备

     1个web程序:部署在7061端口,启动 【dotnet NginxWeb.dll --urls="http://*:7061" --ip="127.0.0.1" --port=7061】

    Nginx程序:监听7000端口

    2. 目的

     比如单独启动部署在7061端口下的web程序,进行访问,我们会发现,除了请求的加载,还有很多静态 css、js、图片等资源的加载,这些资源的加载也是占服务器带宽的,假设带宽为1m,几个大图片直接就占满了。

    所以这里引入动静分离,将静态资源单独隔离出来,不占据主服务器的带宽,同时也有利于静态资源做缓存处理。 

    3. 实操

    方案1:在Nginx同一个Server实现动静分离

    剖析:

    将wwwroot文件夹从发布包中单独处理出来,然后通过location配置绝对地址,实现静态资源的分离。

    缺点:动静资源在一个虚拟主机中,那么静态资源和动态资源共享同一个资源,如果静态或者动态资源访问量比较大,把资源消耗殆尽,动态和静态资源互相会进行影响,导致系统整体上性能下降。

    代码分享:

    1. worker_processes 1;
    2. events {
    3. worker_connections 1024;
    4. }
    5. http {
    6. include mime.types;
    7. default_type application/octet-stream;
    8. sendfile on;
    9. keepalive_timeout 65;
    10. server {
    11. listen 7000; #监听端口
    12. server_name test1; #随意配置一个地址即可,优先走代理
    13. #动态资源
    14. location / {
    15. proxy_pass http://localhost:7061; #代理地址
    16. }
    17. #静态资源
    18. location ~ \.(ico|js|css|png|jpg|mp4)$ {
    19. root C:/Users/Administrator/Desktop/publish/wwwroot;
    20. }
    21. error_page 500 502 503 504 /50x.html;
    22. location = /50x.html {
    23. root html;
    24. }
    25. }
    26. }

    方案2:在Nginx多个Server下实现动静分离

    剖析:

      使用主机7000端口监听动态资源,使用主机7001端口监听静态资源,在7000的主机下通过代理的形式链接 静态资源: proxy_pass http://localhost:7001; #代理地址

    缺点:虽然是两个Sever,但这都是虚拟,还是在一台服务器上,一台服务器的承受能力毕竟是有限的。

    代码分享:

    1. worker_processes 1;
    2. events {
    3. worker_connections 1024;
    4. }
    5. http {
    6. include mime.types;
    7. default_type application/octet-stream;
    8. sendfile on;
    9. keepalive_timeout 65;
    10. #1.动态资源Server
    11. server {
    12. listen 7000; #监听端口
    13. server_name test1; #随意配置一个地址即可,优先走代理
    14. #动态资源
    15. location / {
    16. proxy_pass http://localhost:7061; #代理地址
    17. }
    18. #静态资源--指向静态代理Server
    19. location ~ \.(ico|js|css|png|jpg|mp4)$ {
    20. proxy_pass http://localhost:7001; #代理地址
    21. }
    22. error_page 500 502 503 504 /50x.html;
    23. location = /50x.html {
    24. root html;
    25. }
    26. }
    27. #2.静态资源Server
    28. server {
    29. listen 7001; #监听端口
    30. server_name test2; #随意配置一个地址即可,优先走代理
    31. #静态资源
    32. location ~ \.(ico|js|css|png|jpg|mp4)$ {
    33. root C:/Users/Administrator/Desktop/publish/wwwroot;
    34. }
    35. error_page 500 502 503 504 /50x.html;
    36. location = /50x.html {
    37. root html;
    38. }
    39. }
    40. }

    方案3:在多个Nginx下实现动静分离

    代码分享:

      即两个Nginx程序,部署在不同服务器,一个处理动态资源,一个处理静态资源,在动态资源的nginx中通过 proxy_pass http://xxxxx:xxxx; 代理到静态资源的服务器上即可。

      nginx_dynamic

      nginx_static

    剖析:

    多个nginx部署在多个服务器上,减轻压力,避免同一台服务器上进行资源竞争。

    更多C++后台开发技术点知识内容包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒体,音视频开发,Linux内核,TCP/IP,协程,DPDK多个高级知识点。

    C/C++Linux服务器开发高级架构师/C++后台开发架构师​免费学习地址

    【文章福利】另外还整理一些C++后台开发架构师 相关学习资料,面试题,教学视频,以及学习路线图,免费分享有需要的可以点击领取

    二. Nginx缓存配置

    1. 背景

     分析一个电商网站的详情页面,如下图,设计到很多微服务:商品详情页HTML页面渲染、价格服务、促销服务、库存状态/配送至服务、广告词服务、预售/秒杀服务、评价服务、试用服务、推荐服务、商品介绍服务、各品类相关的一些特殊服务。

    常见的解决方案:

     前端通过ajax动态加载,服务端则把这些文案以html的形式缓存到Redis中,如下图:

    剖析:

     一个详情页html 主体达平均150 kb, 那么在500QPS 已接近千M局域网宽带极限,所以必须减少内网通信。

    2. Nginx缓存

    相关模块【ngx_http_proxy_module】 http://nginx.org/en/docs/http/ngx_http_proxy_module.html

     针对上面占满内网带宽的情况,可以在Ngxin这一层做静态文件缓存,然后后台维护商品的时候删除缓存(修改商品→删除缓存),架构图如下:

    3. 配置说明

    其它补充:

    proxy_set_header Host $host; #用于后端的real server区分不同的虚拟主机;

    proxy_set_header X-Real-IP $remote_addr; #记录客户端真实ip地址,而不是代理服务器地址,需要后端web服务器开启日志相应功能接收;

    proxy_cache_methods GET HEAD; #表示对客户端请求的GET 和 HEAD方法进行缓存;

    proxy_cache_revalidate on; #本地缓存过期会检查后端服务器该缓存是否存在,避免后端重传占据带宽;

    proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_valid any 1m; #针对于不同的响应码进行缓存不同的时间设定;

    proxy_cache_min_uses 1; #某一个请求被响应多少次才会被缓存,默认是1,可以将该值设置为大一些;

    proxy_cache_use_stale error timeout invalid_header http_500 http_502 http_503 http_504; #指明哪种场景可以使用过期缓存,提升用户体验;

    4. 实操

    这里对一个web页面进行缓存,不进行redis的存储。

    剖析:

     (1). 首先在nginx的根目录下创建文件夹 ypfCache/nginx , 用来存放缓存。

    (2). 启动7061端口的web程序,启动nginx程序,访问nginx,发现缓存目录下多了个文件。

    (3). 关闭7061端口的web程序,重新访问nginx,继续可以访问,说明缓存成功了。

    代码分享:

    1. worker_processes 1;
    2. events {
    3. worker_connections 1024;
    4. }
    5. http {
    6. include mime.types;
    7. default_type application/octet-stream;
    8. sendfile on;
    9. keepalive_timeout 65;
    10. #缓存声明
    11. proxy_cache_path ypfcache/nginx/ levels=1:2 keys_zone=mycache:64m;
    12. server {
    13. listen 7000; #监听端口
    14. server_name test1; #随意配置一个地址即可,优先走代理
    15. location / {
    16. proxy_pass http://localhost:7061; #代理地址
    17. #缓存相关配置
    18. proxy_cache mycache;
    19. proxy_set_header Host $host;
    20. proxy_set_header X-Real-IP $remote_addr;
    21. proxy_cache_methods GET HEAD;
    22. proxy_cache_revalidate on;
    23. proxy_cache_valid 200 302 10m;
    24. proxy_cache_valid 404 1m;
    25. proxy_cache_valid any 1m;
    26. proxy_cache_min_uses 1;
    27. proxy_cache_use_stale error timeout invalid_header http_500 http_502 http_503 http_504;
    28. }
    29. error_page 500 502 503 504 /50x.html;
    30. location = /50x.html {
    31. root html;
    32. }
    33. }
    34. }

    三. Nginx性能调优

    1. worker_processes number

    每个worker进程都是单线程的进程,它们会调用各个模块以实现多种多样的功能。如果这些模块确认不会出现阻塞式的调用,那么,有多少CPU内核就应该配置多少个进程;反之,如果有可能出现阻塞式调用,那么需要配置稍多一些的worker进程。例如,如果业务方面会致使用户请求大量读取本地磁盘上的静态资源文件,而且服务器上的内存较小,以至于大部分的请求访问静态资源文件时都必须读取磁盘(磁头的寻址是缓慢的),而不是内存中的磁盘缓存,那么磁盘I/O调用可能会阻塞住worker进程少量时间,进而导致服务整体性能下降。

    2. 每个worker 进程的最大连接数

    语法:worker_connections number; 默认:worker_connections 1024

    3. worker_cpu_affinity cpumask[cpumask……]绑定Nginx worker进程到指定的CPU内核

    为什么要绑定worker进程到指定的CPU内核呢?假定每一个worker进程都是非常繁忙的,如果多个worker进程都在抢同一个CPU,那么这就会出现同步问题。反之,如果每一个worker进程都独享一个CPU,就在内核的调度策略上实现了完全的并发。 例如,如果有4颗CPU内核,就可以进行如下配置: worker_processes 4; worker_cpu_affinity 1000 0100 0010 0001; 注意 worker_cpu_affinity配置仅对Linux操作系统有效。

    4. Nginx worker 进程优先级设置

    语法:worker_priority nice; 默认:worker_priority 0; 优先级由静态优先级和内核根据进程执行情况所做的动态调整(目前只有±5的调整)共同决定。nice值是进程的静态优先级,它的取值范围是–20~+19,–20是最高优先级,+19是最低优先级。因此,如果用户希望Nginx占有更多的系统资源,那么可以把nice值配置得更小一些,但不建议比内核进程的nice值(通常为–5)还要小

    5. Nginx worker进程可以打开的最大句柄描述符个数

    语法: worker_rlimit_nofile limit; 默认:空 更改worker进程的最大打开文件数限制。如果没设置的话,这个值为操作系统的限制。设置后你的操作系统和Nginx可以处理比“ulimit -a”更多的文件,所以把这个值设高,这样nginx就不会有“too many open files”问题了。

    6. 是否打开accept锁

    语法:accept_mutex[on|off] 默认:accept_mutext on; accept_mutex是Nginx的负载均衡锁,当某一个worker进程建立的连接数量达到worker_connections配置的最大连接数的7/8时,会大大地减小该worker进程试图建立新TCP连接的机会,accept锁默认是打开的,如果关闭它,那么建立TCP连接的耗时会更短,但worker进程之间的负载会非常不均衡,因此不建议关闭它。

    7. 使用accept锁后到真正建立连接之间的延迟时间

    语法:accept_mutex_delay Nms; 默认:accept_mutex_delay 500ms; 在使用accept锁后,同一时间只有一个worker进程能够取到accept锁。这个accept锁不是堵塞锁,如果取不到会立刻返回。如果只有一个worker进程试图取锁而没有取到,他至少要等待accept_mutex_delay定义的时间才能再次试图取锁。

    四. Nginx集群

    1. 准备两台服务器

    【192.168.140.1】

    【192.168.140.2】

    2. Nginx的安装

    两台服务器上均进行nginx的安装,步骤详见 https://www.cnblogs.com/yaopengfei/p/13766324.html

    3. Keepalive的安装

    (1). 两个服务器均进行安装keepalive

    【yum install keepalived】

    (2). 修改配置文件

    【cd /etc/keepalived/keepalived.conf】

    查看代码

    1. global_defs {
    2. notification_email { # keepalived服务宕机异常出现的时候,发送通知邮件 可以是多个 acassen@firewall.loc # 收件人邮箱1
    3. failover@firewall.loc # 收件人邮箱2
    4. sysadmin@firewall.loc # 收件人邮箱3
    5. }
    6. notification_email_from Alexandre.Cassen@firewall.loc #邮件发件人
    7. smtp_server 192.168.200.1 # 邮件服务器地址
    8. smtp_connect_timeout 30 # 超时时间
    9. router_id LVS_DEVEL # 机器标识 局域网内唯一即可
    10. vrrp_skip_check_adv_addr # 默认是不跳过检查。检查收到的VRRP通告中的所有地址可能会比较耗时,设置此命令的意思是,如果通告与接收的上一个通告来自相同的master路由器,则不执行检查(跳过检查)。
    11. #vrrp_strict # 严格遵守VRRP协议。下列情况将会阻止启动Keepalived:1. 没有VIP地址。2. 单播邻居。3. 在VRRP版本2中有IPv6地址。
    12. vrrp_garp_interval 0 # 小数类型,单位秒,在一个网卡上每组gratuitous arp消息之间的延迟时间,默认为0,一个发送的消息=n组 arp报文
    13. vrrp_gna_interval 0 # 小数类型,单位秒, 在一个网卡上每组na消息之间的延迟时间,默认为0
    14. }
    15. vrrp_instance VI_1 {
    16. state MASTER # 服务器状态 MASTER是主服务器 BACKUP是备份服务器 主服务器的priority要比备份服务器大
    17. interface ens33 # 通信端口 通过ip addr可以看到 根据自己的机器配置
    18. virtual_router_id 51 # vrrp实例id keepalived集群,实例id必须一致
    19. priority 100 # 权重比 主服务器的priority要比备份服务器大
    20. advert_int 1 # 心跳间隔 单位秒 keepalived多机器集群 通过心跳检测,如果发送心跳没反应 就立刻接管;
    21. authentication { # 服务器之间通信密码
    22. auth_type PASS
    23. auth_pass 1111
    24. }
    25. virtual_ipaddress { # 自定义虚拟IP
    26. 192.168.91.199
    27. }
    28. }

    (3). 进行启动

    【systemctl start keepalived.service】 启动 【systemctl stop keepalived.service】 关闭 【systemctl restart keepalived.service】重启

    (4). 日志查看 【tail -f /usr/local/nginx/logs/access.log】 【tail -f /var/log/messages】 (5). 进程查看 【ps -ef|grep keep】

    4. 配置Nginx重启脚本

    (1). 创建脚本,nginx_restart.sh

    1. #!/bin/bash
    2. echo 'xxxxxx'
    3. count_nginx=`ps -ef|grep -w nginx|grep -v grep|wc -l`
    4. echo $count_nginx
    5. if [ $count_nginx -eq 0 ];then
    6. /usr/local/nginx/sbin/nginx
    7. sleep 2
    8. if [ `ps -ef|grep -w nginx|grep -v grep|wc -l` -eq 0 ];then
    9. systemctl stop keepalived.service
    10. fi
    11. fi

    (2). keepalived配置中添加如下内容

    1. vrrp_script chk_http_port {
    2. script "/root/nginx_restart.sh" #脚本地址
    3. interval 2 #检测脚本执行的间隔
    4. weight 2 #比重
    5. }

    原文链接:第三节:Nginx动静分离、缓存配置、性能调优、集群配置 - Yaopengfei - 博客园

  • 相关阅读:
    HK32F030MF4P6 EXTI外部中断例程
    acwing算法基础之基础算法--整数二分算法
    FPGA 之 时序分析
    Wireshark数据抓包分析之传输层协议(TCP协议)
    iceoryx源码阅读(四)——共享内存通信(二)
    快速排序(sort用法)
    [附源码]Python计算机毕业设计Django图书馆出版物预订系统
    第4章丨IRIS Global —— 对象使用多维存储
    第八章《Java高级语法》第6节:匿名类
    开发工具——IDE安装 / IDEA子module依赖导入失败编译提示xx找不到符号 / IDEA在Git提交时卡顿
  • 原文地址:https://blog.csdn.net/a410974689/article/details/128161662