使用 TC 和 Netem 模擬網(wǎng)絡(luò)異常

參考:https://juejin.cn/post/6844903673760350221

在某些情況下,我們需要模擬網(wǎng)絡(luò)很差的狀態(tài)來測試軟件能夠正常工作辞居,比如網(wǎng)絡(luò)延遲楷怒、丟包、亂序瓦灶、重復(fù)等鸠删。Linux 系統(tǒng)下強(qiáng)大的流量控制工具 TC 能很輕松地完成這個需求,TC 命令行工具是 IProute2 軟件包中的軟件贼陶,可以根據(jù)系統(tǒng)版本自行安裝刃泡。
這篇文章介紹的功能主要是通過 Netem 這個內(nèi)核模塊來實現(xiàn)的。Netem 是 Network Emulator 的縮寫每界,關(guān)于更多功能以及參數(shù)的詳細(xì)解釋可以參閱 TC-Netem 的 Man Page捅僵。
Netem 與 TC 簡要說明
Netem 是 Linux 2.6 及以上內(nèi)核版本提供的一個網(wǎng)絡(luò)模擬功能模塊。該功能模塊可以用來在性能良好的局域網(wǎng)中眨层,模擬出復(fù)雜的互聯(lián)網(wǎng)傳輸性能庙楚。例如:低帶寬、傳輸延遲趴樱、丟包等等情況馒闷。使用 Linux 2.6 (或以上) 版本內(nèi)核的很多 Linux 發(fā)行版都默認(rèn)開啟了該內(nèi)核模塊,比如:Fedora叁征、Ubuntu纳账、Redhat、OpenSuse捺疼、CentOS疏虫、Debian 等等。
TC 是 Linux 系統(tǒng)中的一個用戶態(tài)工具,全名為 Traffic Control (流量控制)卧秘。TC 可以用來控制 Netem 模塊的工作模式呢袱,也就是說如果想使用 Netem 需要至少兩個條件,一是內(nèi)核中的 Netem 模塊被啟用翅敌,另一個是要有對應(yīng)的用戶態(tài)工具 TC 羞福。

TC 能做的事情很多,除了本文介紹的還有帶寬控制蚯涮、優(yōu)先級控制等等治专。這些功能是通過類似 Netem 的內(nèi)核模塊實現(xiàn)的。
    

網(wǎng)絡(luò)狀況模擬
網(wǎng)絡(luò)狀況欠佳從用戶角度來說就是下載東西慢(網(wǎng)頁一直加載遭顶、視頻卡頓张峰、圖片加載很久等),從網(wǎng)絡(luò)報文角度來看卻有很多情況:比如:延遲(某個機(jī)器發(fā)送報文很慢)液肌、丟包(發(fā)送的報文在網(wǎng)絡(luò)中丟失需要一直重傳)挟炬、亂序(報文順序錯亂鸥滨,需要大量計算時間來重新排序)嗦哆、重復(fù)(報文有大量重復(fù),導(dǎo)致網(wǎng)絡(luò)擁堵)婿滓、錯誤(接收到的報文有誤只能丟棄重傳)等老速。
對于這些情況,都可以用 Netem 來模擬凸主。需要注意的是橘券,Netem 是直接作用于指定網(wǎng)卡上的,也就是說所有從該網(wǎng)卡發(fā)送出去的包都會收到配置參數(shù)的影響卿吐,所以最好搭建臨時的虛擬機(jī)進(jìn)行測試旁舰。
在下面的例子中 add 表示為指定網(wǎng)卡添加 Netem 配置,change 表示修改已經(jīng)存在的 Netem 配置到新的值嗡官,replace 表示替換已經(jīng)存在的 Netem 配置的值箭窜。如果要刪除網(wǎng)卡上的 Netem 配置可以使用 del。
$ tc qdisc del dev enp0s5 root復(fù)制代碼
1. 模擬延遲傳輸
最簡單的例子是所有的報文延遲 100ms 發(fā)送:
$ tc qdisc add dev enp0s5 root netem delay 100ms復(fù)制代碼
如果你想在一個局域網(wǎng)里模擬遠(yuǎn)距離傳輸?shù)难舆t可以用這個方法衍腥,比如實際用戶訪問網(wǎng)站延遲為 101 ms磺樱,而你測試環(huán)境網(wǎng)絡(luò)交互只需要 1ms,那么只要添加 100ms 額外延遲就行婆咸。
$ tc qdisc replace dev enp0s5 root netem delay 100ms

