lvs+srs(dr模型)

參考:

https://my.oschina.net/fengjihu/blog/416883 (srs集羣模式)

http://blog.csdn.net/reblue520/article/details/50857078 (lvs負載均衡)

http://www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html (arp_ignore和arp_announce)

http://www.linuxvirtualserver.org/docs/arp.html (lvs arp問題)

http://www.linuxvirtualserver.org/VS-DRouting.html (lvs dr模式)

目的:

通過lvs推流到多個流服務器以緩解服務器壓力,利用邊緣服務器的功能可以訪問到所有流,又可以節約帶寬,因爲是直播,所以推過來的流都是不同ip的,所以可以利用lvs hash ip的功能將同一流的包轉發到同一流服務器,這樣就解決了流的存放問題。

lvs dr模式原理簡介:

wKiom1kcCGrSiCwPAAAo30AS-7w834.gif

    在dr模式下,director、real server和vip都在同一網段中,這就帶來了幾個問題:

1.在此模式下,vip接收到的請求不能簡單地通過轉發給real server,因爲當請求過來的時候,如果簡單地轉發,因爲三臺都能連外網,所以轉發的時候real server會直接回復給請求方,而請求方收到ip,發現不是自己請求的會丟棄。

    所以,每個real server上面都綁定了vip,當收到vip來的請求包的時候,real server 用vip作爲源地址回覆。


2.我們解決了1的問題,但是這又帶來了新的問題:director和real server都有vip,而且在同一網段中,所以vip請求到來的時候,網關會廣播請求,所以不管是director還是realserver他們都會收到請求,假設我們director先收到了,它是怎麼進行負載均衡調度的呢?

    利用ip是不行的,如果用realserver的真實ip,那麼就會回到1的問題上去,所以只能用vip作爲目的ip。事實上,dr模式下,lvs是根據mac地址來進行負載均衡調度的,因爲每臺的mac地址都不同,所以只有對應mac的rs(realserver簡寫,懶得打)會收到請求,並且因爲自己確實有vip,所以能響應請求。 


3.那麼,我們又怎麼確保director第一個收到呢?在同一網段中,每臺服務器都會收到vip請求廣播包,我們怎麼保證rs既能響應這些請求又不首先響應?這就要用到arp_ignore和arp_announce或者hidden interface的功能。

    在dr模式下,rs的配置是有些特殊的。比較常見的一種是把vip綁定到lo口上,因爲大多數linux內核版本不會響應迴環口ip的arp報文請求,所以當收到vip廣播請求報文的時候,rs不會響應。因爲director是把vip綁定到某個非迴環口上的,所以director可以第一個收到並響應vip請求報文。 另一種常見的做法是,rs把vip綁定到某個不在使用中的接口上,然後利用hidden interface的功能禁掉此接口的arp響應,因爲沒有arp響應,所以這個端口必須不使用,否則影響正常通信。 

         我們的案例使用的是第三種常見的方法:設置arp_ignore 爲1,這個參數的作用是隻回答目標IP地址是來訪網絡接口本地地址的ARP查詢請求

            舉個例子,假設本機上兩個網口,eth0上綁定的ip爲1.1.1.1,eth1上綁定的是2.2.2.2,那麼設置arp_ignore爲1後,當eth0收到2.2.2.2的arp請求報文後不會響應,同理eth1收到1.1.1.1的arp請求報文不會響應(eth0:0子網卡不確定可不可以,待測試)

 然後,設置arp_announce爲2,這個的作用是使用出口網口的mac作爲源mac。

    舉個例子,假設本機有eth0:1.1.1.1,eth1:2.2.2.2 ,假設本機收到了1.1.1.1的請求包,卻從eth1口發送包,那麼數據幀的源mac應該是寫eth0的mac還是eth1的mac?  正常情況下是寫eth1的,但是linux比較特殊,默認是寫eth0的,設爲2,是讓它默認寫eth1的。      

         爲什麼這裏需要用到呢?因爲vip包是director第一個響應的,所以網關的arp表保留的是director的mac,假設rs,eth0配的真實ip,eth1配的vip,那麼,當收到director改寫mac的vip請求包後,它響應並從eth0回送包(我們不應該讓eth1接受到包,否則又回到2),如果此時填的是eth1,也就是vip所在的mac,那麼網關發現這個是vip的新mac就會更新arp表,從而造成vip搶佔(這個是別人的說法,我不太認同,因爲就算用eth0的mac也會被更新,一樣搶佔,待我找到靠譜的答案再更新此問題)


