桥下の民 - Nginx
type: channel
link: https://wordplay.work/index.php/category/Nginx
items: Keepalived
items: Nginx 优化之 keepalive
items: Nginx 高可用
items: Nginx 配置文件 nginx.conf 详解
items: Nginx 基础使用

Keepalived
type: item
date: 2024-01-25T16:37:00+00:00
description: 一、Keepalived 介绍 Keepalived 是 Linux 下一个轻量级别的高可用解决方案，通过虚拟路由冗余协议来实现服务或者网络的高可用。 起初是为 LVS 设计的，专门用来监控集群系统中各个服务节点的状态。 如果某个服务器节点出现故障，Keepalived 将检测到后自动将节点从集群系统中剔除。 而在故障节点恢复正常后，Keepalived 又可以自动将此节点重新加入集群中。 这些工作自动完成，不需要人工干预，需要人工完成的只是修复出现故障的节点。 1.1、特点： 1、部署简单，只需要配置一个配置文件即可。 2、加入了虚拟路由冗余协议，可以保证业务或网络不间断稳定运行。 1.2、核心功能： 1.2.1、健康检查 采用 tcp 三次握手，icmp 请求，http 请求，udp、echo 请求等方式对负载均衡器后面的实际的服务器 (通常是承载真实业务的服务器) 进行保活。 1.2.2、故障切换 主要应用在配置了主备的服务器上，使用虚拟路由冗余协议维持主备之间的心跳。 当主服务器出现问题时，由备服务器承载对应的业务，从而在最大限度上减少损失，并提供服务的稳定性。 1.3、VRRP 协议 在现实的网络环境中，主机之间的通信都是通过配置静态路由（默认网关）来完成的。 而主机之间的路由器一旦出现故障，就会通信失败。 因此在这种通信模式下，路由器就会有单点瓶颈问题，为了解决这个问题，引入了 VRRP 协议（虚拟路由冗余协议）。 通过 VRRP 可以在网络发生故障时透明的进行设备切换而不影响主机之间的数据通信。 VRRP 可以将两台或多台物理路由器设备虚拟成一个虚拟路由器，这个虚拟路由器通过虚拟 IP（一个或多个）对外提供服务，而在虚拟路由器内部是多个物理路由器协同工作，VRRP 角色如下： 1.3.1、角色 虚拟路由器：VRRP 组中所有的路由器，拥有虚拟的 IP+MAC (00-00-5e-00-01-VRID) 地址。 主路由器（master）：虚拟路由器内部通常只有一台物理路由器对外提供服务，主路由器是由选举算法产生，对外提供各种网络功能。 备份路由器（backup）：VRRP 组中除主路由器之外的所有路由器，不对外提供任何服务，只接受主路由的通告，当主路由器挂掉之后，重新进行选举算法接替 master 路由器。 master 路由器由选举算法产生，它拥有对外服务的 VIP，提供各种网络服务，如 ARP 请求、数据转发、ICMP 等等，而 backup 路由器不拥有 VIP，也不对外提供网络服务。 当 master 发生故障时，backup 将重新进行选举，产生一个新的 master 继续对外提供服务。 1.3.2、VRRP 工作模式 VRRP 有三种工作状态，分别是： Initialize 状态 Master 状态 Backup 状态 选举机制: 抢占模式：一旦有优先级高的路由器加入，立即成为 Master。 非抢占模式：只要 Master 不挂掉，优先级高的路由器只能等待。 二、Keepalived 原理 keepalived 工作在 TCP/IP 参考模型的第三、四和第五层，也就是网络层、传输层和应用层。 网络层：通过 ICMP 协议向集群每个节点发送一个 ICMP 数据包（类似于 ping 功能），如果某个节点没有返回响应数据包，那么认定此节点发生了故障，Keepalived 将报告此节点失效，并从集群中剔除故障节点。 传输层：通过 TCP 协议的端口连接和扫描技术来判断集群节点是否正常，keepalived 一旦在传输层探测到这些端口没有响应数据返回，就认为这些端口所对应的节点发生故障，从集群中剔除故障节点。 应用层：用户可以通过编写程序脚本来运行 keepalived，keepalived 根据脚本来检测各种程序或者服务是否正常，如果检测到有故障，则把对应的服务从服务器中删除。 2.1、组件架构 我们将整个体系结构分层用户层和内核层： Scheduler I/O Multiplexer I/O 复用分发调用器，负责安排 Keepalived 所有的内部的任务请求 Memory Management 内存管理机制，提供了访问内存的一下通用方法 Keepalived Control Plane 控制面板，实现对配置文件的编译和解析，Keepalived 的配置文件解析比较特殊，它并不是一次解析所有模块的配置，而是只有在用到某模块时才解析相应的配置 Core components Keepalived 的核心组件，包含了一系列功能模块，主要有 watch dog、Checkers、VRRP Stack、IPVS wrapper、Netlink Reflector。 watch dog 一个极为简单又非常有效的检测工…

