1、nginx负载均衡中常见的算法及原理有哪些?
- 轮询
轮询,nginx默认方式。一次将请求分配给各个后台服务器。
upstream backserver {
server 10.0.0.7;
server 10.0.0.8;
}
- 加权轮询
根据权重加权依次轮询,默认为1,实现类似于LVS中的WRR,WLC等。默认时和rr效果一样。
upstream backserver {
server 10.0.0.7 weight 20;
server 10.0.0.8 weight 30;
}
- 源地址hash
源地址hash调度方法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计算,以实现会话保持。
upstream backserver {
ip_hash;
server 10.0.0.7;
server 10.0.0.8;
}
- 目的url hash
根据请求的url的hash值分配服务器,当后台服务器为缓存时,效率较高。Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。
upstream backserver {
consistent_hash $remote_addr;
server 10.0.0.7;
server 10.0.0.8;
}
- 最少连接数
最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC。
upstream backserver {
least_conn;
server 10.0.0.7;
server 10.0.0.8;
}
- 最快响应时间
根据服务器响应时间来分发,响应时间短,分发越多。Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。
upstream backserver {
fair;
server 10.0.0.7;
server 10.0.0.8;
}
2、使用rewrite规则实现将所有到a域名的访问rewrite到b域名
当访问a.example.com时跳转到b.example.com
nginx配置:
[root@centos7-01 ~]# cat /usr/local/nginx/conf/vhost/web.conf
server {
listen 80;
server_name a.example.com;
rewrite / http://b.example.com permanent;
}
server {
listen 80;
server_name b.example.com;
location / {
root /www/test;
index index.html;
}
}
准备测试页面
[root@centos7-01 conf]# mkdir -p /www/test
[root@centos7-01 conf]# echo "rewrite test" > /www/test/index.html
[root@centos7-01 conf]# systemctl reload nginx
修改hosts解析
192.168.184.101 a.example.com b.example.com
访问测试
3、实现反向代理客户端IP透传
环境:
client(192.168.184.1)--->proxy(192.168.184.101)--->web(192.168.184.102)
解析配置:
192.168.184.101 a.example.com
proxy服务器配置:
[root@centos7-01 conf]# cat /usr/local/nginx/conf/vhost/web.conf
server {
listen 80;
server_name a.example.com;
location / {
proxy_pass http://192.168.184.102;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[root@centos7-01 ~]# systemctl reload nginx
web服务器配置:
#开启日志格式,记录x_forwarded_for
[root@centos7-02 ~]# vi /usr/local/nginx/conf/nginx.conf
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;
[root@centos7-02 ~]# systemctl reload nginx
client测试访问:
C:\Windows\System32>curl http://a.example.com
查看web服务器上的日志
#可以看到IP 192.168.184.1已经透传
[root@centos7-02 logs]# tail -f access.log
192.168.184.101 - - [09/Apr/2022:08:53:58 +0800] "GET / HTTP/1.0" 200 612 "-" "curl/7.79.1" "192.168.184.1"
4、利用LNMP实现wordpress站点搭建
环境:
192.168.184.101:nginx、php
192.168.184.102:mysql
域名解析:
192.168.184.101 wordpress.example.com
运行以下脚本安装mysql数据库
[root@centos7-02 ~]# cat install_mysql80.sh
#!/bin/bash
yum -y install libaio numactl-libs
id -g mysql &> /dev/null || groupadd mysql
id mysql &> /dev/null || useradd -r -g mysql -s /bin/nologin mysql
mkdir -p /data/mysql && chown -R mysql.mysql /data/mysql
[ -f mysql-8.0.27-linux-glibc2.12-x86_64.tar.xz ] || wget https://cdn.mysql.com/archives/mysql-8.0/mysql-8.0.27-linux-glibc2.12-x86_64.tar.xz
tar xf mysql-8.0.27-linux-glibc2.12-x86_64.tar.xz -C /usr/local/
mv /usr/local/mysql-8.0.27-linux-glibc2.12-x86_64 /usr/local/mysql
chown -R mysql.mysql /usr/local/mysql/
echo 'PATH=/usr/local/mysql/bin:$PATH' > /etc/profile.d/mysql.sh
. /etc/profile.d/mysql.sh
cat > /etc/my.cnf <<EOF
[mysqld]
datadir=/data/mysql
skip_name_resolve=1
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql.log
pid-file=/data/mysql/mysql.pid
[client]
socket=/data/mysql/mysql.sock
EOF
/usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --datadir=/data/mysql
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
chkconfig --add mysqld
service mysqld start
创建wordpress数据库账号:
[root@centos7-02 ~]# mysql -uroot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.27 MySQL Community Server - GPL
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database wordpress;
Query OK, 1 row affected (0.01 sec)
mysql> create user wordpress@'192.168.184.%' identified by "123456";
Query OK, 0 rows affected (0.00 sec)
mysql> grant all on wordpress.* to wordpress@'192.168.184.%';
Query OK, 0 rows affected (0.00 sec)
安装PHP7.4
#安装依赖包(需要EPEL源)
[root@centos02 conf]# yum -y install gcc libxml2-devel bzip2-devel libmcrypt-devel sqlite-devel oniguruma oniguruma-devel
#下载安装包
[root@centos02 ~]# wget https://www.php.net/distributions/php-7.4.28.tar.bz2
#编译安装
[root@centos7-01 ~]# tar xf php-7.4.28.tar.bz2
[root@centos7-01 ~]# cd php-7.4.28
[root@centos7-01 php-7.4.28]# ./configure \
--prefix=/usr/local/php \
--enable-mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-openssl \
--with-zlib \
--with-config-file-path=/etc \
--with-config-file-scan-dir=/etc/php.d \
--enable-mbstring \
--enable-xml \
--enable-sockets \
--enable-fpm \
--enable-maintainer-zts \
--disable-fileinfo
[root@centos7-01 php-7.4.28]# make -j 4 && make install
#配置PATH变量
[root@centos7-01 php-7.4.28]# echo 'PATH=/usr/local/php/bin:$PATH' > /etc/profile.d/custom.sh
[root@centos7-01 php-7.4.28]# . /etc/profile.d/custom.sh
[root@centos7-01 php-7.4.28]# php --version
PHP 7.4.28 (cli) (built: Mar 8 2022 10:47:52) ( ZTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
#准备php配置文件和启动文件
[root@centos7-01 php-7.4.28]# cp php.ini-production /etc/php.ini
[root@centos7-01 php-7.4.28]# cp sapi/fpm/php-fpm.service /usr/lib/systemd/system/
[root@centos7-01 php-7.4.28]# cd /usr/local/php/etc/
[root@centos7-01 etc]# cp php-fpm.conf.default php-fpm.conf
[root@centos7-01 etc]# cd php-fpm.d/
[root@centos7-01 php-fpm.d]# cp www.conf.default www.conf
[root@centos7-01 php-fpm.d]# sed -i 's/ProtectSystem=full/ProtectSystem=false/' /usr/lib/systemd/system/php-fpm.service
#修改以下配置文件中的内容
[root@centos7-01 php-fpm.d]# vi /usr/local/php/etc/php-fpm.d/www.conf
user = nginx
group = nginx
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
pm.status_path = /status
ping.path = /ping
#调整上传图片大小
[root@centos7-01 ~]# vi /etc/php.ini
post_max_size = 100M
upload_max_filesize = 50M
#开启 opcache 加速
[opcache]
; Determines if Zend OPCache is enabled
opcache.enable=1
zend_extension=opcache.so
编译安装nginx
#运行以下脚本
[root@centos7-01 ~]# cat install_nginx.sh
#!/bin/bash
SRC_DIR=/usr/local/src
NGINX_URL=http://nginx.org/download/
NGINX_FILE=nginx-1.18.0
TAR=.tar.gz
NGINX_INSTALL_DIR=/usr/local/nginx
CPUS=`lscpu |awk '/^CPU\(s\)/{print $2}'`
color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
os_type () {
awk -F'[ "]' '/^NAME/{print $2}' /etc/os-release
}
os_version () {
awk -F'"' '/^VERSION_ID/{print $2}' /etc/os-release
}
check () {
[ -e ${NGINX_INSTALL_DIR} ] && { color "nginx 已安装,请卸载后再安装" 1; exit; }
cd ${SRC_DIR}
if [ -e ${NGINX_FILE}${TAR} ];then
color "相关文件已准备好" 0
else
color '开始下载 nginx 源码包' 0
wget ${NGINX_URL}${NGINX_FILE}${TAR}
[ $? -ne 0 ] && { color "下载 ${NGINX_FILE}${TAR}文件失败" 1; exit; }
fi
}
install () {
color "开始安装 nginx" 0
if id nginx &> /dev/null;then
color "nginx 用户已存在" 1
else
useradd -s /sbin/nologin -r nginx
color "创建 nginx 用户" 0
fi
color "开始安装 nginx 依赖包" 0
if [ `os_type` == "CentOS" -a `os_version` == '8' ] ;then
yum -y -q install make gcc-c++ libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
elif [ `os_type` == "CentOS" -a `os_version` == '7' ];then
yum -y -q install make gcc pcre-devel openssl-devel zlib-devel perl-ExtUtils-Embed
else
apt update &> /dev/null
apt -y install make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev &> /dev/null
fi
cd $SRC_DIR
tar xf ${NGINX_FILE}${TAR}
NGINX_DIR=`echo ${NGINX_FILE}${TAR}| sed -nr 's/^(.*[0-9]).*/\1/p'`
cd ${NGINX_DIR}
./configure --prefix=${NGINX_INSTALL_DIR} --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
make -j $CPUS && make install
[ $? -eq 0 ] && color "nginx 编译安装成功" 0 || { color "nginx 编译安装失败,退出!" 1 ;exit; }
echo "PATH=${NGINX_INSTALL_DIR}/sbin:${PATH}" > /etc/profile.d/nginx.sh
cat > /lib/systemd/system/nginx.service <<EOF
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=/bin/rm -f ${NGINX_INSTALL_DIR}/logs/nginx.pid
ExecStartPre=${NGINX_INSTALL_DIR}/sbin/nginx -t
ExecStart=${NGINX_INSTALL_DIR}/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
LimitNOFILE=100000
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now nginx &> /dev/null
systemctl is-active nginx &> /dev/null || { color "nginx 启动失败,退出!" 1 ; exit; }
color "nginx 安装完成" 0
}
check
install
配置nginx
[root@centos7-01 www]# mkdir -p /www/wordpress
[root@centos7-01 www]# chown nginx.nginx /www/wordpress/
[root@centos7-01 ~]# vi /usr/local/nginx/conf/nginx.conf
#http语句块中添加
client_max_body_size 100m;
include /usr/local/nginx/conf/vhost/*.conf;
[root@centos7-01 ~]# mkdir /usr/local/nginx/conf/vhost
[root@centos7-01 ~]# vi /usr/local/nginx/conf/vhost/web.conf
server {
listen 80;
server_name wordpress.example.com;
server_tokens off;
location / {
root /www/wordpress;
index index.php index.html index.htm;
}
location ~ .php$|status|ping {
root /www/wordpress;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}
}
[root@centos7-01 ~]# systemctl reload nginx
[root@centos7-01 ~]# systemctl enable --now php-fpm.service
准备php测试页面
[root@centos7-01 www]# cat /www/wordpress/info.php
<?php phpinfo(); ?>
验证测试页和状态页
wordpress部署
[root@centos7-01 ~]# wget https://cn.wordpress.org/latest-zh_CN.tar.gz
[root@centos7-01 ~]# tar xf latest-zh_CN.tar.gz
[root@centos7-01 ~]# cp -r wordpress/* /www/wordpress/
[root@centos7-01 ~]# chown -R nginx.nginx /www/wordpress/