阿里函數(shù)計(jì)算實(shí)現(xiàn)簡(jiǎn)單React Native熱更新后臺(tái)

函數(shù)計(jì)算作為云計(jì)算中新一代的計(jì)算單元,有著不需要管理服務(wù)器設(shè)施和更精準(zhǔn)的計(jì)費(fèi)方式的優(yōu)勢(shì)。它依托于云服務(wù)商的多種云資源(對(duì)象存儲(chǔ),日志服務(wù)等),將需要計(jì)算的業(yè)務(wù)邏輯濃縮在一個(gè)函數(shù)中拟淮,并協(xié)調(diào)多種其他云資源。收費(fèi)方式也采用按調(diào)用次數(shù)和運(yùn)行時(shí)間為計(jì)費(fèi)單位谴忧,使得計(jì)算資源的計(jì)費(fèi)更精準(zhǔn)很泊。對(duì)用戶(hù)來(lái)說(shuō),在保證業(yè)務(wù)正常運(yùn)轉(zhuǎn)的前提下沾谓,節(jié)省下不少業(yè)務(wù)閑時(shí)的服務(wù)器成本委造。

2014年AWS發(fā)布Lambda函數(shù)計(jì)算服務(wù),經(jīng)過(guò)幾年的發(fā)展函數(shù)計(jì)算也越來(lái)越受到開(kāi)發(fā)者的關(guān)注均驶。
2017年昏兆,阿里云發(fā)布自己的函數(shù)計(jì)算服務(wù)

本文記錄基于阿里云函數(shù)計(jì)算服務(wù),簡(jiǎn)單實(shí)現(xiàn)app熱更新后端妇穴。

為什么使用函數(shù)計(jì)算

阿里云的官方文檔中介紹了幾種函數(shù)計(jì)算適用的場(chǎng)景:

  • 媒資內(nèi)容分析處理:通過(guò)對(duì)象存儲(chǔ)上傳事件可以觸發(fā)多個(gè)函數(shù)爬虱,完成轉(zhuǎn)碼隶债、元數(shù)據(jù)抽取等功能。通過(guò)事件觸發(fā)機(jī)制跑筝,您能夠快速整合不同服務(wù)死讹,構(gòu)建一個(gè)彈性、高可用的視頻后端系統(tǒng)曲梗。
  • Severless后端服務(wù):可以使用 函數(shù)計(jì)算和 API網(wǎng)關(guān) 構(gòu)建后端回俐,以驗(yàn)證和處理 API 請(qǐng)求。采用函數(shù)服務(wù)構(gòu)建靈活拓展架構(gòu),輕松創(chuàng)造豐富稀并、個(gè)性化的應(yīng)用程序體驗(yàn)。
  • IoT消息實(shí)時(shí)處理:您可以使用函數(shù)計(jì)算高效的處理實(shí)時(shí)流數(shù)據(jù)单默。例如碘举,實(shí)時(shí)過(guò)濾、聚合搁廓、分析IoT設(shè)備產(chǎn)生的數(shù)據(jù)引颈,并將產(chǎn)生的結(jié)構(gòu)化數(shù)據(jù)保存到數(shù)據(jù)庫(kù)中。

可以看出涨缚,函數(shù)計(jì)算主要應(yīng)用在事件出發(fā)->簡(jiǎn)單處理數(shù)據(jù)->存入數(shù)據(jù)庫(kù)或?qū)ο蟠鎯?chǔ)場(chǎng)景下鳄梅。

這個(gè)場(chǎng)景也剛好適用于APP熱更新的后端的幾個(gè)核心業(yè)務(wù):

  • 上傳新代碼:上傳代碼到OSS事件->分析代碼->更新最新版本信息
  • 發(fā)布最新代碼:發(fā)布事件->查詢(xún)要發(fā)布代碼->發(fā)布代碼到環(huán)境
  • APP查詢(xún)更新:最新版本查詢(xún)事件->比對(duì)app版本與最新版本->返回結(jié)果

從費(fèi)用方面考慮偷遗,函數(shù)計(jì)算現(xiàn)在的免費(fèi)配額基本可以滿(mǎn)是日常試用,所以決定用函數(shù)計(jì)算來(lái)支撐熱更新服務(wù)售滤。

架構(gòu)總覽

使用函數(shù)計(jì)算,主要是通過(guò)云上的資源來(lái)觸發(fā)函數(shù)台诗,然后由函數(shù)處理數(shù)據(jù)完箩,并調(diào)度其他云資源。
熱更新服務(wù)架構(gòu)圖

架構(gòu)縱覽

基本組件

