2018-09-27

《Docker環(huán)境下的前后端分離部署與運(yùn)維》課程腳本

[TOC]

一、Docker虛擬機(jī)常用命令

  1. 先更新軟件包

    yum -y update
    
  2. 安裝Docker虛擬機(jī)

    yum install -y docker
    
  3. 運(yùn)行、重啟、關(guān)閉Docker虛擬機(jī)

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

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

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

    docker images
    
  7. 刪除鏡像

    docker rmi 鏡像名稱
    
  8. 運(yùn)行容器

    docker run 啟動(dòng)參數(shù)  鏡像名稱
    
  9. 查看容器列表

    docker ps -a
    
  10. 停止、掛起、恢復(fù)容器

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

    docker inspect 容器ID
    
  2. 刪除容器

    docker rm 容器ID
    
  3. 數(shù)據(jù)卷管理

    docker volume create 數(shù)據(jù)卷名稱  #創(chuàng)建數(shù)據(jù)卷
    docker volume rm 數(shù)據(jù)卷名稱  #刪除數(shù)據(jù)卷
    docker volume inspect 數(shù)據(jù)卷名稱  #查看數(shù)據(jù)卷
    
  4. 網(wǎng)絡(luò)管理

    docker network ls 查看網(wǎng)絡(luò)信息
    docker network create --subnet=網(wǎng)段 網(wǎng)絡(luò)名稱
    docker network rm 網(wǎng)絡(luò)名稱
    
  5. 避免VM虛擬機(jī)掛起恢復(fù)之后,Docker虛擬機(jī)斷網(wǎng)

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

?```shell
#重啟網(wǎng)絡(luò)服務(wù)
systemctl  restart network
?```

二、安裝PXC集群,負(fù)載均衡,雙機(jī)熱備

  1. 安裝PXC鏡像

    docker pull percona/percona-xtradb-cluster:5.7.21
    

    強(qiáng)烈推薦同學(xué)們安裝5.7.21版本的PXC鏡像,兼容性最好,在容器內(nèi)可以執(zhí)行apt-get安裝各種程序包。最新版的PXC鏡像內(nèi),無(wú)法執(zhí)行apt-get,也就沒法安裝熱備份工具了。

  2. 為PXC鏡像改名

    docker tag percona/percona-xtradb-cluster pxc
    
  3. 創(chuàng)建net1網(wǎng)段

    docker network create --subnet=172.18.0.0/16 net1
    
  4. 創(chuàng)建5個(gè)數(shù)據(jù)卷

    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. 創(chuàng)建備份數(shù)據(jù)卷(用于熱備份數(shù)據(jù))

    docker volume create --name backup
    
  6. 創(chuàng)建5節(jié)點(diǎn)的PXC集群

    注意,每個(gè)MySQL容器創(chuàng)建之后,因?yàn)橐獔?zhí)行PXC的初始化和加入集群等工作,耐心等待1分鐘左右再用客戶端連接MySQL。另外,必須第1個(gè)MySQL節(jié)點(diǎn)啟動(dòng)成功,用MySQL客戶端能連接上之后,再去創(chuàng)建其他MySQL節(jié)點(diǎn)。

    #創(chuàng)建第1個(gè)MySQL節(jié)點(diǎn)
    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
    #創(chuàng)建第2個(gè)MySQL節(jié)點(diǎn)
    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
    #創(chuàng)建第3個(gè)MySQL節(jié)點(diǎn)
    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
    #創(chuàng)建第4個(gè)MySQL節(jié)點(diǎn)
    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
    #創(chuàng)建第5個(gè)MySQL節(jié)點(diǎn)
    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. 宿主機(jī)上編寫Haproxy配置文件

    vi /home/soft/haproxy/haproxy.cfg
    

    配置文件如下:

    global
     #工作目錄
     chroot /usr/local/etc/haproxy
     #日志文件,使用rsyslog服務(wù)中l(wèi)ocal5日志設(shè)備(/var/log/local5),等級(jí)info
     log 127.0.0.1 local5 info
     #守護(hù)進(jìn)程運(yùn)行
     daemon
    
    defaults
     log global
     mode    http
     #日志格式
     option  httplog
     #日志中不記錄負(fù)載均衡的心跳檢測(cè)記錄
     option  dontlognull
        #連接超時(shí)(毫秒)
     timeout connect 5000
        #客戶端超時(shí)(毫秒)
     timeout client  50000
     #服務(wù)器超時(shí)(毫秒)
        timeout server  50000
    
    #監(jiān)控界面    
    listen  admin_stats
     #監(jiān)控界面的訪問的IP和端口
     bind  0.0.0.0:8888
     #訪問協(xié)議
        mode        http
     #URI相對(duì)地址
        stats uri   /dbs
     #統(tǒng)計(jì)報(bào)告格式
        stats realm     Global\ statistics
     #登陸帳戶信息
        stats auth  admin:abc123456
    #數(shù)據(jù)庫(kù)負(fù)載均衡
    listen  proxy-mysql
     #訪問的IP和端口
     bind  0.0.0.0:3306  
        #網(wǎng)絡(luò)協(xié)議
     mode  tcp
     #負(fù)載均衡算法(輪詢算法)
     #輪詢算法:roundrobin
     #權(quán)重算法:static-rr
     #最少連接算法:leastconn
     #請(qǐng)求源IP算法:source 
        balance  roundrobin
     #日志格式
        option  tcplog
     #在MySQL中創(chuàng)建一個(gè)沒有權(quán)限的haproxy用戶,密碼為空。Haproxy使用這個(gè)賬戶對(duì)MySQL數(shù)據(jù)庫(kù)心跳檢測(cè)
        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檢測(cè)死鏈
        option  tcpka  
    
  9. 創(chuàng)建兩個(gè)Haproxy容器

    #創(chuàng)建第1個(gè)Haproxy負(fù)載均衡服務(wù)器
    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
    #進(jìn)入h1容器,啟動(dòng)Haproxy
    docker exec -it h1 bash
    haproxy -f /usr/local/etc/haproxy/haproxy.cfg
    #創(chuàng)建第2個(gè)Haproxy負(fù)載均衡服務(wù)器
    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
    #進(jìn)入h2容器,啟動(dòng)Haproxy
    docker exec -it h2 bash
    haproxy -f /usr/local/etc/haproxy/haproxy.cfg
    
  10. Haproxy容器內(nèi)安裝Keepalived,設(shè)置虛擬IP

