21. SpringCloud之配置中心ConfigServer源碼 & 配置刷新源碼解讀

image.png

1萎河、前言

分布式配置中心ConfigServer的使用方式 :

SpringCloud之ConfigServer配置中心以及Bus消息總線

2、配置中心服務(wù)端

2.1荸型、源碼入口

@EnableConfigServer 這個(gè)注解僅僅起到一個(gè)標(biāo)識(shí)的作用,沒(méi)有引入任何東西

那么就 還是spi的方式

找到Maven: org.springframework.cloud:spring-cloud-config-server:2.0.0.RELEASE2包下的META-INF/Spring.factories.

image.png

2.2繁涂、接口的注冊(cè)

在配置中心服務(wù)端會(huì)創(chuàng)建很多接口,比如

  • 配置信息的加解密接口
  • 查看 配置中心服務(wù) 拉取到的配置信息接口 :我們可以直接在調(diào)用查看配置信息, 配置中心客戶端在啟動(dòng)的時(shí)候拱她,也會(huì)調(diào)用這個(gè)接口從配置中心服務(wù)端獲取對(duì)應(yīng)的配置信息。

SPI從spring.factories導(dǎo)入的org.springframework.cloud.config.server.config.ConfigServerAutoConfiguration類扔罪。

image.png

會(huì)導(dǎo)入 ConfigServerEncryptionConfiguration秉沼,ConfigServerMvcConfiguration這兩個(gè)類,接口的創(chuàng)建就在這兩個(gè)類中矿酵。

2.3.1唬复、獲取配置信息的接口注冊(cè)

ConfigServerMvcConfiguration類里會(huì)用@Bean 注冊(cè) EnvironmentController接口

image.png

EnvironmentController 就是用來(lái)請(qǐng)求獲取 配置信息的Controller類,類上有@RestController+ @RequestMapping注解。

image.png

里面有各種形式的接口來(lái)獲取配置信息坏瘩。

image.png
image.png

2.3.2盅抚、加解密接口的注冊(cè)

ConfigServerEncryptionConfiguration 會(huì)用@Bean 注冊(cè) EncryptionController接口

image.png

EncryptionController就是一個(gè)Controller類 ,有@RestController + @RequestMapping 注解,里面會(huì)配置 加解密接口倔矾。

2.3.2.1妄均、加密接口

image.png

2.3.2.2、解密接口

image.png

2.3哪自、獲取配置信息接口 源碼

獲取配置信息的接口請(qǐng)求路徑有很多種形式,我們挑/{label}/{name}-{profiles}.properties 這種丰包,對(duì)應(yīng)的是EnvironmentController的 這個(gè)接口。 看看源碼的執(zhí)行流程壤巷。

image.png

調(diào)用這個(gè)接口 , 獲取 master分支, micro-order服務(wù),dev環(huán)境的配置文件.

http://localhost:9101/master/micro-order-dev.properties

斷點(diǎn)進(jìn)到了這個(gè)接口, 走labelled方法獲取環(huán)境對(duì)象

image.png

調(diào)用EnvironmentEncryptorEnvironmentRepository對(duì)象的findOne方法

image.png

調(diào)用 SearchPathCompositeEnvironmentRepository類的findOne方法邑彪。

由于SearchPathCompositeEnvironmentRepository類沒(méi)有實(shí)現(xiàn)findOne方法,會(huì)調(diào)到它的父類AbstractScmEnvironmentRepository的findOne方法。

image.png

進(jìn)入getLocations 方法

image.png

進(jìn)入 MultipleJGitEnvironmentRepository類的 getLocations()胧华。

MultipleJGitEnvironmentRepository 的父類 是JGitEnvironmentRepository 類寄症,調(diào)父類的getLocations方法宙彪。

image.png

如果請(qǐng)求接口傳入 git分支參數(shù), 那么獲取的lebel就是請(qǐng)求傳的,否則默認(rèn)獲取的是master分支的有巧。

然后調(diào)refresh方法释漆,獲取這個(gè)分支下的所有配置。

image.png

createGitClient() 篮迎,會(huì)先檢查git本地倉(cāng)庫(kù)是否存在,不存在就會(huì)創(chuàng)建git本地倉(cāng)庫(kù)男图。

image.png

