百萬PV網站架構

百萬PV網站架構

背景知識

網站架構通常人爲是根據客戶需求分析的結果,準肯定位網站目標人羣,設定網站的總體架構,規劃,設計網站欄目及其內容,指定網站開發流程順序,最大限度地進行高效資源分析與管理的設計。前端

PV(Page View,頁面訪問量)即點擊量,一般是衡量一個網絡新聞頻道或者網站甚至一條網絡新聞的主要指標。PV對於網站,就像收視率之餘電視,從某種程度上已經成爲投資者衡量商業網站表現的最重要尺度。java

對於PV的解釋就是一個訪問者在24小時內到底看了網站的幾個頁面。這裏須要注意的是,同一我的瀏覽網站的同一個頁面,不重複計算PV量,點100次也只能算1次。mysql

實驗概述

本案例設計纔有四層模型,主要分爲前端反向代理層,Web層,數據庫緩存層和數據庫層。前端代理層採用主備模式,Web層採用集羣模式,數據庫緩存層採用主備模式,數據庫採用主從模式。
百萬PV網站架構linux

實驗環境

因爲本人電腦配置的侷限,因此只在四臺虛擬機上演示,具體配置以下:
主機名
IP地址 系統版本 用途
master 192.168.58.140 CentOS 7 Nginx代理主機、redis緩存主機、MySQL數據主庫
backup 192.168.58.132 CentOS 7 Nginx代理備機、redis緩存備機、MySQL數據從庫
tomcat1 192.168.58.133 CentOS 7 Web服務
tomcat2 192.168.58.130 CentOS 7 Web服務

實驗部署

主從Nginx服務器上部署nginx和keepalived

經過安裝nginx源,而後直接使用yum倉庫安裝nginx和keepalived,其中keepalived主要是提供虛擬IP,實現nginx代理層的HA(High Available:高可用)。nginx

在192.168.58.140的主機上操做:
[root@localhost ~]# rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/\
> nginx-release-centos-7-0.el7.ngx.noarch.rpm
#安裝epel源
[root@localhost ~]# yum install -y keepalived nginx
#安裝nginx和keepalived
[root@localhost ~]# vim /etc/keepalived/keepalived.conf 
#修改keepalived配置文件,配置以下圖

百萬PV網站架構

下面去建立/opt/shell/nginx.sh這個腳本文件web

[root@localhost ~]# mkdir /opt/shell
[root@localhost ~]# vim /opt/shell/nginx.sh

#!/bin/bash
k=`ps -ef | grep keepalived | grep -v grep | wc -l`
if [ $k -gt 0 ];then
        /bin/systemctl start nginx.service
else
/bin/systemctl stop nginx.service
fi
#這個腳本含義就是若是keepalived已經啓動,那麼每兩秒鐘檢查並啓動一次nginx服務
[root@localhost ~]# chmod +x /opt/shell/nginx.sh 
[root@localhost ~]# systemctl start keepalived.service 
#在主服務器上啓動keepalived服務

百萬PV網站架構
百萬PV網站架構
百萬PV網站架構
在從服務器上操做redis

[root@localhost ~]# rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/\
> nginx-release-centos-7-0.el7.ngx.noarch.rpm
#安裝epel源
[root@localhost ~]# yum install -y keepalived nginx
#安裝nginx和keepalived
[root@localhost ~]# scp 192.168.58.140:/etc/keepalived/keepalived.conf /etc/keepalived/
#將主服務器上的keepalived配置文件複製到本機上,而後進行修改
[root@localhost ~]# mkdir /opt/shell/
[root@localhost ~]# scp 192.168.58.40:/opt/shell/nginx.sh /opt/shell/
#將主服務上nginx腳本複製到本機上,兩個腳本都同樣,功能也同樣
[root@localhost ~]# systemctl start keepalived.service 
#在從服務器上啓動keepalived服務

百萬PV網站架構
百萬PV網站架構
百萬PV網站架構
測試,訪問192.168.58.188,能夠看到下圖,訪問到的是主服務器sql

[root@localhost ~]# systemctl stop keepalived.service    #將主服務器的keepalived關閉

百萬PV網站架構
百萬PV網站架構

