「Chris Richardson 微服務(wù)系列」使用 API 網(wǎng)關(guān)構(gòu)建微服務(wù)

編者的話|本文來自 Nginx 官方博客掸刊,是微服務(wù)系列文章的第二篇琢蛤,本文將探討:微服務(wù)架構(gòu)是如何影響客戶端到服務(wù)端的通信害捕,并提出一種使用 API 網(wǎng)關(guān)的方法。

作者介紹:Chris Richardson墨叛,是世界著名的軟件大師止毕,經(jīng)典技術(shù)著作《POJOS IN ACTION》一書的作者,也是 cloudfoundry.com 最初的創(chuàng)始人漠趁,Chris Richardson 與 Martin Fowler扁凛、Sam Newman、Adrian Cockcroft 等并稱為世界十大軟件架構(gòu)師闯传。

Chris Richardson 所著所有文章已獨家授權(quán) DaoCloud 翻譯并刊載谨朝。

本系列包含 7 篇文章,介紹了微服務(wù)的設(shè)計甥绿、構(gòu)建和部署字币,并與傳統(tǒng)的單體架構(gòu)進行了比較。本系列將分析微服務(wù)架構(gòu)的各種因素共缕,你也將了解微服務(wù)架構(gòu)模型的優(yōu)劣纬朝、是否適合你的項目,以及如何應(yīng)用骄呼。

Chris Richardson 微服務(wù)系列全 7 篇:

  1. 微服務(wù)架構(gòu)的優(yōu)勢與不足
  2. 使用 API 網(wǎng)關(guān)構(gòu)建微服務(wù)
  3. 深入微服務(wù)架構(gòu)的進程間通信
  4. 服務(wù)發(fā)現(xiàn)的可行方案以及實踐案例
  5. 微服務(wù)的事件驅(qū)動數(shù)據(jù)管理
  6. 選擇微服務(wù)部署策略
  7. 將單體應(yīng)用改造為微服務(wù)

本期內(nèi)容

微服務(wù)系列文章的第一篇介紹了微服務(wù)架構(gòu)模式,討論了使用微服務(wù)的優(yōu)缺點判没,以及為什么微服務(wù)雖然復(fù)雜度高卻是復(fù)雜應(yīng)用程序的理想選擇蜓萄。

在決定以一組微服務(wù)來構(gòu)建自己的應(yīng)用時,你需要確定應(yīng)用客戶端如何與微服務(wù)交互澄峰。

在單體式程序中嫉沽,通常只有一組冗余的或者負(fù)載均衡的服務(wù)提供點。在微服務(wù)架構(gòu)中俏竞,每一個微服務(wù)暴露一組細粒度的服務(wù)提供點绸硕。在本篇文章中堂竟,我們來看它如何影響客戶端到服務(wù)端通信,并提出一種使用 API 網(wǎng)關(guān)的方法玻佩。

簡要概述

讓我們想象一下出嘹,你要為一個購物應(yīng)用程序開發(fā)一個原生移動客戶端。你很可能需要實現(xiàn)一個產(chǎn)品詳情頁面咬崔,展示任何指定商品的信息税稼。

下圖展示了 Amazon Android 應(yīng)用在商品詳情頁顯示的內(nèi)容。

Richardson-microservices-part2-1_amazon-apps

即使只是個智能手機應(yīng)用垮斯,產(chǎn)品詳情頁面也顯示了大量的信息郎仆。該頁面不僅包含基本的產(chǎn)品信息(如名稱、描述兜蠕、價格)扰肌,而且還顯示了如下內(nèi)容:

  • 購物車中的商品數(shù)量
  • 歷史訂單
  • 客戶評論
  • 低庫存預(yù)警
  • 送貨選項
  • 各種推薦,包括經(jīng)常與該商品一起購買的其它商品熊杨、購買該商品的客戶購買的其它商品曙旭、購買該商品的客戶看過的其它商品
  • 其它的購物選擇