架構:

director ip:192.168.2.119(lvs調度器服務器ip)

virtual  ip:192.168.2.111(調度用的虛擬ip)

real1    ip:192.168.2.127(srs源端服務器ip1)

real2    ip:192.168.2.138(srs源端服務器ip2)

srs ip:192.168.2.221 (此爲srs邊緣服務器ip)

爲了實驗方便,默認都關閉iptables和selinux


real1:

echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore

echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

    echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce

echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

cd  /etc/sysconfig/network-scripts/

cp ifcfg-lo  ifcfg-lo:0

vi ifcfg-lo:0 內容如下:


            DEVICE=lo:0

            IPADDR=192.168.2.111

            NETMASK=255.255.255.255

            BROADCAST=192.168.2.111

            BROADCAST=127.255.255.255

            ONBOOT=yes

            NAME=loopback

service network  restart

vi  /usr/local/srs/conf/edge.conf 內容如下:

            listen              1935;

            max_connections     1000;

            pid                 objs/edge.pid;

            srs_log_file        ./objs/edge.log;

            vhost __defaultVhost__ {

            }


service srs restart  

route add -host 192.168.2.111 dev lo:0  #加這條是爲了保證本機響應包的源ip爲vip不變

real2:

配置和real1一樣,略

srs 邊緣服務器的配置:

vi  /usr/local/srs/conf/edge.conf 

            listen              1935;

            max_connections     1000;

            pid                 objs/edge.pid;

            srs_log_file        ./objs/edge.log;

            vhost __defaultVhost__ {

                mode            remote;

                origin          192.168.2.138:1935  192.168.2.127:1935;  (經測試,當192.168.2.138和192.168.2.127存在不同流的時候,

            }                                 用這種配置邊緣服務器可以訪問兩臺服務器上的所有流)              

        service srs restart

direct 的配置:

vi  /etc/sysctl.conf

net.ipv4.ip_forward = 1 (lvs轉發包,所以這個要爲1,開啓轉發功能)

sysctl -p

yum install ipvsadm  -y (lvs是通過ipvsadm這個軟件包管理的,就類似於netfiter和iptables的關係)

cd  /etc/sysconfig/network-scripts/

cp ifcfg-eth0  ifcfg-eth0:0

vi ifcfg-eth0:0 內容如下:

            DEVICE=eth0:0

            BOOTPROTO=static

            HWADDR=00:0C:29:5B:58:99

            ONBOOT=yes

            IPADDR=192.168.2.111

            GATEWAY=192.168.2.1

            NETMASK=255.255.255.0


service network  restart

route add 192.168.2.111 dev eth0:0

ipvsadm  -A -t 192.168.2.111:1935 -s sh (添加服務,-s指定調度算法,sh是source_hash的意思,根據來源ip調度到同一臺服務器)

ipvsadm  -a  -t 192.168.2.111:1935 -r 192.168.2.138:1935 -m  (添加後端服務器)

ipvsadm  -a  -t 192.168.2.111:1935 -r 192.168.2.127:1935 -m

ipvsadm -Ln (這個命令可以查看ipvs當前的狀態)

推流測試:

/usr/local/src/srs/trunk/objs/ffmpeg/bin/ffmpeg  -re -i test.flv -vcodec copy -acodec copy -f flv -y rtmp://192.168.2.111/live/livestream1

/usr/local/src/srs/trunk/objs/ffmpeg/bin/ffmpeg  -re -i test2.flv -vcodec copy -acodec copy -f flv -y rtmp://192.168.2.111/live/livestream2

通過rtmp://192.168.2.221/live/livestream1和rtmp://192.168.2.221/live/livestream2 查看確認視頻可正常播放


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