注意事項(xiàng):云主機(jī)不支持虛擬IP,另外很多公司的網(wǎng)絡(luò)禁止創(chuàng)建虛擬IP(回家創(chuàng)建),還有宿主機(jī)一定要關(guān)閉防火墻和SELINUX,很多同學(xué)都因?yàn)檫@個(gè)而失敗的,切記切記

#進(jìn)入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
#啟動(dòng)Keepalived
service keepalived start
#宿主機(jī)執(zhí)行ping命令
ping 172.18.0.201

配置文件內(nèi)容如下:

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
    }
}
#進(jìn)入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
#啟動(dòng)Keepalived
service keepalived start
#宿主機(jī)執(zhí)行ping命令
ping 172.18.0.201

配置文件內(nèi)容如下:

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. 宿主機(jī)安裝Keepalived,實(shí)現(xiàn)雙機(jī)熱備

    #宿主機(jī)執(zhí)行安裝Keepalived
    yum -y install keepalived
    #修改Keepalived配置文件
    vi /etc/keepalived/keepalived.conf
    #啟動(dòng)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. 熱備份數(shù)據(jù)

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

    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的數(shù)據(jù)

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

    重新創(chuàng)建其余4個(gè)節(jié)點(diǎn),組件PXC集群

三、PXC 特別注意事項(xiàng)

PXC的主節(jié)點(diǎn)和從節(jié)點(diǎn)分別代表什么意義?

PXC中的主節(jié)點(diǎn)和從節(jié)點(diǎn)跟Replication主從節(jié)點(diǎn)是有巨大差別的。

首先Replication集群的數(shù)據(jù)同步只能是從主節(jié)點(diǎn)到從節(jié)點(diǎn),而且節(jié)點(diǎn)的身份是固定的,主節(jié)點(diǎn)永遠(yuǎn)是Master,從節(jié)點(diǎn)永遠(yuǎn)是Slave,不能互換。