使用單體應(yīng)用程序架構(gòu)時,移動客戶端通過向應(yīng)用程序發(fā)起一次 REST 調(diào)用(GET api.company.com/productdetails/)來獲取這些數(shù)據(jù)猴凹。負(fù)載均衡器將請求路由給 N 個相同的應(yīng)用程序?qū)嵗械钠渲兄灰恼H缓螅瑧?yīng)用程序會查詢各種數(shù)據(jù)庫表郊霎,并將響應(yīng)返回給客戶端沼头。

相反,若是采用微服務(wù)架構(gòu)书劝,顯示在產(chǎn)品頁上的數(shù)據(jù)會分布在不同的微服務(wù)上进倍。下面列舉了可能與產(chǎn)品詳情頁數(shù)據(jù)有關(guān)的一些微服務(wù):

  • 購物車服務(wù)——購物車中的件數(shù)
  • 訂單服務(wù)——歷史訂單
  • 目錄服務(wù)——商品基本信息,如名稱购对、圖片和價格
  • 評論服務(wù)——客戶的評論
  • 庫存服務(wù)——低庫存預(yù)警
  • 送貨服務(wù)——送貨選項猾昆、期限和費用,這些信息單獨從送貨方 API 獲取
  • 推薦服務(wù)——推薦商品

我們需要決定移動客戶端如何訪問這些服務(wù)骡苞。讓我們看看有哪些方法垂蜗。

客戶端與微服務(wù)直接通信

從理論上講,客戶端可以直接向每個微服務(wù)發(fā)送請求解幽。每個微服務(wù)都有一個公開的端點(https ://.api.company.name)贴见。該 URL 映射到微服務(wù)的負(fù)載均衡器,由后者負(fù)責(zé)在可用實例之間分發(fā)請求躲株。為了獲取產(chǎn)品詳情片部,移動客戶端將逐一向上文列出的 N 個服務(wù)發(fā)送請求。

遺憾的是霜定,這種方法存在挑戰(zhàn)和局限档悠。問題之一是客戶端需求和每個微服務(wù)暴露的細粒度 API 不匹配廊鸥。在這個例子中,客戶端需要發(fā)送 7 個獨立請求辖所。在更復(fù)雜的應(yīng)用程序中惰说,可能要發(fā)送更多的請求;按照 Amazon 的說法奴烙,他們在顯示他們的產(chǎn)品頁面時就調(diào)用了數(shù)百個服務(wù)助被。然而,客戶端通過 LAN 發(fā)送許多請求切诀,這在公網(wǎng)上可能會很低效揩环,在移動網(wǎng)絡(luò)上就根本不可行。這種方法還使得客戶端代碼非常復(fù)雜幅虑。

客戶端直接調(diào)用微服務(wù)的另一個問題是丰滑,部分服務(wù)使用的協(xié)議對 web 并不友好。一個服務(wù)可能使用 Thrift 二進制 RPC倒庵,而另一個服務(wù)可能使用 AMQP 消息傳遞協(xié)議褒墨。不管哪種協(xié)議對于瀏覽器或防火墻都不夠友好,最好是內(nèi)部使用擎宝。在防火墻之外郁妈,應(yīng)用程序應(yīng)該使用諸如 HTTP 和 WebSocket 之類的協(xié)議。

這種方法的另一個缺點是绍申,它會使得微服務(wù)難以重構(gòu)噩咪。隨著時間推移,我們可能想要更改系統(tǒng)拆分成服務(wù)的方式极阅。例如胃碾,我們可能合并兩個服務(wù),或者將一個服務(wù)拆分成兩個或更多服務(wù)筋搏。然而仆百,如果客戶端與微服務(wù)直接通信,那么執(zhí)行這類重構(gòu)就非常困難了奔脐。

由于上述三種問題的原因俄周,客戶端直接與服務(wù)器端通信的方式很少在實際中使用。

使用 API 網(wǎng)關(guān)構(gòu)建微服務(wù)

通常來說髓迎,使用 API 網(wǎng)關(guān)是更好的解決方式峦朗。API 網(wǎng)關(guān)是一個服務(wù)器,也可以說是進入系統(tǒng)的唯一節(jié)點竖般。這與面向?qū)ο笤O(shè)計模式中的 Facade 模式很像。API 網(wǎng)關(guān)封裝內(nèi)部系統(tǒng)的架構(gòu)茶鹃,并且提供 API 給各個客戶端涣雕。它還可能還具備授權(quán)艰亮、監(jiān)控、負(fù)載均衡挣郭、緩存迄埃、請求分片和管理、靜態(tài)響應(yīng)處理等功能兑障。下圖展示了一個適應(yīng)當(dāng)前架構(gòu)的 API 網(wǎng)關(guān)侄非。

