超詳細(xì)的秒殺架構(gòu)設(shè)計(jì)

前言:秒殺系統(tǒng)相信很多人見過伪货,比如京東或者淘寶的秒殺叫搁,小米手機(jī)的秒殺奈辰,那么秒殺系統(tǒng)的后臺(tái)是如何實(shí)現(xiàn)的呢潮针?我們?nèi)绾卧O(shè)計(jì)一個(gè)秒殺系統(tǒng)呢张抄?對(duì)于秒殺系統(tǒng)應(yīng)該考慮哪些問題黄娘?如何設(shè)計(jì)出健壯的秒殺系統(tǒng)伶贰?本期我們就來探討一下這個(gè)問題:

image

博客的目錄

一:秒殺系統(tǒng)應(yīng)該考慮的問題

二:秒殺系統(tǒng)的設(shè)計(jì)和技術(shù)方案

三:系統(tǒng)架構(gòu)圖

四:總結(jié)

一:秒殺應(yīng)該考慮哪些問題

1.1:超賣問題

分析秒殺的業(yè)務(wù)場(chǎng)景,最重要的有一點(diǎn)就是超賣問題迅脐,假如備貨只有100個(gè)愁溜,但是最終超賣了200疾嗅,一般來講秒殺系統(tǒng)的價(jià)格都比較低,如果超賣將嚴(yán)重影響公司的財(cái)產(chǎn)利益冕象,因此首當(dāng)其沖的就是解決商品的超賣問題代承。

1.2:高并發(fā)

秒殺具有時(shí)間短、并發(fā)量大的特點(diǎn)渐扮,秒殺持續(xù)時(shí)間只有幾分鐘论悴,而一般公司都為了制造轟動(dòng)效應(yīng),會(huì)以極低的價(jià)格來吸引用戶墓律,因此參與搶購(gòu)的用戶會(huì)非常的多膀估。短時(shí)間內(nèi)會(huì)有大量請(qǐng)求涌進(jìn)來,后端如何防止并發(fā)過高造成緩存擊穿或者失效耻讽,擊垮數(shù)據(jù)庫都是需要考慮的問題察纯。

1.3:接口防刷

現(xiàn)在的秒殺大多都會(huì)出來針對(duì)秒殺對(duì)應(yīng)的軟件,這類軟件會(huì)模擬不斷向后臺(tái)服務(wù)器發(fā)起請(qǐng)求针肥,一秒幾百次都是很常見的饼记,如何防止這類軟件的重復(fù)無效請(qǐng)求,防止不斷發(fā)起的請(qǐng)求也是需要我們針對(duì)性考慮的

1.4:秒殺url

對(duì)于普通用戶來講慰枕,看到的只是一個(gè)比較簡(jiǎn)單的秒殺頁面握恳,在未達(dá)到規(guī)定時(shí)間,秒殺按鈕是灰色的捺僻,一旦到達(dá)規(guī)定時(shí)間,灰色按鈕變成可點(diǎn)擊狀態(tài)。這部分是針對(duì)小白用戶的匕坯,如果是稍微有點(diǎn)電腦功底的用戶束昵,會(huì)通過F12看瀏覽器的network看到秒殺的url,通過特定軟件去請(qǐng)求也可以實(shí)現(xiàn)秒殺葛峻∏鲁或者提前知道秒殺url的人,一請(qǐng)求就直接實(shí)現(xiàn)秒殺了术奖。這個(gè)問題我們需要考慮解決

1.5:數(shù)據(jù)庫設(shè)計(jì)

秒殺有把我們服務(wù)器擊垮的風(fēng)險(xiǎn)礁遵,如果讓它與我們的其他業(yè)務(wù)使用在同一個(gè)數(shù)據(jù)庫中,耦合在一起采记,就很有可能牽連和影響其他的業(yè)務(wù)佣耐。如何防止這類問題發(fā)生,就算秒殺發(fā)生了宕機(jī)唧龄、服務(wù)器卡死問題兼砖,也應(yīng)該讓他盡量不影響線上正常進(jìn)行的業(yè)務(wù)

1.6:大量請(qǐng)求問題