但是PXC上的主節(jié)點(diǎn)指的是第一個(gè)啟動(dòng)的節(jié)點(diǎn),它不僅要啟動(dòng)MySQL服務(wù),還要用Galera創(chuàng)建PXC集群。這些工作完成之后,主節(jié)點(diǎn)自動(dòng)降級(jí)成普通節(jié)點(diǎn)。其他節(jié)點(diǎn)啟動(dòng)的時(shí)候只需要啟動(dòng)MySQL服務(wù),然后再加入到PXC集群即可,所以這些節(jié)點(diǎn)從啟動(dòng)到關(guān)閉,身份一直都是普通節(jié)點(diǎn)。

為什么Node1能啟動(dòng),而其他的PXC節(jié)點(diǎn)啟動(dòng)就閃退呢?

這是因?yàn)镹ode1啟動(dòng)的時(shí)候要做跟多工作,上面已經(jīng)提及了。所以你沒等node1把PXC集群創(chuàng)建出來(lái),你就飛快的啟動(dòng)其他PXC節(jié)點(diǎn),它們找不到Node1啟動(dòng)的PXC集群,所以就自動(dòng)閃退了。

正確的辦法是啟動(dòng)Node1之后,等待10秒鐘,然后用Navicat訪問一下,能訪問了,再去啟動(dòng)其他PXC節(jié)點(diǎn)

如果PXC集群在運(yùn)行的狀態(tài)下,在宿主機(jī)上直接關(guān)機(jī),或者停止Docker服務(wù),為什么下次啟動(dòng)哪個(gè)PXC節(jié)點(diǎn)都會(huì)閃退?

這個(gè)要從PXC集群的節(jié)點(diǎn)管理說(shuō)起,PXC節(jié)點(diǎn)的數(shù)據(jù)目錄是/var/lib/mysql,好在這個(gè)目錄被我們映射到數(shù)據(jù)卷上了。比如你訪問v1數(shù)據(jù)卷就能看到node1的數(shù)據(jù)目錄。這其中有個(gè)grastate.dat的文件,它里面有個(gè)safe_to_bootstrap參數(shù)被PXC用來(lái)記載誰(shuí)是最后退出PXC集群的節(jié)點(diǎn)。比如node1是最后關(guān)閉的節(jié)點(diǎn),那么PXC就會(huì)在把safe_to_bootstrap設(shè)置成1,代表node1節(jié)點(diǎn)最后退出,它的數(shù)據(jù)是最新的。下次啟動(dòng)必須先啟動(dòng)node1,然后其他節(jié)點(diǎn)與node1同步。

如果你在PXC節(jié)點(diǎn)都正常運(yùn)行的狀態(tài)下關(guān)閉宿主機(jī)Docker服務(wù)或者電源,那么PXC來(lái)不及判斷誰(shuí)是最后退出的節(jié)點(diǎn),所有PXC節(jié)點(diǎn)一瞬間就都關(guān)上了,哪個(gè)節(jié)點(diǎn)的safe_to_boostrap參數(shù)就都是0。解決這個(gè)故障也很好辦,那就是挑node1,把該參數(shù)改成1,然后正常啟動(dòng)node1,再啟動(dòng)其他節(jié)點(diǎn)就行了。

PXC集群只有一個(gè)節(jié)點(diǎn),關(guān)閉了這個(gè)節(jié)點(diǎn)的容器,下次還能啟動(dòng)起來(lái)嗎?

