加速數(shù)據(jù)讀取的利器——緩存

定義
緩存,在我們?nèi)粘i_發(fā)中是必不可少的一種解決性能問題的方法弥激。簡(jiǎn)單的說进陡,cache 就是為了提升系統(tǒng)性能而開辟的一塊內(nèi)存空間。

作用
緩存的主要作用是暫時(shí)在內(nèi)存中保存業(yè)務(wù)系統(tǒng)的數(shù)據(jù)處理結(jié)果微服,并且等待下次訪問使用趾疚。在日常開發(fā)的很多場(chǎng)合,由于受限于硬盤IO的性能或者我們自身業(yè)務(wù)系統(tǒng)的數(shù)據(jù)處理和獲取可能非常費(fèi)時(shí)以蕴,當(dāng)我們發(fā)現(xiàn)我們的系統(tǒng)這個(gè)數(shù)據(jù)請(qǐng)求量很大的時(shí)候糙麦,頻繁的IO和頻繁的邏輯處理會(huì)導(dǎo)致硬盤和CPU資源的瓶頸出現(xiàn)。緩存的作用就是將這些來自不易的數(shù)據(jù)保存在內(nèi)存中丛肮,當(dāng)有其他線程或者客戶端需要查詢相同的數(shù)據(jù)資源時(shí)赡磅,直接從緩存的內(nèi)存塊中返回?cái)?shù)據(jù),這樣不但可以提高系統(tǒng)的響應(yīng)時(shí)間宝与,同時(shí)也可以節(jié)省對(duì)這些數(shù)據(jù)的處理流程的資源消耗焚廊,整體上來說冶匹,系統(tǒng)性能會(huì)有大大的提升。

常用使用場(chǎng)景:

  • 在高并發(fā)的數(shù)據(jù)庫訪問時(shí)咆瘟,為了抗住數(shù)據(jù)庫并發(fā)連接壓力嚼隘,將數(shù)據(jù)緩存起來,當(dāng)有請(qǐng)求過來袒餐,直接返回?cái)?shù)據(jù)飞蛹;
  • 當(dāng)應(yīng)用中的數(shù)據(jù),更新周期較長(zhǎng)匿乃,而且每次都查數(shù)據(jù)庫的情況下桩皿,可以采用周期更新數(shù)據(jù),從而有效減少數(shù)據(jù)庫無效的訪問幢炸,保證效率泄隔;

衡量指標(biāo)
對(duì)于使用緩存來加速數(shù)據(jù)讀取的情況,一個(gè)很關(guān)鍵的指標(biāo)是緩存命中率宛徊,因?yàn)槿绻彺婷新时容^低的話佛嬉,就意味著還有不少的讀請(qǐng)求要回到數(shù)據(jù)庫中。

2. 介紹一種緩存機(jī)制

本節(jié)以JAVA重構(gòu)時(shí)使用的緩存機(jī)制為例闸天,講解我們?nèi)粘9ぷ髦谐S玫囊环N比較高效的緩存機(jī)制暖呕。具體如下圖所示:

技術(shù)架構(gòu)圖.png

以上緩存機(jī)制使用了一級(jí)緩存(Memcache) + 二級(jí)本地緩存(Guava)的二級(jí)緩存機(jī)制。

  • 其中苞氮,Memcache是一個(gè)高性能的分布式的內(nèi)存對(duì)象緩存系統(tǒng)湾揽,通過在內(nèi)存里維護(hù)一個(gè)統(tǒng)一的巨大的hash表,它能夠用來存儲(chǔ)各種格式的數(shù)據(jù)笼吟,包括圖像库物、視頻、文件以及數(shù)據(jù)庫檢索的結(jié)果等贷帮。簡(jiǎn)單的說就是將數(shù)據(jù)調(diào)用到內(nèi)存中戚揭,然后從內(nèi)存中讀取,從而大大提高讀取速度撵枢。
  • Guava是一個(gè)全內(nèi)存的本地緩存實(shí)現(xiàn)民晒,它提供了線程安全的實(shí)現(xiàn)機(jī)制。能夠保證當(dāng)多個(gè)請(qǐng)求獲取同一個(gè)key值時(shí)锄禽,只允許一個(gè)線程訪問服務(wù)器潜必,其他線程阻塞等待(系統(tǒng)處理:直接返回,不用阻塞)沟绪,這樣就能很好的減輕服務(wù)端壓力刮便;另外,比起服務(wù)端向Memcache獲取緩存绽慈,本地緩存減少了網(wǎng)絡(luò)IO開銷恨旱,提升數(shù)據(jù)返回的速度,減少了客戶端響應(yīng)的時(shí)間坝疼。