部署Web主從服務器

首先在web主從服務器上安裝tomcat服務器。下列步驟在兩臺web服務器上都要執行,因爲tomcat是基於java開發的,因此要搭建java環境shell

[root@localhost ~]# tar xf apache-tomcat-8.5.23.tar.gz
#解壓tomcat到當前目錄
[root@localhost ~]# tar xf jdk-8u144-linux-x64.tar.gz
#解壓jdk到當前目錄
[root@localhost ~]# cp -r jdk1.8.0_144/ /usr/local/java
#將jdk包複製到指定目錄中並更名爲java
vim /etc/profile
#修改系統環境變量文件,在最後一行加入下面幾句,目的是讓系統可以識別java

export JAVA_HOME=/usr/local/java
export JRE_HOME=/usr/local/java/jre
export PATH=$PATH:/usr/local/java/bin
export CLASSPATH=./:/usr/local/java/lib:/usr/local/java/jre/lib

[root@localhost ~]# source /etc/profile
#使/etc/profile文件刷新生效

[root@localhost ~]# java -version #驗證可以識別java命令
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

[root@localhost ~]# cp -r apache-tomcat-8.5.23 /usr/local/tomcat8
#將tomcat複製到指定目錄中,並重命名爲tomcat8
[root@localhost ~]# ln -s /usr/local/tomcat8/bin/startup.sh /usr/bin/tomcatup
#將tomcat開啓命令創建軟連接並重命名爲到/usr/bin/tomcatup
[root@localhost ~]# ln -s /usr/local/tomcat8/bin/shutdown.sh /usr/bin/tomcatdown
#將tomcat關閉命令創建軟連接並重命名爲到/usr/bin/tomcatdown

下面返回nginx主從代理服務器中配置upstream模塊。數據庫

