拆分数据库
数据库拆分环境规划
主机名称 应用环境 外网地址 内网地址
web01 nginx+php 10.0.0.7 172.16.1.7
db01 mysql 172.16.1.51
1.准备一台新的服务器,安装好对应版本的数据库 (统一使用的是mariadb5.5) [172.16.1.51]
[root@db01 ~]# yum install mariadb mariadb-server -y
[root@db01 ~]# systemctl start mariadb
[root@db01 ~]# systemctl enable mariadb
[root@db01 ~]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 3717/mysqld
2.在旧的环境先进行打包操作(备份数据) [172.16.1.7]
[root@web01 ~]# mysqldump -uroot -p'Bgx123.com' --all-databases --single-transaction > mysql-all.sql
3.货拉拉--->远程传输--->新的环境 [172.16.1.7]
[root@web01 ~]# scp mysql-all.sql root@172.16.1.51:/tmp
root@172.16.1.51's password:
mysql-all.sql 100% 1423KB 30.9MB/s 00:00
4.在新的数据库进行恢复(恢复数据) [172.16.1.51] (设置密码:mysqladmin password 'Bgx123.com')
[root@db01 ~]# mysql -uroot </tmp/mysql-all.sql
[root@db01 ~]# systemctl restart mariadb
[root@db01 ~]# mysql -uroot #旧环境的数据库登陆密码被恢复至新的数据库
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
[root@db01 ~]# mysql -uroot -pBgx123.com #登陆方式
MariaDB [(none)]> grant all on . to 'all'@'%' identified by 'Bgx123.com'; #配置远程web应用服务能连接数据库服务的用户
5.应用程序指向新的数据库(应用割接) [172.16.1.7]
[root@web01 ~]# systemctl stop mariadb #停止数据库
配置wordpress的应用割接 /code/wordpress/wp-config.php
/** WordPress数据库的名称 */
define('DB_NAME', 'wordpress');
/** MySQL数据库用户名 */
define('DB_USER', 'all');
/** MySQL数据库密码 */
define('DB_PASSWORD', 'Bgx123.com');
/** MySQL主机 */
define('DB_HOST', '172.16.1.51');
配置zh的应用割接 /code/zh/system/config/database.php
$config['master'] = array (
'charset' => 'utf8',
'host' => '172.16.1.51',
'username' => 'all',
'password' => 'Bgx123.com',
'dbname' => 'zh',
);
6.扩展知识,如何查找web应用程序保存数据库指向的文件
[root@web01 code]# grep -R "Bgx123.com" ./
快速扩展一台web节点环境规划
主机名称 应用环境 外网地址 内网地址
web01 nginx+php 10.0.0.7 172.16.1.7
web02 nginx+php 10.0.0.8 172.16.1.8
db01 mysql 172.16.1.51
通过web01现有环境快速的扩展一台web02的服务器,数据库统一使用db01
创建www用户
[root@web02 ~]# groupadd -g666 www
[root@web02 ~]# useradd -u666 -g666 www安装LNP
[root@web02 ~]# scp -rp root@172.16.1.7:/etc/yum.repos.d/* /etc/yum.repos.d/
[root@web02 ~]# scp -rp root@172.16.1.7:/etc/pki/rpm-gpg/* /etc/pki/rpm-gpg/
[root@web02 ~]# yum install nginx -y
[root@web02 ~]# yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb
将web01的nginx配置文件导入到web02
[root@web02 ~]# scp -rp root@172.16.1.7:/etc/nginx /etc/将web01的php配置文件导入到web02
[root@web02 ~]# scp -rp root@172.16.1.7:/etc/php-fpm.d /etc/将web01的产品代码打包传输到web02服务器上,在web1上线进行打包操作 web01操作
[root@web01 ~]# tar czf code.tar.gz /code
[root@web01 ~]# scp code.tar.gz root@172.16.1.8:/tmp
在web02服务器上进行解压
[root@web02 ~]# tar xf /tmp/code.tar.gz -C /
- 最后启动nginx与php-fpm,并加入开机自启
[root@web03 ~]# systemctl start nginx php-fpm
[root@web03 ~]# systemctl enable nginx php-fpm
新增一台nfs共享存储
主机名称 应用环境 外网地址 内网地址
web01 nginx+php 10.0.0.7 172.16.1.7
web02 nginx+php 10.0.0.8 172.16.1.8
nfs nfs 172.16.1.31
db01 mysql 172.16.1.51
1.准备一台服务器,安装nfs,并共享对应的目录 172.16.1.31
[root@nfs ~]# groupadd -g 666 www
[root@nfs ~]# useradd -u666 -g666 www
[root@nfs ~]# yum install nfs-utils -y
[root@nfs ~]# mkdir /data/{wordpress,zh}
2.配置nfs共享
[root@nfs ~]# cat /etc/exports
/data/wordpress 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
/data/zh 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
[root@nfs ~]# chown -R www.www /data/
3.重启nfs
[root@nfs ~]# systemctl restart nfs-server
Wordpress
4.web应用程序如何将静态资源保存至nfs存储中
http://blog.oldboy.com/wp-content/uploads/2019/03/123-1024x689.jpg
/code/wordpress/wp-content/uploads/2019/03/123-1024x689.jpg
1) 拷贝静态资源多的web服务器图片至nfs存储上
[root@web02 ~]# scp -rp /code/wordpress/wp-content/uploads/* root@172.16.1.31:/data/wordpress/
2) 回到nfs上重新进行一次授权
[root@nfs ~]# chown -R www.www /data/wordpress
3) web02进行挂载
[root@web02 ~]# mount -t nfs 172.16.1.31:/data/wordpress /code/wordpress/wp-content/uploads/
[root@web01 ~]# mount -t nfs 172.16.1.31:/data/wordpress /code/wordpress/wp-content/uploads/
Wecenter
http://zh.oldboy.com/uploads/article/20190324/fb6bdb2110ce135fcd8d133bb1ad25a3.jpg
[root@web02 ~]# scp -rp /code/zh/uploads/* root@172.16.1.31:/data/zh/
[root@nfs ~]# chown -R www.www /data/zh/ #重新授权
[root@web02 ~]# mount -t nfs 172.16.1.31:/data/zh /code/zh/uploads/
[root@web01 ~]# mount -t nfs 172.16.1.31:/data/zh /code/zh/uploads/
nginx代理
.正向与反向代理的区别
区别在于形式上服务的"对象"不一样
正向代理代理的对象是客户端,为客户端服务 为了解决客户端上网问题
反向代理代理的对象是服务端,为服务端服务
用户请求的时候HOST的值是www.bgx.com, 那么代理服务会像后端传递请求的还是www.bgx.com
proxy_set_header Host $http_host;
将remote_addr的值为客户端的ip
proxy_set_header X-Real-IP $remote_addr;
客户端通过代理服务访问后端服务, 后端服务通过该变量会记录真实客户端地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Proxy代理网站常用优化配置如下,将配置写入新文件,调用时使用include引用即可
[root@Nginx ~]# vim /etc/nginx/proxy_params
proxy_http_version 1.1;
proxy_set_header Host remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
1.环境准备
角色 外网IP(NAT) 内网IP(LAN) 主机名
Proxy eth0:10.0.0.5 eth1:172.16.1.5 lb01
web01 eth1:172.16.1.7 web01
2.web01服务器, 配置一个网站,监听在8080
[root@web01 ~]# vim /etc/nginx/conf.d/web.conf
server {
listen 8080;
server_name web.oldboy.com;
location / {
root /code_8080;
index index.html;
}
}
[root@web01 conf.d]# mkdir /code_8080
[root@web01 conf.d]# echo "web01-7...." >/code_8080/index.html
[root@web01 conf.d]# systemctl restart nginx
2.proxy代理服务器, 监听的80端口。将所有的用户的请求代理至后端
[root@lb01 ~]# cd /etc/nginx/conf.d/
[root@lb01 conf.d]# cat proxy_web_node1.conf
server {
listen 80;
server_name web.oldboy.com;
location / {
proxy_pass http://172.16.1.7:8080;
include proxy_params;
}
}
[root@lb01 conf.d]# systemctl enable nginx
[root@lb01 conf.d]# systemctl start nginx
nginx负载均衡
名词
调度节点 说的也是具有代理的负载均衡服务
硬件 F5、radware
软件 Nginx、Haproxy、LVS
云 slb、ulb、clb
角色 外网IP(NAT) 内网IP(LAN) 主机名
LB01 eth0:10.0.0.5 eth1:172.16.1.5 lb01
web01 eth0:10.0.0.7 eth1:172.16.1.7 web01
web02 eth0:10.0.0.8 eth1:172.16.1.8
1.Web01服务器上配置nginx, 并创建对应html文件
[root@web01 ~]# cd /etc/nginx/conf.d/
[root@web01 conf.d]# cat node.conf
server {
listen 80;
server_name node.oldboy.com;
location / {
root /node;
index index.html;
}
}
[root@web01 conf.d]# mkdir /node
[root@web01 conf.d]# echo "Web01..." > /node/index.html
[root@web01 conf.d]# systemctl restart nginx
2.Web02服务器上配置nginx, 并创建对应html文件
[root@web02 ~]# cd /etc/nginx/conf.d/
[root@web02 conf.d]# cat node.conf
server {
listen 80;
server_name node.oldboy.com;
location / {
root /node;
index index.html;
}
}
[root@web02 conf.d]# mkdir /node
[root@web02 conf.d]# echo "Web02..." > /node/index.html
[root@web02 conf.d]# systemctl restart nginx
3.配置Nginx负载均衡
[root@lb01 ~]# cd /etc/nginx/conf.d/
[root@lb01 conf.d]# cat node_proxy.conf
upstream node {
server 172.16.1.7:80;
server 172.16.1.8:80;
}
server {
listen 80;
server_name node.oldboy.com;
location / {
proxy_pass http://node;
include proxy_params;
}
}
[root@lb01 conf.d]# systemctl restart nginx
4.准备Nginx负载均衡调度使用的proxy_params
[root@Nginx ~]# vim /etc/nginx/proxy_params
proxy_set_header Host remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
Nginx负载均衡调度算法
调度算法 概述
轮询 按请求逐一分配到不同的后端服务器(默认)
weight 加权轮询,weight值越大,分配到的访问几率越高
ip_hash 每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务器
url_hash 按照访问URL的hash结果来分配请求,是每个URL定向到同一个后端服务器
least_conn 最少链接数,那个机器链接数少就分发
1.Nginx负载均衡[wrr]轮询具体配置
upstream load_pass {
server 10.0.0.7:80;
server 10.0.0.8:80;
}
2.Nginx负载均衡[weight]权重轮询具体配置
upstream load_pass {
server 10.0.0.7:80 weight=5;
server 10.0.0.8:80;
}
3.Nginx负载均衡ip_hash具体配置, 不能和weight一起使用。
#如果客户端都走相同公网, 会导致某一台服务器连接过多
upstream load_pass {
ip_hash;
server 10.0.0.7:80;
server 10.0.0.8:80;
}
Nginx负载均衡后端状态 后端Web服务器在前端Nginx负载均衡调度中的状态
状态 概述
down 当前的server暂时不参与负载均衡
backup 预留的备份服务器
max_fails 允许请求失败的次数
fail_timeout 经过max_fails失败后, 服务暂停时间
max_conns 限制最大的接收连接数
1.测试down状态, 测试该Server不参与负载均衡的调度
upstream load_pass {
#不参与任何调度, 一般用于停机维护
server 10.0.0.7:80 down;
}
2.测试backup以及down状态
upstream load_pass {
server 10.0.0.7:80 down;
server 10.0.0.8:80 backup;
server 10.0.0.9:80 max_fails=1 fail_timeout=10s;
}
3.测试max_fails失败次数和fail_timeout多少时间内失败多少次则标记down
upstream load_pass {
server 10.0.0.7:80;
server 10.0.0.8:80 max_fails=2 fail_timeout=10s;
}
4.测试max_conns最大TCP连接数
upstream load_pass {
server 10.0.0.7:80;
server 10.0.0.8:80 max_conns=1;
}
7.使用nginx负载均衡时,如何将后端请求超时的服务器流量平滑的切换到另一台上。
如果后台服务连接超时,Nginx是本身是有机制的,如果出现一个节点down掉的时候,Nginx会更据你具体负载均衡的设置,将请求转移到其他的节点上,但是,如果后台服务连接没有down掉,但是返回错误异常码了如:504、502、500,这个时候你需要加一个负载均衡的设置,如下:
proxy_next_upstream http_500 | http_502 | http_503 | http_504 |http_404;
意思是,当其中一台返回错误码404,500...等错误时,可以分配到下一台服务器程序继续处理,提高平台访问成功率。
server {
listen 80;
server_name xuliangwei.com;
location / {
proxy_pass http://node;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
}
}
Nginx负载均衡会话共享
在使用负载均衡的时候会遇到会话保持的问题,可通过如下方式进行解决
1.使用nginx的ip_hash,根据客户端的来源IP,将请求分配到相同服务器上。
2.基于服务端的Session会话共享(mysql/memcache/redis/file)
在解决负载均衡会话问题我们需要了解session和cookie。
1.用户第一次请求服务端网站时,服务端会生成对应的session_id,然后使用set-cookie响应头,将sessio_id存储至浏览器的cookie中。
2.客户端尝试登陆服务端网站时,浏览器的请求头会自动携带cookie信息,这个cookie信息保存的值是session_id
3.客户端登陆服务端网站后,服务端会将session_id存储(mysql|redis|file)中,
当用户下次请求网站时会去查询用户提交的cookie作为key去存储里找对应的value(session)
注意:
同一域名下的网站登陆后cookie都是一样的。
所以无论负载后端有几台WEB服务器,无论请求分配到哪一台服务器上,同一个客户端的cookie是不会发生变化的。
也就是说cookie对应的session是唯一的。
所以,这里只要保证多台业务服务器访问同一个共享服务器(memcache/redis/mysql/file)就行了。
1.首先在多台web上都安装并配置phpmyadmin
#1.安装phpmyadmin(web01和web02上都装)
[root@web01 conf.d]# cd /code
[root@web01 code]# wget https://files.phpmyadmin.net/phpMyAdmin/4.8.5/phpMyAdmin-4.8.5-all-languages.zip
[root@web01 code]# unzip phpMyAdmin-4.8.5-all-languages.zip
#2.配置phpmyadmin连接远程的数据库
[root@web01 code]# ln -s /code/phpMyAdmin-4.8.5-all-languages /code/phpmyadmin
[root@web01 code]# cp phpmyadmin/config.sample.inc.php phpmyadmin/config.inc.php
[root@web01 code]# vim phpmyadmin/config.inc.php
/* Server parameters */
$cfg['Servers'][$i]['host'] = '172.16.1.51';
#3.将代码拷贝一份到web02
2.在多台web上准备phpmyadmin的nginx配置文件
[root@web01 ~]# cat /etc/nginx/conf.d/php.conf
server {
listen 80;
server_name php.oldboy.com;
root /code/phpmyadmin;
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;
}
}
#重启Nginx服务
[root@web01 ~]# systemctl restart nginx
3.配置负载均衡服务,调度到后端两台web节点
[root@lb01 ~]# cat /etc/nginx/conf.d/proxy_php.com.conf
upstream php {
server 172.16.1.7:80;
server 172.16.1.8:80;
}
server {
listen 80;
server_name php.oldboy.com;
location / {
proxy_pass http://php;
include proxy_params;
}
}
#检查语法并重启nginx
[root@lb01 conf.d]# nginx -t
[root@lb01 conf.d]# systemctl restart nginx
4.准备redis内存数据库存储session会话
#1.安装redis内存数据库
[root@db01 ~]# yum install redis -y
#2.配置redis监听在172.16.1.0网段上
[root@db01 ~]# sed -i '/^bind/c bind 127.0.0.1 172.16.1.51' /etc/redis.conf
#3.启动redis
[root@db01 ~]# systemctl start redis
[root@db01 ~]# systemctl enable redis
5.配置php连接redis服务
#1.修改/etc/php.ini文件
[root@web ~]# vim /etc/php.ini
session.save_handler = redis
session.save_path = "tcp://172.16.1.51:6379"
;session.save_path = "tcp://172.16.1.51:6379?auth=123" #如果redis存在密码,则使用该方式
#2.注释php-fpm.d/www.conf里面的两条内容,否则session内容会一直写入/var/lib/php/session目录中
;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session
6.使用浏览器登陆网站,获取对应的cookie信息
7.检查redis中是否存在cookie对应的session
172.16.1.51:6379> keys *
1) "PHPREDIS_SESSION:393ff522ed2a7e26ba44f6d925f991f2"
172.16.1.51:6379>
8.此时用户的cookie始终都不会发生任何变化,无论请求被负载调度到那一台后端web节点服务器都不会出现没有登陆情况。
架构的演变
单台-->
拆分数据库 (集群或高可用)
拆分静态资源
扩展多台web服务器
接入负载均衡,实现集群
代理
正向代理
反向代理
代理的类型
代理模型
四层 nginx1.9支持 快
七层 nginx主要 应用场景
lvs 仅仅支持四层
haproxy、nginx 都支持四层和七层
负载均衡、调度算法、后端的状态、
总结:代理仅能代理一个太服务,而负载均衡能代理一组资源池(N多台服务器)
本周作业
1台负载
2-3台web 2台php(blog,zh) 1台java(jpress)
1台nfs
1台数据库、mysql、redis
下周内容:
nginxRewrite
Nginx https
Nginx高可用keepalived
-----nginx常用模块、nginx常见问题
了解和扩展
nginx+tomcat --->jpress
nginx+uwsgi --->pythonDjango
---------------------------------------------------------------------------------------gdisk分区
-------新增了一块5T磁盘,用于共享,提供给web服务器存储静态资源
[root@nfs ~]# lsblk #查看磁盘
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:16 0 4.9T 0 disk
[root@nfs ~]# yum install gdisk -y #查过2t的存储空间不能使用fdisk,必须使用gdisk
[root@nfs ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 99G 0 part
├─centos-root 253:0 0 50G 0 lvm /
├─centos-swap 253:1 0 2G 0 lvm [SWAP]
└─centos-home 253:2 0 47G 0 lvm /home
sdb 8:16 0 4.9T 0 disk
sr0 11:0 1 4.2G 0 rom
[root@nfs ~]# gdisk /dev/sdb
GPT fdisk (gdisk) version 0.8.10
Creating new GPT entries.
Command (? for help): ?
b back up GPT data to a file
c change a partition's name
d delete a partition
i show detailed information on a partition
l list known partition types
n add a new partition
o create a new empty GUID partition table (GPT)
p print the partition table
q quit without saving changes
r recovery and transformation options (experts only)
s sort partitions
t change a partition's type code
v verify disk
w write table to disk and exit
x extra functionality (experts only)
? print this menu
Command (? for help): n
Partition number (1-128, default 1):
First sector (34-10485759966, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-10485759966, default = 10485759966) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'
Command (? for help): p
Disk /dev/sdb: 10485760000 sectors, 4.9 TiB
Logical sector size: 512 bytes
Disk identifier (GUID): B01B90A9-F7CA-4F10-8FDE-EA7BEB308DBF
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 10485759966
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 2048 10485759966 4.9 TiB 8300 Linux filesystem
Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.
[root@nfs ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 99G 0 part
├─centos-root 253:0 0 50G 0 lvm /
├─centos-swap 253:1 0 2G 0 lvm [SWAP]
└─centos-home 253:2 0 47G 0 lvm /home
sdb 8:16 0 4.9T 0 disk
└─sdb1 8:17 0 4.9T 0 part
sr0 11:0 1 4.2G 0 rom
格式化
[root@nfs ~]# mkfs.xfs /dev/sdb1
挂载
[root@nfs ~]# mkdir /data
[root@nfs ~]# mount /dev/sdb1 /data/
[root@nfs ~]# df -h|grep /data
/dev/sdb1 4.9T 33M 4.9T 1% /data