SpringCloud組件之Hystrix

在分布式環(huán)境中反镇,許多服務(wù)依賴項中的一些必然會失敗。Hystrix是一個庫,通過添加延遲容忍和容錯邏輯张足,幫助你控制這些分布式服務(wù)之間的交互。Hystrix通過隔離服務(wù)之間的訪問點(diǎn)坎藐、停止級聯(lián)失敗和提供回退選項來實現(xiàn)這一點(diǎn)为牍,所有這些都可以提高系統(tǒng)的整體彈性

hystrix.jpg

一、Hystrix宗旨和工作原理

Hystrix的宗旨:

  • 防止任何單個依賴項耗盡所有容器(如Tomcat)用戶線程
  • 在任何可行的地方提供回退岩馍,以保護(hù)用戶不受失敗的影響
  • 使用隔離技術(shù)(如隔離板碉咆、泳道和斷路器模式)來限制任何一個依賴項的影響
  • 通過近實時的度量、監(jiān)視和警報來優(yōu)化發(fā)現(xiàn)時間
  • 通過配置的低延遲傳播來優(yōu)化恢復(fù)時間
  • 避免在整個依賴客戶端執(zhí)行中出現(xiàn)故障蛀恩,而不僅僅是在網(wǎng)絡(luò)流量中

Hystrix工作原理

info.png

當(dāng)需要完成某項任務(wù)時疫铜,通過 Hystrix 將任務(wù)包裹起來,交由 Hystrix 來完成任務(wù)双谆,從而享受 Hystrix 帶來保護(hù)

  • 1壳咕、構(gòu)建命令

Hystrix 提供了兩個Command席揽, HystrixCommand 和 HystrixObservableCommand,可以使用這兩個對象來包裹待執(zhí)行的任務(wù),Hystrix應(yīng)用自己的一系列保護(hù)機(jī)制谓厘,在執(zhí)行用戶任務(wù)的各節(jié)點(diǎn)(執(zhí)行前幌羞、執(zhí)行后、異常竟稳、超時等)做一系列的事情

  • 2属桦、執(zhí)行命令
    有四種方式執(zhí)行command
  • R execute():同步執(zhí)行,從依賴服務(wù)得到單一結(jié)果對象
  • Future<R> queue():異步執(zhí)行他爸,返回一個 Future 以便獲取執(zhí)行結(jié)果聂宾,也是單一結(jié)果對象
  • Observable<R> observe():hot observable,創(chuàng)建Observable后會訂閱Observable诊笤,可以返回多個結(jié)果
  • Observable<R> toObservable():cold observable系谐,返回一個Observable,只有訂閱時才會執(zhí)行盏混,可以返回多個結(jié)果
  • 3揣炕、檢查緩存

如果啟用了 Hystrix Cache帐我,任務(wù)執(zhí)行前將先判斷是否有相同命令執(zhí)行的緩存拿诸。如果有則直接返回緩存的結(jié)果擦囊;如果沒有緩存的結(jié)果,但啟動了緩存混聊,將緩存本次執(zhí)行結(jié)果以供后續(xù)使用

  • 4弹谁、檢查斷路器是否打開

斷路器(circuit-breaker)和保險絲類似,保險絲在發(fā)生危險時將會燒斷以保護(hù)電路句喜,而斷路器可以在達(dá)到我們設(shè)定的閥值時觸發(fā)短路(比如請求失敗率達(dá)到50%)预愤,拒絕執(zhí)行任何請求。如果斷路器被打開咳胃,Hystrix 將不會執(zhí)行命令植康,直接進(jìn)入Fallback處理邏輯

  • 5、檢查線程池/信號量情況

Hystrix 隔離方式有線程池隔離和信號量隔離展懈。當(dāng)使用Hystrix線程池時销睁,Hystrix 默認(rèn)為每個依賴服務(wù)分配10個線程,當(dāng)10個線程都繁忙時存崖,將拒絕執(zhí)行命令冻记。信號量同理

  • 6、執(zhí)行具體的任務(wù)

通過HystrixObservableCommand.construct()或者HystrixCommand.run()來運(yùn)行用戶真正的任務(wù)

  • 7来惧、計算鏈路健康情況