當(dāng)然搜贤,使用Guava作為本地緩存,需要滿足以下的適用場(chǎng)景:

  • 愿意消耗一部分應(yīng)用服務(wù)器的內(nèi)存來提升速度钝凶;
  • 預(yù)料某些值會(huì)被多次調(diào)用仪芒;
  • 緩存數(shù)據(jù)不會(huì)超過內(nèi)存總量;

那么耕陷,我們是否有疑問掂名,反正,我這邊至少有2點(diǎn)疑問:

  1. 如何保證一級(jí)緩存和二級(jí)緩存的數(shù)據(jù)一致性哟沫;
  2. 如何保證一級(jí)緩存更新后饺蔑,不同的服務(wù)器下的二級(jí)緩存都會(huì)進(jìn)行同步更新;
    基于上面的問題嗜诀,又因?yàn)槲覀兠鎸?duì)的是一個(gè)黑盒的緩存框架猾警,現(xiàn)有的日志無法直接驗(yàn)證這2點(diǎn),那么直接上代碼:
//Memcache緩存更新隆敢,然后刪掉本地緩存
 public void putCache(String key, Object value) {
        long startTime = System.currentTimeMillis();
        LOG.info("Start put cache, key = {}, value = {}", key, JSON.toJSONString(value));
        ReentrantLock lock = this.getLock(key);
        if(null != lock && lock.tryLock()) {
            try {
                CacheObject cacheObject = CacheObject.generateCacheObject(value);
         this.memcachedClient.set(key, cacheObject.getUnixExpireTimeInSeconds(), cacheObject);
               
 this.punishCacheRefreshEvent(JSON.toJSONString(Lists.newArrayList(new String[]{key})));
                LOG.info("Put data to Memcached cost {}ms", Long.valueOf(System.currentTimeMillis() - startTime));
            } finally {
                lock.unlock();
            }
        }

    }
//調(diào)zk刪本地緩存的方法
private void punishCacheRefreshEvent(String cacheKeyListStr) {
        long startTime = System.currentTimeMillis();
        this.curatorService.writeDataToNode("/localCache/event/delete", cacheKeyListStr);
        LOG.info("Punish cache refresh event to ZK cost {}ms, keys = {}", Long.valueOf(System.currentTimeMillis() - startTime), cacheKeyListStr);
    }

通過上面的代碼发皿,可知更新緩存操作時(shí),均有日志記錄拂蝎。進(jìn)入####-wrapper.log可進(jìn)行驗(yàn)證穴墅,上日志:

