百萬PV架構詳解

百萬PV架構

●先了解一下什麼是PV
PV(page view)即頁面瀏覽量,通常是衡量一個網絡新聞頻道或網站甚至一條網絡新聞的主要指標。網頁瀏覽數是評價網站流量最常用的指標之一,簡稱爲PV。監測網站PV的變化趨勢和分析其變化原因是很多站長定期要做的工作。 Page Views中的Page一般是指普通的html網頁,也包含php、jsp等動態產生的html內容。來自瀏覽器的一次html內容請求會被看作一個PV,逐漸累計成爲PV總數。

●環境及組件介紹

操作系統 IP地址 角色 web組件
Centos7 192.168.70 .136 主服務器 keepalived、nginx、mysql、redis
Centos7 192.168.70.137 從服務器 keepalived、nginx、mysql、redis
Centos7 192.168.70 .134 web後端1 tomcat、項目
Centos7 192.168.70 .132 web後端2 tomcat、項目

●使用的軟件包
nginx1.8.1:http://101.96.10.46/nginx.org/download/nginx-1.8.1.tar.gz
web服務包:https://pan.baidu.com/s/143ZRkqfUxJJIBzO_yz7gPg
密碼:wsgd
mysql解壓版https://pan.baidu.com/s/11b_ccrosT0IPdnXhRrU4yQ
密碼:ruh5

一、主從服務器配置keepalived

1、安裝

[root@localhost ~]# yum install keepalived -y

2、修改keepalive配置文件

[root@localhost ~]# vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
     notification_email {
         [email protected]
         [email protected]
         [email protected]
     }
     notification_email_from [email protected]
     smtp_server 192.168.70.131      #指向本機
     smtp_connect_timeout 30
     router_id NGINX_01                   #備機爲NGINX_02
}

vrrp_instance VI_1 {
        state MASTER                        #備機爲BACKUP
        interface ens33                       #網卡名稱
        virtual_router_id 51                #備機52,不與主相同
        priority 100                               #優先級,備機優先級要低於主機
        advert_int 1
        authentication {
                auth_type PASS
                auth_pass 1111
        }
        virtual_ipaddress {
                192.168.70.100                #虛擬Ip地址
        }
}

==========以下是配置keepalive的順帶着啓動nginx===========
個人看法,不太希望這樣做,因爲每兩秒嘗試啓動nginx,nginx會兩秒打一次error日誌,提示端口被佔用無法啓動,這樣反而造成了不必要的磁盤讀寫。

 Configuration File for keepalived

#定義NGINX啓動腳本位置,每兩秒檢查一次
vrrp_script nginx {
                script "/opt/shell/nginx.sh"
                interval 2
}

#刪除原本內容,添加route_id,備機爲NGINX_02
global_defs {
                route_id NGINX_01
}

vrrp_instance VI_1 {
        state MASTER    #主機爲MASTER
        interface ens33 #網卡名稱
        virtual_router_id 51    #備機爲52
        priority 100             #優先級,備機爲99
        advert_int 1
        authentication {
                auth_type PASS
                auth_pass 1111
        }
#觸發腳本
track_script {
                nginx
}

#虛擬IP
        virtual_ipaddress {
                192.168.70.100
        }
}

3、啓動keepalived

[root@localhost ~]# systemctl start keepalived.service

4、查看虛擬ip

[root@localhost ~]# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:5b:aa:ce brd ff:ff:ff:ff:ff:ff
    inet 192.168.70.131/24 brd 192.168.70.255 scope global dynamic ens33
       valid_lft 1403sec preferred_lft 1403sec
    inet 192.168.70.100/32 scope global ens33         #虛擬ip
       valid_lft forever preferred_lft forever
    inet6 fe80::49c4:1329:39cd:4427/64 scope link 
       valid_lft forever preferred_lft forever

注:備機也要啓動keepalived,然後關閉主機keepalived,看虛擬Ip會不會漂移到備機。

二、安裝nginx

上傳nginx安裝包至/opt目錄下
1、安裝環境包

[root@localhost opt]# yum -y install gcc gcc-c++ autoconf gd-devel automake zlib zlib-devel openssl openssl-devel pcre*