API 網(wǎng)關(guān)負(fù)責(zé)服務(wù)請求路由、組合及協(xié)議轉(zhuǎn)換流译〕言梗客戶端的所有請求都首先經(jīng)過 API 網(wǎng)關(guān),然后由它將請求路由到合適的微服務(wù)福澡。API 網(wǎng)關(guān)經(jīng)常會通過調(diào)用多個微服務(wù)并合并結(jié)果來處理一個請求叠赦。它可以在 web 協(xié)議(如 HTTP 與 WebSocket)與內(nèi)部使用的非 web 友好協(xié)議之間轉(zhuǎn)換。

API 網(wǎng)關(guān)還能為每個客戶端提供一個定制的 API革砸。通常除秀,它會向移動客戶端暴露一個粗粒度的 API。以產(chǎn)品詳情的場景為例算利,API 網(wǎng)關(guān)可以提供一個端點(/productdetails?productid=xxx)册踩,使移動客戶端可以通過一個請求獲取所有的產(chǎn)品詳情。API 網(wǎng)關(guān)通過調(diào)用各個服務(wù)(產(chǎn)品信息效拭、推薦暂吉、評論等等)并合并結(jié)果來處理請求。

Netflix API 網(wǎng)關(guān)是一個很好的 API 網(wǎng)關(guān)實例允耿。Netflix 流媒體服務(wù)提供給成百上千種類型的設(shè)備使用借笙,包括電視、機頂盒较锡、智能手機业稼、游戲系統(tǒng)、平板電腦等等蚂蕴。

最初低散,Netflix 試圖為他們的流媒體服務(wù)提供一個通用的 API。然而他們發(fā)現(xiàn)骡楼,由于各種各樣的設(shè)備都有自己獨特的需求熔号,這種方式并不能很好地工作。如今鸟整,他們使用一個 API 網(wǎng)關(guān)引镊,通過運行與針對特定設(shè)備的適配器代碼,來為每種設(shè)備提供定制的 API。通常弟头,一個適配器通過調(diào)用平均 6 到 7 個后端服務(wù)來處理每個請求吩抓。Netflix API 網(wǎng)關(guān)每天處理數(shù)十億請求。

API 網(wǎng)關(guān)的優(yōu)點和缺點

如你所料赴恨,使用 API 網(wǎng)關(guān)有優(yōu)點也有不足疹娶。使用 API 網(wǎng)關(guān)的最大優(yōu)點是,它封裝了應(yīng)用程序的內(nèi)部結(jié)構(gòu)伦连。客戶端只需要同網(wǎng)關(guān)交互雨饺,而不必調(diào)用特定的服務(wù)。API 網(wǎng)關(guān)為每一類客戶端提供了特定的 API惑淳,這減少了客戶端與應(yīng)用程序間的交互次數(shù)额港,還簡化了客戶端代碼。

API 網(wǎng)關(guān)也有一些不足汛聚。它增加了一個我們必須開發(fā)锹安、部署和維護的高可用組件。還有一個風(fēng)險是倚舀,API 網(wǎng)關(guān)變成了開發(fā)瓶頸叹哭。為了暴露每個微服務(wù)的端點,開發(fā)人員必須更新 API 網(wǎng)關(guān)痕貌。API網(wǎng)關(guān)的更新過程要盡可能地簡單风罩,這很重要;否則舵稠,為了更新網(wǎng)關(guān)超升,開發(fā)人員將不得不排隊等待捷沸。不過赖歌,雖然有這些不足,但對于大多數(shù)現(xiàn)實世界的應(yīng)用程序而言冕广,使用 API 網(wǎng)關(guān)是合理的落追。