接著判斷 git本地倉(cāng)庫(kù) 文件夾是否存在, 判斷的文件夾路徑 由getWorkingDirectory()返回,我這mac電腦的路徑是

/var/folders/tb/w7qkq1w54w3g25_3_jp0w6500000gn/T/config-repo-8553408175024803312, 的子路徑下是否有 .git/index.lock文件甜橱,是否存在git的鎖逊笆,有的話就刪除。

windows的本地倉(cāng)庫(kù)路徑 好像是什么 C://work/config/tmp啥的岂傲。

image.png

接下來(lái)判斷 本地倉(cāng)庫(kù)/var/folders/tb/w7qkq1w54w3g25_3_jp0w6500000gn/T/config-repo-8553408175024803312 下是否有.git文件存在难裆。

如果存在就直接返回這個(gè)路徑下的git操作對(duì)象, 不存在就會(huì) 新建一個(gè)這個(gè)路徑,然后在下面生成.git文件

image.png

我們先把這個(gè)文件夾刪除刪除掉譬胎。讓他重新創(chuàng)建一個(gè)差牛。

image.png

這個(gè)就會(huì)創(chuàng)建一個(gè)這樣的目錄,并且生成.git文件堰乔。并且 設(shè)置遠(yuǎn)程倉(cāng)庫(kù)地址

image.png

并且會(huì)執(zhí)行g(shù)it clone 指令,把整個(gè) 倉(cāng)庫(kù)克隆到本地倉(cāng)庫(kù)脐恩。

image.png

這個(gè)時(shí)候镐侯,這個(gè)路徑下有 整個(gè)配置文件的config文件夾了。

/var/folders/tb/w7qkq1w54w3g25_3_jp0w6500000gn/T/config-repo-8553408175024803312/config :

image.png

拉取完配置文件之后驶冒,判斷是否需要更新苟翻,如果需要的話,就會(huì)先執(zhí)行 git fetch指令,

git checkout 切換分支 到 我們接口請(qǐng)求對(duì)應(yīng)的分支下骗污。

然后執(zhí)行 merge指令, 把文件更新到最新的狀態(tài)崇猫。

image.png

這個(gè)時(shí)候,服務(wù)端 已經(jīng)把所有最新的配置文件 拉取到本地倉(cāng)庫(kù)了需忿。

然后返回getLocations 返回 本地倉(cāng)庫(kù)的地址,以及服務(wù)名诅炉,環(huán)境,分支屋厘,版本號(hào)涕烧。

image.png

然后會(huì)把對(duì)應(yīng)服務(wù)的配置文件 放到 enviroment對(duì)象 里的PropertySources 數(shù)組中,返回enviroment對(duì)象汗洒。

image.png

再把Environment對(duì)象 议纯, 本地倉(cāng)庫(kù)路徑 替換成git倉(cāng)庫(kù)地址,變成這樣溢谤。然后返回

image.png

最后瞻凤,從environment對(duì)象里獲取 micro-order-dev.properties里的內(nèi)容憨攒,把map變成 字符串形式,返回出去阀参。

image.png

2.4浓恶、服務(wù)端 本地配置倉(cāng)庫(kù) 初始化

當(dāng)然,配置中心服務(wù)端 不會(huì)只等到 被請(qǐng)求接口了才會(huì) 去git拉取 配置文件到本地倉(cāng)庫(kù)结笨,而是在啟動(dòng)完成之后會(huì)由線程池 定時(shí)觸發(fā) 健康檢測(cè)包晰。在健康檢測(cè)里,就會(huì)從git 更新 配置文件到本地倉(cāng)庫(kù)炕吸。

走的也是 請(qǐng)求git,創(chuàng)建本地倉(cāng)庫(kù),git clone, 然后merge更新伐憾。

image.png

3、配置中心客戶端

配置中心客戶端 會(huì)在啟動(dòng)的時(shí)候請(qǐng)求 配置中心服務(wù)端 獲取 配置信息赫模, 然后塞到自己的environment 對(duì)象的propertySource屬性中树肃。

3.1、源碼入口

同樣是spi瀑罗。

Maven: org.springframework.cloud:spring-cloud-config-client:2.0.0.RELEASE2包下的META-INF/spring.factories胸嘴。

image.png

3.1.1、加載 key為 BootstrapConfiguration的類