每次開始執(zhí)行command冗栗、結(jié)束執(zhí)行command以及發(fā)生異常等情況時,都會記錄執(zhí)行情況,例如:成功隅居、失敗钠至、拒絕以及超時等情況,會定期處理這些數(shù)據(jù)胎源,再根據(jù)設(shè)定的條件來判斷是否開啟斷路器

  • 8棕洋、命令失敗時執(zhí)行 Fallback 邏輯

在命令失敗時執(zhí)行用戶指定的 Fallback 邏輯。上圖中的斷路乒融、線程池拒絕、信號量拒絕摄悯、執(zhí)行執(zhí)行赞季、執(zhí)行超時都會進(jìn)入 Fallback 處理

  • 9、返回執(zhí)行結(jié)果

原始結(jié)果將以O(shè)bservable形式返回奢驯,在返回給用戶之前申钩,會根據(jù)調(diào)用方式的不同做一些處理

更多詳細(xì)的工作原理,可前往: How is Works

二瘪阁、HystrixCommand注解

我們的配置都是基于 HystrixCommand 的撒遣,我們通過在方法上添加 @HystrixCommand 注解并配置注解的參數(shù)來實現(xiàn)配置,但有的時候一個類里面會有多個 Hystrix 方法管跺,每個方法都是類似配置的話會冗余很多代碼义黎,這時候我們可以在類上使用 @DefaultProperties 注解來給整個類的 Hystrix 方法設(shè)置一個默認(rèn)值。
參數(shù)介紹

  • commandKey: 用來標(biāo)識一個 Hystrix 命令豁跑,默認(rèn)會取被注解的方法名廉涕。需要注意:Hystrix 里同一個鍵的唯一標(biāo)識并不包括 groupKey,建議取一個獨(dú)一二無的名字艇拍,防止多個方法之間因為鍵重復(fù)而互相影響
  • groupKey:一組Hystrix命令的集合狐蜕,統(tǒng)計、報告卸夕、默認(rèn)取類名层释,可不配置
  • threadPoolKey:標(biāo)識一個線程池,如果沒設(shè)置會取groupKey快集,很多情況下都是同一個類內(nèi)的方法共用一個線程池
  • commandProperties:與此命令相關(guān)的屬性
  • threadPoolProperties:與線程池相關(guān)的屬性
  • observableExcutionMode:當(dāng)Hystrix命令被包裝成RxJava的Observer異步執(zhí)行時贡羔,此配置指定了Observable被執(zhí)行的模式,默認(rèn)是ObservableExecutionMode.EAGER, Obserable會在被創(chuàng)建后立刻執(zhí)行碍讨,而ObservableExecutionMode.EAGER模式下治力,則會產(chǎn)生一個Observable被Subscribe執(zhí)行,此配置項可以不配置
  • ignoreExceptions:默認(rèn)Hystrix在執(zhí)行方法時捕獲到異常時執(zhí)行回退勃黍,并統(tǒng)計失敗率以修改熔斷器的狀態(tài)宵统,而被忽略的異常則會直接拋到外層,不執(zhí)行回退,也不影響熔斷器的狀態(tài)
  • raiseHystrixExceptions:當(dāng)配置項包括 HystrixRuntimeException 時马澈,所有的未被忽略的異常都會被包裝成HystrixRuntimeException瓢省,配置其他種類的異常好像并沒有什么影響
  • fallbackMethod:方法執(zhí)行時容斷、錯誤痊班、超時會執(zhí)行的回退方法勤婚,需要保證返回值一致

三、hystrix配置屬性詳解

Hystrix配置屬性詳解涤伐,所有屬性默認(rèn)都是default,如需針對某個服務(wù)馒胆,將default改為那個服務(wù)名即可

  1. Execution:控制HystrixCommand.run()如何運(yùn)行
  2. Fallback:控制HystrixCommand.getFallback()如何運(yùn)行
  3. Circuit Breadker:控制斷路器的行為
  4. Metrics:捕獲HystrixCommand和HystrixObervableCommand執(zhí)行消息相關(guān)的配置屬性
  5. Request Context:設(shè)置請求上下文的屬性
  6. Collapser Properties:設(shè)置請求合并的屬性
  7. Thread Pool Properties:設(shè)置線程池的屬性