$ ping dev-node-02
PING dev-node-02 (192.168.100.212) 56(84) bytes of data.
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=1 ttl=64 time=102 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=2 ttl=64 time=100 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=3 ttl=64 time=100 ms
^C
--- dev-node-02 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 100.293/101.053/102.795/1.061 ms復(fù)制代碼
如果在網(wǎng)絡(luò)中看到非常穩(wěn)定的時延,很可能是某個地方加了定時器,因為網(wǎng)絡(luò)線路很復(fù)雜第岖,傳輸過程一定會有變化毙死。因此實際情況網(wǎng)絡(luò)延遲一定會有變化的,Netem 也考慮到這一點(diǎn),提供了額外的參數(shù)來控制延遲的時間分布憨闰。完整的參數(shù)列表為:
DELAY := delay TIME [ JITTER [ CORRELATION ]]]
[ distribution { uniform | normal | pareto | paretonormal } ]復(fù)制代碼
除了延遲時間 TIME 之外询兴,還有三個可選參數(shù):

        JITTER:抖動,增加一個隨機(jī)時間長度起趾,讓延遲時間出現(xiàn)在某個范圍诗舰。
    
    
        CORRELATION:相關(guān),下一個報文延遲時間和上一個報文的相關(guān)系數(shù)训裆。
    
    
        distribution:分布眶根,延遲的分布模式”吡穑可以選擇的值有 uniform属百、 normal、pareto 和 paretonormal变姨。
    

先說說 JITTER族扰,如果設(shè)置為 20ms,那么報文延遲的時間在 100ms  ± 20ms 之間定欧,具體值隨機(jī)選擇:
$ tc qdisc replace dev enp0s5 root netem delay 100ms 20ms