實現(xiàn) API 網(wǎng)關(guān)

到目前為止盈滴,我們已經(jīng)探討了使用 API 網(wǎng)關(guān)的動力及其優(yōu)缺點。下面讓我們看一下需要考慮的各種設(shè)計問題轿钠。

性能和可擴展性

只有少數(shù)公司擁有 Netflix 這樣的規(guī)模巢钓,需要每天處理每天需要處理數(shù)十億請求。不管怎樣疗垛,對于大多數(shù)應(yīng)用程序而言症汹,API 網(wǎng)關(guān)的性能和可擴展性都非常重要。因此贷腕,將 API 網(wǎng)關(guān)構(gòu)建在一個支持異步背镇、I/O 非阻塞的平臺上是合理的咬展。有多種不同的技術(shù)可以實現(xiàn)一個可擴展的 API 網(wǎng)關(guān)。在 JVM 上瞒斩,可以使用一種基于 NIO 的框架挚赊,比如 Netty、Vertx济瓢、Spring Reactor 或 JBoss Undertow 中的一種。一個非常流行的非 JVM 選項是 Node.js妹卿,它是一個基于 Chrome JavaScript 引擎構(gòu)建的平臺旺矾。

另一個方法是使用 NGINX Plus。NGINX Plus 提供了一個成熟的夺克、可擴展的箕宙、高性能 web 服務(wù)器和一個易于部署的、可配置可編程的反向代理铺纽。NGINX Plus 可以管理身份驗證柬帕、訪問控制、負(fù)載均衡請求狡门、緩存響應(yīng)陷寝,并提供應(yīng)用程序可感知的健康檢查和監(jiān)控。

使用響應(yīng)式編程模型

API 網(wǎng)關(guān)通過簡單地將請求路由給合適的后端服務(wù)來處理部分請求其馏,而通過調(diào)用多個后端服務(wù)并合并結(jié)果來處理其它請求凤跑。對于部分請求,比如產(chǎn)品詳情相關(guān)的多個請求叛复,它們對后端服務(wù)的請求是獨立于其它請求的仔引。為了最小化響應(yīng)時間,API 網(wǎng)關(guān)應(yīng)該并發(fā)執(zhí)行獨立請求褐奥。

然而咖耘,有時候,請求之間存在依賴撬码。在將請求路由到后端服務(wù)之前儿倒,API 網(wǎng)關(guān)可能首先需要調(diào)用身份驗證服務(wù)驗證請求的合法性。類似地耍群,為了獲取客戶心愿單中的產(chǎn)品信息义桂,API 網(wǎng)關(guān)必須首先獲取包含這些信息的客戶資料,然后再獲取每個產(chǎn)品的信息蹈垢。關(guān)于 API 組合慷吊,另一個有趣的例子是 Netflix Video Grid。

使用傳統(tǒng)的異步回調(diào)方法編寫 API 組合代碼會讓你迅速墜入回調(diào)地獄曹抬。代碼會變得混亂溉瓶、難以理解且容易出錯。一個更好的方法是使用響應(yīng)式方法,以一種聲明式樣式編寫 API 網(wǎng)關(guān)代碼堰酿。響應(yīng)式抽象概念的例子有 Scala 中的 Future疾宏、Java 8 中的 CompletableFuture 和 JavaScript 中的P romise,還有最初微軟為 .NET 平臺開發(fā)的 Reactive Extensions(RX)触创。Netflix 創(chuàng)建了 RxJava for JVM坎藐,專門用于他們的 API 網(wǎng)關(guān)。此外哼绑,還有 RxJS for JavaScript岩馍,它既可以在瀏覽器中運行,也可以在 Node.js 中運行抖韩。使用響應(yīng)式方法能讓你編寫簡單但高效的 API 網(wǎng)關(guān)代碼蛀恩。