[root@localhost ~]# vim /etc/nginx/nginx.conf
.....省略
#gzip  on;
 upstream tomcat_pool {
                server 192.168.58.133:8080 weight=1;  #配置web服務器池,並啓用輪詢
                server 192.168.58.130:8080 weight=1;
                ip_hash;           
        }       
        server {
                listen 80;
                server_name 192.168.58.188;   #配置主機名,爲虛擬IP 
                location / {
                        proxy_pass http://tomcat_pool;  #啓用反向代理功能
                        proxy_set_header X-Real-IP $remote_addr;
                }       
        }       
    include /etc/nginx/conf.d/*.conf;
}

重啓兩臺nginx代理服務器的nginx服務,這裏直接kill掉nginx進程,而後nginx又會從新開啓,這是由於有keepalived服務的存在,每兩秒會檢查並啓動nginx腳本,另外咱們修改兩臺tomcat服務器的主頁,從而驗證輪詢機制。

#主服務器
[root@localhost ~]# netstat -ntap | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      65181/nginx: master 
[root@localhost ~]# kill 65181
[root@localhost ~]# netstat -ntap | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      126988/nginx: maste 
#從服務器
[root@localhost ~]# netstat -ntap | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4012/nginx: master  
[root@localhost ~]# kill 4012
[root@localhost ~]# netstat -ntap | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      74342/nginx: master 

[root@localhost ~]# cat /usr/local/tomcat8/webapps/ROOT/index.jsp 
<h1>server 133!!</h1>
[root@localhost ~]# tomcatup
#啓動tomcat

[root@localhost ~]# cat /usr/local/tomcat8/webapps/ROOT/index.jsp 
<h1>server 130!!</h1>

以上步驟tomcat中都須要作,惟一不一樣的就是首頁內容不同。效果以下,每刷新一次,分別訪問兩臺tomcat服務器。
百萬PV網站架構
(實驗結果並不能輪詢,只有在其中一臺tomcat服務器down了後,纔會去訪問兩外一臺tomcat,等待大佬解決。)
百萬PV網站架構

部署MySQL服務器

這裏使用的是mariadb數據庫,這個數據庫是centos7中自帶的,在兩臺mysql服務器上都要執行下面的操做

[root@localhost ~]# rpm -q mariadb
mariadb-5.5.56-2.el7.x86_64
[root@localhost ~]# systemctl start mariadb.service
#開啓mariadb數據庫服務
[root@localhost ~]# netstat -anpt | grep 3306
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      28092/mysqld  
[root@localhost ~]# mysql_secure_installation    #常規安全設置,會出現下列選項
Enter current password for root (enter for none):    #輸入當前root密碼,默認爲空
Set root password? [Y/n]                             #是否輸入密碼 Y
New password:                                        #設置密碼爲abc123
Re-enter new password:                               #從新輸入密碼
Password updated successfully!
Reloading privilege tables..
 ... Success!
Remove anonymous users? [Y/n]                        #移除匿名用戶
Disallow root login remotely? [Y/n]                  #不容許遠程登陸,選擇n
Remove test database and access to it? [Y/n]         #移除test數據庫而且訪問它
Reload privilege tables now? [Y/n]                   #如今從新加載權限表 Y
Thanks for using MariaDB!                            #設置成功

導入實驗網站的數據庫sql文件

[root@localhost mnt]# mysql -u root -p  < slsaledb-2014-4-10.sql
Enter password:

將用於實驗的一個網上商場的源碼解壓到兩臺tomcat服務器的指定目錄中

[root@localhost ~]# tar xf SLSaleSystem.tar.gz -C /usr/local/tomcat8/webapps/
[root@localhost mnt]# vim /usr/local/tomcat8/webapps/SLSaleSystem/WEB-INF/classes/applicationContext-mybatis.xml

修改tomcat中用於鏈接數據庫的文件中的帳號和密碼

[root@localhost ~]# cd /usr/local/tomcat8/webapps/SLSaleSystem/WEB-INF/classes
[root@localhost classes]# vim jdbc.properties 
driverClassName=com.mysql.jdbc.Driver
url=jdbc\:mysql\://192.168.58.188\:3306/slsaledb?useUnicode\=true&characterEncoding\=UTF-8      
#虛擬IP
uname=root
#用戶名
password=abc123
#密碼
minIdle=10
maxIdle=50
initialSize=5
maxActive=100
maxWait=100
removeAbandonedTimeout=180
removeAbandoned=true

百萬PV網站架構
到數據庫中給上面的訪問用戶受權

[root@localhost mnt]# mysql -u root -p
Enter password: 
MariaDB [(none)]> GRANT all ON slsaledb.* TO 'root'@'%' IDENTIFIED BY 'abc123';
Query OK, 0 rows affected (0.04 sec)

MariaDB [(none)]> flush privileges; 
Query OK, 0 rows affected (0.00 sec)

網站測試,訪問http://192.168.58.133:8080、http://192.168.58.130:8080、http://192.168.58.188測試是否都能訪問,用戶名爲root,密碼爲abc123,測試成功
百萬PV網站架構

部署redis主從緩存服務器

Redis是一個key-value存儲系統。和Memcached相似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操做,並且這些操做都是原子性的。在此基礎上,redis支持各類不一樣方式的排序。與memcached同樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操做寫入追加的記錄文件,而且在此基礎上實現了master-slave(主從)同步。

Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案,當用Redis作Master-slave的高可用方案時,假如master宕機了,Redis自己(包括它的不少客戶端)都沒有實現自動進行主備切換,而Redis-sentinel自己也是一個獨立運行的進程,它能監控多個master-slave集羣,發現master宕機後能進行自動切換.

主從服務器都先安裝redis軟件包
[root@localhost ~]# yum install -y epel-release
[root@localhost ~]# yum install redis -y
[root@localhost ~]# vim /etc/redis.conf

bind 127.0.0.1  
#默認的bind 接口是127.0.0.1,也就是本地迴環地址。這樣的話,訪問redis服務只能經過本機的客戶端鏈接,這裏須要修改成
bind 0.0.0.0

[root@localhost ~]# systemctl start redis.service  #啓動服務
[root@localhost ~]# netstat -anpt | grep 6379      #查看對應端口已經打開
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      6495/redis-server 0 

[root@localhost ~]# redis-cli -h 192.168.58.140 -p 6379   #測試鏈接
192.168.58.140:6379> set name test                        #建立數據
OK
192.168.58.140:6379> get name
"test"

在從服務器中的/etc/redis.conf文件要多修改一個配置

[root@localhost ~]# vim /etc/redis.conf 
slaveof 192.168.58.140 6379
#指定主redis服務器的ip及端口,重啓服務

配置tomcat訪問目錄

<bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy" >
                <constructor-arg ref="jedisPoolConfig"/>
                <constructor-arg value="192.168.58.188"/>
                <constructor-arg value="6379"/>
            </bean>

百萬PV網站架構
如下測試緩存效果

[root@localhost mnt]# redis-cli -h 192.168.58.188 -p 6379
keyspace_hits:5                     #訪問緩存命中率,說明web都是從redis中取數據,並無直接鏈接數據庫
keyspace_misses:0

配置redis集羣主從切換,只在主服務器是操做

[root@localhost mnt]# redis-cli -h  192.168.58.140 info Replication
#獲取當前服務器的角色
# Replication
role:master                          #沒有設置主從,因此兩臺都是master
connected_slaves:0
master_repl_offset:5279
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:5278

百萬PV網站架構

[root@localhost mnt]# vim /etc/redis-sentinel.conf #設置sentinel進程配置文件
protected-mode no
sentinel monitor mymaster 192.168.58.140 6379 1    #1表示1臺從服務器,改成主服務器IP
sentinel down-after-milliseconds mymaster 30000    #3000毫秒內一直返回無效回覆纔會被 Sentinel 標記爲主觀下線
[root@localhost mnt]# service redis-sentinel start
#啓動sentinel模式
[root@localhost mnt]# netstat -anpt | grep 26379
tcp        0      0 0.0.0.0:26379           0.0.0.0:*               LISTEN      36677/redis-sentine 
[root@localhost mnt]# redis-cli -h 192.168.58.140 -p 26379 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.58.140:6379,slaves=0,sentinels=1
#目前主服務器爲192.168.58.140

驗證主從切換

[root@localhost mnt]# redis-cli -h 192.168.58.140 -p 26379 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.58.140:6379,slaves=1,sentinels=1
#這時候也192.168.58.140是主服務器
[root@localhost mnt]# service redis stop
#中止主服務器的redis服務
[root@localhost mnt]# redis-cli -h 192.168.58.140 -p 26379 info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.58.132:6379,slaves=1,sentinels=1
#能夠看到這時候主服務器的ip爲192.168.58.132,這裏一旦主服務器切換後,原來的master再恢復後,也不會切換了,直到192.168.58.132宕機,纔會再進行切換

驗證主從同步

[root@localhost mnt]# redis-cli -h 192.168.58.132 -p 6379
192.168.58.132:6379> set user yx
OK
192.168.58.132:6379> get user
"yx"

[root@localhost mnt]# redis-cli -h 192.168.58.140 -p 6379
192.168.58.140:6379> get user
"yx"
#能夠看到同步成功

部署數據庫主從同步

修改主服務器配置文件

[root@localhost mnt]# vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
binlog-ignore-db=mysql,information_schema
character_set_server=utf8
log_bin=mysql_bin
server_id=1
log_slave_updates=true
sync_binlog=1  

[root@localhost mnt]# systemctl restart mariadb.service
[root@localhost mnt]# mysql -u root -p
Enter password: 
MariaDB [(none)]> grant replication slave on *.* to 'rep'@'192.168.58.%' identified by '123456';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> show master status;
+------------------+----------+--------------+--------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB         |
+------------------+----------+--------------+--------------------------+
| mysql_bin.000001 |      472 |              | mysql,information_schema |
+------------------+----------+--------------+--------------------------+
1 row in set (0.00 sec)

在從服務器上配置

[root@localhost mnt]# vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
server_id=2         #server_id主從不能同樣
[root@localhost mnt]# systemctl restart mariadb.service
MariaDB [(none)]> change master to master_host='192.168.58.140',master_user='rep',master_password='123456',master_log_file='mysql_bin.000001',master_log_pos=245;
#給rep用戶授予同步權限
MariaDB [(none)]> start slave;
MariaDB [(none)]> show slave status\G;
....省略
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

百萬PV網站架構
如下圖片說明網站能正常訪問
百萬PV網站架構
百萬PV網站架構

相關文章
相關標籤/搜索