2、解壓,編譯nginx

[root@localhost opt]# tar zxf nginx-1.8.1.tar.gz
[root@localhost opt]# cd nginx-1.8.1/
[root@localhost nginx-1.8.1]# ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-http_image_filter_module \
--with-http_stub_status_modulev

3、安裝

[root@localhost nginx-1.8.1]# make && make install

4、創建nginx用戶

[root@localhost nginx-1.8.1]# useradd -M -s /sbin/nologin nginx

5、優化命令路徑

[root@localhost nginx-1.8.1]# ln -s /usr/local/nginx/sbin/nginx /usr/sbin/

6、添加代理並簡單優化

[root@localhost nginx-1.8.1]# cd /usr/local/nginx/conf/
[root@localhost conf]# vim nginx.conf

#用戶nginx,單核
user  nginx;
worker_processes  1;

#每個核心連接數2048
events {
    worker_connections  2048;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

#隱藏版本號
    server_tokens off;

#sendfile參數用於開啓文件的高效傳輸模式。
    sendfile   on;
    tcp_nopush on;
    tcp_nodelay on;
    server_names_hash_bucket_size 128;
    server_names_hash_max_size 512;
    client_header_timeout 15s;
    client_body_timeout 15s;
    send_timeout 60s;

   keepalive_timeout  65;
#壓縮模塊
    gzip  on;
    gzip_buffers  4 64k;
    gzip_http_version 1.1;
    gzip_comp_level 2;
    gzip_min_length 1k;
    gzip_vary on;
    gzip_types text/plain text/javascript application/x-javascript text/css text/xml application/xml applicatin/xml+rss;

#反向代理
    upstream tomcat_pool {
                server 192.168.70.134:8080;
                server 192.168.70.132:8080;
                ip_hash;        #會話穩固,防止停留頁面過久導致需要重新登錄。
        }
        server {
                listen 80;
                server_name 192.168.70.100;     #虛擬Ip
                location / {
                        proxy_pass http://tomcat_pool;
                        proxy_set_header X-Real-IP $remote_addr;
                        expires 1d;
                }
        }

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

}

7、檢查配置文件語法

[root@localhost conf]# nginx -t

nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

8、啓動nginx

[root@localhost conf]# nginx

三、安裝tomcat

上傳jdk和tomcat到/opt目錄下
1、解壓jdk和tomcat

[root@localhost opt]# tar zxf jdk-8u144-linux-x64.tar.gz
[root@localhost opt]# tar zxf apache-tomcat-8.5.23.tar.gz

2、更名jdk爲java

[root@localhost opt]# mv jdk1.8.0_144/ java

3、添加環境變量

[root@localhost opt]# vim ~/.bashrc

#末行添加如下三行
export JAVA_HOME=/opt/java
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin

4、刷新環境變量,查看java版本

[root@localhost opt]# source ~/.bashrc
[root@localhost opt]# java -version

java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

5、更名tomcat爲tomcat8

[root@localhost opt]# mv apache-tomcat-8.5.23 tomcat8

6、修改默認首頁進行測試,兩臺tomcat都需要操作

[root@localhost opt]# cd tomcat8/webapps/ROOT/
[root@localhost ROOT]# vim index.jsp

#刪除原有的內容,添加如下本機ip,用於測試
#134主機添加如下
<h1> this is 134 server <h1>
#132主機添加如下
<h1> this is 132 server <h1>

7、建立命令軟鏈接,啓動tomcat

[root@localhost ROOT]# ln -s /opt/tomcat8/bin/startup.sh /usr/bin/tomcatup
[root@localhost ROOT]# ln -s /opt/tomcat8/bin/shutdown.sh /usr/bin/tomcatdown
[root@localhost ROOT]# tomcatup #啓動tomcat

Using CATALINA_BASE:   /opt/tomcat8
Using CATALINA_HOME:   /opt/tomcat8
Using CATALINA_TMPDIR: /opt/tomcat8/temp
Using JRE_HOME:        /opt/java
Using CLASSPATH:       /opt/tomcat8/bin/bootstrap.jar:/opt/tomcat8/bin/tomcat-juli.jar
Tomcat started.