2017-06-15 10:54:03.120 [ItemListCacheTask-6-exe0] INFO  MemcachedService       - Punish cache refresh event to ZK cost 4ms, keys = ["master####_TAE_ITEM_LIST_BRAND_AREA_ID_2_174756"]
 2017-06-15 10:54:03.120 [ItemListCacheTask-6-exe0] INFO  MemcachedService       - Put data to Memcached cost 5ms
 2017-06-15 10:54:03.121 [pool-2-thread-1 ] INFO  MemcachedService       - Will delete caches : ["master####_TAE_ITEM_LIST_BRAND_AREA_ID_2_174756"]
 2017-06-15 10:54:03.214 [ItemListCacheTask-6-exe0] INFO  MemcachedService       - Start put cache, key = master####_TAE_ITEM_LIST_BRAND_AREA_ID_2_174826, value = {"index_config":{"brandAreaButton":0,"brandAreaRedirectUrl":"","brandSpecialData":{"indexTopTitle":"測(cè)試我","style":"2"},"categorySwitch":1,"checkMaxVersion":"","checkMinVersion":"","couponSloganPicture":"/taobao/web_shopGuide591948637e93c_960_1280.jpg","curTab":1,"currentAndroidVersion":"","currentIosVersion":"","defaultChannelId":"","displayActivityName":1,"displayTab2Dot":0,"footerPicture":"/taobao/web_shopGuide5912d39b6305e_248_88.gif","globalPromotionData":{"image":"/taobao/web_shopGuide59194870cb96c_960_1280.jpg"},"historyDescript":"今天的新品都完了喲~\r\n看看之前錯(cuò)過了什么吧!","indexTips":"每天百款新品温自,10點(diǎn)更新,10點(diǎn)","isIndex":1,"itemPromotionStyleData":{"autoIncrement":"1","data":[{"id":"1","image":"/taobao/web_shopGuide591007923bbfe_138_138.png","name":"測(cè)試"}]},"leftIcon":1,"listStyle":1,"loadingImage":"/taobao/web_shopGuide591409020acac_224_226.jpg","noneIndex":1,"pictureTag":{"eveningMall":"/taobao/web_shopGuide591007cb5fe2b_68_68.png","superBurst":"/taobao/web_shopGuide591007da338bb_68_68.png","timedSpike":"/taobao/web_shopGuide591007d2c8544_68_68.png","today":"/taobao/web_shopGuide59194893e88b4_68_68.png"},"playTimes":12345667,"redirectCart":0,"refreshText":"每天10點(diǎn)玄货,有新鮮貨出沒\r\n每天20點(diǎn),有新鮮貨出沒\r\n每天30點(diǎn)捣作,有新鮮貨出沒\r\n全場(chǎng)低折誉结,你要的都在這\r\n達(dá)人推薦,買什么都知道\r\n柚幣福利券躁,驚喜不停\r\n柚姨幫你砍價(jià)啦~","shareSwitch":0,"sloganPicture":"/taobao/web_shopGuide5923f38252a22_750_350.jpg","tab1Title":"","tab2Title":"","useTbkSdk":1},"next_brand_area_data":{"1":{"tae_item":{"activityId":178382,"areaStyle":1,"brandAreaId":174560,"customTag":"","description":"","endAt":1513735200000,"isCoin":0,"isShowHot":1,"keplerSaleItemCount":1,"lowDiscount":0.0,"maxVersion":"","minVersion":"","name":"7號(hào)最后瘋搶","oneItemPic":"","orderCount":0,"ordinal":23,"picture":"","platform":"","promotionText":"","saleItemCount":49,"sortType":0,"tagIds":""},"common_item":{"$ref":"$.next_brand_area_data.1.tae_item"}},"2":{"tae_item":{},"common_item":{"activityId":170517,"areaStyle":1,"brandAreaId":166847,"customTag":"","description":"","endAt":1524103200000,"isCoin":0,"isShowHot":1,"keplerSaleItemCount":2,"lowDiscount":0.0,"maxVersion":"","minVersion":"","name":"京東用品尿褲?rùn)淮?,"oneItemPic":"","orderCount":0,"ordinal":0,"picture":"","platform":"","promotionText":"","saleItemCount":2,"sortType":0,"tagIds":""}}},"item_list":[],"brand_area_info":{"appId":2,"areaTimerType":1,"bannerPictureArray":[{"brandAreaId":174826,"createdAt":1496217409000,"height":"476","id":13816,"linkType":10017,"linkValue":"","type":1,"url":"/taobao/web_brand_area592e76550b369_361_476.jpg","width":"361"},{"brandAreaId":174826,"createdAt":1496217409000,"height":"440","id":13817,"linkType":0,"linkValue":"","type":1,"url":"/taobao/web_brand_area592e76640658a_1280_440.jpg","width":"1280"}],"bpLinkType":10017,"bpLinkValue":"","brandAreaType":1,"brandPicture":"/taobao/web_brand_area592e76550b369_361_476.jpg","description":"專場(chǎng)簡(jiǎn)介:123","endAt":1504836000000,"id":174826,"isActive":1,"isCoin":0,"isShowHot":1,"isTop":0,"isZijian":0,"listStyle":2,"name":"淑錚專場(chǎng)2","oridinal":0,"payErrorMessage":"","promotionText":"促銷信息:促銷會(huì)顯示成什么樣子呢惩坑?","saleItemCount":0,"sortType":1,"startAt":1496217380000,"timerType":2,"topItems":"null","topTag":"頂部標(biāo)簽1"}}, expireTimeInSeconds = 2592000