Nginx 优化之 keepalive
type: item
date: 2023-10-04T08:44:00+00:00
description: 一、nginx 之 tcp_nopush、tcp_nodelay、sendfile 1.1、TCP_NODELAY 你怎么可以强制 socket 在它的缓冲区里发送数据？ 一个解决方案是 TCP 堆栈的 tcp_nodelay 选项。这样就可以使缓冲区中的数据立即发送出去。 Nginx 的 tcp_nodelay 选项使得在打开一个新的 socket 时增加了 tcp_nodelay 选项。但这时会造成一种情况： 终端应用程序每产生一次操作就会发送一个包，而典型情况下一个包会拥有一个字节的数据以及 40 个字节长的包头，于是产生 4000% 的过载，很轻易地就能令网络发生拥塞。为了避免这种情况，TCP 堆栈实现了等待数据 0.2 秒钟，因此操作后它不会发送一个数据包，而是将这段时间内的数据打成一个大的包。这一机制是由 Nagle 算法保证。 Nagle 化后来成了一种标准并且立即在因特网上得以实现。它现在已经成为默认配置了，但有些场合下把这一选项关掉也是合乎需要的。现在假设某个应用程序发出了一个请求，希望发送小块数据。我们可以选择立即发送数据或者等待产生更多的数据然后再一次发送两种策略。 如果我们马上发送数据，那么交互性的以及客户 / 服务器型的应用程序将极大地受益。如果请求立即发出那么响应时间也会快一些。以上操作可以通过设置套接字的 TCP_NODELAY = on 选项来完成，这样就禁用了 Nagle 算法。（不需要等待 0.2s） 1.2、TCP_NOPUSH 在 nginx 中，tcp_nopush 配置和 tcp_nodelay “互斥”。它可以配置一次发送数据的包大小。也就是说，它不是按时间累计 0.2 秒后发送包，而是当包累计到一定大小后就发送。 注：在 nginx 中，tcp_nopush 必须和 sendfile 搭配使用。 1.3、sendfile 现在流行的 web 服务器里面都提供 sendfile 选项用来提高服务器性能，那到底 sendfile 是什么，怎么影响性能的呢？ sendfile 实际上是 Linux2.0 + 以后的推出的一个系统调用，web 服务器可以通过调整自身的配置来决定是否利用 sendfile 这个系统调用。先来看一下不用 sendfile 的传统网络传输过程： read (file,tmp_buf, len); write (socket,tmp_buf, len); 硬盘 >> kernel buffer >> user buffer>> kernel socket buffer >> 协议栈 一般来说一个网络应用是通过读硬盘数据，然后写数据到 socket 来完成网络传输的。上面 2 行用代码解释了这一点，不过上面 2 行简单的代码掩盖了底层的很多操作。来看看底层是怎么执行上面 2 行代码的： 系统调用 read () 产生一个上下文切换：从 user mode 切换到 kernel mode，然后 DMA 执行拷贝，把文件数据从硬盘读到一个 kernel buffer 里。 数据从 kernel buffer 拷贝到 user buffer，然后系统调用 read () 返回，这时又产生一个上下文切换：从 kernel mode 切换到 user mode。 系统调用 write () 产生一个上下文切换：从 user mode 切换到 kernel mode，然后把步骤 2 读到 user buffer 的数据拷贝到 kernel buffer（数据第 2 次拷贝到 kernel buffer），不过这次是个不同的 kernel buffer，这个 buffer 和 socket 相关联。 系统调用 write () 返回，产生一个上下文切换：从 kernel mode 切换到 user mode（第 4 次切换了），然后 DMA 从 kernel buffer 拷贝数据到协议栈（第 4 次拷贝了）。 上面 4 个步骤有 4 次上下文切换，有 4 次拷贝，我们发现如果能减少切换次数和拷贝次数将会有效提升性能。在 kernel2.0+ 版本中，系统调用 sendfile () 就是用来简化上面步骤提升性能的。sendfile () 不但能减少切换次数而且还能减少拷贝次数。 再来看一下用 sendfile () 来进行网络传输的过程： sendfile (socket,file, len); 硬盘 >> kernel buffer (快速拷贝到 kernelsocket buffer) >> 协议栈 系统调用 sendfile () 通过 DMA 把硬盘数据拷贝到 kernel buffer，然后数据被 kernel 直接拷贝到另外一个与 socket 相关的 kerne…