8、web網頁用虛擬ip訪問

192.168.70.100
顯示後臺我們設置的tomcat頁面即可,然後關閉一臺tomcat看頁面會不會變

百萬PV架構詳解
百萬PV架構詳解

四、mysql主從複製

上傳mysql壓縮包到/opt目錄下
1、解壓mysql

[root@localhost opt]# tar zxf mysql-5.7.21-linux-glibc2.12-x86_64.tgz
[root@localhost opt]# mv mysql-5.7.21-linux-glibc2.12-x86_64 mysql

2、修改配置文件

[root@localhost opt]# vim /etc/my.cnf

[client]
port = 3306
socket = /tmp/mysql.sock

[mysqld]
character-set-server = utf8mb4
skip_name_resolve = 1
user = mysql
port = 3306
server-id = 1           #注意,備機的mysql,server-id不能與主機相同
socket = /tmp/mysql.sock
basedir = /opt/mysql/
datadir = /opt/mysql/data
pid-file = /opt/mysql/data/mysql.pid
log_bin=/opt/mysql/data/mysql-bin
log-error = /opt/mysql/data/log-error.log
innodb_data_home_dir = /opt/mysql/data
slow-query-log-file=/opt/mysql/data/slow.log
relay-log-index = /opt/mysql/data/relaylog
relay-log-info-file = /opt/mysql/data/relaylog
relay-log = /opt/mysql/data/relaylog
open_files_limit = 10240
table_open_cache = 2048
back_log = 300
max_connections = 10000
max_connect_errors = 20
explicit_defaults_for_timestamp = 1
max_allowed_packet = 64M
thread_cache_size = 300
query_cache_size = 256M
query_cache_limit = 2M
query_cache_min_res_unit = 2k
default-storage-engine = InnoDB
thread_stack = 512K
transaction_isolation = READ-COMMITTED
tmp_table_size = 256M
max_heap_table_size = 256M
key_buffer_size = 2G
sort_buffer_size = 2M
join_buffer_size = 6M
read_buffer_size = 4M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 15G
myisam_repair_threads = 1
interactive_timeout = 1800
wait_timeout = 28800
innodb_data_file_path = ibdata1:120M;ibdata2:200M;ibdata3:200M:autoextend
innodb_buffer_pool_size = 1G
innodb_thread_concurrency = 0
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M
innodb_log_file_size = 512M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_purge_threads = 0
slow_query_log = 1
long_query_time = 3
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-ignore-db = information_schema
#slave-skip-errors = 1032,1062,1026,1114,1146,1048,1396

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
[mysqldump]
quick
max_allowed_packet = 64M

3、初始化mysql,設置密碼

[root@localhost opt]# ln -s /opt/mysql/bin/* /usr/bin/
[root@localhost opt]# mysql/bin/mysqld --initialize-insecure #初始化
[root@localhost opt]# mysqld_safe & #啓動
[root@localhost opt]# mysqladmin -uroot password #設置密碼
[root@localhost opt]# mysql -uroot -p #登陸查看

4、設置mysql主從複製

#以下在主庫上操作
mysql> grant replication slave on *.* to 'replication'@'192.168.70.%' identified by '123123' with grant  option;     #授權replication用戶權限

mysql> flush privileges;           #刷新權限

mysql> show master status;   #查看二進制日誌位置
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      885 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

#以下在從庫上操作
mysql>  change master to master_host='192.168.70.136',master_user='replication',master_password='123123',,master_log_file='mysql-bin.000002',master_log_pos=885;

mysql> start slave;

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.70.136
                                    ..........................
            Slave_IO_Running: Yes          #要看到這兩項爲yes,主從複製成
            Slave_SQL_Running: Yes

5、主庫導入sql語句

[root@localhost opt]# mysql -uroot -p < slsaledb-2014-4-10.sql

6、項目的mysql用戶授權

mysql> grant all on . to 'root'@'%' identified by '123123';
mysql> flush privileges;

五、redis緩存服務器配置

1、下載epel源和redis

