58集團(tuán)RPC框架SCF的設(shè)計(jì)與實(shí)踐

一、前 言

RPC 是遠(yuǎn)程過(guò)程調(diào)用(Remote Procedure Call)的縮寫,它是一種通過(guò)網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)程序上請(qǐng)求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。舉例來(lái)說(shuō)观腊,部署在 A 節(jié)點(diǎn)上的應(yīng)用調(diào)用部署在 B 節(jié)點(diǎn)上的應(yīng)用提供的接口,A 節(jié)點(diǎn)需要將調(diào)用的數(shù)據(jù)信息通過(guò)網(wǎng)絡(luò)傳遞到 B 節(jié)點(diǎn)算行,B 節(jié)點(diǎn)根據(jù)接收到的數(shù)據(jù)信息找到具體的接口執(zhí)行梧油,并將執(zhí)行的結(jié)果通過(guò)網(wǎng)絡(luò)返回給節(jié)點(diǎn) A。

RPC 框架封裝網(wǎng)絡(luò)傳輸州邢、序列化婶溯、負(fù)載均衡、故障剔除等通用能力偷霉,使得 A 節(jié)點(diǎn)可以像調(diào)用本地方法一樣簡(jiǎn)單地調(diào)用遠(yuǎn)程接口迄委。

SCF 是 58 自主研發(fā)的 RPC 框架,致力于在分布式環(huán)境下提供高性能类少、高可靠和透明化的 RPC 遠(yuǎn)程調(diào)用方案叙身。

服務(wù)管理平臺(tái)是基于 SCF 框架的服務(wù)治理平臺(tái),具有服務(wù)節(jié)點(diǎn)自動(dòng)注冊(cè)與發(fā)現(xiàn)硫狞、負(fù)載均衡信轿、服務(wù)鑒權(quán)、全方位監(jiān)控残吩、完善的告警等特點(diǎn)财忽。

二、整體架構(gòu)

整體架構(gòu)
  • SCF 服務(wù)方: 指使用 SCF 框架服務(wù)端能力泣侮,提供可以被遠(yuǎn)程調(diào)用的接口的應(yīng)用即彪。

  • SCF 調(diào)用方: 指使用 SCF 框架客戶端能力,調(diào)用服務(wù)方提供接口的應(yīng)用活尊。

  • 控制中心: 核心是維護(hù) SCF 服務(wù)方和 SCF 調(diào)用方之間的調(diào)用關(guān)系隶校,生成調(diào)用方需要使用的服務(wù)配置信息漏益,支持當(dāng)調(diào)用關(guān)系調(diào)整時(shí),實(shí)時(shí)向調(diào)用方推送新的配置信息深胳。

  • 監(jiān)控中心: 統(tǒng)一收集服務(wù)方和調(diào)用方的流量數(shù)據(jù)绰疤,并提供實(shí)時(shí)告警功能,可以提高業(yè)務(wù)人員對(duì)服務(wù)的整體把控能力舞终,幫助服務(wù)負(fù)責(zé)人提高服務(wù)穩(wěn)定性轻庆。

  • 可視化管理平臺(tái): 提供給業(yè)務(wù)的管理界面,可以查看服務(wù)方和調(diào)用方的流量監(jiān)控?cái)?shù)據(jù)敛劝、配置服務(wù)方和調(diào)用方的調(diào)用信息榨了、設(shè)置豐富的告警等。

SCF 服務(wù)方和 SCF 調(diào)用方構(gòu)成了 SCF 框架的主要組成部分攘蔽,可以實(shí)現(xiàn)基本的 RPC 遠(yuǎn)程調(diào)用。

控制中心呐粘、監(jiān)控中心和可視化管理平臺(tái)三個(gè)部分屬于服務(wù)管理平臺(tái)满俗,是對(duì) SCF 框架基本能力的補(bǔ)充,對(duì)服務(wù)的治理提供了有效的手段作岖。

三唆垃、SCF 框架

3.1SCF 調(diào)用模式
SCF 調(diào)用模式

RPC 框架最基本的能力是提供遠(yuǎn)程調(diào)用,SCF 提供了同步調(diào)用和回調(diào)調(diào)用兩種調(diào)用模式痘儡。

SCF 調(diào)用模式
3.2同步調(diào)用

同步調(diào)用是業(yè)務(wù)使用最多的一種方式辕万,也是框架默認(rèn)的調(diào)用方式。調(diào)用方在調(diào)用服務(wù)的接口時(shí)沉删,執(zhí)行調(diào)用的線程會(huì)被阻塞渐尿,等待調(diào)用完成。如果服務(wù)方返回了結(jié)果或等待時(shí)間超過(guò)設(shè)置的超時(shí)時(shí)間矾瑰,線程被喚醒砖茸,獲取返回結(jié)果或捕獲超時(shí)的異常。