只不過(guò)這里配置的key是BootstrapConfiguration類型的,springboot啟動(dòng)的時(shí)候默認(rèn)加載的是key為EnableAutoConfiguration的類斩祭。

key為BootstrapConfiguration的類 是由監(jiān)聽(tīng)器加載的劣像。

有個(gè) BootstrapApplicationListener 監(jiān)聽(tīng)器類,實(shí)現(xiàn)了ApplicationListener接口摧玫,當(dāng)Spring容器發(fā)布 ApplicationEnvironmentPreparedEvent 事件時(shí)耳奕,會(huì)調(diào)用實(shí)現(xiàn)的onApplicationEvent方法。

image.png

這里就會(huì)加載META-INF/Spring.factories 下配置的key為 BootstrapConfiguration類型的類诬像。

image.png

關(guān)于事件是啥時(shí)候發(fā)布的屋群,可以看一下調(diào)用鏈,也是在Springboot的run方法里調(diào)用的坏挠。

image.png

3.1.2芍躏、ConfigServicePropertySourceLocator實(shí)例和ConfigClientProperties實(shí)例的注冊(cè)

META-INF/spring.factories文件里配置了 key為BootstrapConfiguration 的有ConfigServiceBootstrapConfiguration類

image.png

ConfigServiceBootstrapConfiguration類會(huì)用@Bean注冊(cè)ConfigServicePropertySourceLocator類 ,并且還會(huì)在方法列表注入配置中心客戶端的配置對(duì)象ConfigClientProperties對(duì)象

ConfigServicePropertySourceLocator實(shí)現(xiàn)PropertySourceLocator接口,實(shí)現(xiàn)locate方法降狠。

image.png

ConfigClientProperties對(duì)象加載 spring.cloud.config為前綴的配置信息

image.png

3.1.3对竣、ConfigServicePropertySourceLocator類locate()的調(diào)用時(shí)機(jī)

之后Springboot在run方法里面的prepareContext方法會(huì)調(diào)用所有 ApplicationContextInitializer接口實(shí)例的 initialize方法。

image.png

有一個(gè)ApplicationContextInitializer接口實(shí)現(xiàn)類 PropertySourceBootstrapConfiguration喊熟,會(huì)注入PropertySourceLocator接口類型的實(shí)例柏肪,也就是ConfigServicePropertySourceLocator實(shí)例。

image.png

然后會(huì)在 initialize方法里調(diào)用所有 PropertySourceLocator接口類型 的實(shí)例的locate方法芥牌。也就會(huì)調(diào)用到 ConfigServicePropertySourceLocator的locate方法烦味。

image.png

3.1.4、ConfigServicePropertySourceLocator的locate()去配置中心服務(wù)端 拉取配置信息

3.1.4.1、去配置中心服務(wù)端 拉取配置信息

ConfigServicePropertySourceLocator的locate方法谬俄,去配置中心服務(wù)端 拉取配置信息柏靶。

先創(chuàng)建一個(gè)restTemplate對(duì)象溃论,getRemoteEnvironment()

image.png

在getRemoteEnvironment()方法里屎蜓,先拼接請(qǐng)求的接口路徑

是 /{name}/{profile}/{label}

替換變量就是 /micro-user/dev/master 接口

image.png
1赊瞬、配置中心服務(wù)端uri的獲取

在我們的配置里先煎,一般都是配serviceId的。

spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=config-server

所以需要根據(jù)服務(wù)名稱 從 注冊(cè)中心 獲取到 配置中心服務(wù)端的 ip+端口巧涧。

Springcloud eureka客戶端從注冊(cè)中心 拉取完服務(wù)列表里薯蝎,會(huì)發(fā)布HeartbeatEvent事件。

SpringCloud之Eureka客戶端源碼解析 這篇有介紹褒侧,這里就簡(jiǎn)單帶過(guò)了良风。

image.png

這里發(fā)布的是HeartbeatEvent事件。

image.png

有一個(gè)監(jiān)聽(tīng) HeartbeatEvent事件的 ApplicationListenerMethodAdapter類闷供,在響應(yīng)事件時(shí),會(huì)反射調(diào)用org.springframework.cloud.config.client.DiscoveryClientConfigServiceBootstrapConfiguration類的 heartbeat方法

image.png

DiscoveryClientConfigServiceBootstrapConfiguration 會(huì)注入ConfigClientProperties 配置中心客戶端配置類ConfigClientProperties對(duì)象