日志路徑:
[jumpserver@master-app-01 ####-####]$ pwd
/data/log/####-####

3. 問題定位

3.1 定位問題的步驟

工作中,經(jīng)常會(huì)碰到運(yùn)營(yíng)后臺(tái)操作后或清除緩存后也拜,接口數(shù)據(jù)未更新的情況以舒。此時(shí),我們需要掌握定位此類問題的技能慢哈,還是以JAVA端重構(gòu)接口的緩存機(jī)制為例蔓钟。

下圖展示了一種刪key類型的清緩存方式,一種_cache類型的更新緩存機(jī)制:

后臺(tái)-緩存.png
  • 第一步:關(guān)注后臺(tái)發(fā)送的topic消息

操作后臺(tái)進(jìn)行數(shù)據(jù)更新后卵贱,如上圖所示滥沫,針對(duì)2種類型的更新緩存模式侣集,會(huì)發(fā)送MQ消息,即JAVA端訂閱的topic消息兰绣。日志路徑:

[jumpserver@master-app-01 ####-####]$ cd /data/web/log/

具體到以下2種類型世分,具體分析:

  1. 刪key類型的接口:日志為log下的refresh_cache文件夾下的info.log,如下:
[jumpserver@master-app-01 refresh_cache]$ pwd
/data/web/log/refresh_cache
[jumpserver@master-app-01 refresh_cache]$ ls
exception          info.20170606.log  info.20170612.log  my_item_info               refresh_by_methods                   tae_item_list_cache
info.20170601.log  info.20170607.log  info.20170613.log  own_item_list_cache        tae_active_item_list_cache
info.20170602.log  info.20170608.log  info.20170614.log  phone_recharge             tae_category_client_item_list_cache
info.20170605.log  info.20170609.log  info.20170615.log  recommend_item_pool_cache  tae_category_client_list_cache
  1. _cache類型的接口:針對(duì)具體的接口缀辩,日志放在不同的文件夾下臭埋,如tae_brand_list相關(guān)的首頁、專場(chǎng)等在refresh_brand_area文件夾下臀玄,專場(chǎng)分類列表在refresh_category_client_item_list文件夾下瓢阴。以首頁專場(chǎng)為例,如下:
[jumpserver@master-app-01 refresh_brand_area]$ pwd
/data/web/log/refresh_brand_area
[jumpserver@master-app-01 refresh_brand_area]$ ls
info.20170511.log  info.20170516.log  info.20170521.log  info.20170526.log  info.20170531.log  info.20170605.log  info.20170610.log  info.20170615.log
info.20170512.log  info.20170517.log  info.20170522.log  info.20170527.log  info.20170601.log  info.20170606.log  info.20170611.log
info.20170513.log  info.20170518.log  info.20170523.log  info.20170528.log  info.20170602.log  info.20170607.log  info.20170612.log
info.20170514.log  info.20170519.log  info.20170524.log  info.20170529.log  info.20170603.log  info.20170608.log  info.20170613.log
info.20170515.log  info.20170520.log  info.20170525.log  info.20170530.log  info.20170604.log  info.20170609.log  info.20170614.log

打開日志文件健无,后臺(tái)操作刪key后荣恐,打印日志如下:

info | 16687 | 1497496242.3234 | 2017:06:15 11:10:42 | 0.002588987350 | 成功發(fā)送消息: {"data":[{"v":1,"app_id":1,"app_key":"001","method":"new_user_special_item","clear_cache":1,"delete_key":true,"append_id":"174844"},{"v":1,"app_id":7,"app_key":"007","method":"new_user_special_item","clear_cache":1,"delete_key":true,"append_id":"174844"}],"time":"2017-06-15 11:10:42","cachebuildUrl":"http:\/\/test.cachebuild.master.youzibuy.com\/router\/rest","uuid":"REFRESH_CACHE__5941fab24ef424.48576463","cache_prefix":"master"}
  • 第二步:關(guān)注JAVA端監(jiān)聽到消息后,是否進(jìn)行了處理

JAVA端的日志路徑:

/data/log/####-####
我們關(guān)注日志文件####-mq-listener.log即可睬涧。在接收到后臺(tái)發(fā)送的topic消息后募胃,JAVA端會(huì)向Memcache系統(tǒng)發(fā)送相關(guān)的刪key or 更新key的請(qǐng)求。

[jumpserver@master-app-01 ####-####]$ tail -f ####-mq-listener.log
 2017-06-15 11:10:42.322 [cacheDeleteContainer-1] WARN  CacheDeleteCommandListener - Current instance is not leader, will not handle cache refresh request from mq.
 2017-06-15 11:10:42.337 [cacheDeleteContainer-1] WARN  AbstractListener       - receieve magic message key ID:master-app-01-47896-1496894034686-3:10103:-1:1:397 content : {"data":[{"v":1,"app_id":1,"app_key":"001","method":"new_user_special_item","clear_cache":1,"delete_key":true,"append_id":"174842"},{"v":1,"app_id":7,"app_key":"007","method":"new_user_special_item","clear_cache":1,"delete_key":true,"append_id":"174842"}],"time":"2017-06-15 11:10:42","cachebuildUrl":"http:\/\/####.master.####.com\/router\/rest","uuid":"REFRESH_CACHE__5941fab24c4025.73699813","cache_prefix":"master"}
 2017-06-15 11:10:42.338 [cacheDeleteContainer-1] WARN  CacheDeleteCommandListener - #### del cache from mq
 2017-06-15 11:10:42.338 [cacheDeleteContainer-1] WARN  CacheDeleteCommandListener - Current instance is not leader, will not handle cache refresh request from mq.
  • 第三步:緩存更新是否成功

該部分監(jiān)控畦浓,我們可以借助MQ平臺(tái):

http://...:**/admin/queues.jsp;jsessionid=gvurz20v706dev474xwsgd95

image.png

我們?cè)诖_認(rèn)上面第二部JAVA端進(jìn)行了消息處理后痹束,可關(guān)注Memcache系統(tǒng)有沒有更新緩存成功。具體的緩存類型讶请,關(guān)注具體的緩存處理祷嘶,其中:

  • 刪key ——> refresh_cache_new_java
  • _cache ——> refresh_cache_java

關(guān)注點(diǎn):

  1. Number of Consumers,即消費(fèi)消息的數(shù)量是否>0夺溢,如果等于0论巍,那么JAVA端的緩存構(gòu)建系統(tǒng)出現(xiàn)故障。
  2. Messages Enqueued和Messages Dequeued的數(shù)量分別+1风响,則表示緩存更新成功嘉汰,若Messages Enqueued數(shù)量+1,而Messages Dequeued數(shù)量不變状勤,則表示緩存更新失敗鞋怀。
image.png

3.2 配置相關(guān)

從后臺(tái)發(fā)送topic消息,到JAVA端接收持搜,二者必須保證發(fā)送的和接收的一致性密似。這樣才能夠最終刷緩存成功。

  • PHP端后臺(tái)配置

我們一般關(guān)注后臺(tái)發(fā)送的topic消息前綴葫盼,如操作主干后臺(tái)残腌,通過日志可知前綴為master。

info | 26698 | 1497521442.5619 | 2017:06:15 18:10:42 | 0.008535861969 | 成功發(fā)送消息: 
{"data":
[
{"v":1,"app_id":1,"app_key":"001","method":"new_user_special_item","clear_cache":1,"delete_key":true,"append_id":"174847"},{"v":1,"app_id":7,"app_key":"007","method":"new_user_special_item","clear_cache":1,"delete_key":true,"append_id":"174847"}
],
"time":"2017-06-1518:10:42",
"cachebuildUrl":"http:\/\/test.cachebuild.master.youzibuy.com\/router\/rest","uuid":"REFRESH_CACHE__59425d22892ac2.15914753",
"cache_prefix":"master"}
  • JAVA端配置

我們一般關(guān)注JAVA端接收消息的前綴,這個(gè)需要和后臺(tái)發(fā)送消息的前綴保持一致抛猫。JAVA端的配置平臺(tái):http://dev.#####.####.com/modifyFile.html?configId=183
關(guān)注disconf-managed-config.properties下的緩存前綴蟆盹,如下:

memcache.key.prifix=master
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市邑滨,隨后出現(xiàn)的幾起案子日缨,更是在濱河造成了極大的恐慌钱反,老刑警劉巖掖看,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異面哥,居然都是意外死亡哎壳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門尚卫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來归榕,“玉大人,你說我怎么就攤上這事吱涉∩残梗” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵怎爵,是天一觀的道長(zhǎng)特石。 經(jīng)常有香客問我,道長(zhǎng)鳖链,這世上最難降的妖魔是什么姆蘸? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮芙委,結(jié)果婚禮上逞敷,老公的妹妹穿的比我還像新娘。我一直安慰自己灌侣,他們只是感情好推捐,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著侧啼,像睡著了一般牛柒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上慨菱,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天焰络,我揣著相機(jī)與錄音,去河邊找鬼符喝。 笑死闪彼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播畏腕,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼缴川,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了描馅?” 一聲冷哼從身側(cè)響起把夸,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铭污,沒想到半個(gè)月后恋日,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嘹狞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年岂膳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片磅网。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谈截,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涧偷,到底是詐尸還是另有隱情簸喂,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布燎潮,位于F島的核電站喻鳄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏跟啤。R本人自食惡果不足惜诽表,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望隅肥。 院中可真熱鬧竿奏,春花似錦、人聲如沸腥放。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秃症。三九已至候址,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間种柑,已是汗流浹背岗仑。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留聚请,地道東北人荠雕。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓稳其,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親炸卑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子既鞠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)盖文,斷路器嘱蛋,智...
    卡卡羅2017閱讀 134,600評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,514評(píng)論 25 707
  • 今天輸液第九天,昨天第八天五续,前天第七天洒敏,是星期一,新?lián)Q的車牌限號(hào)返帕,豆豆履新第一天桐玻,爆發(fā)了激烈的爭(zhēng)吵,我自己做完鹽浴...
    寧小靜的日記閱讀 256評(píng)論 0 0
  • 說起我對(duì)繪畫的學(xué)習(xí)荆萤,是源于對(duì)國(guó)畫的看法。我以前在學(xué)習(xí)書法的時(shí)候铣卡,每天都會(huì)在一個(gè)叫墨池的軟件上打自己寫的字链韭,與一些墨...
    輝高閱讀 466評(píng)論 4 11
  • 最近在用Eclipse寫C++程序,今天把Eclipse設(shè)置上踩過的坑總結(jié)一下 1. program 'g++' ...
    張二虎閱讀 1,096評(píng)論 0 0