服務(wù)調(diào)用

基于微服務(wù)的應(yīng)用程序是一個分布式系統(tǒng),必須使用一種進程間通信機制茂浮。有兩種類型的進程間通信機制可供選擇双谆。一種是使用異步的、基于消息傳遞的機制席揽。有些實現(xiàn)使用諸如 JMS 或 AMQP 那樣的消息代理顽馋,而其它的實現(xiàn)(如 Zeromq)則沒有代理,服務(wù)間直接通信幌羞。

另一種進程間通信類型是諸如 HTTP 或 Thrift 那樣的同步機制趣避。通常,一個系統(tǒng)會同時使用異步和同步兩種類型新翎。它甚至還可能使用同一類型的多種實現(xiàn)程帕。總之地啰,API 網(wǎng)關(guān)需要支持多種通信機制愁拭。

服務(wù)發(fā)現(xiàn)

API 網(wǎng)關(guān)需要知道它與之通信的每個微服務(wù)的位置(IP 地址和端口)。在傳統(tǒng)的應(yīng)用程序中亏吝,或許可以硬連線這個位置岭埠,但在現(xiàn)代的、基于云的微服務(wù)應(yīng)用程序中蔚鸥,這并不是一個容易解決的問題惜论。基礎(chǔ)設(shè)施服務(wù)(如消息代理)通常會有一個靜態(tài)位置止喷,可以通過 OS 環(huán)境變量指定馆类。但是,確定一個應(yīng)用程序服務(wù)的位置沒有這么簡單弹谁。應(yīng)用程序服務(wù)的位置是動態(tài)分配的乾巧,而且句喜,單個服務(wù)的一組實例也會隨著自動擴展或升級而動態(tài)變化。

總之沟于,像系統(tǒng)中的其它服務(wù)客戶端一樣咳胃,API 網(wǎng)關(guān)需要使用系統(tǒng)的服務(wù)發(fā)現(xiàn)機制,可以是服務(wù)器端發(fā)現(xiàn)旷太,也可以是客戶端發(fā)現(xiàn)展懈。下一篇文章將更詳細地描述服務(wù)發(fā)現(xiàn)。現(xiàn)在供璧,需要注意的是标沪,如果系統(tǒng)使用客戶端發(fā)現(xiàn),那么 API 網(wǎng)關(guān)必須能夠查詢服務(wù)注冊中心嗜傅,這是一個包含所有微服務(wù)實例及其位置的數(shù)據(jù)庫。

處理局部失敗

在實現(xiàn) API 網(wǎng)關(guān)時檩赢,還需要處理局部失敗的問題吕嘀。該問題出現(xiàn)在所有的分布式系統(tǒng)中。當(dāng)一個服務(wù)調(diào)用另一個服務(wù)贞瞒,而后者響應(yīng)慢或不可用的時候偶房,就會出現(xiàn)這個問題。API 網(wǎng)關(guān)不能因為無限期地等待下游服務(wù)而阻塞军浆。不過棕洋,如何處理失敗取決于特定的場景以及哪個服務(wù)失敗。例如乒融,在產(chǎn)品詳情場景下掰盘,如果推薦服務(wù)無響應(yīng),那么 API 網(wǎng)關(guān)應(yīng)該向客戶端返回產(chǎn)品詳情的其它內(nèi)容赞季,因為它們對用戶依然有用愧捕。推薦內(nèi)容可以為空,也可以用一個固定的 TOP 10 列表取代申钩。不過次绘,如果產(chǎn)品信息服務(wù)無響應(yīng),那么 API 網(wǎng)關(guān)應(yīng)該向客戶端返回一個錯誤信息撒遣。