3.3回調(diào)調(diào)用

回調(diào)調(diào)用是指調(diào)用服務(wù)接口之后殴穴,接口立即返回凉夯,調(diào)用接口的線程不需要等待服務(wù)端的返回結(jié)果,因此不存在阻塞的情況采幌。如果服務(wù)端有返回結(jié)果或等待超過(guò)設(shè)置的超時(shí)時(shí)間劲够,由框架中單獨(dú)的回調(diào)線程處理返回的結(jié)果或超時(shí)異常。因此在調(diào)用前必須設(shè)置接口的回調(diào)實(shí)現(xiàn)類休傍。

3.4超時(shí)處理

在實(shí)際生產(chǎn)環(huán)境中征绎,服務(wù)端方健康狀況不可控、網(wǎng)絡(luò)情況復(fù)雜可能出現(xiàn)各種異常情況磨取。因此炒瘸,上述同步或回調(diào)調(diào)用中淤堵,不是所有的調(diào)用都一定能得到服務(wù)方返回的結(jié)果,為了避免調(diào)用方無(wú)限制的等待顷扩,必須設(shè)置調(diào)用的超時(shí)時(shí)間拐邪。在超過(guò)設(shè)置的時(shí)間內(nèi)沒有得到返回結(jié)果,就通過(guò)超時(shí)異常的方式通知調(diào)用方隘截。

SCF 中使用經(jīng)典的 TimeWheel 算法實(shí)現(xiàn)調(diào)用任務(wù)的過(guò)期扎阶。

TimeWheel

內(nèi)部使用數(shù)組模擬類似時(shí)鐘的環(huán)形數(shù)據(jù)結(jié)構(gòu),每一個(gè)格子代表一個(gè)時(shí)間間隔婶芭,每個(gè)格子對(duì)應(yīng)一個(gè)任務(wù)的鏈表东臀,在添加過(guò)期任務(wù)時(shí),通過(guò)過(guò)期時(shí)間和當(dāng)前時(shí)間計(jì)算出任務(wù)應(yīng)該在第幾個(gè)格子里并計(jì)算應(yīng)該是走到第幾圈時(shí)觸發(fā)超時(shí)犀农。

假設(shè)圖中每個(gè)格子表示 100ms惰赋,則一圈代表 800ms,當(dāng)前是走到第 1 圈的第 2 個(gè)格子呵哨。如果任務(wù) 500ms 后超時(shí)赁濒,(500+200)% 800=7,因此將任務(wù)放到第 7 個(gè)格子對(duì)應(yīng)的鏈表中孟害,并標(biāo)記第 1 圈超時(shí)拒炎。如果任務(wù) 1000ms 后超時(shí),(1000+200)% 800=4挨务,(1000+200)/800=1击你,因此將任務(wù)放入第 4 個(gè)格子對(duì)應(yīng)的鏈表中,并標(biāo)記第 2 圈超時(shí)谎柄。

上述過(guò)期算法存在有兩個(gè)關(guān)鍵點(diǎn)需要注意:

  1. 過(guò)期時(shí)間存在誤差丁侄,誤差范圍是每個(gè)格子代表的時(shí)間。

  2. 掃描任務(wù)過(guò)期的線程應(yīng)該和執(zhí)行過(guò)期操作的線程獨(dú)立朝巫,避免執(zhí)行過(guò)期操作影響到后續(xù)任務(wù)的過(guò)期掃描绒障。

3.5序列化

在網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)只能是 0 和 1 組成的二進(jìn)制數(shù)據(jù),而通常我們請(qǐng)求的數(shù)據(jù)信息是面向?qū)ο笾芯唧w類的對(duì)象捍歪,序列化就是實(shí)現(xiàn)對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或傳輸?shù)男问降倪^(guò)程户辱,反序列化是序列化的逆過(guò)程。

SCF 框架采用了自定義的序列化實(shí)現(xiàn)方式糙臼,下面主要介紹序列化是如何實(shí)現(xiàn)非對(duì)稱序列化和泛型序列化庐镐。

3.5.1非對(duì)稱序列化

互聯(lián)網(wǎng)是一個(gè)變化非常快的行業(yè)变逃,在發(fā)布一個(gè)接口之后必逆,隨著業(yè)務(wù)的發(fā)展必然會(huì)產(chǎn)生對(duì)接口傳輸對(duì)象進(jìn)行調(diào)整的情況,因此就有了增加或刪除類中的成員變量的需求。如果不能支持服務(wù)方和調(diào)用方的類存在非對(duì)稱的成員名眉,業(yè)務(wù)升級(jí)將會(huì)非常麻煩粟矿。