[root@localhost opt]# yum install -y epel-release
[root@localhost opt]# yum install redis -y

2、修改配置文件

[root@localhost opt]# vim /etc/redis.conf

主從服務器
  61行 bind 0.0.0.0
從服務器添加
266行 slaveof 192.169.70.136 6379

3、主從服務器啓動redis

[root@localhost opt]# systemctl start redis

4、驗證主從功能

[root@localhost opt]# redis-cli -h 192.168.70.136 -p 6379

#主服務器寫入
192.168.70.136:6379> set name lisi
OK
192.168.70.136:6379> get name 
"lisi"
#從服務器
192.168.70.137:6379> get name     #能獲取值說明主從同步成功
"lisi"

5、搭建主從切換
注:主服務器上操作

[root@localhost opt]# vim /etc/redis-sentinel.conf

protected-mode no#是否開啓保護模式
sentinel monitor mymaster 192.168.70.137 6379 1 #1表示1臺從
sentinel down-after-milliseconds mymaster 3000  #切換時間爲3000毫秒

#主從都啓動羣集
[root@localhost opt]# systemctl start redis-sentinel.service

#查看羣集狀態

[root@localhost opt]# redis-cli -h 192.168.70.136 -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   #可以看到下面行有從137
master0:name=mymaster,status=odown,address=192.168.70.137:6379,slaves=0,sentinels=2

六、部署項目

#兩臺tomcat主機上操作
1、上傳項目包,解壓縮到指定目錄

[root@localhost opt]# tar zxf SLSaleSystem.tar.gz -C /opt/tomcat8/webapps/

2、修改tomcat配置文件,確定項目位置

[root@localhost opt]# cd /opt/tomcat8/conf/
[root@localhost conf]# vim server.xml

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        #接近尾行位置添加如下
<Context path="" docBase="SLSaleSystem" reloadable="true" debug="0"></Context>

3、修改項目文件,指定連接數據庫和redis緩存服務

[root@localhost conf]# cd /opt/tomcat8/webapps/SLSaleSystem/WEB-INF/classes/

#修改爲虛擬ip
url=jdbc\:mysql\://192.168.70.100\:3306/slsaledb?useUnicode\=true&characterEncoding\=UTF-8
#數據庫授權的用戶
uname=root
#密碼
password=123123

#修改redis緩存服務器ip地址

[root@localhost classes]# vim applicationContext-mybatis.xml

    <!--redis 配置 開始-->
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property  name="maxActive"  value="90" />
            <property  name="maxIdle"   value="5" />
            <property  name="maxWait"  value="1000" />
            <property  name="testOnBorrow"  value="true" />
        </bean>
        <bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy" >
            <constructor-arg ref="jedisPoolConfig"/>
            <constructor-arg value="192.168.70.100"/>      #虛擬ip
            <constructor-arg value="6379"/>
        </bean>
        <bean id="redisAPI" class="org.slsale.common.RedisAPI">
            <property name="jedisPool" ref="jedisPool"/>
        </bean>

4、配置完重新啓動tomcat

[root@localhost classes]# tomcatdown
[root@localhost classes]# tomcatup

5、網頁中訪問
192.168.70.100
#默認賬號admin
#默認密碼123456
百萬PV架構詳解
百萬PV架構詳解

6、查看redis緩存服務

[root@localhost opt]# redis-cli -h 192.168.70.136 -p 6379

192.168.70.136:6379> info
keyspace_hits:2    #找到這兩行,這個是命中次數
keyspace_misses:0

注:點擊進網頁內容出現感嘆屬於正常,緩存服務器需要一段時間緩存內容。
redis緩存服務器主從切換的問題,主宕機,從會頂替上來,但再次啓動主的時候,從不會讓出當前master的角色,除非手動切換,或從宕機。
這個項目是很久很久的一個項目,拿來學習理解下百萬pv架構還行,學習爲主,另外想要達到百萬pv,硬件性能是必不可少的,軟件層面上的優化也是必須的。
本文主要介紹百萬pv的架構及其中一些服務之間的關係,謹以介紹學習,實際操作以自己公司環境爲主。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章