搭建一个常规的大流量网站

2018-12-02  本文已影响0人  AnnaJIAN

client-nginx-3apache
1,mysql(1主2从),2,redis(1主2从)

本人的工作环境:Mac一台,里面安装虚拟机ubuntu,在ubuntu上安装docker,准备用docker安装所有的集群环境。虚拟机ubuntu IP 192.168.33.12

vagrant@dragon:/vagrant$ docker images
REPOSITORY          TAG                    IMAGE ID            CREATED             SIZE
ubuntu18            nginx114               712b30d0ad70        34 seconds ago      224MB
ubuntu18            nginx114php72mysql57   7f183e09be60        40 minutes ago      687MB
ubuntu18            apache24php72          15f84056ba6f        8 days ago          275MB
ubuntu              latest                 93fd78260bd1        11 days ago         86.2MB
mysql               latest                 f991c20cb508        2 weeks ago         486MB
centos              latest                 75835a67d134        7 weeks ago         200MB
以nginx作为服务器负载均衡,分发到3台apache。

本地已经有了一个ubuntu18+nginx1.14镜像,和一个ubuntu18+apache2.4+php7.2镜像

#开启ubuntu18+nginx1.14容器,映射到主机80端口
vagrant@dragon:~$ docker run -itd -p 80:80 --name=nginx 15f84056ba6f
#开启ubuntu18+apache2.4+php7.2容器,映射到主机81端口
vagrant@dragon:~$ docker run -itd -p 81:80 --name=apache1 15f84056ba6f
#开启ubuntu18+apache2.4+php7.2容器,映射到主机82端口 
vagrant@dragon:~$ docker run -itd -p 82:80 --name=apache2 15f84056ba6f
#开启ubuntu18+apache2.4+php7.2容器,映射到主机83端口
vagrant@dragon:~$ docker run -itd -p 83:80 --name=apache3 15f84056ba6f
vagrant@dragon:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
ed245060bd62        15f84056ba6f        "/bin/bash"         3 seconds ago       Up 2 seconds        0.0.0.0:83->80/tcp   apache3
f58fecbc3fdc        15f84056ba6f        "/bin/bash"         10 seconds ago      Up 9 seconds        0.0.0.0:82->80/tcp   apache2
37a2f561cb28        15f84056ba6f        "/bin/bash"         20 seconds ago      Up 19 seconds       0.0.0.0:81->80/tcp   apache1
6f7d1f4203ec        712b30d0ad70        "/bin/bash"         2 minutes ago       Up 2 minutes        0.0.0.0:80->80/tcp   nginx

通过浏览器192.168.33.12:端口号检查机器都能正常访问

在nginx.conf中添加配置
http {
    server {
        listen 80;

        location / {
            proxy_pass http://apache_services;
            proxy_redirect default;
        }
    }
    
    #负载均衡,按权重,服务器分发流量
    upstream  apache_services {
        server    192.168.33.12:81  weight=1;
        server    192.168.33.12:82  weight=2;
        server    192.168.33.12:83  weight=3;
    }
}

重启服务器,访问192.168.33.12:80

Bad Request
Your browser sent a request that this server could not understand.
Additionally, a 400 Bad Request error was encountered while trying to use an ErrorDocument to handle the request.

Apache/2.4.29 (Ubuntu) Server at 172.17.0.4 Port 80

可能是数据包信息不全吧,百度了一下。加上协议头,就可以正常访问各台服务器的首页了。

proxy_set_header   Host  $http_host;
proxy_set_header   X-Real-IP   $remote_addr;
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

但是访问其他服务器下的子目录是无法成功的。分发的服务器上面没有需要访问的目录。需要将请求跳转到后端。
修改配置,完整的配置如下:

http {
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.php index.html index.htm index.nginx-debian.html;
        server_name 192.168.33.12;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ @apache_services;
        }

        location @apache_services {
                proxy_pass http://apache_services;
                proxy_set_header   Host  $http_host;
                proxy_set_header   X-Real-IP   $remote_addr;
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
                proxy_intercept_errors on;
                recursive_error_pages on;
        }
    }
    upstream  apache_services {
        server    192.168.33.12:81  weight=1;
        server    192.168.33.12:82  weight=2;
        server    192.168.33.12:83  weight=3;
    }
}

可以尝试其他的分发模式,暂时使用权重的模式。

安装mysql,一主两从。

本地已经有了一个mysql8镜像。创建一个mysql-master的容器,把3308暴露给宿主机,登录mysql-master,在里面创建一个shop的数据库。创建一个user表,随便插入几条数据用于测试。

