基于keepalived+nginx的web高性能的集群项目
项目步骤:
-
安装部署6台Linux虚拟机服务器,做好网络初始化工作(配置静态ip地址和dns服务器、主机名、禁用firewalld和selinux功能)
-
安装Ansible服务器并配置免密通道用于自动化运维,部署Prometheus、node_exporter构建监控体系
-
搭建基于Bind的DNS服务器提供域名解析,安装MySQL5.7.37数据库服务后端接口项目。
-
部署堡垒机并设置tcpwrappers限制访问,部署防火墙服务器发布内网Web与堡垒机服务。
-
开展SNAT、DNAT和堡垒机发布测试,用ab进行压力测试;用脚本安装Nginx,配置虚拟主机、HTTPS及VTS流量监控模块。并使用grafana出图展示监控的效果。
-
在两台Web服务器上均安装Nginx的VTS模块(用于虚拟主机流量监控),以此了解Nginx的访问状况和负载情况。同时,安装了MySQL对应的exporter模块。
-
部署Nginx七层负载均衡并结合Keepalived,实现集群负载均衡保障服务稳定
-
使用自研Pythoy接口程序作为Web应用并部署对应MySQL服务器,最后进行综合压力测试。
文档简绍了,DMZ区里面Prometheus, Ansible,nfs等各种的服务的搭建配置过程
下面来具体讲解nginx的负载均衡和配置文件详解
深入剖析Nginx配置:
一、Nginx主配置文件详解
Nginx的主配置文件通常是nginx.conf,它是Nginx服务器的核心配置文件,决定了服务器的基本行为和功能。下面我们逐段分析其关键部分:
#user nobody; #nginx woker进程启动的时候会使用那个用户去启动
worker_processes 2; #指定2个woker进程,一般情况下与cpu核心的个数一致 4个核心的cpu,建议4个woker进程 auto 表示 自动匹配你的cpu核心数量

worker_processes用于设置Nginx工作进程的数量。一般来说,将其设置为与CPU核心数相同,可以充分利用服务器的多核性能,提高处理效率。如果设置为auto,Nginx会自动检测并匹配CPU核心数量。
#error_log logs/error.log; #错误日志
#error_log logs/error.log notice;
#error_log logs/error.log info;

这部分是错误日志的配置。通过修改error_log指令,可以指定错误日志的存储路径和日志级别。日志级别从低到高分别为info、notice、warn、error、crit,不同级别记录的信息详细程度不同,可根据实际需求选择合适的级别。
#pid logs/nginx.pid; #master进程的pid号

pid指令用于指定Nginx主进程的PID文件路径。PID文件记录了Nginx主进程的进程ID,方便管理和监控Nginx的运行状态。
events {
worker_connections 2048; #定义一个worker进程可以同时并发连接多少个请求 总的请求数=woker进程数*2048
}