如果緩存數(shù)據(jù)可用邮偎,那么 API 網(wǎng)關(guān)還可以返回緩存數(shù)據(jù)。例如义黎,鑒于產(chǎn)品價格不會頻繁變動禾进,如果價格服務(wù)不可用,API 網(wǎng)關(guān)可以返回緩存的價格數(shù)據(jù)廉涕。數(shù)據(jù)可以由 API 網(wǎng)關(guān)自己緩存命迈,也可以存儲在像 Redis 或 Memcached 之類的外部緩存中贩绕。通過返回默認(rèn)數(shù)據(jù)或者緩存數(shù)據(jù),API 網(wǎng)關(guān)可以確保系統(tǒng)故障不影響用戶體驗壶愤。

在編寫代碼調(diào)用遠程服務(wù)方面淑倾,Netflix Hystrix 是一個格外有用的庫。Hystrix 會暫停超出特定閾限的調(diào)用征椒。它實現(xiàn)了一個“斷路器(circuit breaker)”模式娇哆,可以防止客戶端對無響應(yīng)的服務(wù)進行不必要的等待。如果服務(wù)的錯誤率超出了設(shè)定的閾值勃救,那么 Hystrix 會啟動斷路器碍讨,所有請求會立即失敗并持續(xù)一定時間。Hystrix 允許用戶定義一個請求失敗后的后援操作蒙秒,比如從緩存讀取數(shù)據(jù)勃黍,或者返回一個默認(rèn)值。如果你正在使用 JVM晕讲,那么你應(yīng)該考慮使用 Hystrix覆获;如果你正在使用一個非 JVM 環(huán)境,那么可以使用一個功能相同的庫瓢省。

總結(jié)

對于大多數(shù)基于微服務(wù)的應(yīng)用程序而言弄息,實現(xiàn) API 網(wǎng)關(guān),將其作為系統(tǒng)的唯一入口很有必要勤婚。API 網(wǎng)關(guān)負(fù)責(zé)服務(wù)請求路由摹量、組合及協(xié)議轉(zhuǎn)換。它為每個應(yīng)用程序客戶端提供一個定制的 API馒胆。API 網(wǎng)關(guān)還可以通過返回緩存數(shù)據(jù)或默認(rèn)數(shù)據(jù)屏蔽后端服務(wù)失敗缨称。在本系列的下一篇文章中,我們將探討服務(wù)間通信祝迂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末具钥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子液兽,更是在濱河造成了極大的恐慌骂删,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件四啰,死亡現(xiàn)場離奇詭異宁玫,居然都是意外死亡,警方通過查閱死者的電腦和手機柑晒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門欧瘪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人匙赞,你說我怎么就攤上這事佛掖⊙铮” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵芥被,是天一觀的道長欧宜。 經(jīng)常有香客問我,道長拴魄,這世上最難降的妖魔是什么冗茸? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮匹中,結(jié)果婚禮上夏漱,老公的妹妹穿的比我還像新娘。我一直安慰自己顶捷,他們只是感情好挂绰,可當(dāng)我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著服赎,像睡著了一般葵蒂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上专肪,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機與錄音堪侯,去河邊找鬼嚎尤。 笑死,一個胖子當(dāng)著我的面吹牛伍宦,可吹牛的內(nèi)容都是我干的芽死。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼次洼,長吁一口氣:“原來是場噩夢啊……” “哼关贵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起卖毁,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤揖曾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后亥啦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炭剪,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年翔脱,在試婚紗的時候發(fā)現(xiàn)自己被綠了奴拦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡届吁,死狀恐怖错妖,靈堂內(nèi)的尸體忽然破棺而出绿鸣,到底是詐尸還是另有隱情,我是刑警寧澤暂氯,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布潮模,位于F島的核電站,受9級特大地震影響株旷,放射性物質(zhì)發(fā)生泄漏再登。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一晾剖、第九天 我趴在偏房一處隱蔽的房頂上張望锉矢。 院中可真熱鬧,春花似錦齿尽、人聲如沸沽损。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绵估。三九已至,卻和暖如春卡骂,著一層夾襖步出監(jiān)牢的瞬間国裳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工全跨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缝左,地道東北人。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓浓若,卻偏偏與公主長得像渺杉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挪钓,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,107評論 2 356

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