ping dev-node-02 PING dev-node-02 (192.168.100.212) 56(84) bytes of data. 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=1 ttl=64 time=108 ms 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=2 ttl=64 time=107 ms 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=3 ttl=64 time=92 ms ......復(fù)制代碼 CORRELATION 指相關(guān)性渔呵,因為網(wǎng)絡(luò)狀況是平滑變化的,短時間里相鄰報文的延遲應(yīng)該是近似的而不是完全隨機(jī)的砍鸠。這個值是個百分比扩氢,如果為 100%,就退化到固定延遲的情況爷辱;如果是 0% 則退化到隨機(jī)延遲的情況录豺。 tc qdisc replace dev enp0s5 root netem delay 100ms 20ms 50%
ping dev-node-02 PING dev-node-02 (192.168.100.212) 56(84) bytes of data. 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=1 ttl=64 time=104 ms 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=2 ttl=64 time=109 ms 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=5 ttl=64 time=101 ms ......復(fù)制代碼 報文的分布和很多現(xiàn)實事件一樣都滿足某種統(tǒng)計規(guī)律,比如最常用的正態(tài)分布饭弓。因此為了更逼近現(xiàn)實情況双饥,可以使用 distribution 參數(shù)來限制它的延遲分布模型。比如讓報文延遲時間滿足正態(tài)分布: tc qdisc replace dev enp0s5 root netem delay 100ms 20ms distribution normal
ping dev-node-02 PING dev-node-02 (192.168.100.212) 56(84) bytes of data. 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=1 ttl=64 time=82.0 ms 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=2 ttl=64 time=82.3 ms 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=3 ttl=64 time=98.1 ms ......復(fù)制代碼 這樣的話弟断,大部分的延遲會在平均值的一定范圍內(nèi)咏花,而很少接近出現(xiàn)最大值和最小值的延遲。 其他分布方法包括:uniform夫嗓、pareto 和 paretonormal迟螺,這些分布方法感興趣的讀者可以自行了解。對于大多數(shù)情況舍咖,隨機(jī)在某個時間范圍里延遲就能滿足需求的矩父。 2. 模擬丟包率 另一個常見的網(wǎng)絡(luò)異常是因為丟包,丟包會導(dǎo)致重傳排霉,從而增加網(wǎng)絡(luò)鏈路的流量和延遲窍株。Netem 的 loss 參數(shù)可以模擬丟包率,比如發(fā)送的報文有 50% 的丟包率(為了容易用 ping 看出來,所以這個數(shù)字我選的很大球订,實際情況丟包率可能比這個小很多后裸,比如 0.5%): tc qdisc change dev enp0s5 root netem loss 50%
ping dev-node-02 PING dev-node-02 (192.168.100.212) 56(84) bytes of data. 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=1 ttl=64 time=0.290 ms 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=4 ttl=64 time=0.308 ms 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=5 ttl=64 time=0.221 ms 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=8 ttl=64 time=0.371 ms 64 bytes from dev-node-02 (192.168.100.212): icmp_seq=9 ttl=64 time=0.315 ms復(fù)制代碼 可以從 icmp_seq 序號看出來大約有一半的報文丟掉了,和延遲類似丟包率也可以增加一個相關(guān)系數(shù)冒滩,表示后一個報文丟包概率和它前一個報文的相關(guān)性微驶。 tc qdisc change dev enp0s5 root netem loss 0.3% 25%復(fù)制代碼
這個命令表示,丟包率是 0.3%开睡,并且當(dāng)前報文丟棄的可能性和前一個報文有 25% 相關(guān)因苹。默認(rèn)的丟包模型為隨機(jī),loss 也支持 state(4-state Markov 模型) 和 gemodel(Gilbert-Elliot 丟包模型) 兩種模型的丟包篇恒,因為兩者都相對復(fù)雜扶檐,這里就不再詳細(xì)介紹了。
需要注意的是胁艰,丟包信息會發(fā)送到上層協(xié)議款筑。如果是 TCP 協(xié)議,那么 TCP 會進(jìn)行重傳腾么,所以對應(yīng)用來說看不到丟包奈梳。這時候要模擬丟包,需要把 loss 配置到網(wǎng)橋或者路由設(shè)備上哮翘。
3. 模擬包重復(fù)
報文重復(fù)和丟包的參數(shù)類似颈嚼,就是重復(fù)率和相關(guān)性兩個參數(shù)毛秘,比如隨機(jī)產(chǎn)生 50% 重復(fù)的包:
tc qdisc change dev enp0s5 root netem duplicate 50% ping dev-node-02
PING dev-node-02 (192.168.100.212) 56(84) bytes of data.
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=2 ttl=64 time=0.284 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=3 ttl=64 time=0.420 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=3 ttl=64 time=0.447 ms (DUP!)
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=4 ttl=64 time=0.437 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=4 ttl=64 time=0.515 ms (DUP!)
......復(fù)制代碼
4. 模擬包損壞
報文損壞和報文重復(fù)的參數(shù)也類似饭寺,比如隨機(jī)產(chǎn)生 2% 損壞的報文(在報文的隨機(jī)位置造成一個比特的錯誤)。
tc qdisc change dev enp0s5 root netem corrupt 2% ping dev-node-02
......
PING dev-node-02 (192.168.100.212) 56(84) bytes of data.
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=3 ttl=64 time=0.362 ms
Warning: time of day goes back (-4611686018427387574us), taking countermeasures.
Warning: time of day goes back (-4611686018427387454us), taking countermeasures.
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=4 ttl=64 time=0.000 ms
wrong data byte #53 should be 0x35 but was 0xb5

16 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f

48 30 31 32 33 34 b5 36 37