按照1.2的考慮,就算使用緩存還是不足以應(yīng)對(duì)短時(shí)間的高并發(fā)的流量的沖擊既棺。如何承載這樣巨大的訪問量讽挟,同時(shí)提供穩(wěn)定低時(shí)延的服務(wù)保證,是需要面對(duì)的一大挑戰(zhàn)丸冕。我們來算一筆賬耽梅,假如使用的是redis緩存,單臺(tái)redis服務(wù)器可承受的QPS大概是4W左右胖烛,如果一個(gè)秒殺吸引的用戶量足夠多的話眼姐,單QPS可能達(dá)到幾十萬,單體redis還是不足以支撐如此巨大的請(qǐng)求量洪己。緩存會(huì)被擊穿妥凳,直接滲透到DB,從而擊垮mysql.后臺(tái)會(huì)將會(huì)大量報(bào)錯(cuò)

二:秒殺系統(tǒng)的設(shè)計(jì)和技術(shù)方案

2.1:秒殺系統(tǒng)數(shù)據(jù)庫設(shè)計(jì)

針對(duì)1.5提出的秒殺數(shù)據(jù)庫的問題,因此應(yīng)該單獨(dú)設(shè)計(jì)一個(gè)秒殺數(shù)據(jù)庫答捕,防止因?yàn)槊霘⒒顒?dòng)的高并發(fā)訪問拖垮整個(gè)網(wǎng)站逝钥。這里只需要兩張表,一張是秒殺訂單表拱镐,一張是秒殺貨品表

image
image

其實(shí)應(yīng)該還有幾張表艘款,商品表:可以關(guān)聯(lián)goods_id查到具體的商品信息,商品圖像沃琅、名稱哗咆、平時(shí)價(jià)格、秒殺價(jià)格等益眉,還有用戶表:根據(jù)用戶user_id可以查詢到用戶昵稱晌柬、用戶手機(jī)號(hào)姥份,收貨地址等其他額外信息,這個(gè)具體就不給出實(shí)例了年碘。

2.2:秒殺url的設(shè)計(jì)

為了避免有程序訪問經(jīng)驗(yàn)的人通過下單頁面url直接訪問后臺(tái)接口來秒殺貨品澈歉,我們需要將秒殺的url實(shí)現(xiàn)動(dòng)態(tài)化,即使是開發(fā)整個(gè)系統(tǒng)的人都無法在秒殺開始前知道秒殺的url屿衅。具體的做法就是通過md5加密一串隨機(jī)字符作為秒殺的url埃难,然后前端訪問后臺(tái)獲取具體的url,后臺(tái)校驗(yàn)通過之后才可以繼續(xù)秒殺涤久。

2.3:秒殺頁面靜態(tài)化

將商品的描述涡尘、參數(shù)、成交記錄响迂、圖像考抄、評(píng)價(jià)等全部寫入到一個(gè)靜態(tài)頁面,用戶請(qǐng)求不需要通過訪問后端服務(wù)器栓拜,不需要經(jīng)過數(shù)據(jù)庫座泳,直接在前臺(tái)客戶端生成,這樣可以最大可能的減少服務(wù)器的壓力幕与。具體的方法可以使用freemarker模板技術(shù)挑势,建立網(wǎng)頁模板,填充數(shù)據(jù)啦鸣,然后渲染網(wǎng)頁

2.4:單體redis升級(jí)為集群redis

秒殺是一個(gè)讀多寫少的場(chǎng)景潮饱,使用redis做緩存再合適不過。不過考慮到緩存擊穿問題诫给,我們應(yīng)該構(gòu)建redis集群香拉,采用哨兵模式,可以提升redis的性能和可用性中狂。

2.5:使用nginx

nginx是一個(gè)高性能web服務(wù)器凫碌,它的并發(fā)能力可以達(dá)到幾萬,而tomcat只有幾百胃榕。通過nginx映射客戶端請(qǐng)求盛险,再分發(fā)到后臺(tái)tomcat服務(wù)器集群中可以大大提升并發(fā)能力。

2.6:精簡(jiǎn)sql