1、Execution

  • execution.isolation.strategy:表示Hystrix.command.run()執(zhí)行時的隔離策略凝果,有以下兩種
    1. Thread:在單獨(dú)的線程上執(zhí)行祝迂,并發(fā)請求受線程池中的線程數(shù)限制
    2. SEMAPHORE:在調(diào)用線程上執(zhí)行,并發(fā)請求量受信號量計數(shù)限制

在默認(rèn)情況下器净,推薦HystrixCommands 使用 thread 隔離策略型雳,HystrixObservableCommand 使用 semaphore 隔離策略。 只有在高并發(fā)(單個實例每秒達(dá)到幾百個調(diào)用)的調(diào)用時山害,才需要修改HystrixCommands 的隔離策略為semaphore 纠俭。semaphore 隔離策略通常只用于非網(wǎng)絡(luò)調(diào)用

hystrix.command.default.execution.isolation.strategy=
  • execution.isolation.thread.timeoutInMilliseconds:設(shè)置調(diào)用者執(zhí)行的超時實際(單位毫秒),默認(rèn)1000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=
  • execution.isolation.thread.interruptOnTimeout:表示設(shè)置執(zhí)行超時時浪慌,中斷HystrixCommand.run() 的執(zhí)行冤荆,默認(rèn)true
hystrix.command.default.execution.isolation.thread.interruptOnTimeout=
  • execution.isolation.semaphore.maxConcurrentRequests:當(dāng)HystrixCommand.run()使用SEMAPHORE隔離策略時,設(shè)置并發(fā)量权纤,默認(rèn)10
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests=
  • execution.isolation.thread.interruptOnCancel:表示設(shè)置是否在取消任務(wù)執(zhí)行時匙赞,中斷HystrixCommand.run()執(zhí)行,默認(rèn)false
hystrix.command.default.execution.isolation.thread.interruptOnCancel=

2妖碉、Fallback

以下屬性控制HystrixCommand.getFallback() 如何執(zhí)行涌庭。這些屬性對隔離策略THREAD 和SEMAPHORE都起作用

  • fallback.isolation.semaphore.maxConcurrentRequests:此屬性設(shè)置從調(diào)用線程允許HystrixCommand.getFallback()方法允許的最大并發(fā)請求數(shù) 如果達(dá)到最大的并發(fā)量,則接下來的請求會被拒絕并且拋出異常欧宜,默認(rèn)10
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests=
  • fallback.enabled:是否開啟fallback功能坐榆,默認(rèn)true
hystrix.command.default.fallback.enabled=

3、Circuit Breaker

控制斷路器的行為

  • circuitBreaker.enabled:是否開啟斷路器功能冗茸,默認(rèn)true
hystrix.command.default.circuitBreaker.enabled=
  • circuitBreaker.requestVolumeThreshold:使斷路器跳閘的最小請求數(shù)量席镀,如果此屬性值為20,則在窗口時間內(nèi)(如10s內(nèi))夏漱,如果只收到19個請求且都失敗了豪诲,則斷路器也不會開啟。默認(rèn)20
hystrix.command.default.circuitBreaker.requestVolumeThreshold=
  • circuitBreaker.errorThresholdPercentage:設(shè)置失敗百分比的閾值挂绰。如果失敗比率超過這個值屎篱,則斷路器跳閘并且進(jìn)入fallback邏輯,默認(rèn)50
hystrix.command.default.circuitBreaker=
  • circuitBreaker.forceOpen:如果設(shè)置true,則強(qiáng)制使斷路器跳閘交播,則會拒絕所有的請求.此值會覆蓋circuitBreaker.forceClosed的值重虑,默認(rèn)false
hystrix.command.default.circuitBreaker.forceOpen=
  • circuitBreaker.forceClosed:如果設(shè)置true,則強(qiáng)制使斷路器進(jìn)行關(guān)閉狀態(tài)秦士,此時會允許執(zhí)行所有請求缺厉,無論是否失敗的次數(shù)達(dá)到circuitBreaker.errorThresholdPercentage值,默認(rèn)false