image.png

在DiscoveryClientConfigServiceBootstrapConfiguration的heartbeat方法统诺,會(huì)調(diào)用refresh()

image.png

refresh()則會(huì)從配置中心客戶端配置類ConfigClientProperties對(duì)象 里拿到我們配置的配置中心服務(wù)端的服務(wù)名稱, 然后從 拉取到的服務(wù)列表里歪脏,獲取 這個(gè)服務(wù)名稱下對(duì)應(yīng)的服務(wù)實(shí)例。

image.png

拿到所有服務(wù)實(shí)例之后, 遍歷獲取 ip+端口粮呢,放到一個(gè)url的列表里婿失,最后設(shè)置到 配置中心客戶端配置類ConfigClientProperties對(duì)象 的uri 屬性中。

image.png

所以啄寡,后面 配置中心 客戶端 直接就可以從 配置中心客戶端配置類ConfigClientProperties對(duì)象里的 uri數(shù)組里豪硅,獲取到 ip+端口, 發(fā)起請(qǐng)求就行了。

2挺物、發(fā)起請(qǐng)求

**遍歷 配置中心客戶端配置類ConfigClientProperties對(duì)象里的 uri數(shù)組, 對(duì) 每個(gè) 配置中心服務(wù)端的 ip+端口進(jìn)行 接口請(qǐng)求懒浮。如果有一個(gè)配置中心服務(wù)端成功返回了 它的配置信息,就返回。 **

先 把用戶名砚著,密碼 用base64 加密 方法請(qǐng)求頭Authorization里次伶,

最后向配置中心服務(wù)端http://192.168.31.211:9101/{name}/{profile}/{label} 發(fā)GET請(qǐng)求,獲取對(duì)應(yīng)的配置信息

image.png

返回的reponse里的Body是一個(gè)Environment對(duì)象稽穆,里面的propertiesSource 列表就是 這個(gè)服務(wù)dev環(huán)境從master分支 對(duì)應(yīng) 的 配置信息冠王。

image.png

最后return,跳出對(duì) 配置中心服務(wù)端的 uri數(shù)組的循環(huán)。

3.1.4.2舌镶、設(shè)置到本地的 Environment對(duì)象的PropertySource中

獲取到Environment對(duì)象之后柱彻,加到name = configService 的CompositePropertySource對(duì)象中,

image.png

最終返回的CompositePropertySource對(duì)象是這樣的,里面有一個(gè)propertySources列表

就是從配置中心服務(wù)端拉到的 配置信息

image.png

然后把新返回的 CompositePropertySource對(duì)象 再添加到name = bootstrapProperties的CompositePropertySource對(duì)象的propertySource列表中,

最終添加到 插入到 配置中心客戶端的 environment對(duì)象中

image.png

最后environment的propertySource就有 從配置中心服務(wù)端拉取的配置信息了餐胀。

image.png

后面其他的bean實(shí)例化,就可以 從 environment里面 獲取 從配置中心服務(wù)端拉取的配置信息哟楷,注入到需要使用的地方了。

4骂澄、配置信息的刷新

如果我們?cè)趃it里的配置信息的配置信息發(fā)生改變吓蘑,SpringCloud提供了 配置中心服務(wù)端 刷新配置信息的功能。

有以下兩種方式 :

  1. 手動(dòng)調(diào)用每臺(tái)服務(wù) actuator組件提供的 /actuator/refresh 接口坟冲。
  2. 引入SpringCloudBus, 當(dāng)配置發(fā)生改變時(shí)磨镶,調(diào)用 /actuator/bus-refresh接口,通過(guò)消息中間件 以廣播的形式 通知 所有 服務(wù) 刷新配置信息健提。 或者 結(jié)合github -webhook琳猫,自動(dòng)調(diào)用 /actuator/bus-refresh接口。

SpringCloudBus 與 手動(dòng)調(diào)用 每臺(tái)服務(wù)的 /actuator/refresh接口 所做的刷新配置的工作 是一樣的私痹,只不過(guò) 不用 一臺(tái)一臺(tái)的 去調(diào) /actuator/refresh 接口脐嫂,而是通過(guò)廣播。

所以我們這里只介紹 /actuator/refresh 接口這種 是怎么刷新 配置的紊遵。