典型的一個(gè)場(chǎng)景是在進(jìn)行扣減庫存的時(shí)候勋又,傳統(tǒng)的做法是先查詢庫存苦掘,再去update。這樣的話需要兩個(gè)sql楔壤,而實(shí)際上一個(gè)sql我們就可以完成的鹤啡。可以用這樣的做法:update miaosha_goods set stock =stock-1 where goos_id ={#goods_id} and version = #{version} and sock>0;這樣的話蹲嚣,就可以保證庫存不會(huì)超賣并且一次更新庫存,還有注意一點(diǎn)這里使用了版本號(hào)的樂觀鎖递瑰,相比較悲觀鎖祟牲,它的性能較好。

2.7:redis預(yù)減庫存

很多請(qǐng)求進(jìn)來泣矛,都需要后臺(tái)查詢庫存,這是一個(gè)頻繁讀的場(chǎng)景疲眷。可以使用redis來預(yù)減庫存您朽,在秒殺開始前可以在redis設(shè)值,比如redis.set(goodsId,100),這里預(yù)放的庫存為100可以設(shè)值為常量),每次下單成功之后,Integer stock = (Integer)redis.get(goosId); 然后判斷sock的值换淆,如果小于常量值就減去1;不過注意當(dāng)取消的時(shí)候,需要增加庫存哗总,增加庫存的時(shí)候也得注意不能大于之間設(shè)定的總庫存數(shù)(查詢庫存和扣減庫存需要原子操作,此時(shí)可以借助lua腳本)下次下單再獲取庫存的時(shí)候,直接從redis里面查就可以了倍试。

2.8:接口限流

秒殺最終的本質(zhì)是數(shù)據(jù)庫的更新讯屈,但是有很多大量無效的請(qǐng)求,我們最終要做的就是如何把這些無效的請(qǐng)求過濾掉县习,防止?jié)B透到數(shù)據(jù)庫涮母。限流的話,需要入手的方面很多:

2.8.1:前端限流

首先第一步就是通過前端限流躁愿,用戶在秒殺按鈕點(diǎn)擊以后發(fā)起請(qǐng)求叛本,那么在接下來的5秒是無法點(diǎn)擊(通過設(shè)置按鈕為disable)。這一小舉措開發(fā)起來成本很小彤钟,但是很有效来候。

2.8.2:同一個(gè)用戶xx秒內(nèi)重復(fù)請(qǐng)求直接拒絕

具體多少秒需要根據(jù)實(shí)際業(yè)務(wù)和秒殺的人數(shù)而定,一般限定為10秒逸雹。具體的做法就是通過redis的鍵過期策略营搅,首先對(duì)每個(gè)請(qǐng)求都從String value = redis.get(userId);如果獲取到這個(gè)

value為空或者為null,表示它是有效的請(qǐng)求梆砸,然后放行這個(gè)請(qǐng)求转质。如果不為空表示它是重復(fù)性請(qǐng)求,直接丟掉這個(gè)請(qǐng)求帖世。如果有效,采用redis.setexpire(userId,value,10).value可以是任意值休蟹,一般放業(yè)務(wù)屬性比較好,這個(gè)是設(shè)置以u(píng)serId為key,10秒的過期時(shí)間(10秒后,key對(duì)應(yīng)的值自動(dòng)為null)

2.8.3:令牌桶算法限流

接口限流的策略有很多狮暑,我們這里采用令牌桶算法鸡挠。令牌桶算法的基本思路是每個(gè)請(qǐng)求嘗試獲取一個(gè)令牌,后端只處理持有令牌的請(qǐng)求搬男,生產(chǎn)令牌的速度和效率我們都可以自己限定拣展,guava提供了RateLimter的api供我們使用。以下做一個(gè)簡(jiǎn)單的例子,注意需要引入guava

public class TestRateLimiter { public static void main(String[] args) { //1秒產(chǎn)生1個(gè)令牌
        final RateLimiter rateLimiter = RateLimiter.create(1); for (int i = 0; i < 10; i++) { //該方法會(huì)阻塞線程缔逛,直到令牌桶中能取到令牌為止才繼續(xù)向下執(zhí)行备埃。
            double waitTime= rateLimiter.acquire();
            System.out.println("任務(wù)執(zhí)行" + i + "等待時(shí)間" + waitTime);
        }
        System.out.println("執(zhí)行結(jié)束");
    }
}

上面代碼的思路就是通過RateLimiter來限定我們的令牌桶每秒產(chǎn)生1個(gè)令牌(生產(chǎn)的效率比較低)姓惑,循環(huán)10次去執(zhí)行任務(wù)。acquire會(huì)阻塞當(dāng)前線程直到獲取到令牌按脚,也就是如果任務(wù)沒有獲取到令牌于毙,會(huì)一直等待。那么請(qǐng)求就會(huì)卡在我們限定的時(shí)間內(nèi)才可以繼續(xù)往下走辅搬,這個(gè)方法返回的是線程具體等待的時(shí)間唯沮。執(zhí)行如下;