hystrix.command.default.circuitBreaker.forceClosed=

4隧土、Mertrics

捕獲和HystrixCommand 和 HystrixObservableCommand 執(zhí)行信息相關(guān)的配置屬性

  • metrics.rollingStats.timeInMilliseconds:設(shè)置統(tǒng)計滾動窗口的時間長度如果此值為10s提针,將窗口分成10個桶,每個桶表示1s時間曹傀,默認(rèn)10000
hystrix.command.default.metrics.rollingStats.timeInMilliseconds=
  • metrics.rollingStats.numBuckets:設(shè)置統(tǒng)計滾動窗口的桶數(shù)量关贵,必須滿足metrics.rollingStats.timeInMilliseconds % metrics.rollingStats.numBuckets == 0,否則異常卖毁,比如:1000/10,1000/20是正確的落萎,1000/7是錯的亥啦,高并發(fā)環(huán)境里,每個桶時間長度建議大于100ms练链,默認(rèn)10
hystrix.command.default.metrics.rollingStats.numBuckets=
  • metrics.rollingPercentile.enabled:設(shè)置執(zhí)行延遲是否被跟蹤翔脱,并且被計算在失敗百分比中。如果設(shè)置為false,則所有的統(tǒng)計數(shù)據(jù)返回-1媒鼓,默認(rèn)true
hystrix.command.default.metrics.rollingPercentile.enabled=
  • metrics.rollingPercentile.timeInMilliseconds:此屬性設(shè)置統(tǒng)計滾動百分比窗口的持續(xù)時間届吁,默認(rèn)60000
hystrix.command.default.metrics.rollingPercentile.timeInMilliseconds=
  • metrics.rollingPercentile.numBuckets:設(shè)置統(tǒng)計滾動百分比窗口的桶數(shù)量,以下配置必須成立绿鸣,metrics.rollingPercentile.timeInMilliseconds % metrics.rollingPercentile.numBuckets == 0疚沐,否則異常,比如1000/10是對的潮模,1000/7是錯的亮蛔,高并發(fā)情況下每個桶的時間長度建議大于1000ms,默認(rèn)6
hystrix.command.default.metrics.rollingPercentile.numBuckets=
  • metrics.rollingPercentile.bucketSize:設(shè)置每個桶保存的執(zhí)行時間的最大值擎厢。如果桶數(shù)量是100究流,統(tǒng)計窗口為10s,如果這10s里有500次執(zhí)行动遭,只有最后100次執(zhí)行會被統(tǒng)計到bucket里去芬探,默認(rèn)100
hystrix.command.default.metrics.rollingPercentile.bucketSize=
  • metrics.healthSnapshot.intervalInMilliseconds:采樣時間間隔
hystrix.command.default.metrics.healthSnapshot.intervalInMilliseconds=

5、Request Context

此屬性控制HystrixCommand使用到的Hystrix的上下文

  • requestCache.enabled:是否開啟請求緩存功能厘惦,默認(rèn)true
hystrix.command.default.requestCache.enabled=
  • requestLog.enabled:是否開啟日志偷仿,打印執(zhí)行HystrixCommand的情況和事件,默認(rèn)true
hystrix.command.default.requestLog.enabled=

6、Collapser Properties

設(shè)置請求合并的屬性

  • maxRequestsInBatch:設(shè)置同時批量執(zhí)行的請求的最大數(shù)量炎疆,默認(rèn)Integer.MAX_VALUE
hystrix.collapser.default.maxRequestsInBatch=
  • timerDelayInMilliseconds:批量執(zhí)行創(chuàng)建多久之后卡骂,再觸發(fā)真正的請求,默認(rèn)10
hystrix.collapser.default.timerDelayInMilliseconds=
  • requestCache.enabled:是否對HystrixCollapser.execute() 和 HystrixCollapser.queue()開啟請求緩存,默認(rèn)true
hystrix.collapser.default.requestCache.enabled=

7形入、Thread Pool Properties