SCF 序列化對(duì)非對(duì)稱類處理的思想是對(duì)類的成員變量進(jìn)行編號(hào),在寫數(shù)據(jù)流的過(guò)程中损拢,成員變量根據(jù)編號(hào) (id)+ 數(shù)據(jù)長(zhǎng)度 (length)+ 數(shù)據(jù) (value) 的方式依次寫入二進(jìn)制流陌粹,反序列化則從流中先讀取 id,判斷需要賦值的類是否存在該 id 的成員福压,如果存在繼續(xù)讀取長(zhǎng)度和數(shù)據(jù)部分掏秩,如果不存在該 id,則根據(jù)讀取的長(zhǎng)度跳過(guò)二進(jìn)制流中該 id 成員對(duì)應(yīng)的數(shù)據(jù)部分荆姆,從而實(shí)現(xiàn)忽略不存在成員的目的蒙幻。

image

針對(duì)以上兩個(gè)版本的實(shí)體,左邊是編號(hào) 1胆筒、2邮破、3 的成員,右邊是 1仆救、4 的成員抒和。序列化和反序列化過(guò)程如下:

image
image

使用基本的 id + length + value 的方式可以實(shí)現(xiàn)非對(duì)稱序列化,但是對(duì)所有的成員都需要寫入 id 和 length 兩個(gè)特殊的標(biāo)識(shí)派桩,增加了二進(jìn)制數(shù)據(jù)的大小。而對(duì)于基本類型蚌斩,其實(shí)長(zhǎng)度是已知的铆惑。通過(guò)對(duì)數(shù)據(jù)類型按下面 type 進(jìn)行劃分:

image

只需要 3bit 就可以表示說(shuō)要的數(shù)據(jù)類型,因此采用 tag = (id << 3)|type 的方式送膳,將 type 嵌入到 tag 字段中员魏,實(shí)現(xiàn)基本類型的數(shù)據(jù)只需要寫入 tag 數(shù)據(jù),不需要寫入 length 字段叠聋,有效減少二進(jìn)制數(shù)據(jù)大小撕阎。

3.5.2泛型序列化

泛型序列化是指在類中存在非具體類型成員變量(Java 中的基類 Object)的對(duì)象序列化。

SCF 中使用全限定類名 hash 的方式碌补,為每一個(gè)類生成唯一 typeId虏束,在寫入泛型成員時(shí),先寫入類的 typeId厦章,再寫入 value 數(shù)據(jù)镇匀。讀取時(shí)一樣通過(guò)先讀取 typeId,查找具體類型袜啃,再根據(jù)類型讀取 value 數(shù)據(jù)汗侵。

四、服務(wù)注冊(cè)與發(fā)現(xiàn)

調(diào)用方通過(guò)網(wǎng)絡(luò)調(diào)用服務(wù)方,必須要知道服務(wù)方節(jié)點(diǎn)的 IP 列表晰韵,才能發(fā)起調(diào)用发乔。最原始的方式是通過(guò)在調(diào)用方使用配置文件的方式指定,但是這種方式在實(shí)際使用中不能動(dòng)態(tài)感知服務(wù)方節(jié)點(diǎn)的變化雪猪,不夠靈活也無(wú)法時(shí)間服務(wù)的自動(dòng)化擴(kuò)縮容栏尚。

服務(wù)注冊(cè)與發(fā)現(xiàn)即自動(dòng)發(fā)現(xiàn)服務(wù)的節(jié)點(diǎn)信息,并且調(diào)用方能及時(shí)感知服務(wù)方節(jié)點(diǎn)的變化情況浪蹂,自動(dòng)調(diào)整流量切換到新的節(jié)點(diǎn)抵栈。

image

SCF 使用 ETCD 集群管理服務(wù)節(jié)點(diǎn),每一個(gè)服務(wù)節(jié)點(diǎn)對(duì)應(yīng) ETCD 中的一個(gè) key坤次,并且為 key 設(shè)置一個(gè) TTL 過(guò)期時(shí)間古劲。通過(guò)心跳刷新 TTL 的方式維持服務(wù)節(jié)點(diǎn)在線狀態(tài)。為隔離 ETCD 集群與業(yè)務(wù)部署環(huán)境缰猴,避免服務(wù)節(jié)點(diǎn)的增加造成 ETCD 集群的連接數(shù)過(guò)高等問(wèn)題产艾,封裝了一層服務(wù)管理節(jié)點(diǎn)做代理,轉(zhuǎn)發(fā)服務(wù)心跳并維護(hù)服務(wù)方和調(diào)用方的狀態(tài)信息滑绒。