當(dāng)然是可以的,因?yàn)镻XC里只有一個(gè)節(jié)點(diǎn),那么這個(gè)節(jié)點(diǎn)一定是按照主節(jié)點(diǎn)啟動(dòng)的,所以啟動(dòng)它的時(shí)候,它會(huì)啟動(dòng)MySQL服務(wù),還創(chuàng)建出PXC集群。即便關(guān)閉了容器,下次再啟動(dòng)還是這個(gè)步驟,不會(huì)出現(xiàn)啟動(dòng)故障。如果說(shuō)PXC集群是由多個(gè)節(jié)點(diǎn)組成的,node1停掉了,其他節(jié)點(diǎn)都正常運(yùn)行。這時(shí)候啟動(dòng)node1是會(huì)出現(xiàn)閃退的,node1剛啟動(dòng)幾秒鐘就掛了。這是因?yàn)閚ode2等一些節(jié)點(diǎn)正在現(xiàn)有的PXC中運(yùn)行,這時(shí)候你啟動(dòng)node1,再創(chuàng)建一個(gè)同名的PXC集群,肯定會(huì)引發(fā)沖突啊。所以node1就閃退了。

遇到這種情況,正確的處理辦法是,把node1容器刪除。別緊張,沒讓你刪除v1數(shù)據(jù)卷,所以數(shù)據(jù)丟不了。然后用從節(jié)點(diǎn)的命令方式創(chuàng)建一個(gè)node1,啟動(dòng)參數(shù)中與某個(gè)節(jié)點(diǎn)同步的設(shè)置就隨便選擇一個(gè)現(xiàn)在運(yùn)行的PXC節(jié)點(diǎn),然后Node1就能啟動(dòng)了。

關(guān)于搭建技術(shù)體系,深入學(xué)習(xí)方面的感言

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

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

? 也正是IT互聯(lián)網(wǎng)公司造富神話太多,也就越來(lái)越多的資本涌入IT圈。有的資本公司做長(zhǎng)線,但是更多的資本公司炒短線。先投資一家小公司,然后再制造行業(yè)輿論和技術(shù)導(dǎo)向,當(dāng)人們被技術(shù)忽悠的瘋狂的時(shí)候,有人肯接盤了,這時(shí)候再把投資的這家小公司賣掉,割一波韭菜就撤。于是我們看到太多太多被熱炒的技術(shù),沒過1年時(shí)間就無(wú)人問津了。比如2014年的iOS技術(shù),2015年的VR技術(shù)等等。當(dāng)年VR技術(shù)被捧到天上,王雪紅一度被業(yè)界認(rèn)為會(huì)用VR讓HTC翻身,可是到現(xiàn)在我們?cè)僖猜牪坏紿TC這家公司的新聞了?;钪€是倒閉了,我們都不知道,大家也不關(guān)心。

? 所以我們選擇一個(gè)技術(shù)方向的時(shí)候,首先要看這個(gè)領(lǐng)域是不是有太多的水分,是不是有太多的熱錢。比如今年3月的時(shí)候,真格基金的徐小平發(fā)了一個(gè)微博說(shuō)自己非??春靡蕴患夹g(shù),于是短短時(shí)間,中國(guó)各家資本公司紛紛涌入?yún)^(qū)塊鏈領(lǐng)域。甚至還出現(xiàn)了2萬(wàn)塊錢的區(qū)塊鏈講師速成班,不管懂不懂計(jì)算機(jī),都能給你在短期內(nèi)培養(yǎng)成區(qū)塊鏈專家,然后你再去培訓(xùn)機(jī)構(gòu)忽悠人,月薪兩萬(wàn),割學(xué)技術(shù)大學(xué)生的韭菜。我想,徐小平在微博上把區(qū)塊鏈捧到天上,何嘗不是一種資本炒作的手法呢。

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

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

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

? 究其原因還是管理者用錯(cuò)了開發(fā)模型,瀑布模型看似合理,但是問題在于編碼階段太靠后,等拿出半成品已經(jīng)小半年時(shí)間過去了。因此瀑布模型適用于那種能提出明確需求,而且到每一處細(xì)節(jié)的客戶。像A客戶這樣的人,我們應(yīng)該用螺旋模型去開發(fā),小規(guī)??焖俚?,只開發(fā)最核心模塊,短期內(nèi)就拿出演示品跟客戶確認(rèn)。這種小步快跑的策略適合提不出具體需求和需求不明確的場(chǎng)合。所以說(shuō),同學(xué),以后你想做管理者,是不是得了解“軟件工程”的知識(shí)?。?/p>