設(shè)置Hystrix Commands的線程池行為全跨,大部分情況線程數(shù)量是10。線程池數(shù)量的計算公式如下:最高峰時每秒的請求數(shù)量 × 99%命令執(zhí)行時間 + 喘息空間亿遂,設(shè)置線程池數(shù)量的主要原則是保持線程池越小越好浓若,因為它是減輕負(fù)載并防止資源在延遲發(fā)生時被阻塞的主要工具

  • coreSize:設(shè)置線程池的core的大小,默認(rèn)10
hystrix.threadpool.default.coreSize=
  • maximumSize:設(shè)置最大的線程池的大小蛇数,只有設(shè)置allowMaximumSizeToDivergeFromCoreSize時挪钓,此值才起作用,默認(rèn)10
hystrix.threadpool.default.maximumSize=
  • maxQueueSize:設(shè)置最大的BlockingQueue隊列的值耳舅。如果設(shè)置-1碌上,則使用SynchronousQueue隊列,如果設(shè)置正數(shù)浦徊,則使用LinkedBlockingQueue隊列馏予,默認(rèn)-1
hystrix.threadpool.default.maxQueueSize=
  • queueSizeRejectionThreshold:因為maxQueueSize值不能被動態(tài)修改,所有通過設(shè)置此值可以實現(xiàn)動態(tài)修改等待隊列長度盔性。即等待的隊列的數(shù)量大于queueSizeRejectionThreshold時(但是沒有達(dá)到maxQueueSize值)霞丧,則開始拒絕后續(xù)的請求進(jìn)入隊列。如果設(shè)置-1冕香,則屬性不啟作用蛹尝,默認(rèn)5
hystrix.threadpool.default.queueSizeRejectionThreshold=
  • keepAliveTimeMinutes:設(shè)置線程多久沒有服務(wù)后,需要釋放(maximumSize-coreSize )個線程悉尾,默認(rèn)1
hystrix.threadpool.default.keepAliveTimeMinutes=
  • allowMaximumSizeToDivergeFromCoreSize:設(shè)置allowMaximumSizeToDivergeFromCoreSize值為true時突那,maximumSize才有作用,默認(rèn)false
hystrix.threadpool.default.allowMaximumSizeToDivergeFromCoreSize=
  • metrics.rollingStats.timeInMilliseconds:設(shè)置滾動窗口的時間构眯,默認(rèn)10000
hystrix.threadpool.default.metrics.rollingStats.timeInMilliseconds=
  • metrics.rollingStats.numBuckets:設(shè)置滾動靜態(tài)窗口分成的桶的數(shù)量陨收,必須滿足metrics.rollingStats.timeInMilliseconds % metrics.rollingStats.numBuckets == 0,默認(rèn)值10鸵赖,高并發(fā)情況下建議每個桶時間長度大于100ms
hystrix.threadpool.default.metrics.rollingStats.numBuckets=

四务漩、Hystrix的使用

1、導(dǎo)入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
    <groupId>cn.gjing</groupId>
    <artifactId>tools-httpclient</artifactId>
    <version>1.0.2</version>
</dependency>

2它褪、啟動類標(biāo)注注解

/**
 * @author Gjing
 */
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class HystrixApplication {

    public static void main(String[] args) {
        SpringApplication.run(HystrixApplication.class, args);
    }
}

3饵骨、編寫service

@Service
public class TestService {

     // 此注解說明該方法要執(zhí)行回退,fallback指定回退方法
    @HystrixCommand(fallbackMethod = "defaultFallback")
    public String hello() {
        HttpClient httpClient = new HttpClient();
        return httpClient.get("http://127.0.0.1:8090/test2", String.class);
    }

    // 回退方法
    public String defaultFallback() {
        return "no hello";
    }
}

4茫打、編寫Controller進(jìn)行測試

/**
 * @author Gjing
 **/
@RestController
public class TestController {

    @Resource
    private TestService testService;

    @PostMapping("/test")
    public String test() {
        return testService.hello();
    }
}

5居触、目標(biāo)服務(wù)的接口

因為hystrix默認(rèn)超時是1秒妖混,所以,我們在目標(biāo)服務(wù)轮洋,加個線程休眠制市,大于1秒即可

