2018-09-27

《Docker環境下的前后端分離部署與運維》課程腳本

[TOC]

一、Docker虛擬機常用命令

  1. 先更新軟件包

    yum -y update
    
  2. 安裝Docker虛擬機

    yum install -y docker
    
  3. 運行、重啟、關閉Docker虛擬機

    service docker start
    service docker start
    service docker stop
    
  4. 搜索鏡像

    docker search 鏡像名稱
    
  5. 下載鏡像

    docker pull 鏡像名稱
    
  6. 查看鏡像

    docker images
    
  7. 刪除鏡像

    docker rmi 鏡像名稱
    
  8. 運行容器

    docker run 啟動參數  鏡像名稱
    
  9. 查看容器列表

    docker ps -a
    
  10. 停止、掛起、恢復容器

docker stop 容器ID
docker pause 容器ID
docker unpase 容器ID
  1. 查看容器信息

    docker inspect 容器ID
    
  2. 刪除容器

    docker rm 容器ID
    
  3. 數據卷管理

    docker volume create 數據卷名稱  #創建數據卷
    docker volume rm 數據卷名稱  #刪除數據卷
    docker volume inspect 數據卷名稱  #查看數據卷
    
  4. 網絡管理

    docker network ls 查看網絡信息
    docker network create --subnet=網段 網絡名稱
    docker network rm 網絡名稱
    
  5. 避免VM虛擬機掛起恢復之后,Docker虛擬機斷網

    vi /etc/sysctl.conf
    
文件中添加`net.ipv4.ip_forward=1`這個配置

?```shell
#重啟網絡服務
systemctl  restart network
?```

二、安裝PXC集群,負載均衡,雙機熱備

  1. 安裝PXC鏡像

    docker pull percona/percona-xtradb-cluster:5.7.21
    

    強烈推薦同學們安裝5.7.21版本的PXC鏡像,兼容性最好,在容器內可以執行apt-get安裝各種程序包。最新版的PXC鏡像內,無法執行apt-get,也就沒法安裝熱備份工具了。

  2. 為PXC鏡像改名

    docker tag percona/percona-xtradb-cluster pxc
    
  3. 創建net1網段

    docker network create --subnet=172.18.0.0/16 net1
    
  4. 創建5個數據卷

    docker volume create --name v1
    docker volume create --name v2
    docker volume create --name v3
    docker volume create --name v4
    docker volume create --name v5
    
  5. 創建備份數據卷(用于熱備份數據)

    docker volume create --name backup
    
  6. 創建5節點的PXC集群

    注意,每個MySQL容器創建之后,因為要執行PXC的初始化和加入集群等工作,耐心等待1分鐘左右再用客戶端連接MySQL。另外,必須第1個MySQL節點啟動成功,用MySQL客戶端能連接上之后,再去創建其他MySQL節點。

    #創建第1個MySQL節點
    docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql -v backup:/data --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc
    #創建第2個MySQL節點
    docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v2:/var/lib/mysql -v backup:/data --privileged --name=node2 --net=net1 --ip 172.18.0.3 pxc
    #創建第3個MySQL節點
    docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v3:/var/lib/mysql --privileged --name=node3 --net=net1 --ip 172.18.0.4 pxc
    #創建第4個MySQL節點
    docker run -d -p 3309:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v4:/var/lib/mysql --privileged --name=node4 --net=net1 --ip 172.18.0.5 pxc
    #創建第5個MySQL節點
    docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -e CLUSTER_JOIN=node1 -v v5:/var/lib/mysql -v backup:/data --privileged --name=node5 --net=net1 --ip 172.18.0.6 pxc
    
  7. 安裝Haproxy鏡像

    docker pull haproxy
    
  8. 宿主機上編寫Haproxy配置文件

    vi /home/soft/haproxy/haproxy.cfg
    

    配置文件如下:

    global
     #工作目錄
     chroot /usr/local/etc/haproxy
     #日志文件,使用rsyslog服務中local5日志設備(/var/log/local5),等級info
     log 127.0.0.1 local5 info
     #守護進程運行
     daemon
    
    defaults
     log global
     mode    http
     #日志格式
     option  httplog
     #日志中不記錄負載均衡的心跳檢測記錄
     option  dontlognull
        #連接超時(毫秒)
     timeout connect 5000
        #客戶端超時(毫秒)
     timeout client  50000
     #服務器超時(毫秒)
        timeout server  50000
    
    #監控界面    
    listen  admin_stats
     #監控界面的訪問的IP和端口
     bind  0.0.0.0:8888
     #訪問協議
        mode        http
     #URI相對地址
        stats uri   /dbs
     #統計報告格式
        stats realm     Global\ statistics
     #登陸帳戶信息
        stats auth  admin:abc123456
    #數據庫負載均衡
    listen  proxy-mysql
     #訪問的IP和端口
     bind  0.0.0.0:3306  
        #網絡協議
     mode  tcp
     #負載均衡算法(輪詢算法)
     #輪詢算法:roundrobin
     #權重算法:static-rr
     #最少連接算法:leastconn
     #請求源IP算法:source 
        balance  roundrobin
     #日志格式
        option  tcplog
     #在MySQL中創建一個沒有權限的haproxy用戶,密碼為空。Haproxy使用這個賬戶對MySQL數據庫心跳檢測
        option  mysql-check user haproxy
        server  MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000  
        server  MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000  
     server  MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000 
     server  MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000
     server  MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000
     #使用keepalive檢測死鏈
        option  tcpka  
    
  9. 創建兩個Haproxy容器

    #創建第1個Haproxy負載均衡服務器
    docker run -it -d -p 4001:8888 -p 4002:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h1 --privileged --net=net1 --ip 172.18.0.7 haproxy
    #進入h1容器,啟動Haproxy
    docker exec -it h1 bash
    haproxy -f /usr/local/etc/haproxy/haproxy.cfg
    #創建第2個Haproxy負載均衡服務器
    docker run -it -d -p 4003:8888 -p 4004:3306 -v /home/soft/haproxy:/usr/local/etc/haproxy --name h2 --privileged --net=net1 --ip 172.18.0.8 haproxy
    #進入h2容器,啟動Haproxy
    docker exec -it h2 bash
    haproxy -f /usr/local/etc/haproxy/haproxy.cfg
    
  10. Haproxy容器內安裝Keepalived,設置虛擬IP