Nginx 高可用
type: item
date: 2023-10-04T04:41:00+00:00
description: 一、Nginx 安装 1、从官网 nginx.org 下载对应的 nginx 包。 2、安装依赖环境。 # 安装 gcc 环境 yum install gcc-c++ # 安装 PCRE 库，用于解析正则表达式 yum install -y pcre pcre-devel # 安装 zlib 库压缩和解压缩依赖 yum install -y zlib zlib-devel # 安装 SSL 安全的加密的套接字协议层，用于 HTTP 安全传输，也就是 https yum install -y openssl openssl-devel 3、解压，需要注意，解压后得到的是源码，源码需要编译后才能安装。 tar -zxvf nginx-1.16.1.tar.gz 4、编译之前，先创建 nginx 临时目录，如果不创建，在启动 nginx 的过程中会报错。 mkdir /var/temp/nginx -p 5、在 nginx 目录，输入如下命令进行配置，目的是为了创建 makefile 文件。 ./configure --prefix=/usr/local/nginx --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-http_gzip_static_module --http-client-body-temp-path=/var/temp/nginx/client --http-proxy-temp-path=/var/temp/nginx/proxy --http-fastcgi-temp-path=/var/temp/nginx/fastcgi --http-uwsgi-temp-path=/var/temp/nginx/uwsgi --http-scgi-temp-path=/var/temp/nginx/scgi 注：代表在命令行中换行，用于提高可读性配置命令： 6、make 编译 & 安装 make make install 7、进入 sbin 目录启动 nginx 启动：nginx ，停止：./nginx -s stop，重新加载：./nginx -s reload。 二、配置反向代理 2.1、配置 upstream upstream [proxyName] { server 192.168.1.173:8080; server 192.168.1.174:8080; server 192.168.1.175:8080; } 2.2、配置 server server { listem 80; server_name www.tomcats.com; location / { proxy_pass http://tomcats; } } 三、配置负载均衡 3.1、使用加权轮询 nginx 默认采用轮询的方式进行负载均衡。 upstream [proxyName] { server 192.168.1.173:8080 weight=1; server 192.168.1.174:8080 weight=5; server 192.168.1.175:8080 weight=2; } 3.2、hash 负载均衡 upstream [proxyName] { ip_hash server 192.168.1.173:8080; server 192.168.1.174:8080; server 192.168.1.175:8080; } 使用 ip_hash 的注意点：不能把后台服务器直接移除，只能标记 down。 3.3、url hash 负载均衡 upstream [proxyName] { hash $request_url; server 192.168.1.173:8080; server 192.168.1.174:8080; server 192.168.1.175:8080; } 3.4、最小连接负载均衡 upstream [proxyName] { least_conn; server 192.168.1.173:8080; server 192.168.1.174:8080; server 192.168.1.175:8080; } 四、upstream 指令参数 max_conns：限制最大同时连接数 1.11.5 之前只能用于商业版。 slow_start：单位秒，权重在指定时间内从 1 上升到指定值，不适用与 hash 负载均衡、随机负…

Nginx 配置文件 nginx.conf 详解
type: item
date: 2022-03-03T12:11:00+00:00
description: 配置示例 #定义Nginx运行的用户和用户组 user www www; #nginx进程数，建议设置为等于CPU总核心数。 worker_processes 8; #全局错误日志定义类型，[ debug | info | notice | warn | error | crit ] error_log /var/log/nginx/error.log info; #进程文件 pid /var/run/nginx.pid; #一个nginx进程打开的最多文件描述符数目，理论值应该是最多打开文件数（系统的值ulimit -n）与nginx进程数相除，但是nginx分配请求并不均匀，所以建议与ulimit -n的值保持一致。 worker_rlimit_nofile 65535; #工作模式与连接数上限 events { #参考事件模型，use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型，如果跑在FreeBSD上面，就用kqueue模型。 use epoll; #单个进程最大连接数（最大连接数=连接数*进程数） worker_connections 65535; } #设定http服务器 http { include mime.types; #文件扩展名与文件类型映射表 default_type application/octet-stream; #默认文件类型 #charset utf-8; #默认编码 server_names_hash_bucket_size 128; #服务器名字的hash表大小 client_header_buffer_size 32k; #上传文件大小限制 large_client_header_buffers 4 64k; #设定请求缓 client_max_body_size 8m; #设定请求缓 sendfile on; #开启高效文件传输模式，sendfile指令指定nginx是否调用sendfile函数来输出文件，对于普通应用设为 on，如果用来进行下载等应用磁盘IO重负载应用，可设置为off，以平衡磁盘与网络I/O处理速度，降低系统的负载。注意：如果图片显示不正常把这个改成off。 autoindex on; #开启目录列表访问，合适下载服务器，默认关闭。 tcp_nopush on; #防止网络阻塞 tcp_nodelay on; #防止网络阻塞 keepalive_timeout 120; #长连接超时时间，单位是秒 #FastCGI相关参数是为了改善网站的性能：减少资源占用，提高访问速度。下面参数看字面意思都能理解。 fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; #gzip模块设置 gzip on; #开启gzip压缩输出 gzip_min_length 1k; #最小压缩文件大小 gzip_buffers 4 16k; #压缩缓冲区 gzip_http_version 1.0; #压缩版本（默认1.1，前端如果是squid2.5请使用1.0）开始压缩的http协议版本(可以不设置,目前几乎全是1.1协议) gzip_comp_level 2; #推荐6压缩级别(级别越高,压的越小,越浪费CPU计算资源) gzip_types text/plain application/x-javascript text/css application/xml; #压缩类型，默认就已经包含text/html，所以下面就不用再写了，写上去也不会有问题，但是会有一个warn。 gzip_vary on; # 是否传输gzip压缩标志 #limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用 upstream blog.ha97.com { #upstream的负载均衡，weight是权重，可以根据机器配置定义权重。weigth参数表示权值，权值越高被分配到的几率越大。 server 192.168.80.121:80 weight=3; server 192.168.80.122:80 weight=2; server 192.168.80.123:80 we…