在熱更新業(yè)務(wù)中拉队,主要涉及了以下幾個(gè)組件弊知。

函數(shù)計(jì)算

函數(shù)計(jì)算作為承載業(yè)務(wù)的應(yīng)用層,替代了傳統(tǒng)使用ECS服務(wù)搭建的應(yīng)用服務(wù)器粱快。

對(duì)象存儲(chǔ)

對(duì)象存儲(chǔ)用來(lái)做簡(jiǎn)單的數(shù)據(jù)持久化和存儲(chǔ)熱更新包秩彤。

日志服務(wù)

日志在函數(shù)計(jì)算中很重要。因?yàn)楹瘮?shù)容器在運(yùn)行結(jié)束后立即被銷(xiāo)毀事哭,運(yùn)行過(guò)程中的日志也會(huì)隨著容器同事銷(xiāo)毀漫雷。只有在函數(shù)運(yùn)行時(shí)將日志輸出到日志服務(wù),才能在之后查詢(xún)到函數(shù)的運(yùn)行記錄慷蠕。也因?yàn)槿绱松浩矗诤瘮?shù)調(diào)試時(shí),我們更需要日志服務(wù)來(lái)查看函數(shù)的運(yùn)行狀況流炕。

API網(wǎng)關(guān)

API網(wǎng)關(guān)為函數(shù)計(jì)算提供了對(duì)外提供Web API接口的能力澎现,同時(shí)也提供了身份認(rèn)證和授權(quán)兩大重要功能仅胞。在API網(wǎng)關(guān)中,用戶(hù)可以定義提供的接口簽名剑辫,并授權(quán)給特定的用戶(hù)使用Web API干旧。

業(yè)務(wù)流

上傳代碼

  1. 用戶(hù)通過(guò)OSS命令行或OSS控制臺(tái)直接上傳代碼到指定目錄
  2. OSS觸發(fā)函數(shù)計(jì)算執(zhí)行相應(yīng)業(yè)務(wù)
  3. 函數(shù)計(jì)算將結(jié)果保存回OSS指定目錄

檢查更新

  1. APP客戶(hù)端訪問(wèn)API網(wǎng)關(guān)提供的API
  2. API網(wǎng)關(guān)調(diào)用函數(shù)計(jì)算檢查版本
  3. API網(wǎng)關(guān)將函數(shù)計(jì)算結(jié)果返回給客戶(hù)端

基本概念

函數(shù)計(jì)算有幾個(gè)主要的概念,在開(kāi)始前需要了解妹蔽。

角色和授權(quán)

函數(shù)計(jì)算本身只處理業(yè)務(wù)邏輯椎眯,當(dāng)函數(shù)計(jì)算需要與阿里云上其他資源交互的時(shí)候,就需要利用阿里云的RAM(訪問(wèn)控制)系統(tǒng)來(lái)給函數(shù)一個(gè)角色和授權(quán)來(lái)和其他云資源交互胳岂。函數(shù)在運(yùn)行時(shí)编整,可以通過(guò)默認(rèn)傳入函數(shù)的context變量獲取角色的憑證,并扮演該角色與已授權(quán)的云資源進(jìn)行交互乳丰。

關(guān)于如何為函數(shù)服務(wù)創(chuàng)建角色的詳細(xì)內(nèi)容可以參考應(yīng)用示例2 - 授權(quán)函數(shù)訪問(wèn)其他云服務(wù)資源

觸發(fā)器和事件

事件是當(dāng)其他云資源需要觸發(fā)函數(shù)計(jì)算處理時(shí)掌测,發(fā)送給函數(shù)計(jì)算服務(wù)的一段包含特定事件詳情的信息。其他云資源可以定義什么時(shí)候觸發(fā)事件(即定義觸發(fā)器)产园,不同資源汞斧,觸發(fā)事件后發(fā)送給函數(shù)計(jì)算的事件詳情不同。

注:目前阿里云上只有AIP網(wǎng)關(guān)OSS對(duì)象存儲(chǔ)支持創(chuàng)建觸發(fā)器什燕。

更多細(xì)節(jié)可參考應(yīng)用示例4 - 觸發(fā)器管理

服務(wù)

服務(wù)是管理函數(shù)的最小單位粘勒,每個(gè)函數(shù)都只屬于一個(gè)服務(wù)。 服務(wù)中可以定義函數(shù)可以使用的'角色'和日志輸出的倉(cāng)庫(kù)屎即,所有函數(shù)共享所屬服務(wù)的這些設(shè)定庙睡。

函數(shù)

函數(shù)是運(yùn)行代碼的容器。用戶(hù)自己編寫(xiě)需要處理的業(yè)務(wù)技俐,并放在相應(yīng)語(yǔ)言的函數(shù)容器中運(yùn)行埃撵。

