1. 程式人生 > >lvs+srs(dr模型)

lvs+srs(dr模型)

srs+lvs

參考:

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模式原理簡介:

技術分享

在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 查看確認視頻可正常播放


lvs+srs(dr模型)