在events块中,worker_connections定义了每个工作进程可以同时处理的最大连接数。这个值乘以worker_processes的值,就是Nginx服务器能够同时处理的最大并发连接数。合理设置该参数可以优化服务器的并发处理能力,但过高的设置可能会导致系统资源耗尽。
http {
include mime.types;
default_type application/octet-stream;

http块是Nginx配置的核心部分,用于配置HTTP服务器的相关参数。include mime.types表示包含MIME类型定义文件,mime.types文件中定义了各种文件类型与对应的MIME类型,使得Nginx能够正确识别和处理不同类型的文件。default_type指定了默认的MIME类型,当Nginx无法识别文件类型时,会使用该默认类型。
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';

log_format用于定义日志格式。上述配置定义了一个名为main的日志格式,其中包含了客户端IP地址($remote_addr)、远程用户($remote_user)、访问时间($time_local)、请求URL($request)、状态码($status)等信息。通过自定义日志格式,可以记录对业务有价值的信息,方便进行日志分析。
#access_log logs/access.log main; #访问日志 main是格式的名字

access_log用于指定访问日志的存储路径和使用的日志格式。开启访问日志记录后,Nginx会将每个请求的相关信息按照指定格式记录到日志文件中,有助于分析网站的访问情况。
sendfile on;
#tcp_nopush on;

sendfile指令用于开启高效的文件传输模式。当设置为on时,Nginx可以直接将文件内容发送到网络连接,而不需要将文件内容先读取到用户空间再发送,从而提高文件传输效率。tcp_nopush指令与sendfile配合使用,在文件传输时将数据一次性发送,减少网络包的数量,提高传输性能。
#keepalive_timeout 0;
keepalive_timeout 65; #长连接 65秒

keepalive_timeout设置了长连接的超时时间。当客户端与服务器建立连接后,如果在指定时间内没有新的请求,连接会被关闭。合理设置长连接超时时间可以减少连接建立和关闭的开销,提高服务器性能。
gzip on; #开启压缩功能,响应报文的body部分进行压缩

gzip指令用于开启Gzip压缩功能。开启后,Nginx会对响应报文的body部分进行压缩,减少数据传输量,提高页面加载速度。在网络带宽有限的情况下,Gzip压缩能显著提升用户体验。
server {
listen 80; #监听的端口
server_name www.sc.com; #网站的域名
#charset koi8-r;
#access_log logs/host.access.log main; #访问日志
#定义路由--》根路径
location / {
root html; #网页根目录 在html文件夹 html在nginx安装的路径下
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;
#}
}

server块用于定义虚拟主机。每个server块可以配置一个独立的网站或服务。listen指定监听的端口,server_name指定网站的域名。location块用于定义不同URL的处理规则,例如location /定义了网站根路径的处理方式,root指定网页根目录,index指定默认首页。error_page用于配置错误页面的跳转,当出现指定的错误状态码时,会跳转到对应的页面。
二、Nginx启动和重启
Nginx的启动、重启和关闭操作是日常运维中常见的任务。在Linux系统中,可以使用以下命令进行操作:
[root@web1 logs]# nginx #启动
[root@web1 conf]# /usr/local/wangguang/sbin/nginx -s reload #重启
[root@web1 ~]#su
[root@web1 ~]# nginx -s reload #重启
[root@web1 ~]# nginx -s stop #关闭
[root@web1 ~]# nginx -t #测试nginx.conf文件

启动Nginx时,直接执行nginx命令即可。重启Nginx有两种方式,一种是使用-s reload选项,这种方式会重新加载配置文件,使新的配置生效,并且不会中断正在处理的请求;另一种是先停止Nginx(-s stop),再重新启动,但这种方式会导致服务短暂中断。在修改配置文件后,建议先使用nginx -t命令测试配置文件的语法正确性,避免因配置错误导致Nginx无法启动。
三、Nginx性能优化相关参数设置
(一)调整工作进程与连接数
worker_processes:如前文所述,该参数应根据服务器的CPU核心数进行合理设置。在单核CPU服务器上,可以设置为1;在多核CPU服务器上,设置为与CPU核心数相同或略小于核心数,以避免进程上下文切换带来的开销。例如,对于4核CPU的服务器,设置worker_processes 4;可以充分利用硬件资源。
worker_connections:这个参数决定了每个工作进程的最大并发连接数。在高并发场景下,可以适当调大该参数,但需要注意系统资源的限制。如果服务器内存充足,网络带宽足够,可以将其设置为较大的值,如4096或8192。但过高的设置可能会导致文件描述符耗尽等问题,需要结合系统参数ulimit -n进行调整。
(二)优化文件描述符限制
Nginx在处理大量连接时,需要足够的文件描述符支持。可以通过修改ulimit的值来增加文件描述符的数量。临时修改可以在命令行中执行ulimit -n 100000,但这种修改在系统重启后会失效。要永久修改,需要编辑/etc/security/limits.conf文件,添加或修改以下内容:
* soft nofile 100000
* hard nofile 100000

修改完成后,重启服务器使设置生效。这样可以确保Nginx在高并发情况下能够正常处理大量连接。
(三)开启高效传输模式
sendfile:开启sendfile功能可以显著提高文件传输效率。在配置文件中设置sendfile on;后,Nginx会使用高效的文件传输方式,减少数据拷贝和系统调用次数。这对于静态文件服务器或文件下载服务来说尤为重要,可以大大减轻服务器的负载。
tcp_nopush和tcp_nodelay:tcp_nopush与sendfile配合使用,将数据一次性发送,减少网络包的数量,提高传输性能。而tcp_nodelay则用于禁用Nagle算法,确保数据及时发送,适用于对实时性要求较高的场景,如Websocket连接。在配置文件中,可以根据实际需求开启这两个参数:
sendfile on;
tcp_nopush on;
tcp_nodelay on;

(四)设置长连接超时时间
keepalive_timeout参数用于设置长连接的超时时间。在实际应用中,需要根据业务场景合理设置该参数。如果网站的用户访问频繁,且请求间隔较短,可以适当延长长连接的超时时间,如设置为120秒;如果用户访问间隔较长,或者服务器资源有限,可以缩短超时时间,如设置为30秒。这样可以在保证用户体验的同时,合理利用服务器资源。
(五)启用Gzip压缩
Gzip压缩可以有效减少数据传输量,提高页面加载速度。在配置文件中开启Gzip压缩非常简单,只需设置gzip on;即可。此外,还可以进一步配置Gzip的相关参数,如压缩级别、压缩类型等:
gzip on;
gzip_min_length 1000; #设置允许压缩的最小文件大小
gzip_comp_level 6; #设置压缩级别,1-9,级别越高压缩比越大,但压缩时间也越长
gzip_types text/plain text/css application/json application/javascript; #设置需要压缩的文件类型

nginx+keepalived 实现web高可用和负载均衡
keepalived简绍

nginx实现负载均衡
- 编译安装nginx,并且配置好负载均衡,请借鉴前面的配置步骤
[root@lb1 conf]# cat nginx.conf
worker_processes 2;
error_log logs/error.log notice;
events {
worker_connections 2048;
}
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;
keepalive_timeout 65;
#定义一个负载均衡器
upstream scapp {
server 192.168.203.144 weight=3;
server 192.168.203.149 max_fails=2 fail_timeout=3;
#health_check interval=10 fails=3 passes=2;
}
gzip on;
server {
listen 80;
location / {
#将用户的访问流量转发到后端的服务器,理解调用负载均衡器scapp
proxy_pass http://scapp;
#让nginx负载均衡器在转发http请求报文的时候,在请求报文的头部信息里增加一个字段X-Real-IP ,这样后端的real server在解封装http请求报文的时候,就知道前面的客户机的ip地址了
proxy_set_header X-Real-IP $remote_addr; #定义一个变量X-Real-IP 复制$remote_addr
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
LB1和LB2的nginx.conf的配置文件,内容是一模一样的,增加了解决realip的问题。
[root@lb-2 conf]# cat nginx.conf
worker_processes 2;
events {
worker_connections 2048;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#定义一个负载均衡器scapp
upstream scapp {
server 192.168.203.144;
server 192.168.203.149;
}
server {
listen 80;
server_name localhost;
location / {
#访问网页根目录直接转发到负载均衡器上进行处理
proxy_pass http://scapp;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
[root@lb-2 conf]#
[root@lb-1 conf]# cat nginx.conf
worker_processes 2;
events {
worker_connections 2048;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
#定义一个负载均衡器scapp
upstream scapp {
server 192.168.203.144;
server 192.168.203.149;
}
server {
listen 80;
server_name localhost;
location / {
#访问网页根目录直接转发到负载均衡器上进行处理
proxy_pass http://scapp;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
[root@lb-1 conf]#
测试配置文件的语法
[root@lb-1 conf]# nginx -t
nginx: the configuration file /usr/local/wangguang/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/wangguang/conf/nginx.conf test is successful
[root@lb-1 conf]#
[root@lb-2 conf]# nginx -t
nginx: the configuration file /usr/local/wangguang/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/wangguang/conf/nginx.conf test is successful
[root@lb-2 conf]#
重启nginx服务
[root@lb1 conf]# nginx -s reload
[root@lb2 conf]# nginx -s reload
在后端的backend 服务器(web1和web2)上nginx.conf配置文件里日志里记录x-real-ip的地址
[root@web1 conf]# pwd
/usr/local/wangguang/conf
[root@web1 conf]# vim nginx.conf
[root@web1 conf]# cat nginx.conf|egrep -v "^#|^$| +#"
worker_processes 2;
events {
worker_connections 2048;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $http_x_real_ip - $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;
keepalive_timeout 65;
vhost_traffic_status_zone;
vhost_traffic_status_filter_by_host on;
server_tokens off;
gzip on;
server {
listen 80;
server_name www.sc.com;
access_log logs/www.access.log main;
error_log logs/www.error.log;
location / {
root html/www;
index index.html index.htm;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
#添加统计功能的路由
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
}
server {
listen 80;
server_name software.sc.com;
access_log logs/software.access.log main;
location / {
root html/software;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
}
}
[root@web1 conf]#
Web2上的配置,目前web1和web2的配置还不一样,最后应该要一样。
[root@web2 conf]# cat nginx.conf|egrep -v "^#|^$| +#"
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $http_x_real_ip - $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;
keepalive_timeout 65;
vhost_traffic_status_zone;
vhost_traffic_status_filter_by_host on;
server {
listen 80;
server_name vts.sc.com;
location / {
root html;
index index.html index.htm;
}
#添加vts功能的配置
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
[root@web2 conf]#
重启nginx服务
[root@web1 conf]# nginx -s reload
[root@web2 conf]# nginx -s reload
关键是增加下面的配置
最后验证效果


HTTPS功能实现
1. 在Web服务器上部署SSL证书
步骤1:上传证书文件
将SSL证书(.pem和.key文件)上传至Web服务器的Nginx配置目录(如/usr/local/wangguang/conf/),并解压:
unzip 11158224_www.sanchuangedu.cn_nginx.zip
步骤2:修改Nginx配置
编辑Nginx配置文件nginx.conf,添加HTTPS服务配置:
server {
listen 443 ssl;
server_name www.sanchuangedu.cn;
ssl_certificate www.sanchuangedu.cn.pem;
ssl_certificate_key www.sanchuangedu.cn.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:重启Nginx服务
验证配置并重启服务:
nginx -t && nginx -s reload
步骤4:验证HTTPS访问
在本地主机修改hosts文件,添加域名解析记录:
192.168.203.144 www.sanchuangedu.cn
通过浏览器访问 https://www.sanchuangedu.cn,确认证书生效。
2. 防火墙发布HTTPS服务
在防火墙服务器上添加DNAT规则,将外网请求转发至内网负载均衡器的VIP:
# 添加HTTPS转发规则
iptables -t nat -A PREROUTING -d 192.168.1.125 -i ens33 -p tcp --dport 443 -j DNAT --to-destination 192.168.203.188
iptables -t nat -A PREROUTING -d 192.168.1.183 -i ens33 -p tcp --dport 443 -j DNAT --to-destination 192.168.203.199
二、基于端口和URL的负载均衡
1. 不同端口的负载均衡
场景:将HTTP(80端口)和HTTPS(443端口)请求分别转发至不同后端服务。
配置示例(以LB1为例):
upstream http_servers {
server 192.168.203.144:80;
server 192.168.203.149:80;
}
upstream https_servers {
server 192.168.203.144:443;
server 192.168.203.149:443;
}
server {
listen 80;
location / {
proxy_pass http://http_servers;
proxy_set_header X-Real-IP $remote_addr;
}
}
server {
listen 443 ssl;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/cert.key;
location / {
proxy_pass https://https_servers;
proxy_set_header X-Real-IP $remote_addr;
}
}
2. 基于URL路径的负载均衡
场景:根据URL路径将请求转发至不同后端服务。
配置示例(以LB1为例):
upstream app_servers {
server 192.168.203.144;
server 192.168.203.149;
}
upstream api_servers {
server 192.168.203.144:5000;
server 192.168.203.149:5000;
}
server {
listen 80;
server_name www.sc.com;
location / {
proxy_pass http://app_servers;
proxy_set_header X-Real-IP $remote_addr;
}
location ~ /api {
proxy_pass http://api_servers;
proxy_set_header X-Real-IP $remote_addr;
}
}
3. 高级URL转发案例
场景:将特定路径(如/chensiyu)转发至外部网站(如京东)。
server {
listen 443 ssl;
server_name www.sanchuangedu.cn;
ssl_certificate www.sanchuangedu.cn.pem;
ssl_certificate_key www.sanchuangedu.cn.key;
location / {
proxy_pass https://backend_servers;
}
location /chensiyu {
proxy_pass https://www.jd.com;
}
}
三、验证与测试
1. 验证HTTPS服务
- 内部测试:通过
curl -k https://www.sanchuangedu.cn检查响应。 - 外网测试:修改本地
hosts文件指向防火墙外网IP,通过浏览器访问验证。
2.日志排查:若转发失败,可通过Nginx日志(logs/error.log)排查问题。
更多推荐



所有评论(0)