注:目前阿里云支持nodejs, pythonjava

實(shí)現(xiàn)步驟

簡(jiǎn)單介紹,搭建熱更新后端的步驟虽另。

工具

用戶(hù)可以在阿里云控制臺(tái)中操作創(chuàng)建服務(wù)函數(shù)暂刘,更方便的做法是使用行數(shù)計(jì)算命令行工具fcli進(jìn)行創(chuàng)建。在下面的步驟中捂刺,采用fcli的方式介紹谣拣。
fcli下載及文檔

初次使用fcli需要使用阿里云賬號(hào)登陸。 注:如果使用子賬號(hào)登陸族展,子賬號(hào)需要有操作RAM和函數(shù)計(jì)算的授權(quán)森缠。
運(yùn)行:

fcli shell

Please input the endpoint (example: https://account_id.cn-shanghai.fc.aliyuncs.com):
> [ENDPOINT]
Please input the access key id:
> [FAKE_ACCESS_KEY_ID]
Please input the access key secret:
> [FAKE_ACCESS_KEY_SECRET]
Store the configuration in: /Users/testuser/.fcli
Welcome to the function compute world. Have fun!

獲取endpoint,請(qǐng)參考服務(wù)入口文檔仪缸。
獲取access key id/secret贵涵,請(qǐng)參考相關(guān)文檔

創(chuàng)建角色授權(quán)

當(dāng)函數(shù)計(jì)算和其他云資源有交互的時(shí)候,需要?jiǎng)?chuàng)建兩種角色授權(quán)宾茂,一種是授權(quán)給其他云資源使用觸發(fā)函數(shù)計(jì)算的角色瓷马, 另一種是授權(quán)給函數(shù)計(jì)算使用云資源的角色。

觸發(fā)函數(shù)計(jì)算

創(chuàng)建觸發(fā)函數(shù)計(jì)算角色跨晴,用來(lái)授權(quán)給其他云資源調(diào)用函數(shù)計(jì)算服務(wù)欧聘。 例如,授權(quán)api網(wǎng)關(guān)調(diào)用函數(shù)計(jì)算端盆,或?qū)ο蟠鎯?chǔ)服務(wù)觸發(fā)函數(shù)計(jì)算怀骤。

運(yùn)行:

mkir fc-invoke-function
mkrp fc-invoke-all -a '"fc:InvokeFunction"' -r '"*"'
attach -p /ram/policies/fc-invoke-all -r /ram/roles/fc-invoke-function

對(duì)象存儲(chǔ)及日志服務(wù)讀寫(xiě)

創(chuàng)建其他云資源調(diào)用角色,用來(lái)讓函數(shù)計(jì)算服務(wù)可以訪問(wèn)日志服務(wù)OSS對(duì)象存儲(chǔ)服務(wù)焕妙。

運(yùn)行:

mksr fc-oss-log-op
mkrp fc-oss-log-gp -a '["oss:GetObject", "oss:PutObject", "log:PostLogStoreLogs", "log:GetLogStore"]' -r '"*"'
attach -p /ram/policies/fc-oss-log-gp -r /ram/roles/fc-oss-log-op
mks oss_demo -r acs:ram::[ALIYUN ACCOUNT id]:role/fc-oss-log-op

注:這里為了演示方便蒋伦,并沒(méi)有限制具體可操作資源,用戶(hù)需要更具具體情況合理的限制可操作資源焚鹊。

創(chuàng)建日志庫(kù)

創(chuàng)建日志庫(kù)來(lái)凉敲,用來(lái)收集函數(shù)日志。 具體步驟可以參考函數(shù)訪問(wèn)日志服務(wù)

這里創(chuàng)建一個(gè)日志項(xiàng)目名為fc-beijing寺旺, 倉(cāng)庫(kù)名為hotpatch的日志庫(kù)。

創(chuàng)建OSS

熱更新的代碼需要存放在OSS中势决,所以需要?jiǎng)?chuàng)建一個(gè)與函數(shù)服務(wù)在同一個(gè)區(qū)存儲(chǔ)空間阻塑。名字為hotpatch, 且讀寫(xiě)權(quán)限為‘公共讀,私有寫(xiě)’果复。

創(chuàng)建函數(shù)服務(wù)

在阿里控制臺(tái)選擇函數(shù)服務(wù)陈莽,創(chuàng)建名為hotpatchService的函數(shù)服務(wù),選擇剛創(chuàng)建的日志庫(kù)hotpatchfc-oss-log-op這個(gè)角色虽抄。