? 這幾年我在教育部舉辦的互聯(lián)網(wǎng)+創(chuàng)新創(chuàng)業(yè)大賽預(yù)賽和決賽當(dāng)評(píng)委的時(shí)候,跟很多大學(xué)生創(chuàng)業(yè)的同學(xué)講到了,你的創(chuàng)業(yè)想法很好,但是很可能項(xiàng)目會(huì)作廢了。起初他們不相信,覺得自己拿到風(fēng)投的錢,幾個(gè)學(xué)軟件的同學(xué)會(huì)編程,這就足夠了。于是次年的時(shí)候,我又見到了這些同學(xué),參賽的題目又換了。我就好奇的問他們,去年的創(chuàng)業(yè)項(xiàng)目做成了嗎?他們跟我說(shuō),創(chuàng)業(yè)項(xiàng)目做砸了。呵呵,果然是這樣。因?yàn)樗麄兊膱F(tuán)隊(duì)里缺少了技術(shù)方面的全才。僅靠專才是不能完成項(xiàng)目開發(fā)的。我再舉一個(gè)例子,某公司的開發(fā)者老張,他是做后端比較擅長(zhǎng),因?yàn)楣ぷ髂觐^比較長(zhǎng)了,于是就被提拔成了項(xiàng)目經(jīng)理。有一天,日方客戶發(fā)來(lái)一封郵件,說(shuō)某模塊的業(yè)務(wù)流程要修改,看看中方這邊多長(zhǎng)時(shí)間能實(shí)現(xiàn),費(fèi)用是多少。于是老張就召集團(tuán)隊(duì)的人開了一次會(huì)。老張擅長(zhǎng)后臺(tái)開發(fā),這次需求覺得沒什么難度,然后問了問數(shù)據(jù)庫(kù)的哥們和前端的哥們,他們說(shuō)也好實(shí)現(xiàn),然后老張就承諾日方兩天就能做完。但是過于樂觀的態(tài)度,很容易引來(lái)噩夢(mèng)般的后果。數(shù)據(jù)庫(kù)的哥們和前端的哥們,寫代碼的時(shí)候才發(fā)現(xiàn)實(shí)現(xiàn)難度很大,最后花了半個(gè)月才做完,浪費(fèi)了大量的加班費(fèi)用。因?yàn)槔蠌埐欢岸?,也不懂?dāng)?shù)據(jù)庫(kù)集群,覺得底下人說(shuō)什么就代表什么。由此看出,管理者技術(shù)必須全面,不能人云亦云,必須保持自己的判斷力。

? 說(shuō)了這么多,也非常感謝大家在慕課網(wǎng)上支持我的課程,后續(xù)我還會(huì)在慕課網(wǎng)上錄制更多的實(shí)戰(zhàn)課,將我們的技術(shù)體系拼圖給逐步完成。目前正在錄制Python的課程和其他的開發(fā)課程,請(qǐng)大家稍加等待。下面列出來(lái)我在慕課網(wǎng)上所有課程的連接,以供大家學(xué)習(xí)。

《MySQL數(shù)據(jù)庫(kù)集群-PXC方案》

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

《Docker環(huán)境下的前后端分離項(xiàng)目部署與運(yùn)維》

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

安裝Redis,配置RedisCluster集群

  1. 安裝Redis鏡像

    docker pull yyyyttttwwww/redis
    
  2. 創(chuàng)建net2網(wǎng)段

    docker network create --subnet=172.19.0.0/16 net2
    
  3. 創(chuàng)建6節(jié)點(diǎn)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配置文件里必須要設(shè)置bind 0.0.0.0,這是允許其他IP可以訪問當(dāng)前redis。如果不設(shè)置這個(gè)參數(shù),就不能組建Redis集群。

  4. 啟動(dòng)6節(jié)點(diǎn)Redis服務(wù)器

    #進(jìn)入r1節(jié)點(diǎn)
    docker exec -it r1 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    #進(jìn)入r2節(jié)點(diǎn)
    docker exec -it r2 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    #進(jìn)入r3節(jié)點(diǎn)
    docker exec -it r3 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    #進(jìn)入r4節(jié)點(diǎn)
    docker exec -it r4 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    #進(jìn)入r5節(jié)點(diǎn)
    docker exec -it r5 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    #進(jìn)入r6節(jié)點(diǎn)
    docker exec -it r6 bash
    cp /home/redis/redis.conf /usr/redis/redis.conf
    cd /usr/redis/src
    ./redis-server ../redis.conf
    
  5. 創(chuàng)建Cluster集群

    #在r1節(jié)點(diǎn)上執(zhí)行下面的指令
    cd /usr/redis/src
    mkdir -p ../cluster
    cp redis-trib.rb ../cluster/
    cd ../cluster
    #創(chuàng)建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
    