image

可以看到任務(wù)執(zhí)行的過程中,第1個(gè)是無需等待的堪遂,因?yàn)橐呀?jīng)在開始的第1秒生產(chǎn)出了令牌介蛉。接下來的任務(wù)請(qǐng)求就必須等到令牌桶產(chǎn)生了令牌才可以繼續(xù)往下執(zhí)行。如果沒有獲取到就會(huì)阻塞(有一個(gè)停頓的過程)溶褪。不過這個(gè)方式不太好币旧,因?yàn)橛脩羧绻诳蛻舳苏?qǐng)求,如果較多的話,直接后臺(tái)在生產(chǎn)token就會(huì)卡頓(用戶體驗(yàn)較差)猿妈,它是不會(huì)拋棄任務(wù)的吹菱,我們需要一個(gè)更優(yōu)秀的策略:如果超過某個(gè)時(shí)間沒有獲取到,直接拒絕該任務(wù)彭则。接下來再來個(gè)案例:

public class TestRateLimiter2 { 
  public static void main(String[] args) { 
    final RateLimiter rateLimiter = RateLimiter.create(1); 
    for (int i = 0; i < 10; i++) { 
      long timeOut = (long) 0.5; 
      boolean isValid = rateLimiter.tryAcquire(timeOut, TimeUnit.SECONDS);
      System.out.println("任務(wù)" + i + "執(zhí)行是否有效:" + isValid); if (!isValid) { continue;
    }
    System.out.println("任務(wù)" + i + "在執(zhí)行");
    }
    System.out.println("結(jié)束");
    }
}

其中用到了tryAcquire方法鳍刷,這個(gè)方法的主要作用是設(shè)定一個(gè)超時(shí)的時(shí)間,如果在指定的時(shí)間內(nèi)預(yù)估(注意是預(yù)估并不會(huì)真實(shí)的等待)贰剥,如果能拿到令牌就返回true倾剿,如果拿不到就返回false.然后我們讓無效的直接跳過,這里設(shè)定每秒生產(chǎn)1個(gè)令牌蚌成,讓每個(gè)任務(wù)嘗試在

0.5秒獲取令牌前痘,如果獲取不到,就直接跳過這個(gè)任務(wù)(放在秒殺環(huán)境里就是直接拋棄這個(gè)請(qǐng)求);程序?qū)嶋H運(yùn)行如下:

image

只有第1個(gè)獲取到了令牌担忧,順利執(zhí)行了芹缔,下面的基本都直接拋棄了,因?yàn)?.5秒內(nèi)瓶盛,令牌桶(1秒1個(gè))來不及生產(chǎn)就肯定獲取不到返回false了最欠。

這個(gè)限流策略的效率有多高呢?假如我們的并發(fā)請(qǐng)求是400萬瞬間的請(qǐng)求,將令牌產(chǎn)生的效率設(shè)為每秒20個(gè)惩猫,每次嘗試獲取令牌的時(shí)間是0.05秒芝硬,那么最終測(cè)試下來的結(jié)果是,每次只會(huì)放行4個(gè)左右的請(qǐng)求,大量的請(qǐng)求會(huì)被拒絕,這就是令牌桶算法的優(yōu)秀之處轧房。

2.9:異步下單

為了提升下單的效率拌阴,并且防止下單服務(wù)的失敗。需要將下單這一操作進(jìn)行異步處理奶镶。最常采用的辦法是使用隊(duì)列迟赃,隊(duì)列最顯著的三個(gè)優(yōu)點(diǎn):異步陪拘、削峰、解耦纤壁。這里可以采用rabbitmq左刽,在后臺(tái)經(jīng)過了限流、庫存校驗(yàn)之后酌媒,流入到這一步驟的就是有效請(qǐng)求欠痴。然后發(fā)送到隊(duì)列里,隊(duì)列接受消息馍佑,異步下單斋否。下完單,入庫沒有問題可以用短信通知用戶秒殺成功拭荤。假如失敗的話,可以采用補(bǔ)償機(jī)制,重試疫诽。

3.0:服務(wù)降級(jí)