創(chuàng)建函數(shù)服務(wù)

創(chuàng)建項(xiàng)目

函數(shù)服務(wù)本身每一個(gè)函數(shù)都是獨(dú)立的代碼片段處理業(yè)務(wù)的某一個(gè)部分走搁,自身就像一個(gè)小的項(xiàng)目。但是迈窟,一個(gè)服務(wù)下的所有函數(shù)私植,卻是在處理同一塊業(yè)務(wù)。

熱更新項(xiàng)目的結(jié)構(gòu)车酣,借鑒了一些開(kāi)源項(xiàng)目包含多個(gè)子項(xiàng)目的代碼管理思路曲稼,把服務(wù)作為一個(gè)項(xiàng)目,每一個(gè)函數(shù)作為子項(xiàng)目湖员。達(dá)到贫悄,服務(wù)的所有函數(shù)代碼使用同一個(gè)代碼庫(kù)管理,但每個(gè)函數(shù)的代碼又是獨(dú)立的可以自行管理依賴(lài)娘摔,測(cè)試窄坦,發(fā)布等操作。

因?yàn)椴捎胣odejs開(kāi)發(fā),所以使用lerna作為管理項(xiàng)目和子項(xiàng)目的工具鸭津。項(xiàng)目目錄如下:

├── README.md
├── lerna.json
├── package.json
├── packages
│   ├── getLatestBundle
│   │   ├── index.js
│   │   └── package.json
│   └── uploadBundle
│       ├── index.js
│       ├── node_modules
│       ├── package-lock.json
│       └── package.json

packages目錄下存放著不同的函數(shù)彤侍,每個(gè)函數(shù)是一個(gè)文件夾, 使用函數(shù)名字命名,例如uploadBundle曙博。沒(méi)個(gè)函數(shù)使用package.json管理依賴(lài)包拥刻。

上傳UploadBundle代碼

在uploadBunde目錄下運(yùn)行

fcli shell
mkf uploadBundle -h index.handler -t nodejs6

上傳getLatestBundle代碼

上傳getLatestBundle代碼

fcli shell
mkf getLatestBundle -h index.handler -t nodejs6

更新代碼

使用編輯器編輯本地代碼后,在函數(shù)文件夾運(yùn)行

fcli shell
upf [FUNCTION NAME] -h index.handler -t nodejs6

創(chuàng)建觸發(fā)器

目前只有OSS對(duì)象存儲(chǔ)服務(wù)父泳,支持創(chuàng)建函數(shù)觸發(fā)器般哼,用戶(hù)可以定義當(dāng)存儲(chǔ)空間內(nèi)某些操作執(zhí)行后觸發(fā)函數(shù),例如用戶(hù)上傳新的對(duì)象后惠窄,觸發(fā)函數(shù)蒸眠。

在熱更新后臺(tái)中,需要在有新代碼上傳后杆融,對(duì)代碼進(jìn)行md5計(jì)算楞卡,并放入測(cè)試環(huán)境。

創(chuàng)建觸發(fā)器config.yaml, 定義OSS觸發(fā)函數(shù)的事件

triggerConfig:
    events:
        - oss:ObjectCreated:*
    filter:
        key:
            prefix: src/
            suffix: .js

在bash中運(yùn)行:

mkt uploadBundle -t oss -r acs:ram::[ALIYUN ACCOUNT id]:role/fc-invoke-function -s acs:oss:[REGION]:[ALIYUN ACCOUNT ID]:hotpatch -c config.yaml

API網(wǎng)關(guān)

當(dāng)使用函數(shù)計(jì)算作為Web API服務(wù)后端時(shí)脾歇,需要使用API網(wǎng)關(guān)來(lái)定義Web API的接口蒋腮,并由API網(wǎng)關(guān)轉(zhuǎn)換客戶(hù)端請(qǐng)求后,調(diào)用函數(shù)計(jì)算服務(wù)藕各。

在更新后臺(tái)中池摧,檢測(cè)版本更新需要以Web API的形式提供給APP客戶(hù)端訪問(wèn)。

步驟:

在阿里云控制臺(tái)中打開(kāi)API網(wǎng)關(guān)激况,創(chuàng)建名為hotpatchAPIGroup分組

創(chuàng)建分組

創(chuàng)建名為getLatestBundle的API

安全方式暫時(shí)選則無(wú)認(rèn)證作彤,在后面的安全章節(jié)中會(huì)介紹如何開(kāi)啟認(rèn)證。

創(chuàng)建API


創(chuàng)建API

請(qǐng)求基礎(chǔ)定義


請(qǐng)求基礎(chǔ)定義

后端基礎(chǔ)定義