64 bytes from dev-node-02 (192.168.100.212): icmp_seq=5 ttl=64 time=0.476 ms
......復(fù)制代碼
5. 模擬包亂序
網(wǎng)絡(luò)傳輸并不能保證順序叫挟,傳輸層 TCP 會對報文進(jìn)行重組保證順序艰匙,所以報文亂序?qū)?yīng)用的影響比上面的幾種問題要小。
報文亂序和前面的參數(shù)不太一樣抹恳,因為上面的報文問題都是獨(dú)立的员凝。針對單個報文做操作就行,而亂序則牽涉到多個報文的重組奋献。模擬報亂序一定會用到延遲(因為模擬亂序的本質(zhì)就是把一些包延遲發(fā)送)健霹,Netem 有兩種方法可以做。
第一種是固定的每隔一定數(shù)量的報文就亂序一次瓶蚂。
# 每 5 個報文(第 5糖埋、10、15…報文)會正常發(fā)送窃这,其他的報文延遲 100ms瞳别。
tc qdisc change dev enp0s5 root netem reorder 50% gap 3 delay 100ms ping -i 0.05 dev-node-02
PING dev-node-02 (192.168.100.212) 56(84) bytes of data.
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=9 ttl=64 time=2.55 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=8 ttl=64 time=100 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=10 ttl=64 time=100 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=11 ttl=64 time=100 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=13 ttl=64 time=0.245 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=12 ttl=64 time=102 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=14 ttl=64 time=1.00 ms
......復(fù)制代碼
要想看到 ping 報文的亂序,我們要保證發(fā)送報文的間隔小于報文的延遲時間 100ms,這里用 -i 0.05 把發(fā)送間隔設(shè)置為 50ms祟敛。
第二種方法的亂序是相對隨機(jī)的疤坝,使用概率來選擇亂序的報文。
tc qdisc change dev enp0s5 root netem reorder 50% 15% delay 300ms ping -i 0.05 dev-node-02
PING dev-node-02 (192.168.100.212) 56(84) bytes of data.
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=4 ttl=64 time=0.423 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=7 ttl=64 time=0.250 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=2 ttl=64 time=301 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=3 ttl=64 time=301 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=9 ttl=64 time=0.238 ms
64 bytes from dev-node-02 (192.168.100.212): icmp_seq=5 ttl=64 time=301 ms
......復(fù)制代碼
50% 的報文會正常發(fā)送馆铁,其他報文(1-50%)延遲 300ms 發(fā)送跑揉,這里選擇的延遲很大是為了能夠明顯看出來亂序的結(jié)果。
6. 其它技巧

        查看已經(jīng)配置的網(wǎng)絡(luò)條件
    

該命令將查看并顯示 enp0s5 網(wǎng)卡的相關(guān)傳輸配置埠巨。
$ tc qdisc show dev enp0s5復(fù)制代碼
推薦兩個工具
Netem 在 TC 中算是比較簡單的模塊畔裕,如果要實現(xiàn)流量控制或者精細(xì)化的過濾需要更復(fù)雜的配置。這里推薦兩個小工具乖订,它們共同的特點(diǎn)是用法簡單扮饶,能滿足特定的需求,而不用自己去倒騰 TC 的命令乍构。
1. Wondershaper
項目地址:https://github.com/magnific0/wondershaper
Netem 只能模擬網(wǎng)絡(luò)狀況甜无,不能控制帶寬,Wondershaper 則能完美解決這個問題哥遮。Wondershaper 實際上是一個 SHELL 腳本岂丘,它使用 TC 來進(jìn)行流量速率調(diào)整,使用 QoS 來處理特定的網(wǎng)絡(luò)接口眠饮。外發(fā)流量通過放在不同優(yōu)先級的隊列中奥帘,來達(dá)到限制傳出流量速率的目的;而傳入流量通過丟包的方式來達(dá)到速率限制的目的仪召。
安裝 Wondershaper

    
        在 Ubuntu / Debian 下安裝 Wondershaper
    

$ sudo apt-get install wondershaper復(fù)制代碼

    
        在 Fdora / CentOS / RHEL 中安裝 Wondershaper
    