/**
 * @author Gjing
 **/
@RestController
public class DemoController {

    @GetMapping("/test2")
    public String test2() throws InterruptedException {
        Thread.sleep(1000);
        return "ok";
    }
}

5、測試

超時進(jìn)入回退方法弊予,并返回了回退方法里的內(nèi)容

1562046883(1).jpg

三祥楣、Feign使用Hystrix

1、增加依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2汉柒、啟動類增加@EnableFeignClients注解

3误褪、增加一個service和回退類

/**
 * @author Gjing
 * name為目標(biāo)服務(wù)名,fallback為回退類
 **/
@FeignClient(name = "demo",fallback = FeignServiceFallbackImpl.class)
public interface FeignService {

    @RequestMapping(value = "/test2", method = RequestMethod.GET)
    String  test2();
}

/**
 * 回退類碾褂,實現(xiàn)feignService
 */
@Component
class FeignServiceFallbackImpl implements FeignService{
    @Override
    public String test2() {
        return "啊哦兽间,出錯了");
    }
}

4、編寫Controller進(jìn)行測試

/**
 * @author Gjing
 **/
@RestController
public class FeignController {

    @Resource
    private FeignService feignService;

    @PostMapping("/testFeign")
    public String testFeign() {
        return feignService.test();
    }
}

如果出錯了正塌,會進(jìn)行回退

erro.jpg

四嘀略、使用監(jiān)控面板dashBoard

1、增加依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2乓诽、啟動類加上注解@EnableHystrixDashboard

3帜羊、配置文件

server:
  port: 8082
spring:
  application:
    name: hystrix-demo
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
# feign使用hystrix進(jìn)行回退
feign:
  hystrix:
    enabled: true
# 端點(diǎn)管理 hystrixDashboard
management:
  endpoints:
    web:
      exposure:
        include: "*"

4、啟動項目问裕,并訪問http://localhost:port/hystrix即可打開如下頁面

d.jpg

通過主頁面的文字介紹,可以知道孵坚,共支持三種不同的監(jiān)控方式*

本文只講解單體應(yīng)用巍杈,因此我們在主頁面輸入http://localhost:8082/actuator/hystrix.stream即可訪問,請求幾次結(jié)果

re.jpg


界面解釋

11


到此本文就結(jié)束了,篇幅較長扛伍,如哪里有字寫錯或單詞打錯筷畦,各位幫忙糾正,本項目源碼:SpringCloud-Demo

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刺洒,一起剝皮案震驚了整個濱河市鳖宾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逆航,老刑警劉巖鼎文,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異因俐,居然都是意外死亡拇惋,警方通過查閱死者的電腦和手機(jī)周偎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撑帖,“玉大人蓉坎,你說我怎么就攤上這事『伲” “怎么了蛉艾?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長灶平。 經(jīng)常有香客問我伺通,道長,這世上最難降的妖魔是什么逢享? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任罐监,我火速辦了婚禮,結(jié)果婚禮上瞒爬,老公的妹妹穿的比我還像新娘弓柱。我一直安慰自己,他們只是感情好侧但,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布矢空。 她就那樣靜靜地躺著,像睡著了一般禀横。 火紅的嫁衣襯著肌膚如雪屁药。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天柏锄,我揣著相機(jī)與錄音酿箭,去河邊找鬼。 笑死趾娃,一個胖子當(dāng)著我的面吹牛缭嫡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播抬闷,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼妇蛀,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了笤成?” 一聲冷哼從身側(cè)響起评架,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炕泳,沒想到半個月后古程,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喊崖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年挣磨,在試婚紗的時候發(fā)現(xiàn)自己被綠了雇逞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡茁裙,死狀恐怖塘砸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晤锥,我是刑警寧澤掉蔬,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站矾瘾,受9級特大地震影響女轿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜壕翩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一蛉迹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧放妈,春花似錦北救、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宅倒,卻和暖如春攘宙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拐迁。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工蹭劈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唠亚。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓链方,卻偏偏與公主長得像持痰,于是被迫代替她去往敵國和親灶搜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

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