image

當(dāng)服務(wù)節(jié)點(diǎn)下線闷堡,ETCD 集群通知服務(wù)管理節(jié)點(diǎn)對(duì)應(yīng)的 key,服務(wù)管理節(jié)點(diǎn)實(shí)時(shí)推送最新的服務(wù)節(jié)點(diǎn)列表信息給調(diào)用方疑故,調(diào)用方動(dòng)態(tài)更新并切換流量杠览。同時(shí)為了兼容推送失敗的異常情況,增加了調(diào)用方定時(shí)根據(jù)時(shí)間戳校驗(yàn)拉取的策略纵势,保證服務(wù)節(jié)點(diǎn)信息的最終一致踱阿。

五、監(jiān)控?cái)?shù)據(jù)采集與存儲(chǔ)

服務(wù)在生產(chǎn)環(huán)境運(yùn)行是否正常钦铁?當(dāng)前服務(wù)流量是多少软舌?有沒有出現(xiàn)調(diào)用異常或超時(shí)的情況牛曹?這些都是服務(wù)的負(fù)責(zé)人需要關(guān)注的問(wèn)題佛点。

5.1數(shù)據(jù)采集

對(duì)于服務(wù)方來(lái)說(shuō),一個(gè)服務(wù)有多個(gè)方法黎比,同時(shí)部署在多個(gè)節(jié)點(diǎn)上超营,同時(shí)會(huì)被不同的調(diào)用方調(diào)用不同的方法。同樣一個(gè)調(diào)用方也會(huì)同時(shí)調(diào)用多個(gè)服務(wù)的不同的方法阅虫。導(dǎo)致整體的收集維度是服務(wù)方和調(diào)用方的乘積量級(jí)糟描,應(yīng)該如何有效采集數(shù)據(jù)呢?

下面給大家介紹一下針對(duì) 58RPC 框架的調(diào)用數(shù)據(jù)的采集方案书妻。

image

從總的架構(gòu)圖中可以看到船响,為了避免流量數(shù)據(jù)收集的壓力躬拢,盡可能充分利用各層的計(jì)算能力分?jǐn)偨y(tǒng)一匯總的壓力。

  1. 收集插件充分利用服務(wù)節(jié)點(diǎn)的計(jì)算能力见间,先進(jìn)行本地?cái)?shù)據(jù)聚合聊闯,以分鐘為單位進(jìn)行數(shù)據(jù)上報(bào)。

  2. 插件上報(bào)根據(jù)服務(wù)名 hash米诉,盡可能保證相同服務(wù)不同節(jié)點(diǎn)的數(shù)據(jù)發(fā)送到同一個(gè)收集服務(wù)器菱蔬,收集服務(wù)器再進(jìn)行一次聚合,進(jìn)一步減少 Cache 統(tǒng)一計(jì)數(shù)的壓力史侣。

5.2數(shù)據(jù)存儲(chǔ)

首先針對(duì)服務(wù)的調(diào)用信息拴泌,我們來(lái)看一下針對(duì)一個(gè)調(diào)用需要存儲(chǔ)的數(shù)據(jù)情況。

image

對(duì)于同一個(gè)維度的監(jiān)控?cái)?shù)據(jù)惊橱,以上字段中只有時(shí)間戳蚪腐、次數(shù)和耗時(shí)數(shù)據(jù)是和實(shí)際的流量相關(guān)的,服務(wù)名 + 服務(wù)節(jié)點(diǎn) + 函數(shù)名稱 + 調(diào)用者 + 類型標(biāo)識(shí)對(duì)同一個(gè)維度是相同的税朴,因此為了減少數(shù)據(jù)的存儲(chǔ)回季,我們定義一個(gè)映射的規(guī)則(S[demo]SN[10.0.0.1]SF[Service.get()]C[callerdemo] 表示服務(wù)方 demo 的 10.0.0.1 機(jī)器上的 Service.get() 方法被調(diào)用方 callerdemo 調(diào)用),將以上 5 個(gè)收集元信息映射成唯一的維度字符串正林,再把所有的維度字符串分別生成一個(gè)唯一的 cid泡一,實(shí)際存儲(chǔ)的監(jiān)控?cái)?shù)據(jù)中使用 cid 替換以上 5 個(gè)收集元信息。

image