# 需啟用 EPEL 倉庫

sudo yum install wondershaper復(fù)制代碼 使用 Wondershaper Wondershaper 的使用非常簡單寨蹋,只有三個參數(shù):網(wǎng)卡名、下行限速扔茅、上行限速已旧。比如要設(shè)置網(wǎng)卡下載速度為 200kb/s,上傳速度為 150kb/s: sudo wondershaper enp0s5 200 150復(fù)制代碼
如果你要將速率限制消除召娜,可以通過運(yùn)行下面的命令來達(dá)到目的运褪。
sudo wondershaper clear enp0s5復(fù)制代碼 2. Comcast 項目地址:https://github.com/tylertreat/comcast Comcast 是一個跨平臺的網(wǎng)絡(luò)模擬工具,旨在其他平臺(OSX玖瘸、Windows秸讹、BSD)也能提供類似網(wǎng)絡(luò)模擬的功能。 它的使用也相對簡單: comcast --device=enp0s5 --latency=250
--target-bw=1000
--default-bw=1000000
--packet-loss=10%
--target-addr=8.8.8.8,10.0.0.0/24
--target-proto=tcp,udp,icmp
--target-port=80,22,1000:2000復(fù)制代碼

        --device 說明要控制的網(wǎng)卡為 enp0s5雅倒。
    
    
        --latency 指定 250ms 的延遲璃诀。
    
    
        --target-bw指定目標(biāo)帶寬。
    
    
        --default-bw 指定默認(rèn)帶寬屯断。
    
    
        --packet-loss 指定丟包率文虏。
    
    
        --target-addr侣诺、 --target-proto、--target-port 參數(shù)指定在滿足這些條件的報文上實施上面的配置氧秘。
    

總結(jié)
可以看出年鸳,TC 的 Netem 模塊主要用來模擬各種網(wǎng)絡(luò)的異常狀況,本身并沒有提供寬帶限制的功能丸相,而且一旦在網(wǎng)卡上配置了 Netem搔确,該網(wǎng)卡上所有的報文都會受影響,如果想精細(xì)地控制部分報文灭忠,需要用到 TC 的 filter 功能膳算。
參考資料
http://www.google.comhttp://t.cn/RsUAV3yhttp://t.cn/RsUwmQXhttp://t.cn/RsUVqk0
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市弛作,隨后出現(xiàn)的幾起案子涕蜂,更是在濱河造成了極大的恐慌,老刑警劉巖映琳,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件机隙,死亡現(xiàn)場離奇詭異,居然都是意外死亡萨西,警方通過查閱死者的電腦和手機(jī)有鹿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谎脯,“玉大人葱跋,你說我怎么就攤上這事≡此螅” “怎么了娱俺?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長咸产。 經(jīng)常有香客問我矢否,道長,這世上最難降的妖魔是什么脑溢? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮赖欣,結(jié)果婚禮上屑彻,老公的妹妹穿的比我還像新娘。我一直安慰自己顶吮,他們只是感情好社牲,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著悴了,像睡著了一般搏恤。 火紅的嫁衣襯著肌膚如雪违寿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天熟空,我揣著相機(jī)與錄音藤巢,去河邊找鬼。 笑死息罗,一個胖子當(dāng)著我的面吹牛掂咒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播迈喉,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼绍刮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了挨摸?” 一聲冷哼從身側(cè)響起孩革,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎得运,沒想到半個月后嫉戚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡澈圈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年彬檀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞬女。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡窍帝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诽偷,到底是詐尸還是另有隱情坤学,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布报慕,位于F島的核電站深浮,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏眠冈。R本人自食惡果不足惜飞苇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜗顽。 院中可真熱鬧布卡,春花似錦、人聲如沸雇盖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崔挖。三九已至贸街,卻和暖如春庵寞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背薛匪。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工捐川, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛋辈。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓属拾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親冷溶。 傳聞我的和親對象是個殘疾皇子渐白,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容