打包部署后端項(xiàng)目

  1. 進(jìn)入人人開源后端項(xiàng)目,執(zhí)行打包(修改配置文件,更改端口,打包三次生成三個(gè)JAR文件)

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

    docker pull java
    
  3. 創(chuàng)建3節(jié)點(diǎn)Java容器

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

    docker pull nginx
    
  5. 創(chuàng)建Nginx容器,配置負(fù)載均衡

    宿主機(jī)上/home/n1/nginx.conf配置文件內(nèi)容如下:

    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;  
            }  
        }
    }
    

    創(chuàng)建第1個(gè)Nginx節(jié)點(diǎn)

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

    宿主機(jī)上/home/n2/nginx.conf配置文件內(nèi)容如下:

    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;  
            }  
        }
    }
    

    創(chuàng)建第2個(gè)Nginx節(jié)點(diǎn)

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

    #進(jìn)入n1節(jié)點(diǎn)
    docker exec -it n1 bash
    #更新軟件包
    apt-get update
    #安裝VIM
    apt-get install vim
    #安裝Keepalived
    apt-get install keepalived
    #編輯Keepalived配置文件(如下)
    vim /etc/keepalived/keepalived.conf
    #啟動(dòng)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
        }
    }
    
    #進(jìn)入n1節(jié)點(diǎn)
    docker exec -it n2 bash
    #更新軟件包
    apt-get update
    #安裝VIM
    apt-get install vim
    #安裝Keepalived
    apt-get install keepalived
    #編輯Keepalived配置文件(如下)
    vim /etc/keepalived/keepalived.conf
    #啟動(dòng)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
        }
    }
    

打包部署后端項(xiàng)目

  1. 在前端項(xiàng)目路徑下執(zhí)行打包指令

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

  3. 創(chuàng)建3節(jié)點(diǎn)的Nginx,部署前端項(xiàng)目

    宿主機(jī)/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;
         }
     }
    }
    
    #啟動(dòng)第fn1節(jié)點(diǎn)
    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
    

    宿主機(jī)/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;
         }
     }
    }
    
    #啟動(dòng)第fn2節(jié)點(diǎn)
    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
    

    宿主機(jī)/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;
         }
     }
    }
    

    啟動(dòng)fn3節(jié)點(diǎn)

    #啟動(dòng)第fn3節(jié)點(diǎn)
    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. 配置負(fù)載均衡

    宿主機(jī)/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;  
            }  
        }
    }
    
    #啟動(dòng)ff1節(jié)點(diǎn)
    docker run -it -d --name ff1 -v /home/ff1/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
    

    宿主機(jī)/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;  
            }  
        }
    }
    
    #啟動(dòng)ff2節(jié)點(diǎn)
    docker run -it -d --name ff2 -v /home/ff2/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
    
  5. 配置雙機(jī)熱備

    #進(jìn)入ff1節(jié)點(diǎn)
    docker exec -it ff1 bash
    #更新軟件包
    apt-get update
    #安裝VIM
    apt-get install vim
    #安裝Keepalived
    apt-get install keepalived
    #編輯Keepalived配置文件(如下)
    vim /etc/keepalived/keepalived.conf
    #啟動(dòng)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
        }
    }
    
    #進(jìn)入ff1節(jié)點(diǎn)
    docker exec -it ff2 bash
    #更新軟件包
    apt-get update
    #安裝VIM
    apt-get install vim
    #安裝Keepalived
    apt-get install keepalived
    #編輯Keepalived配置文件(如下)
    vim /etc/keepalived/keepalived.conf
    #啟動(dòng)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
        }
    }
    

    ?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容