Nginx 基础使用
type: item
date: 2022-02-28T17:21:00+00:00
description: 一、目录结构 # tree nginx/ nginx/ ├── client_body_temp ├── conf │ ├── fastcgi.conf │ ├── fastcgi.conf.default │ ├── fastcgi_params │ ├── fastcgi_params.default │ ├── include │ │ ├── xxx.conf │ ├── koi-utf │ ├── koi-win │ ├── mime.types │ ├── mime.types.default │ ├── nginx.conf │ ├── nginx.conf.default │ ├── scgi_params │ ├── scgi_params.default │ ├── uwsgi_params │ ├── uwsgi_params.default │ └── win-utf ├── fastcgi_temp ├── html │ ├── 50x.html │ └── index.html ├── logs │ ├── access.log │ ├── error.log │ └── nginx.pid ├── proxy_temp ├── sbin │ └── nginx ├── scgi_temp └── uwsgi_temp 其中这几个文件夹client_body_temp、fastcgi_temp、proxy_temp、scgi_temp在刚安装后是没有的，主要用来存放运行过程中的临时文件。 conf：用来存放配置文件相关。 html：用来存放静态文件的默认目录 html、css 等。 sbin：nginx 的主程序。 Nginx 依赖于 3 个库：PCRE，zlib 和 OpenSSL： 如果通过操作系统的包管理器安装 Nginx (例如，在 Ubuntu/Debian 上使用 apt，在 CentOS/RHEL 上使用 yum 或 dnf)，那么这些依赖库通常会作为 Nginx 包的依赖项自动安装。 如果选择从源代码编译安装 Nginx，那么就需要手动下载并编译 PCRE、zlib 和 OpenSSL 的源代码。 # PCRE version 4.4 - 8.40 wget https://ftp.pcre.org/pub/pcre/pcre-8.40.tar.gz && tar xzvf pcre-8.40.tar.gz # zlib version 1.1.3 - 1.2.11 wget http://www.zlib.net/zlib-1.2.11.tar.gz && tar xzvf zlib-1.2.11.tar.gz # OpenSSL version 1.0.2 - 1.1.0 wget https://www.openssl.org/source/openssl-1.1.0f.tar.gz && tar xzvf openssl-1.1.0f.tar.gz 安装 tree 命令： yum update yum install -y tree 二、基本运行原理 2.1、基本配置 最小配置： worker_processes 1; // 默认为1，表示开启一个业务进程，启动多少work进程，对应服务器物理cpu的内核数。 events { //事件驱动模块 worker_connections 1024; // 表示单个业务进程可接受的连接数 } http { include mime.types; // 把其他配置引入到当前配置当中。引入http mime 类型，服务器端（nginx）发给客户端，告诉客户端是什么格式的东西（http协议头中） default_type application/octet-stream; // 如果mime类型没有匹配上，默认使用二进制流的方式传输 sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } } 未开启 sendfile： 开启 sendfile： server： 2.2、servername 匹配规则 需要注意的是 servername 匹配分先后顺序，写在前面的匹配上就不会继续往下匹配了。 2.2.1、完整匹配 可以在同一 servername 中匹配多个域名 server_name v…