后端基礎(chǔ)定義

定義返回結(jié)果

{
    "isBase64Encoded":true|false,
    "statusCode":httpStatusCode,
    "headers":{response headers},
    "body":"..."
}

注:更詳細(xì)步驟可參考API網(wǎng)關(guān)觸發(fā)函數(shù)計(jì)算

安全

在之前創(chuàng)建API時(shí)乌逐,選擇了無(wú)認(rèn)證竭讳,在學(xué)習(xí)使用函數(shù)計(jì)算作為API服務(wù)后端時(shí)是可以簡(jiǎn)化概念,把重點(diǎn)放在如何鏈接兩個(gè)服務(wù)上浙踢。 在真實(shí)項(xiàng)目中绢慢,我們依然希望API的訪問(wèn)是可控的,只有授權(quán)過(guò)的客戶(hù)端才可以訪問(wèn)洛波。

API網(wǎng)關(guān)服務(wù)提供了一種基于應(yīng)用的認(rèn)證授權(quán)的機(jī)制呐芥,用戶(hù)可以在API網(wǎng)關(guān)中創(chuàng)建一個(gè)應(yīng)用,并在API中設(shè)置安全方式為阿里云APP, 簽名算法為HmacSHA256奋岁。 之后思瘟,在授權(quán)信息中添加應(yīng)用訪問(wèn)API的授權(quán)。

注:詳細(xì)步驟可參考授權(quán)給應(yīng)用

后記

熱更新后端作為技術(shù)驗(yàn)證項(xiàng)目闻伶,已經(jīng)部署在測(cè)試環(huán)境滨攻,生產(chǎn)環(huán)境暫時(shí)沒(méi)有開(kāi)啟。

目前,還有幾處不完善的地方:

  • 發(fā)布函數(shù)
  • 客戶(hù)端命令行
  • 針對(duì)不同版本做diff patch光绕,使更新包更小女嘲。

TODO

  • 公開(kāi)項(xiàng)目代碼

附錄

參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诞帐,隨后出現(xiàn)的幾起案子欣尼,更是在濱河造成了極大的恐慌,老刑警劉巖停蕉,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愕鼓,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡慧起,警方通過(guò)查閱死者的電腦和手機(jī)菇晃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蚓挤,“玉大人磺送,你說(shuō)我怎么就攤上這事〔右猓” “怎么了估灿?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)缤剧。 經(jīng)常有香客問(wèn)我馅袁,道長(zhǎng),這世上最難降的妖魔是什么鞭执? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮芒粹,結(jié)果婚禮上兄纺,老公的妹妹穿的比我還像新娘。我一直安慰自己化漆,他們只是感情好估脆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著座云,像睡著了一般疙赠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上朦拖,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天圃阳,我揣著相機(jī)與錄音,去河邊找鬼璧帝。 笑死捍岳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播锣夹,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼页徐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了银萍?” 一聲冷哼從身側(cè)響起变勇,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贴唇,沒(méi)想到半個(gè)月后搀绣,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滤蝠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年豌熄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片物咳。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锣险,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出览闰,到底是詐尸還是另有隱情芯肤,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布压鉴,位于F島的核電站崖咨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏油吭。R本人自食惡果不足惜击蹲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望婉宰。 院中可真熱鬧歌豺,春花似錦、人聲如沸心包。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蟹腾。三九已至痕惋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娃殖,已是汗流浹背值戳。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留炉爆,地道東北人述寡。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓柿隙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親鲫凶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子禀崖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)螟炫,斷路器波附,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • 我們與理想失之交臂了 但并不阻擋我們要遠(yuǎn)行的步伐 因?yàn)椴恢褂形覀? ...
    小胖要減肥123閱讀 457評(píng)論 1 1
  • 周四得早上,忙完了工作還是工作室昼钻!夜晚和家人一起吃飯掸屡,逛了一會(huì)街!身體持續(xù)不舒服然评,本來(lái)打算今天去看的仅财,明天必須去了!
    DeathKnightR閱讀 150評(píng)論 0 0
  • 到附近社區(qū)參加活動(dòng)碗淌,一進(jìn)活動(dòng)室盏求,就看到五六張大桌子,每張桌子都被七八個(gè)孩子圍著亿眠,用毛筆沾著粉紅的顏色專(zhuān)注地畫(huà)一個(gè)個(gè)...
    山上有云閱讀 675評(píng)論 0 1
  • 很多人都不太清楚舞蹈有哪些碎罚,我就借思維導(dǎo)圖普及一下舞蹈類(lèi)別,看看大家喜歡哪種呢纳像?
    吾小娟閱讀 1,343評(píng)論 2 5