假如在秒殺過程中出現(xiàn)了某個(gè)服務(wù)器宕機(jī)舅世,或者服務(wù)不可用,應(yīng)該做好后備工作奇徒。之前的博客里有介紹通過Hystrix進(jìn)行服務(wù)熔斷和降級(jí)雏亚,可以開發(fā)一個(gè)備用服務(wù),假如服務(wù)器真的宕機(jī)了摩钙,直接給用戶一個(gè)友好的提示返回罢低,而不是直接卡死,服務(wù)器錯(cuò)誤等生硬的反饋胖笛。

三:總結(jié)

秒殺流程圖:

image

這就是我設(shè)計(jì)出來的秒殺流程圖,當(dāng)然不同的秒殺體量針對(duì)的技術(shù)選型都不一樣网持,這個(gè)流程可以支撐起幾十萬的流量,如果是成千萬破億那就得重新設(shè)計(jì)了长踊。比如數(shù)據(jù)庫的分庫分表功舀、隊(duì)列改成用kafka、redis增加集群數(shù)量等手段身弊。通過本次設(shè)計(jì)主要是要表明的是我們?nèi)绾螒?yīng)對(duì)高并發(fā)的處理辟汰,并開始嘗試解決它,在工作中多思考阱佛、多動(dòng)手能提升我們的能力水平帖汞,加油!如果本篇博客有任何錯(cuò)誤凑术,請(qǐng)麻煩指出來翩蘸,不勝感激。

轉(zhuǎn)載:https://www.cnblogs.com/wyq178/p/11261711.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末麦萤,一起剝皮案震驚了整個(gè)濱河市鹿鳖,隨后出現(xiàn)的幾起案子扁眯,更是在濱河造成了極大的恐慌,老刑警劉巖翅帜,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姻檀,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡涝滴,警方通過查閱死者的電腦和手機(jī)绣版,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歼疮,“玉大人杂抽,你說我怎么就攤上這事『啵” “怎么了缩麸?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任弧械,我火速辦了婚禮,結(jié)果婚禮上空民,老公的妹妹穿的比我還像新娘刃唐。我一直安慰自己,他們只是感情好界轩,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布画饥。 她就那樣靜靜地躺著,像睡著了一般耸棒。 火紅的嫁衣襯著肌膚如雪荒澡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天与殃,我揣著相機(jī)與錄音单山,去河邊找鬼。 笑死幅疼,一個(gè)胖子當(dāng)著我的面吹牛米奸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播爽篷,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼悴晰,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起铡溪,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤漂辐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后棕硫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體髓涯,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年哈扮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纬纪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡滑肉,死狀恐怖包各,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情靶庙,我是刑警寧澤问畅,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站六荒,受9級(jí)特大地震影響按声,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恬吕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望须床。 院中可真熱鬧铐料,春花似錦、人聲如沸豺旬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽族阅。三九已至篓跛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坦刀,已是汗流浹背愧沟。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鲤遥,地道東北人沐寺。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像盖奈,于是被迫代替她去往敵國(guó)和親混坞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

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

  • 秒殺應(yīng)該考慮哪些問題 超賣問題 高并發(fā) 接口防刷 秒殺 URL 數(shù)據(jù)庫設(shè)計(jì) 大量請(qǐng)求問題 秒殺系統(tǒng)的設(shè)計(jì)和技術(shù)方案...
    tuonioooo閱讀 505評(píng)論 0 0
  • 搞清楚秒殺的關(guān)鍵問題所在,有哪些解決辦法究孕。 知識(shí)要點(diǎn)架構(gòu)設(shè)計(jì)原理如何最大程度分流減壓如何抵擋突發(fā)大流量根據(jù)業(yè)務(wù)場(chǎng)景...
    與詩小睡閱讀 259評(píng)論 0 0
  • ![Flask](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAW...
    極客學(xué)院Wiki閱讀 7,240評(píng)論 0 3
  • 不知不覺易趣客已經(jīng)在路上走了快一年了厨诸,感覺也該讓更多朋友認(rèn)識(shí)知道易趣客镶殷,所以就謝了這篇簡(jiǎn)介,已做創(chuàng)業(yè)記事泳猬。 易趣客...
    Physher閱讀 3,410評(píng)論 1 2
  • 雙胎妊娠有家族遺傳傾向批钠,隨母系遺傳。有研究表明得封,如果孕婦本人是雙胎之一埋心,她生雙胎的機(jī)率為1/58;若孕婦的父親或母...
    鄴水芙蓉hibiscus閱讀 3,696評(píng)論 0 2