01 面试题
面试题: 说一下如何实现的负载均衡
1.使用的proxy_pass模块
2.通过proxy_pass模块转发给upstream模块定义的地址池
3.使用的是默认的rr轮训算法分发到后端的服务器
02 负载均衡配置
# 写一个简单的配置
[root@likexy-nginx-01 conf.d]# cat lb.conf
server {
listen 80;
server_name www.lb.com;
root /code;
location / {
index lb.html;
}
}
[root@likexy-nginx-01 conf.d]# cat /code/lb.html
Nginx 01
[root@likexy-nginx conf.d]# cat lb.conf
server {
root /code;
server_name www.lb.com;
listen 80;
location / {
index lbb.html;
}
}
[root@likexy-nginx conf.d]# cat /code/lbb.html
Nginx 000
02-1 Nginx负载均衡调度算法
# RR轮询 默认
# weight 加权轮询
# ip_hash IP哈希
# url_hash URL哈希
# learn_conn 最小链接数
02-2 weight(加权轮询)
[root@Nginx-LB conf.d]# cat proxy-data
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
[root@Nginx-LB conf.d]# cat lb.conf
upstream webs {
server 172.2.25.10 weight=10; # 服务器权重
server 172.2.25.11 weight=5; # 这两个服务器访问比例为2:1
}
server {
listen 80;
server_name www.lb.lb.com;
location / {
proxy_pass http://webs;
include /etc/nginx/conf.d/proxy-data;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504; # 响应码为500 502 503 504为错误,使用下一个服务器
# 应用场景为Nginx正常启动但是PHP出现异常。这个时候访问网页会出现报错
}
}
02-3 ip-hash
# 如果成功访问,则会一直访问这个服务器
# 缺点:由此可见,这个的缺点是负载均衡不均衡
# 优点:可以解决session会话问题
upstream webs {
ip_hash; # 配置IP——hash
server 172.2.25.10;
server 172.2.25.11;
}
03 Nginx服务器状态
upstream webs {
server 10.0.0.30 down; # down 不参与负载的调度
server 10.0.0.20;
server 10.0.0.10;
server 10.0.0.9;
server 10.0.0.8 backup; # backup 类似备胎 其他服务器都挂掉后,10.0.0.8才进入负载的调度
}
04 负载均衡安全检查
# 前提:安装安全检查模块
[root@Nginx-LB conf.d]# cat lb.conf
upstream webs {
ip_hash;
server 172.2.25.10;
server 172.2.25.11;
check interval=3000 rise=2 fall=3 timeout=1000 type=tcp ;
#interval 检测间隔时间,单位为毫秒
#rise 表示请求2次正常,标记此后端的状态为up
#fall 表示请求3次失败,标记此后端的状态为down
#type 类型为tcp
#timeout 超时时间,单位为毫秒
}
server {
listen 80;
server_name www.lb.lb.com;
location / {
proxy_pass http://webs;
include /etc/nginx/conf.d/proxy-data;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
}
location /upstream_check {
check_status; # 新添加的模块
}
}
# 都正常的情况
图1 都是正常的情况
# 出现异常
图2 出现异常的状况
05 负载均衡会话保持
05-1 安装Phpmyadmin
# Nginx负载均衡会话保持
# 基于 Nginx 的ip_hash
# 基于服务端的session会话(MySQL,Redis......)
# phpmyadmin通过页面管理数据库,phpmyadmin会将会话保存到自己的磁盘
# web01,02部署phpmyadmin
[root@likexy-nginx admin]# cat /etc/nginx/conf.d/admin.conf
server {
root /code/admin;
listen 81;
server_name www.admin.mysql.com;
location / {
index index.php index.html;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[root@likexy-nginx admin]# pwd
/code/admin
[root@likexy-nginx admin]# wget https://files.phpmyadmin.net/phpMyAdmin/4.8.4/phpMyAdmin-4.8.4-all-languages.zip
[root@likexy-nginx admin]# unzip phpMyAdmin-4.8.4-all-languages.zip
[root@likexy-nginx admin]# mv phpMyAdmin-4.8.4-all-languages/* .
[root@likexy-nginx admin]# cp config.sample.inc.php config.inc.php
# 修改第31行,localhost 改成 数据库IP地址
[root@likexy-nginx admin]# vim config.inc.php
$cfg['Servers'][$i]['host'] = '172.2.25.12';
# 添加文件权限
[root@Nginx-01 php]# cd /var/lib/php
[root@Nginx-01 php]# chmod 777 -Rf .
# 为源码文件设置用户和组
[root@Nginx-01 phpmyadmin]# pwd
/code/phpmyadmin
[root@Nginx-01 phpmyadmin]# chown www:www *
# 提示不能使用空密码
图3 PhpMyadmin登录界面
MariaDB [ ( none) ] > CREATE USER 'like' @'%' IDENTIFIED BY '123123' ;
Query OK, 0 rows affected ( 0.002 sec)
MariaDB [ ( none) ] > GRANT ALL PRIVILEGES ON * . * TO 'like' @'%' WITH GRANT OPTION ;
Query OK, 0 rows affected ( 0.000 sec)
MariaDB [ ( none) ] > FLUSH PRIVILEGES ;
Query OK, 0 rows affected ( 0.001 sec)
图4 PhpMyadmin登录之后的页面
# 如果没有网页登录,没有任何文件
[root@Nginx-01 session]# pwd
/var/lib/php/session
[root@Nginx-01 session]# ls
[root@Nginx-01 session]#
# 但是在进行网页请求时,cookie和session相同
图5 查看Session和Cookie
# 登录进去之后,cookie和session改变了
图6 Session和Cookie变了
# 如果删除掉session里面的内容,那么用户就会强制登出
# 所以要把Web所有的session目录内容放到一个位置
05-2 Redis会话保持
# 在数据库服务器安装Redis
[root@MariaDB-01 ~]# yum install -y redis
# 配置Redis
[root@MariaDB-01 ~]# vim /etc/redis/redis.conf
# 修改75行的bind,后面添加IP地址
75 bind 127.0.0.1 172.2.25.15
# 配置Redis的启动项
[root@MariaDB-01 ~]# systemctl restart redis
[root@MariaDB-01 ~]# systemctl enable redis
# 检查端口
[root@MariaDB-01 ~]# lsof -i:6379
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 3877 redis 6u IPv4 37548 0t0 TCP localhost:redis (LISTEN)
redis-ser 3877 redis 7u IPv4 37549 0t0 TCP 172-2-25-15.lightspeed.miamfl.sbcglobal.net:redis (LISTEN)
# 修改PHP配置将会话写入Redis服务(在Web服务器修改)
[root@Nginx-01 ~]# vim /etc/php.ini
将1222行的 session.save_handler = files改成 session.save_handler = redis
将1255 行的 ;session.save_path = "/tmp"改成 session.save_path = "tcp://172.2.25.15:6379" # 如果Redis存在密码,则修改为tcp://172.2.25.15:6379?auth=密码
将874 行的; extension=mysqli 改成 extension=redis.so
# 在Web服务器修改,注释掉两行内容,在最下面
[root@Nginx-01 ~]# vim /etc/php-fpm.d/www.conf
;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session
图7 注释掉这两行
# 重启PHP服务
[root@Nginx-01 ~]# systemctl restart php-fpm.service
# 报错原因的PHP没安装Redis模块
图8 PHP没安装Redis模块报错
05-3 PHP安装Redis模块
# 在Web服务器下载Redis源码包
[root@web01:~]# wget http://pecl.php.net/get/redis-4.0.1.tgz
[root@Nginx-01 opt]# tar -zxvf redis-4.0.1.tgz
# 生成configure文件
[root@Nginx-01 redis-4.0.1]# phpize
[root@Nginx-LB redis-4.0.1]# ./configure
[root@Nginx-01 redis-4.0.1]# make && make install
# 重启PHP服务
[root@Nginx-01 ~]# systemctl restart php-fpm.service
图9 PhpMyadmin登录界面
# 这样就可以看到Web服务器的session文件
图10 可以看到Redis存储的Session文件
05-4 报错
# 访问的时候会遇到这个问题,原因是时间没同步,因为数据库要保证事务的一致性
[root@likexy-nginx ~]# yum install ntpdate -y
[root@likexy-nginx ~]# crontab -e
* * * * * /sbin/ntpdate ntp.aliyun.com
图11 报错检查时间是否一致