vagrant@dragon:~$ docker run -it -p 3308:3306 -e MYSQL\_ROOT\_PASSWORD=anna --name=mysql-master -d mysql
eaf146a35f87fa4c51e21fc5c9b8772ffe09dca2c748b7210def7b36ece3d00e
vagrant@dragon:~$ mysql -P3308 -uroot -panna -h192.168.33.12
mysql> create database shop;
Query OK, 1 row affected (0.09 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| shop               |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

在apache容器中安装mysql-client,然后测试。
从容器apache1,apache2,apache3,都可以登陆mysql-master 容器。

root@f58fecbc3fdc:/var/www/html# mysql -uroot -panna -h192.168.33.12 -P3308

添加测试代码

$mysqli = new mysqli("192.168.33.12", "root", "anna", "shop", "3308");
if(!$mysqli)  {
    echo "连接失败!";
}else{
        echo "连接成功!<br/>";
        if ($rows = mysqli_query($mysqli, "SELECT name FROM users LIMIT 10")) {
                printf("Select returned %d rows.<br>", mysqli_num_rows($rows));

                while($row = mysqli_fetch_assoc($rows)){
                        $name = $row['name'];
                        echo $name . "<br/>";
                }
                /* free result set */
                mysqli_free_result($result);
        }
}

起初报错, 找不到mysqli

root@f58fecbc3fdc:/var/www/html# tail -f /var/log/apache2/error.log
PHP Warning:  PHP Startup: Unable to load dynamic library 'mysqli' (tried: /usr/lib/php/20170718/mysqli (/usr/lib/php/20170718/mysqli: cannot open shared object file: No such file or directory), /usr/lib/php/20170718/mysqli.so (/usr/lib/php/20170718/mysqli.so: undefined symbol: mysqlnd_global_stats)) in Unknown on line 0

打开php.ini, 修改配置,重启apache就好了。浏览器可以打印出测试代码结果,lamp算是连通了。

root@f58fecbc3fdc:/var/www/html# vi /etc/php/7.2/apache2/php.ini
#去掉;分号
extension=mysqli

保存镜像文件,然后开始下一步。

把mysql 容器中的data文件夹挂载到主机中,以免丢失数据。

创建几个文件夹。

vagrant@dragon:~$ mkdirdocker-mysql-data-volumn
vagrant@dragon:~/docker-mysql-data-volumn$ ls
mysql-master  mysql-slave1  mysql-slave2
vagrant@dragon:~/docker-mysql-data-volumn/mysql-master$ ls
conf  data  logs
#停止master,
vagrant@dragon:~$ docker stop mysql-master
mysql-master
#挂载数据卷启动mysql-master,把容器中的文件映射到相应的主机文件中。
vagrant@dragon:~$ docker run --name mysql-master -p 3308:3306 -v 
/docker-mysql-data-volumn/mysql-master/data:/var/lib/mysql -v 
/docker-mysql-data-volumn/mysql-master/conf:/etc/mysql/conf.d -e 
MYSQL_ROOT_PASSWORD=anna -d mysql:latest
#再次查看主机中的文件夹,多了很多文件,能在里面找到shop数据库和user.ibd表,说明映射成功了
vagrant@dragon:~/docker-mysql-data-volumn/mysql-master/data$ ls
#innodb_temp   binlog.000002  ca.pem           ib_buffer_pool  ibdata1  mysql.ibd           public_key.pem   shop      undo_002
auto.cnf       binlog.index   client-cert.pem  ib_logfile0     ibtmp1   performance_schema  server-cert.pem  sys
binlog.000001  ca-key.pem     client-key.pem   ib_logfile1     mysql    private_key.pem     server-key.pem   undo_001
#创建的数据库和表都在
root@dragon:~/docker-mysql-data-volumn/mysql-master/data/shop# ls
users.ibd

停止容器,再启动容器,访问浏览器测试页,能够返回数据库信息。说明停止容器不会丢失数据。

vagrant@dragon:~$ docker stop mysql-master
vagrant@dragon:~$ docker start mysql-master

再测试删除容器,创建新的mysql容器,把主机中数据卷再挂进去,访问测试页,能够返回数据库信息。说明挂载数据方式正确。登陆新创建的mysql容器,也能找到原来的数据库和表。

vagrant@dragon:~$ docker run --name mysql-master -p 3308:3306 -v 
~/docker-mysql-data-volumn/mysql-master/data:/var/lib/mysql -v
~/docker-mysql-data-volumn/mysql-master/conf:/etc/mysql/conf.d -e 
MYSQL_ROOT_PASSWORD=anna -d mysql:latest
vagrant@dragon:~$ docker exec -it mysql-master /bin/bash
root@6ed7044fb592:/var/lib/mysql# ls
#innodb_temp   binlog.000003  binlog.000007  client-cert.pem  ib_logfile1  mysql.ibd           server-cert.pem  undo_001
auto.cnf       binlog.000004  binlog.index   client-key.pem   ibdata1      performance_schema  server-key.pem   undo_002
binlog.000001  binlog.000005  ca-key.pem     ib_buffer_pool   ibtmp1       private_key.pem     shop
binlog.000002  binlog.000006  ca.pem         ib_logfile0      mysql    public_key.pem      sys

挂载映射的路径是绝对路径,可以用docker inspect [容器ID], 查看映射位置。

"Mounts": [
    {
        "Type": "bind",
        "Source": "/docker-mysql-data-volumn/mysql-master/data",
        "Destination": "/var/lib/mysql",

Mysql映射备份完成。开始下一步。

再开启2个mysql容器,作为mysql-slave,配置mysql-master 到mysql-slave 主从自动备份参数。
vagrant@dragon:~$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
4e6f46dce08b        mysql:latest        "docker-entrypoint..."   5 seconds ago       Up 5 seconds        33060/tcp, 0.0.0.0:3310->3306/tcp   mysql-slave2
53befd8865db        mysql:latest        "docker-entrypoint..."   40 seconds ago      Up 39 seconds       33060/tcp, 0.0.0.0:3309->3306/tcp   mysql-slave1
c06a9146d955        mysql               "docker-entrypoint..."   5 minutes ago       Up 5 minutes        33060/tcp, 0.0.0.0:3308->3306/tcp   mysql-master

在mysql-master中给mysql-slave1,mysql-slave2加权限。

vagrant@dragon:~$ mysql -uroot -panna -h192.168.33.12 -P 3308 -A shop;

搭建redis,和redis从数据库,使3个apache容器能和redis主通信。再配置redis主从备份。

批量写入大量数据,做负载均衡测试,缓存性能测试,数据库优化,索引测试。

Refers

nginx 作为负载均衡,反向代理
nginx 负载均衡配置各种参数
nginx try_files upstream配置
docker 挂载目录
mysql 主从搭建
Master与Slave配置

上一篇下一篇

猜你喜欢

热点阅读