注意事項:云主機不支持虛擬IP,另外很多公司的網絡禁止創建虛擬IP(回家創建),還有宿主機一定要關閉防火墻和SELINUX,很多同學都因為這個而失敗的,切記切記

#進入h1容器
docker exec -it h1 bash
#更新軟件包
apt-get update
#安裝VIM
apt-get install vim
#安裝Keepalived
apt-get install keepalived
#編輯Keepalived配置文件(參考下方配置文件)
vim /etc/keepalived/keepalived.conf
#啟動Keepalived
service keepalived start
#宿主機執行ping命令
ping 172.18.0.201

配置文件內容如下:

vrrp_instance  VI_1 {
    state  MASTER
    interface  eth0
    virtual_router_id  51
    priority  100
    advert_int  1
    authentication {
        auth_type  PASS
        auth_pass  123456
    }
    virtual_ipaddress {
        172.18.0.201
    }
}
#進入h2容器
docker exec -it h2 bash
#更新軟件包
apt-get update
#安裝VIM
apt-get install vim
#安裝Keepalived
apt-get install keepalived
#編輯Keepalived配置文件
vim /etc/keepalived/keepalived.conf
#啟動Keepalived
service keepalived start
#宿主機執行ping命令
ping 172.18.0.201

配置文件內容如下:

vrrp_instance  VI_1 {
    state  MASTER
    interface  eth0
    virtual_router_id  51
    priority  100
    advert_int  1
    authentication {
        auth_type  PASS
        auth_pass  123456
    }
    virtual_ipaddress {
        172.18.0.201
    }
}
  1. 宿主機安裝Keepalived,實現雙機熱備

    #宿主機執行安裝Keepalived
    yum -y install keepalived
    #修改Keepalived配置文件
    vi /etc/keepalived/keepalived.conf
    #啟動Keepalived
    service keepalived start
    

    Keepalived配置文件如下:

    vrrp_instance VI_1 {
        state MASTER
        interface ens33
        virtual_router_id 51
        priority 100
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.99.150
        }
    }
    
    virtual_server 192.168.99.150 8888 {
        delay_loop 3
        lb_algo rr 
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
    
        real_server 172.18.0.201 8888 {
            weight 1
        }
    }
    
    virtual_server 192.168.99.150 3306 {
        delay_loop 3
        lb_algo rr 
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
    
        real_server 172.18.0.201 3306 {
            weight 1
        }
    }
    
  2. 熱備份數據

    #進入node1容器
    docker exec -it node1 bash
    #更新軟件包
    apt-get update
    #安裝熱備工具
    apt-get install percona-xtrabackup-24
    #全量熱備
    innobackupex --user=root --password=abc123456 /data/backup/full
    
  3. 冷還原數據
    停止其余4個節點,并刪除節點

    docker stop node2
    docker stop node3
    docker stop node4
    docker stop node5
    docker rm node2
    docker rm node3
    docker rm node4
    docker rm node5
    

    node1容器中刪除MySQL的數據

    #刪除數據
    rm -rf /var/lib/mysql/*
    #清空事務
    innobackupex --user=root --password=abc123456 --apply-back /data/backup/full/2018-04-15_05-09-07/
    #還原數據
    innobackupex --user=root --password=abc123456 --copy-back  /data/backup/full/2018-04-15_05-09-07/
    

    重新創建其余4個節點,組件PXC集群

三、PXC 特別注意事項

PXC的主節點和從節點分別代表什么意義?

PXC中的主節點和從節點跟Replication主從節點是有巨大差別的。

首先Replication集群的數據同步只能是從主節點到從節點,而且節點的身份是固定的,主節點永遠是Master,從節點永遠是Slave,不能互換。

但是PXC上的主節點指的是第一個啟動的節點,它不僅要啟動MySQL服務,還要用Galera創建PXC集群。這些工作完成之后,主節點自動降級成普通節點。其他節點啟動的時候只需要啟動MySQL服務,然后再加入到PXC集群即可,所以這些節點從啟動到關閉,身份一直都是普通節點。

為什么Node1能啟動,而其他的PXC節點啟動就閃退呢?

這是因為Node1啟動的時候要做跟多工作,上面已經提及了。所以你沒等node1把PXC集群創建出來,你就飛快的啟動其他PXC節點,它們找不到Node1啟動的PXC集群,所以就自動閃退了。

正確的辦法是啟動Node1之后,等待10秒鐘,然后用Navicat訪問一下,能訪問了,再去啟動其他PXC節點

如果PXC集群在運行的狀態下,在宿主機上直接關機,或者停止Docker服務,為什么下次啟動哪個PXC節點都會閃退?

這個要從PXC集群的節點管理說起,PXC節點的數據目錄是/var/lib/mysql,好在這個目錄被我們映射到數據卷上了。比如你訪問v1數據卷就能看到node1的數據目錄。這其中有個grastate.dat的文件,它里面有個safe_to_bootstrap參數被PXC用來記載誰是最后退出PXC集群的節點。比如node1是最后關閉的節點,那么PXC就會在把safe_to_bootstrap設置成1,代表node1節點最后退出,它的數據是最新的。下次啟動必須先啟動node1,然后其他節點與node1同步。

如果你在PXC節點都正常運行的狀態下關閉宿主機Docker服務或者電源,那么PXC來不及判斷誰是最后退出的節點,所有PXC節點一瞬間就都關上了,哪個節點的safe_to_boostrap參數就都是0。解決這個故障也很好辦,那就是挑node1,把該參數改成1,然后正常啟動node1,再啟動其他節點就行了。

PXC集群只有一個節點,關閉了這個節點的容器,下次還能啟動起來嗎?

當然是可以的,因為PXC里只有一個節點,那么這個節點一定是按照主節點啟動的,所以啟動它的時候,它會啟動MySQL服務,還創建出PXC集群。即便關閉了容器,下次再啟動還是這個步驟,不會出現啟動故障。如果說PXC集群是由多個節點組成的,node1停掉了,其他節點都正常運行。這時候啟動node1是會出現閃退的,node1剛啟動幾秒鐘就掛了。這是因為node2等一些節點正在現有的PXC中運行,這時候你啟動node1,再創建一個同名的PXC集群,肯定會引發沖突啊。所以node1就閃退了。

遇到這種情況,正確的處理辦法是,把node1容器刪除。別緊張,沒讓你刪除v1數據卷,所以數據丟不了。然后用從節點的命令方式創建一個node1,啟動參數中與某個節點同步的設置就隨便選擇一個現在運行的PXC節點,然后Node1就能啟動了。

關于搭建技術體系,深入學習方面的感言

? 本門課程的數據庫部分只講到數據庫集群怎么搭建,如果想要完全駕馭數據庫,僅憑這點知識還是遠遠不夠的。像我在PXC免費課中講到的,我們首先要有一個明確的知識體系,下一步就是做知識分解,一點點把技術拼圖給完成。我見過非常多,東學一下,西學一下的人,即便有10年的工作經驗,依然難成大器。比如說前些年VR挺火的,現在區塊鏈技術也挺火的。我是個快要畢業的大學生,我想學這些技術幫我找一份好的工作。其實這種想法不是不對,但是過于急功近利。我先把話題說的遠一點,咱們一會兒再回來說技術規劃的事情。

? 在2013年,雷軍和董明珠打了個賭,如果小米在5年內營業額超過格力,董明珠輸給雷軍10個億,反之也是如此。兩家企業相比較,大家更看好雷軍的小米。這是因為中國的制造業利潤太薄,制造業盈利存在上限的天花板,所以我們能準確預測出一家制造業企業未來的盈利空間。但是互聯網公司就不是這樣,想象空間太巨大。比如說馬云的阿里巴巴,從1999年創建,到2014年上市,用了15年時間。劉強東的京東商城,差不多也用了15年時間上市。但是到了黃錚的拼多多這里,只用了3年時間就完成了上市,他還一舉超過劉強東,成為中國第六富豪。IT界一夜成名的還有滴滴打車的程維、美團的王興等等。

? 也正是IT互聯網公司造富神話太多,也就越來越多的資本涌入IT圈。有的資本公司做長線,但是更多的資本公司炒短線。先投資一家小公司,然后再制造行業輿論和技術導向,當人們被技術忽悠的瘋狂的時候,有人肯接盤了,這時候再把投資的這家小公司賣掉,割一波韭菜就撤。于是我們看到太多太多被熱炒的技術,沒過1年時間就無人問津了。比如2014年的iOS技術,2015年的VR技術等等。當年VR技術被捧到天上,王雪紅一度被業界認為會用VR讓HTC翻身,可是到現在我們再也聽不到HTC這家公司的新聞了。活著還是倒閉了,我們都不知道,大家也不關心。

? 所以我們選擇一個技術方向的時候,首先要看這個領域是不是有太多的水分,是不是有太多的熱錢。比如今年3月的時候,真格基金的徐小平發了一個微博說自己非常看好以太坊技術,于是短短時間,中國各家資本公司紛紛涌入區塊鏈領域。甚至還出現了2萬塊錢的區塊鏈講師速成班,不管懂不懂計算機,都能給你在短期內培養成區塊鏈專家,然后你再去培訓機構忽悠人,月薪兩萬,割學技術大學生的韭菜。我想,徐小平在微博上把區塊鏈捧到天上,何嘗不是一種資本炒作的手法呢。

? 最后說回到技術領域這塊。比如你是一個大學生,想投身一個有發展的技術方向,那么不妨拿起手機看看那些常用的APP上都用到了什么技術,這才是能落地能普及的。比如說刷抖音很容易上癮,上劃一條是你喜歡的視頻,再上劃一下,又是你感興趣的視頻。還有每個人打開淘寶APP,首頁的內容都不一樣,都是你喜歡的商品,看什么東西都想賣。淘寶也很絕,即使你不花錢買東西,只要你點擊看了一個你喜歡的商品,從此以后,你各項愛好都被淘寶所感知了。這種技術是大數據上的協同過濾。說簡單一點,就是掌握了你很少資料的情況下,去分析跟你有相同行為的人的喜好,于是推算出你的喜好。比如你點擊了某個牌子的運動鞋,那么淘寶的協同過濾就會計算購買了這個運動鞋的用戶,還買了什么東西,這些用戶共性的東西,就是你的愛好。所以你再打開淘寶APP,看到的都是你喜歡的東西。抖音啊,今日頭條啊,都是這樣的技術。所以你學大數據,這個技術是能落地的,太多產品在用這個技術了。相比較而言,區塊鏈和人工智能就顯得太高冷了。不是說技術不好,但是距離大規模普及還是有很遠的距離。比如說區塊鏈吧,上半年好多企業都在炒作,不跟區塊鏈掛鉤好像都不是科技企業,甚至南方有家茶葉公司,把名字都改成了帶有區塊鏈字眼。這就像荷蘭的郁金香泡沫,當人們都意識到郁金香根本就不值那么高價格的時候,于是泡沫就破裂了。比如極路由公司,把自己的路由器搞成了能挖礦,每天平均賺4塊錢。我們知道1萬塊錢存到支付寶上,一天也產生不了1塊錢的利益。現在幾百塊錢的極路由每天產生4塊錢的收益,不就相當你花幾百塊錢享受幾萬塊錢的利息收益嗎,多讓人瘋狂啊。極路由一邊忽悠消費者,一邊又去忽悠投資人,還跟互聯網金融公司合作,弄了多種套餐玩法。投資人和消費者都被忽悠熱血沸騰,拿出十幾萬塊錢,買極路由器,幻想自己在家當地主,天天幾百塊錢收入。但是不到半年時間,極路由的技術+金融戲法就玩不下去了,老板欠了3.5個億跑路了。同學們也不妨搜索一下因為區塊鏈破產的消費者和炒作者。你投身這樣的領域覺得靠譜嗎?

? 所以選擇技術規劃一定要挑選成熟的,應用范圍廣泛的。比如大數據、Java體系、前端體系、Python體系等等。所以就像我在免費課里說到的,你選擇好一個發力的方向,剩下的就是如何分解知識點了。比如說,你學了Java的一部分,沒去深挖微服務架構和集群架構。如果你只停留在做單體項目,比如說SSM實現一個管理項目,VUE做一個網站等等,那我可以保證,你在IT開發這個領域很難堅持10年。經常聽說,做開發30歲要轉行,公司里幾乎看不見40歲還做開發的人。其中的原因很多人沒講到關鍵點,作為創業者和企業家的角度來看,如果一個開發者,技術只停留在用SSM架構套各種業務,今天做一個管理系統,明天做一個管理系統。因為單體項目很難支撐高并發,所以你做的項目基本都是在小公司內部使用。隨著你工作年限增加,對企業來說用人成本也就變高了。用一個2年經驗的開發者,也會使用SSM做項目,成本還低,那為什么不用這樣的人呢。所以你就被企業無情的拋棄了,根本原因是技術停滯,成本太高。這時候你再想跳槽到大企業,技術和年齡都達不到要求了。所以我建議年輕人,參加工作以后,雖然崗位有界限,但是技術無界限。前端、后臺、數據庫、原型設計、項目管理,多少都要學一些,沒人教,就自己總結。只有技術全才,才能勝任技術團隊的管理者,才不會被企業淘汰。

? 其實我見過很多項目都是被不稱職的管理者給弄黃的。也許你也有同感,這個項目A公司做過,B公司做過,現在客戶找到我們又要重做一版,這是為什么呢?項目開發的失敗率也太高了吧。這通常是項目管理者技術不過關導致的,比如說A客戶去南方考察,覺得某公司的管理系統特別好,我想也做一套。于是找到了你,A客戶是大老板,下面具體的業務細節說不太清楚,腦子里也沒有清晰的想法,反正想到什么就東一句、西一句的,然后你貿然選用了瀑布模型開發。經過了需求分析、文檔設計,總算進入到了開發。經過兩個月的開發,終于可以拿出半成品給A客戶了,這時候A客戶說你做的不是他想要的東西,要不你推到重做把,要不我找別的公司去做。然后別的公司做了,A客戶依然不滿意,于是開啟了無限的重做模式。

? 究其原因還是管理者用錯了開發模型,瀑布模型看似合理,但是問題在于編碼階段太靠后,等拿出半成品已經小半年時間過去了。因此瀑布模型適用于那種能提出明確需求,而且到每一處細節的客戶。像A客戶這樣的人,我們應該用螺旋模型去開發,小規模快速迭代,只開發最核心模塊,短期內就拿出演示品跟客戶確認。這種小步快跑的策略適合提不出具體需求和需求不明確的場合。所以說,同學,以后你想做管理者,是不是得了解“軟件工程”的知識啊!

? 這幾年我在教育部舉辦的互聯網+創新創業大賽預賽和決賽當評委的時候,跟很多大學生創業的同學講到了,你的創業想法很好,但是很可能項目會作廢了。起初他們不相信,覺得自己拿到風投的錢,幾個學軟件的同學會編程,這就足夠了。于是次年的時候,我又見到了這些同學,參賽的題目又換了。我就好奇的問他們,去年的創業項目做成了嗎?他們跟我說,創業項目做砸了。呵呵,果然是這樣。因為他們的團隊里缺少了技術方面的全才。僅靠專才是不能完成項目開發的。我再舉一個例子,某公司的開發者老張,他是做后端比較擅長,因為工作年頭比較長了,于是就被提拔成了項目經理。有一天,日方客戶發來一封郵件,說某模塊的業務流程要修改,看看中方這邊多長時間能實現,費用是多少。于是老張就召集團隊的人開了一次會。老張擅長后臺開發,這次需求覺得沒什么難度,然后問了問數據庫的哥們和前端的哥們,他們說也好實現,然后老張就承諾日方兩天就能做完。但是過于樂觀的態度,很容易引來噩夢般的后果。數據庫的哥們和前端的哥們,寫代碼的時候才發現實現難度很大,最后花了半個月才做完,浪費了大量的加班費用。因為老張不懂前端,也不懂數據庫集群,覺得底下人說什么就代表什么。由此看出,管理者技術必須全面,不能人云亦云,必須保持自己的判斷力。

? 說了這么多,也非常感謝大家在慕課網上支持我的課程,后續我還會在慕課網上錄制更多的實戰課,將我們的技術體系拼圖給逐步完成。目前正在錄制Python的課程和其他的開發課程,請大家稍加等待。下面列出來我在慕課網上所有課程的連接,以供大家學習。

《MySQL數據庫集群-PXC方案》

https://coding.imooc.com/class/274.html

《Docker環境下的前后端分離項目部署與運維》

https://coding.imooc.com/class/219.html

安裝Redis,配置RedisCluster集群

  1. 安裝Redis鏡像

    docker pull yyyyttttwwww/redis
    
  2. 創建net2網段

    docker network create --subnet=172.19.0.0/16 net2
    
  3. 創建6節點Redis容器

    docker run -it -d --name r1 -p 5001:6379 --net=net2 --ip 172.19.0.2 redis bash
    docker run -it -d --name r2 -p 5002:6379 --net=net2 --ip 172.19.0.3 redis bash
    docker run -it -d --name r3 -p 5003:6379 --net=net2 --ip 172.19.0.4 redis bash
    docker run -it -d --name r4 -p 5004:6379 --net=net2 --ip 172.19.0.5 redis bash
    docker run -it -d --name r5 -p 5005:6379 --net=net2 --ip 172.19.0.6 redis bash
    

    注意:redis配置文件里必須要設置bind 0.0.0.0,這是允許其他IP可以訪問當前redis。如果不設置這個參數,就不能組建Redis集群。

  4. 啟動6節點Redis服務器

    #進入r1節點
    docker exec -it r1 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    #進入r2節點
    docker exec -it r2 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    #進入r3節點
    docker exec -it r3 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    #進入r4節點
    docker exec -it r4 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    #進入r5節點
    docker exec -it r5 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    #進入r6節點
    docker exec -it r6 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    
  5. 創建Cluster集群

    #在r1節點上執行下面的指令
    cd /usr/redis/src
    mkdir -p ../cluster
    cp redis-trib.rb ../cluster/
    cd ../cluster
    #創建Cluster集群
    ./redis-trib.rb create --replicas 1 172.19.0.2:6379 172.19.0.3:6379 172.19.0.4:6379 172.19.0.5:6379 172.19.0.6:6379 172.19.0.7:6379
    

打包部署后端項目

  1. 進入人人開源后端項目,執行打包(修改配置文件,更改端口,打包三次生成三個JAR文件)

    mvn clean install -Dmaven.test.skip=true
    
  2. 安裝Java鏡像

    docker pull java
    
  3. 創建3節點Java容器

    #創建數據卷,上傳JAR文件
    docker volume create j1
    #啟動容器
    docker run -it -d --name j1 -v j1:/home/soft --net=host java
    #進入j1容器
    docker exec -it j1 bash
    #啟動Java項目
    nohup java -jar /home/soft/renren-fast.jar
    
    #創建數據卷,上傳JAR文件
    docker volume create j2
    #啟動容器
    docker run -it -d --name j2 -v j2:/home/soft --net=host java
    #進入j1容器
    docker exec -it j2 bash
    #啟動Java項目
    nohup java -jar /home/soft/renren-fast.jar
    
    #創建數據卷,上傳JAR文件
    docker volume create j3
    #啟動容器
    docker run -it -d --name j3 -v j3:/home/soft --net=host java
    #進入j1容器
    docker exec -it j3 bash
    #啟動Java項目
    nohup java -jar /home/soft/renren-fast.jar
    
  4. 安裝Nginx鏡像

    docker pull nginx
    
  5. 創建Nginx容器,配置負載均衡

    宿主機上/home/n1/nginx.conf配置文件內容如下:

    user  nginx;
    worker_processes  1;
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
     
     proxy_redirect          off;
     proxy_set_header        Host $host;
     proxy_set_header        X-Real-IP $remote_addr;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     client_max_body_size    10m;
     client_body_buffer_size   128k;
     proxy_connect_timeout   5s;
     proxy_send_timeout      5s;
     proxy_read_timeout      5s;
     proxy_buffer_size        4k;
     proxy_buffers           4 32k;
     proxy_busy_buffers_size  64k;
     proxy_temp_file_write_size 64k;
     
     upstream tomcat {
         server 192.168.99.104:6001;
         server 192.168.99.104:6002;
         server 192.168.99.104:6003;
     }
     server {
            listen       6101;
            server_name  192.168.99.104; 
            location / {  
                proxy_pass   http://tomcat;
                index  index.html index.htm;  
            }  
        }
    }
    

    創建第1個Nginx節點

    docker run -it -d --name n1 -v /home/n1/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
    
    

    宿主機上/home/n2/nginx.conf配置文件內容如下:

    user  nginx;
    worker_processes  1;
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
     
     proxy_redirect          off;
     proxy_set_header        Host $host;
     proxy_set_header        X-Real-IP $remote_addr;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     client_max_body_size    10m;
     client_body_buffer_size   128k;
     proxy_connect_timeout   5s;
     proxy_send_timeout      5s;
     proxy_read_timeout      5s;
     proxy_buffer_size        4k;
     proxy_buffers           4 32k;
     proxy_busy_buffers_size  64k;
     proxy_temp_file_write_size 64k;
     
     upstream tomcat {
         server 192.168.99.104:6001;
         server 192.168.99.104:6002;
         server 192.168.99.104:6003;
     }
     server {
            listen       6102;
            server_name  192.168.99.104; 
            location / {  
                proxy_pass   http://tomcat;
                index  index.html index.htm;  
            }  
        }
    }
    

    創建第2個Nginx節點

    docker run -it -d --name n2 -v /home/n2/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
    
  6. 在Nginx容器安裝Keepalived

    #進入n1節點
    docker exec -it n1 bash
    #更新軟件包
    apt-get update
    #安裝VIM
    apt-get install vim
    #安裝Keepalived
    apt-get install keepalived
    #編輯Keepalived配置文件(如下)
    vim /etc/keepalived/keepalived.conf
    #啟動Keepalived
    service keepalived start
    
    vrrp_instance VI_1 {
        state MASTER
        interface ens33
        virtual_router_id 51
        priority 100
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 123456
        }
        virtual_ipaddress {
            192.168.99.151
        }
    }
    virtual_server 192.168.99.151 6201 {
        delay_loop 3
        lb_algo rr
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
        real_server 192.168.99.104 6101 {
            weight 1
        }
    }
    
    #進入n1節點
    docker exec -it n2 bash
    #更新軟件包
    apt-get update
    #安裝VIM
    apt-get install vim
    #安裝Keepalived
    apt-get install keepalived
    #編輯Keepalived配置文件(如下)
    vim /etc/keepalived/keepalived.conf
    #啟動Keepalived
    service keepalived start
    
    vrrp_instance VI_1 {
        state MASTER
        interface ens33
        virtual_router_id 51
        priority 100
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 123456
        }
        virtual_ipaddress {
            192.168.99.151
        }
    }
    virtual_server 192.168.99.151 6201 {
        delay_loop 3
        lb_algo rr
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
        real_server 192.168.99.104 6102 {
            weight 1
        }
    }
    

打包部署后端項目

  1. 在前端項目路徑下執行打包指令

    npm run build
    
  2. build目錄的文件拷貝到宿主機的/home/fn1/renren-vue、/home/fn2/renren-vue、/home/fn3/renren-vue的目錄下面

  3. 創建3節點的Nginx,部署前端項目

    宿主機/home/fn1/nginx.conf的配置文件

    user  nginx;
    worker_processes  1;
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
     
     proxy_redirect          off;
     proxy_set_header        Host $host;
     proxy_set_header        X-Real-IP $remote_addr;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     client_max_body_size    10m;
     client_body_buffer_size   128k;
     proxy_connect_timeout   5s;
     proxy_send_timeout      5s;
     proxy_read_timeout      5s;
     proxy_buffer_size        4k;
     proxy_buffers           4 32k;
     proxy_busy_buffers_size  64k;
     proxy_temp_file_write_size 64k;
     
     server {
         listen 6501;
         server_name  192.168.99.104;
         location  /  {
             root  /home/fn1/renren-vue;
             index  index.html;
         }
     }
    }
    
    #啟動第fn1節點
    docker run -it -d --name fn1 -v /home/fn1/nginx.conf:/etc/nginx/nginx.conf -v /home/fn1/renren-vue:/home/fn1/renren-vue --privileged --net=host nginx
    

    宿主機/home/fn2/nginx.conf的配置文件

    user  nginx;
    worker_processes  1;
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
     
     proxy_redirect          off;
     proxy_set_header        Host $host;
     proxy_set_header        X-Real-IP $remote_addr;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     client_max_body_size    10m;
     client_body_buffer_size   128k;
     proxy_connect_timeout   5s;
     proxy_send_timeout      5s;
     proxy_read_timeout      5s;
     proxy_buffer_size        4k;
     proxy_buffers           4 32k;
     proxy_busy_buffers_size  64k;
     proxy_temp_file_write_size 64k;
     
     server {
         listen 6502;
         server_name  192.168.99.104;
         location  /  {
             root  /home/fn2/renren-vue;
             index  index.html;
         }
     }
    }
    
    #啟動第fn2節點
    docker run -it -d --name fn2 -v /home/fn2/nginx.conf:/etc/nginx/nginx.conf -v /home/fn2/renren-vue:/home/fn2/renren-vue --privileged --net=host nginx
    

    宿主機/home/fn3/nginx.conf的配置文件

    user  nginx;
    worker_processes  1;
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
     
     proxy_redirect          off;
     proxy_set_header        Host $host;
     proxy_set_header        X-Real-IP $remote_addr;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     client_max_body_size    10m;
     client_body_buffer_size   128k;
     proxy_connect_timeout   5s;
     proxy_send_timeout      5s;
     proxy_read_timeout      5s;
     proxy_buffer_size        4k;
     proxy_buffers           4 32k;
     proxy_busy_buffers_size  64k;
     proxy_temp_file_write_size 64k;
     
     server {
         listen 6503;
         server_name  192.168.99.104;
         location  /  {
             root  /home/fn3/renren-vue;
             index  index.html;
         }
     }
    }
    

    啟動fn3節點

    #啟動第fn3節點
    docker run -it -d --name fn3 -v /home/fn3/nginx.conf:/etc/nginx/nginx.conf -v /home/fn3/renren-vue:/home/fn3/renren-vue --privileged --net=host nginx
    
  4. 配置負載均衡

    宿主機/home/ff1/nginx.conf配置文件

    user  nginx;
    worker_processes  1;
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
     
     proxy_redirect          off;
     proxy_set_header        Host $host;
     proxy_set_header        X-Real-IP $remote_addr;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     client_max_body_size    10m;
     client_body_buffer_size   128k;
     proxy_connect_timeout   5s;
     proxy_send_timeout      5s;
     proxy_read_timeout      5s;
     proxy_buffer_size        4k;
     proxy_buffers           4 32k;
     proxy_busy_buffers_size  64k;
     proxy_temp_file_write_size 64k;
     
     upstream fn {
         server 192.168.99.104:6501;
         server 192.168.99.104:6502;
         server 192.168.99.104:6503;
     }
     server {
            listen       6601;
            server_name  192.168.99.104; 
            location / {  
                proxy_pass   http://fn;
                index  index.html index.htm;  
            }  
        }
    }
    
    #啟動ff1節點
    docker run -it -d --name ff1 -v /home/ff1/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
    

    宿主機/home/ff2/nginx.conf配置文件

    user  nginx;
    worker_processes  1;
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
     
     proxy_redirect          off;
     proxy_set_header        Host $host;
     proxy_set_header        X-Real-IP $remote_addr;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     client_max_body_size    10m;
     client_body_buffer_size   128k;
     proxy_connect_timeout   5s;
     proxy_send_timeout      5s;
     proxy_read_timeout      5s;
     proxy_buffer_size        4k;
     proxy_buffers           4 32k;
     proxy_busy_buffers_size  64k;
     proxy_temp_file_write_size 64k;
     
     upstream fn {
         server 192.168.99.104:6501;
         server 192.168.99.104:6502;
         server 192.168.99.104:6503;
     }
     server {
            listen       6602;
            server_name  192.168.99.104; 
            location / {  
                proxy_pass   http://fn;
                index  index.html index.htm;  
            }  
        }
    }
    
    #啟動ff2節點
    docker run -it -d --name ff2 -v /home/ff2/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
    
  5. 配置雙機熱備

    #進入ff1節點
    docker exec -it ff1 bash
    #更新軟件包
    apt-get update
    #安裝VIM
    apt-get install vim
    #安裝Keepalived
    apt-get install keepalived
    #編輯Keepalived配置文件(如下)
    vim /etc/keepalived/keepalived.conf
    #啟動Keepalived
    service keepalived start
    
    vrrp_instance VI_1 {
        state MASTER
        interface ens33
        virtual_router_id 52
        priority 100
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 123456
        }
        virtual_ipaddress {
            192.168.99.152
        }
    }
    virtual_server 192.168.99.151 6701 {
        delay_loop 3
        lb_algo rr
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
        real_server 192.168.99.104 6601 {
            weight 1
        }
    }
    
    #進入ff1節點
    docker exec -it ff2 bash
    #更新軟件包
    apt-get update
    #安裝VIM
    apt-get install vim
    #安裝Keepalived
    apt-get install keepalived
    #編輯Keepalived配置文件(如下)
    vim /etc/keepalived/keepalived.conf
    #啟動Keepalived
    service keepalived start
    
    vrrp_instance VI_1 {
        state MASTER
        interface ens33
        virtual_router_id 52
        priority 100
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 123456
        }
        virtual_ipaddress {
            192.168.99.152
        }
    }
    virtual_server 192.168.99.151 6701 {
        delay_loop 3
        lb_algo rr
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
        real_server 192.168.99.104 6602 {
            weight 1
        }
    }
    

    ?

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,923評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,740評論 3 420
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,856評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,175評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,931評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,321評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,383評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,533評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,082評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,891評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,618評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,319評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,732評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,987評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,794評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,076評論 2 375

推薦閱讀更多精彩內容