百萬(wàn)PV架構(gòu)
●先了解一下什么是PV
PV(page view)即頁(yè)面瀏覽量,通常是衡量一個(gè)網(wǎng)絡(luò)新聞?lì)l道或網(wǎng)站甚至一條網(wǎng)絡(luò)新聞的主要指標(biāo)。網(wǎng)頁(yè)瀏覽數(shù)是評(píng)價(jià)網(wǎng)站流量最常用的指標(biāo)之一,簡(jiǎn)稱(chēng)為PV。監(jiān)測(cè)網(wǎng)站PV的變化趨勢(shì)和分析其變化原因是很多站長(zhǎng)定期要做的工作。 Page Views中的Page一般是指普通的html網(wǎng)頁(yè),也包含php、jsp等動(dòng)態(tài)產(chǎn)生的html內(nèi)容。來(lái)自瀏覽器的一次html內(nèi)容請(qǐng)求會(huì)被看作一個(gè)PV,逐漸累計(jì)成為PV總數(shù)。
●環(huán)境及組件介紹
操作系統(tǒng) | IP地址 | 角色 | web組件 |
---|---|---|---|
Centos7 | 192.168.70 .136 | 主服務(wù)器 | keepalived、nginx、mysql、redis |
Centos7 | 192.168.70.137 | 從服務(wù)器 | keepalived、nginx、mysql、redis |
Centos7 | 192.168.70 .134 | web后端1 | tomcat、項(xiàng)目 |
Centos7 | 192.168.70 .132 | web后端2 | tomcat、項(xiàng)目 |
●使用的軟件包
nginx1.8.1:http://101.96.10.46/nginx.org/download/nginx-1.8.1.tar.gz
web服務(wù)包:https://pan.baidu.com/s/143ZRkqfUxJJIBzO_yz7gPg
密碼:wsgd
mysql解壓版https://pan.baidu.com/s/11b_ccrosT0IPdnXhRrU4yQ
密碼:ruh5
一、主從服務(wù)器配置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 { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.70.131 #指向本機(jī) smtp_connect_timeout 30 router_id NGINX_01 #備機(jī)為NGINX_02 } vrrp_instance VI_1 { state MASTER #備機(jī)為BACKUP interface ens33 #網(wǎng)卡名稱(chēng) virtual_router_id 51 #備機(jī)52,不與主相同 priority 100 #優(yōu)先級(jí),備機(jī)優(yōu)先級(jí)要低于主機(jī) advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.70.100 #虛擬Ip地址 } }
==========以下是配置keepalive的順帶著啟動(dòng)nginx===========
個(gè)人看法,不太希望這樣做,因?yàn)槊績(jī)擅雵L試啟動(dòng)nginx,nginx會(huì)兩秒打一次error日志,提示端口被占用無(wú)法啟動(dòng),這樣反而造成了不必要的磁盤(pán)讀寫(xiě)。
Configuration File for keepalived #定義NGINX啟動(dòng)腳本位置,每?jī)擅霗z查一次 vrrp_script nginx { script "/opt/shell/nginx.sh" interval 2 } #刪除原本內(nèi)容,添加route_id,備機(jī)為NGINX_02 global_defs { route_id NGINX_01 } vrrp_instance VI_1 { state MASTER #主機(jī)為MASTER interface ens33 #網(wǎng)卡名稱(chēng) virtual_router_id 51 #備機(jī)為52 priority 100 #優(yōu)先級(jí),備機(jī)為99 advert_int 1 authentication { auth_type PASS auth_pass 1111 } #觸發(fā)腳本 track_script { nginx } #虛擬IP virtual_ipaddress { 192.168.70.100 } }
3、啟動(dòng)keepalived
[root@localhost ~]# systemctl start keepalived.service
4、查看虛擬ip
[root@localhost ~]# ip addr
1: lo: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: 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
注:備機(jī)也要啟動(dòng)keepalived,然后關(guān)閉主機(jī)keepalived,看虛擬Ip會(huì)不會(huì)漂移到備機(jī)。
二、安裝nginx
上傳nginx安裝包至/opt目錄下
1、安裝環(huán)境包
[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、創(chuàng)建nginx用戶(hù)
[root@localhost nginx-1.8.1]# useradd -M -s /sbin/nologin nginx
5、優(yōu)化命令路徑
[root@localhost nginx-1.8.1]# ln -s /usr/local/nginx/sbin/nginx /usr/sbin/
6、添加代理并簡(jiǎn)單優(yōu)化
[root@localhost nginx-1.8.1]# cd /usr/local/nginx/conf/
[root@localhost conf]# vim nginx.conf
#用戶(hù)nginx,單核 user nginx; worker_processes 1; #每個(gè)核心連接數(shù)2048 events { worker_connections 2048; } http { include mime.types; default_type application/octet-stream; #隱藏版本號(hào) server_tokens off; #sendfile參數(shù)用于開(kāi)啟文件的高效傳輸模式。 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; #會(huì)話(huà)穩(wěn)固,防止停留頁(yè)面過(guò)久導(dǎo)致需要重新登錄。 } 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、檢查配置文件語(yǔ)法
[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、啟動(dòng)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、添加環(huán)境變量
[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、刷新環(huán)境變量,查看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、修改默認(rèn)首頁(yè)進(jìn)行測(cè)試,兩臺(tái)tomcat都需要操作
[root@localhost opt]# cd tomcat8/webapps/ROOT/
[root@localhost ROOT]# vim index.jsp
#刪除原有的內(nèi)容,添加如下本機(jī)ip,用于測(cè)試 #134主機(jī)添加如下
this is 134 server
#132主機(jī)添加如下
this is 132 server
7、建立命令軟鏈接,啟動(dòng)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 #啟動(dòng)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網(wǎng)頁(yè)用虛擬ip訪(fǎng)問(wèn)
192.168.70.100
顯示后臺(tái)我們?cè)O(shè)置的tomcat頁(yè)面即可,然后關(guān)閉一臺(tái)tomcat看頁(yè)面會(huì)不會(huì)變
四、mysql主從復(fù)制
上傳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 #注意,備機(jī)的mysql,server-id不能與主機(jī)相同 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,設(shè)置密碼
[root@localhost opt]# ln -s /opt/mysql/bin/* /usr/bin/
[root@localhost opt]# mysql/bin/mysqld –initialize-insecure #初始化
[root@localhost opt]# mysqld_safe & #啟動(dòng)
[root@localhost opt]# mysqladmin -uroot password #設(shè)置密碼
[root@localhost opt]# mysql -uroot -p #登陸查看
4、設(shè)置mysql主從復(fù)制
#以下在主庫(kù)上操作 mysql> grant replication slave on *.* to 'replication'@'192.168.70.%' identified by '123123' with grant option; #授權(quán)replication用戶(hù)權(quán)限 mysql> flush privileges; #刷新權(quán)限 mysql> show master status; #查看二進(jìn)制日志位置 +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000002 | 885 | | | | +------------------+----------+--------------+------------------+-------------------+ #以下在從庫(kù)上操作 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 statusG; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.70.136 .......................... Slave_IO_Running: Yes #要看到這兩項(xiàng)為yes,主從復(fù)制成 Slave_SQL_Running: Yes
5、主庫(kù)導(dǎo)入sql語(yǔ)句
[root@localhost opt]# mysql -uroot -p < slsaledb-2014-4-10.sql
6、項(xiàng)目的mysql用戶(hù)授權(quán)
mysql> grant all on . to 'root'@'%' identified by '123123';
mysql> flush privileges;
五、redis緩存服務(wù)器配置
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
主從服務(wù)器 61行 bind 0.0.0.0 從服務(wù)器添加 266行 slaveof 192.169.70.136 6379
3、主從服務(wù)器啟動(dòng)redis
[root@localhost opt]# systemctl start redis
4、驗(yàn)證主從功能
[root@localhost opt]# redis-cli -h 192.168.70.136 -p 6379
#主服務(wù)器寫(xiě)入 192.168.70.136:6379> set name lisi OK 192.168.70.136:6379> get name "lisi" #從服務(wù)器 192.168.70.137:6379> get name #能獲取值說(shuō)明主從同步成功 "lisi"
5、搭建主從切換
注:主服務(wù)器上操作
[root@localhost opt]# vim /etc/redis-sentinel.conf
protected-mode no#是否開(kāi)啟保護(hù)模式 sentinel monitor mymaster 192.168.70.137 6379 1 #1表示1臺(tái)從 sentinel down-after-milliseconds mymaster 3000 #切換時(shí)間為3000毫秒
#主從都啟動(dòng)群集
[root@localhost opt]# systemctl start redis-sentinel.service
#查看群集狀態(tài)
[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
六、部署項(xiàng)目
#兩臺(tái)tomcat主機(jī)上操作
1、上傳項(xiàng)目包,解壓縮到指定目錄
[root@localhost opt]# tar zxf SLSaleSystem.tar.gz -C /opt/tomcat8/webapps/
2、修改tomcat配置文件,確定項(xiàng)目位置
[root@localhost opt]# cd /opt/tomcat8/conf/
[root@localhost conf]# vim server.xml
#接近尾行位置添加如下
3、修改項(xiàng)目文件,指定連接數(shù)據(jù)庫(kù)和redis緩存服務(wù)
[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 #數(shù)據(jù)庫(kù)授權(quán)的用戶(hù) uname=root #密碼 password=123123
#修改redis緩存服務(wù)器ip地址
[root@localhost classes]# vim applicationContext-mybatis.xml
#虛擬ip
4、配置完重新啟動(dòng)tomcat
[root@localhost classes]# tomcatdown
[root@localhost classes]# tomcatup
5、網(wǎng)頁(yè)中訪(fǎng)問(wèn)
192.168.70.100
#默認(rèn)賬號(hào)admin
#默認(rèn)密碼123456
6、查看redis緩存服務(wù)
[root@localhost opt]# redis-cli -h 192.168.70.136 -p 6379
192.168.70.136:6379> info keyspace_hits:2 #找到這兩行,這個(gè)是命中次數(shù) keyspace_misses:0
注:點(diǎn)擊進(jìn)網(wǎng)頁(yè)內(nèi)容出現(xiàn)感嘆屬于正常,緩存服務(wù)器需要一段時(shí)間緩存內(nèi)容。
redis緩存服務(wù)器主從切換的問(wèn)題,主宕機(jī),從會(huì)頂替上來(lái),但再次啟動(dòng)主的時(shí)候,從不會(huì)讓出當(dāng)前master的角色,除非手動(dòng)切換,或從宕機(jī)。
這個(gè)項(xiàng)目是很久很久的一個(gè)項(xiàng)目,拿來(lái)學(xué)習(xí)理解下百萬(wàn)pv架構(gòu)還行,學(xué)習(xí)為主,另外想要達(dá)到百萬(wàn)pv,硬件性能是必不可少的,軟件層面上的優(yōu)化也是必須的。
本文主要介紹百萬(wàn)pv的架構(gòu)及其中一些服務(wù)之間的關(guān)系,謹(jǐn)以介紹學(xué)習(xí),實(shí)際操作以自己公司環(huán)境為主。