在實(shí)際的應(yīng)用中觅廓,最開始版本只存儲(chǔ)調(diào)用的元數(shù)據(jù)鼻忠,在展示的時(shí)候根據(jù)展示的維度進(jìn)行數(shù)據(jù)查詢聚合導(dǎo)致監(jiān)控?cái)?shù)據(jù)展示特別慢,因?yàn)樾枰?jīng)過(guò)大量的數(shù)據(jù)查詢和合并杈绸,為了調(diào)高監(jiān)控?cái)?shù)據(jù)的查詢速度帖蔓,使用了寫擴(kuò)散的方式,針對(duì)一個(gè)調(diào)用元數(shù)據(jù)蝇棉,做如下圖所示的擴(kuò)散:

image

從上圖可以看出讨阻,實(shí)際存儲(chǔ)的時(shí)候?qū)⑽磥?lái)經(jīng)常需要展示的數(shù)據(jù)先計(jì)算好直接存入庫(kù)中芥永,展示的時(shí)候只需要直接根據(jù)維度的 cid 直接查詢結(jié)果即可篡殷,有效提高了查詢速度。

六埋涧、總 結(jié)

SCF 框架作為 58 分布式架構(gòu)的基礎(chǔ)組件板辽,支撐了 58 集團(tuán)內(nèi)部萬(wàn)級(jí)別節(jié)點(diǎn)的網(wǎng)絡(luò)調(diào)用。本文主要介紹基本調(diào)用和監(jiān)控相關(guān)內(nèi)容棘催。還有很多負(fù)載均衡劲弦、網(wǎng)絡(luò)管理、故障節(jié)點(diǎn)剔除醇坝、服務(wù)鑒權(quán)邑跪、服務(wù)限流等模塊沒有展開。SCF 框架經(jīng)過(guò)多次的迭代,從最初的最簡(jiǎn)單的遠(yuǎn)程調(diào)用到現(xiàn)在服務(wù)治理周邊功能的完善画畅,后續(xù)也將不斷優(yōu)化砸琅,歡迎感興趣的同學(xué)一起溝通交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末轴踱,一起剝皮案震驚了整個(gè)濱河市症脂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌淫僻,老刑警劉巖诱篷,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異雳灵,居然都是意外死亡棕所,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門细办,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)橙凳,“玉大人,你說(shuō)我怎么就攤上這事笑撞〉盒ィ” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵茴肥,是天一觀的道長(zhǎng)坚踩。 經(jīng)常有香客問(wèn)我,道長(zhǎng)瓤狐,這世上最難降的妖魔是什么瞬铸? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮础锐,結(jié)果婚禮上嗓节,老公的妹妹穿的比我還像新娘。我一直安慰自己皆警,他們只是感情好拦宣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著信姓,像睡著了一般鸵隧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上意推,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天豆瘫,我揣著相機(jī)與錄音,去河邊找鬼菊值。 笑死外驱,一個(gè)胖子當(dāng)著我的面吹牛育灸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昵宇,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼描扯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了趟薄?” 一聲冷哼從身側(cè)響起绽诚,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎杭煎,沒想到半個(gè)月后恩够,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡羡铲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年蜂桶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片也切。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扑媚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雷恃,到底是詐尸還是另有隱情疆股,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布倒槐,位于F島的核電站旬痹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏讨越。R本人自食惡果不足惜两残,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望把跨。 院中可真熱鬧人弓,春花似錦、人聲如沸着逐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)滨嘱。三九已至峰鄙,卻和暖如春浸间,著一層夾襖步出監(jiān)牢的瞬間太雨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工魁蒜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留囊扳,地道東北人吩翻。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像锥咸,于是被迫代替她去往敵國(guó)和親狭瞎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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

  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說(shuō)明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí)搏予,會(huì)觸發(fā)此異常熊锭。 O...
    我想起個(gè)好名字閱讀 5,307評(píng)論 0 9
  • feisky云計(jì)算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 3,843評(píng)論 0 5
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,097評(píng)論 1 32
  • 包含的重點(diǎn)內(nèi)容:JAVA基礎(chǔ)JVM 知識(shí)開源框架知識(shí)操作系統(tǒng)多線程TCP 與 HTTP架構(gòu)設(shè)計(jì)與分布式算法數(shù)據(jù)庫(kù)知...
    消失er閱讀 4,317評(píng)論 1 10
  • 每一次回首過(guò)往雪侥,都只想唱:時(shí)間都去哪兒了…… 畢業(yè)第五年碗殷,沒有換過(guò)工作。所有的折騰或安逸背后都是有原因的:公司人少...
    樂(lè)小檬閱讀 180評(píng)論 0 0