關(guān)于服務(wù)刷新配置的 大致原理 我在SpringCloud之ConfigServer配置中心以及Bus消息總線里有介紹過(guò)账千。大致有兩點(diǎn) :

  • 替換當(dāng)前spring上下文的environment對(duì)象的propertySources對(duì)象里的配置信息為最新從 配置中心服務(wù)端拉去的配置。
  • 為了bean里 有@Value之類的引用重新 賦值 暗膜,刷新作用域?yàn)锧RefreshScope 的bean匀奏,讓這些bean重新 初始化,重新從 environment對(duì)象里獲取配置, 將最新值注入到 @Value的屬性中。

4.1学搜、重新拉取配置信息, 替換 environment對(duì)象的propertySources

首先找到 /actuator/refresh接口所在的源碼位置娃善。

RefreshEndpoint類的refresh方法

image.png

當(dāng)我們調(diào)用 /actuator/refresh接口,就會(huì)進(jìn)到這里瑞佩。進(jìn)入contextRefresher的refresh()

image.png

先把當(dāng)前的Environment對(duì)象的PropertySources列表保存聚磺。然后調(diào)用addConfigFilesToEnvironment方法。

image.png

addConfigFilesToEnvironment方法里 會(huì) 重新 創(chuàng)建一個(gè)SpringApplication類炬丸,

  • 指定environment為當(dāng)前Spring上下文environment對(duì)象的備份瘫寝。PropertySources的引用是相同的。
  • 要加載的source類 是 Empty類, 是個(gè)空的類。
  • 并且指定 WebApplicationType.NONE矢沿,不啟動(dòng)spring里的web容器相關(guān)的東西滥搭。
  • 并且手動(dòng)加入 BootstrapApplicationListener監(jiān)聽(tīng)器類,注意捣鲸,這個(gè)類 是會(huì) 加載META-INF/spring.factories 文件里配置的 key為 BootstrapConfiguration的類的瑟匆。

之后調(diào)用SpringApplication的run方法。

image.png

解讀一下這是要干嘛栽惶。其實(shí)就是 啟動(dòng)了一個(gè)特別輕量級(jí)的springboot容器愁溜。什么功能也不啟用,web相關(guān)的東西也不啟用外厂。 然后run的時(shí)候冕象,就會(huì)加載 SPI里配置的相關(guān)的類。其他什么bean都不注冊(cè)汁蝶,因?yàn)樗麄魅氲腸lass是個(gè)空的類渐扮。

新的Spring容器里要實(shí)例化的bean也就只有這么幾個(gè)spi導(dǎo)入進(jìn)來(lái)的

image.png

加載spi之后,那么肯定就會(huì)加載到 配置中心客戶端 的 ConfigServicePropertySourceLocator類, 然后又可以借用 ApplicationContextInitializer接口實(shí)例 去調(diào)用PropertySourceLocator接口的實(shí)現(xiàn)類onfigServicePropertySourceLocator類的 locate()方法掖棉,重新從配置中心服務(wù)端 拉取配置墓律。

拉取完配置之后,傳入的environment對(duì)象的propertySources對(duì)象 就又有 從配置中心服務(wù)端 拉取的配置了。

新創(chuàng)建的spring容器 的 environment對(duì)象:

image.png

最后返回這個(gè)Spring上下文對(duì)象幔亥。

返回之后,就是 與之前的 Environment對(duì)象里PropertySources集合進(jìn)行比較交換耻讽。把更改后的配置信息 更新到 當(dāng)前spring上下文的Environment對(duì)象里。

由于剛才新創(chuàng)建并啟動(dòng)的Spring容器傳入的 Environment對(duì)象里 的 propertySources 對(duì)象 的引用 就是 當(dāng)前spring上下文的Environment對(duì)象里的帕棉。所以就直接用 當(dāng)前spring上下文的Environment對(duì)象里的propertySources對(duì)象進(jìn)行比較针肥。

image.png

然后返回 有改動(dòng)的 配置文件的key的 集合。

到這里, Environment對(duì)象里 的 propertySources 已經(jīng)被替換成最新拉取的配置了香伴。

4.2慰枕、刷新作用域?yàn)锧RefreshScope 的bean

更新完 Environment對(duì)象里 的 propertySources之后,下面還有一行很重要的代碼即纲。

刷新 作用域?yàn)?@RefreshScope的所有bean捺僻。

image.png

刷新其實(shí)就是把他們?nèi)慷间N毀了。

image.png

直接把@RefreshScope作用域里存放bean的 緩存清了崇裁。

image.png

作用域Scope接口

作用域其實(shí)就是Scope接口的實(shí)現(xiàn)類 來(lái)實(shí)現(xiàn) 管理bean的方式。

Spring在獲取bean的時(shí)候束昵,會(huì)調(diào)用 Scope接口的實(shí)現(xiàn)類的get方法拔稳,來(lái)獲取bean。并傳入ObjectFactory對(duì)象锹雏。

image.png

Spring創(chuàng)建bean:

image.png

ObjectFactory的getObject方法是會(huì)去創(chuàng)建bean的巴比。Scope接口的實(shí)現(xiàn)類的get方法需要自己來(lái)判斷 bean是不是存在,不存在 就調(diào)用 ObjectFactory的getObject方法去創(chuàng)建bean, 然后返回這個(gè)bean。 存在就直接 返回轻绞。

像spring里的單例作用域采记,get方法里如果不存在,創(chuàng)建完bean之后政勃,就會(huì)存起來(lái)唧龄,下次get就從緩存里拿,不會(huì)再創(chuàng)建新的實(shí)例奸远,以保證從spring容器里獲取的該bean永遠(yuǎn)返回的是同一個(gè)實(shí)例既棺。

而spring里的多例作用域, get方法里如果不存在,創(chuàng)建完bean之后,它不會(huì)緩存起來(lái)懒叛,下次來(lái)還當(dāng)沒(méi)有丸冕,總是創(chuàng)建最新的,所以 從spring容器里獲取的該beanu永遠(yuǎn)是新創(chuàng)建的實(shí)例薛窥。

RefreshScope 如何管理bean胖烛?

RefreshScope是借用內(nèi)部緩存來(lái) 管理bean的。

get方法

走到父類GenericScope的get方法,

image.png

會(huì)往BeanLifecycleWrapperCache進(jìn)行緩存诅迷。

image.png

然后返回BeanLifecycleWrapper.get方法佩番,判斷bean是不是實(shí)例化,沒(méi)有實(shí)例化就調(diào)用ObjectFactory的getObject方法, 實(shí)例化了就直接返回竟贯。

image.png

bean的銷毀

所以現(xiàn)在我們調(diào)用 /actuator/refresh接口刷新配置時(shí)答捕,就把 RefreshScope作用域里的緩存全部都清了, 下次這些bean 被用到時(shí),進(jìn)RefreshScope的get方法 屑那,緩存里沒(méi)有, 那么就會(huì)重新實(shí)例化這些bean拱镐。重新這些實(shí)例化bean,那么這些bean里用到 @value的地方 就會(huì)從 最新的environment對(duì)象里獲取最新的配置持际,注入進(jìn)去, 以達(dá)到 刷新配置的效果沃琅。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蜘欲,隨后出現(xiàn)的幾起案子益眉,更是在濱河造成了極大的恐慌,老刑警劉巖姥份,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件郭脂,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡澈歉,警方通過(guò)查閱死者的電腦和手機(jī)展鸡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)埃难,“玉大人莹弊,你說(shuō)我怎么就攤上這事涤久。” “怎么了忍弛?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵响迂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我细疚,道長(zhǎng)蔗彤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任惠昔,我火速辦了婚禮幕与,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘镇防。我一直安慰自己啦鸣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布来氧。 她就那樣靜靜地躺著诫给,像睡著了一般。 火紅的嫁衣襯著肌膚如雪啦扬。 梳的紋絲不亂的頭發(fā)上中狂,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音扑毡,去河邊找鬼胃榕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瞄摊,可吹牛的內(nèi)容都是我干的勋又。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼换帜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼楔壤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起惯驼,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蹲嚣,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后祟牲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體隙畜,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年说贝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了禾蚕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡狂丝,死狀恐怖换淆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情几颜,我是刑警寧澤倍试,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蛋哭,受9級(jí)特大地震影響县习,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谆趾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一躁愿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沪蓬,春花似錦彤钟、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至云挟,卻和暖如春梆砸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背园欣。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工帖世, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沸枯。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓日矫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親辉饱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子搬男,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355