一篇文章帶你深入理解FlinkSQL中的窗口

前言

???????? 時間語義扔仓,要配合窗口操作才能發(fā)揮作用翘簇。最主要的用途版保,當(dāng)然就是開窗口彻犁、根據(jù)時間段做計算了汞幢。下面我們就來看看 Table API 和 SQL 中溉瓶,怎么利用時間字段做窗口操作堰酿。在 Table API 和 SQL 中触创,主要有兩種窗口:Group Windows 和 Over Windows(時間語義的文章推薦

一哼绑、分組窗口(Group Windows)

???????? 分組窗口(Group Windows)會根據(jù)時間或行計數(shù)間隔抖韩,將行聚合到有限的組(Group)中茂浮,并對每個組的數(shù)據(jù)執(zhí)行一次聚合函數(shù)席揽。???????? Table API 中的 Group Windows 都是使用.window(w:GroupWindow)子句定義的幌羞,并且必須由 as 子句指定一個別名。為了按窗口對表進(jìn)行分組熊痴,窗口的別名必須在 group by 子句中果善,像常規(guī)的分組字段一樣引用。例子:

val?table?=?input
.window([w:?GroupWindow]?as?'w)
.groupBy('w,?'a)
.select('a,?'w.start,?'w.end,?'w.rowtime,?'b.count)

???????? Table API 提供了一組具有特定語義的預(yù)定義 Window 類,這些類會被轉(zhuǎn)換為底層DataStream 或 DataSet 的窗口操作惜论。?????????

? ? ? ? Table API 支持的窗口定義馆类,和我們熟悉的一樣乾巧,主要也是三種:滾動(Tumbling)沟于、滑動(Sliding會話(Session)旷太。

1.1 ?滾動窗口

? ? ? ?滾動窗口(Tumbling windows)要用 Tumble 類來定義供璧,另外還有三個方法:

  • over:定義窗口長度
  • on:用來分組(按時間間隔)或者排序(按行數(shù))的時間字段
  • as:別名睡毒,必須出現(xiàn)在后面的 groupBy 中

實(shí)現(xiàn)案例

  1. 需求????????設(shè)置滾動窗口為10秒鐘統(tǒng)計id出現(xiàn)的次數(shù)冗栗。
  2. 數(shù)據(jù)準(zhǔn)備
sensor_1,1547718199,35.8
sensor_6,1547718201,15.4
sensor_7,1547718202,6.7
sensor_10,1547718205,38.1
sensor_1,1547718206,32
sensor_1,1547718208,36.2
sensor_1,1547718210,29.7
sensor_1,1547718213,30.9
  1. 代碼實(shí)現(xiàn)
package?windows

import?org.apache.flink.streaming.api.TimeCharacteristic
import?org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import?org.apache.flink.streaming.api.scala._
import?org.apache.flink.streaming.api.windowing.time.Time
import?org.apache.flink.table.api.scala._
import?org.apache.flink.table.api.{EnvironmentSettings,?Table,?Tumble}
import?org.apache.flink.types.Row

/**
?*?@Package?Windows
?*?@File :FlinkSQLTumBlingTie.java
?*?@author?大數(shù)據(jù)老哥
?*?@date?2020/12/25?21:58
?*?@version?V1.0
?*??????????設(shè)置滾動窗口?*/
object?FlinkSQLTumBlingTie?{
??def?main(args:?Array[String]):?Unit?=?{
????val?env?=?StreamExecutionEnvironment.getExecutionEnvironment
????env.setParallelism(1)
????env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)

????val?settings?=?EnvironmentSettings.newInstance()
??????.useBlinkPlanner()
??????.inStreamingMode()
??????.build()
????val?tableEnv?=?StreamTableEnvironment.create(env,?settings)

????//?讀取數(shù)據(jù)
????val?inputPath?=?"./data/sensor.txt"
????val?inputStream?=?env.readTextFile(inputPath)
???

????//?先轉(zhuǎn)換成樣例類類型(簡單轉(zhuǎn)換操作)
????val?dataStream?=?inputStream
??????.map(data?=>?{
????????val?arr?=?data.split(",")
????????SensorReading(arr(0),?arr(1).toLong,?arr(2).toDouble)
??????})
??????.assignTimestampsAndWatermarks(new?BoundedOutOfOrdernessTimestampExtractor[SensorReading](Time.seconds(1))?{
????????override?def?extractTimestamp(element:?SensorReading):?Long?=?element.timestamp?*?1000L
??????})

????val?sensorTable:?Table?=?tableEnv.fromDataStream(dataStream,?'id,?'temperature,?'timestamp.rowtime?as?'ts)
????//?注冊表
????tableEnv.createTemporaryView("sensor",?sensorTable)
????//?table?實(shí)現(xiàn)
????val?resultTable?=?sensorTable
??????.window(Tumble?over?10.seconds?on?'ts?as?'tw)?//?每10秒統(tǒng)計一次,滾動時間窗口
??????.groupBy('id,?'tw)
??????.select('id,?'id.count,?'tw.end)
????//sql?實(shí)現(xiàn)
????val?sqlTable?=?tableEnv.sqlQuery(
??????"""
????????|select
????????|id,
????????|count(id)?,
????????|tumble_end(ts,interval?'10'?second)
????????|from?sensor
????????|group?by
????????|id,
????????|tumble(ts,interval?'10'?second)????????|""".stripMargin)

????/***
?????*?.window(Tumble?over?10.minutes?on?'rowtime?as?'w)?(事件時間字段?rowtime)
?????*?.window(Tumble?over?10.minutes?on?'proctime?as?'w)(處理時間字段?proctime)
?????*?.window(Tumble?over?10.minutes?on?'proctime?as?'w)?(類似于計數(shù)窗口棕洋,按處理時間排序乒融,10?行一組)?????*/
????resultTable.toAppendStream[Row].print("talbe")
????sqlTable.toRetractStream[Row].print("sqlTable")
????
????env.execute("FlinkSQLTumBlingTie")
??}

??case?class?SensorReading(id:?String,?timestamp:?Long,?temperature:?Double)

}

1.2 滑動窗口

滑動窗口(Sliding windows)要用 Slide 類來定義,另外還有四個方法:

  • over:定義窗口長度
  • every:定義滑動步長
  • on:用來分組(按時間間隔)或者排序(按行數(shù))的時間字段
  • as:別名奢驯,必須出現(xiàn)在后面的 groupBy 中

實(shí)現(xiàn)案例

  1. 需求描述???????? ??設(shè)置窗口大小為10秒鐘設(shè)置滑動距離為5秒鐘瘪阁,統(tǒng)計id的出現(xiàn)的次數(shù)管跺。
  2. 數(shù)據(jù)準(zhǔn)備
sensor_1,1547718199,35.8
sensor_6,1547718201,15.4
sensor_7,1547718202,6.7
sensor_10,1547718205,38.1
sensor_1,1547718206,32
sensor_1,1547718208,36.2
sensor_1,1547718210,29.7
sensor_1,1547718213,30.9
  1. 實(shí)現(xiàn)代碼
package?windows

import?org.apache.flink.streaming.api.TimeCharacteristic
import?org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import?org.apache.flink.streaming.api.scala._
import?org.apache.flink.streaming.api.windowing.time.Time
import?org.apache.flink.table.api.{EnvironmentSettings,?Slide,?Table}
import?org.apache.flink.table.api.scala._
import?org.apache.flink.types.Row
import?windows.FlinkSQLTumBlingTie.SensorReading

/**
?*?@Package?windows
?*?@File :FlinkSQLSlideTime.java
?*?@author?大數(shù)據(jù)老哥
?*?@date?2020/12/27?22:19
?*?@version?V1.0
?*??????????滑動窗口?*/
object?FlinkSQLSlideTime?{
??def?main(args:?Array[String]):?Unit?=?{
????//構(gòu)建運(yùn)行環(huán)境
????val?env?=?StreamExecutionEnvironment.getExecutionEnvironment
????env.setParallelism(1)?//?設(shè)置分區(qū)為1?方便后面測試
????env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)?//事件時間

????val?settings?=?EnvironmentSettings.newInstance()
??????.useBlinkPlanner()
??????.inStreamingMode()
??????.build()
????//?創(chuàng)建表env
????val?tableEnv?=?StreamTableEnvironment.create(env,?settings)

????//?讀取數(shù)據(jù)
????val?inputPath?=?"./data/sensor.txt"
????val?inputStream?=?env.readTextFile(inputPath)

????//?先轉(zhuǎn)換成樣例類類型(簡單轉(zhuǎn)換操作)
????val?dataStream?=?inputStream
??????.map(data?=>?{
????????val?arr?=?data.split(",")
????????SensorReading(arr(0),?arr(1).toLong,?arr(2).toDouble)
??????})
??????.assignTimestampsAndWatermarks(new?BoundedOutOfOrdernessTimestampExtractor[SensorReading](Time.seconds(1))?{
????????override?def?extractTimestamp(element:?SensorReading):?Long?=?element.timestamp?*?1000L
??????})

????val?sensorTable:?Table?=?tableEnv.fromDataStream(dataStream,?'id,?'temperature,?'timestamp.rowtime?as?'ts)
????//?注冊表
????tableEnv.createTemporaryView("sensor",?sensorTable)
????//?table?API?實(shí)現(xiàn)
????val?tableApi?=?sensorTable.window(Slide?over?10.seconds?every?5.seconds?on?'ts?as?'w)
??????.groupBy('w,?'id)
??????.select('id,?'id.count,?'w.end)
????val?tableSql?=?tableEnv.sqlQuery(
??????"""
????????|select
????????|id,
????????|count(id),
????????|HOP_END(ts,INTERVAL?'10'?SECOND,?INTERVAL?'5'?SECOND?)as?w
????????|from?sensor
????????|group?by
????????|HOP(ts,INTERVAL?'10'?SECOND,?INTERVAL?'5'?SECOND),id????????|""".stripMargin)

????tableApi.toAppendStream[Row].print("tableApi")
????tableSql.toAppendStream[Row].print("tableSql")
????/**
.window(Slide?over?10.minutes?every?5.minutes?on?'rowtime?as?'w)?(事件時間字段?rowtime)
.window(Slide?over?10.minutes?every?5.minutes?on?'proctime?as?'w)?(處理時間字段?proctime)?
.window(Slide?over?10.rows?every?5.rows?on?'proctime?as?'w)?(類似于計數(shù)窗口,按處理時間排序艇拍,10?行一組)???**/
????env.execute("FlinkSQLSlideTime")
??}
}

1.3 會話窗口

? ? ? ?會話窗口(Session windows)要用 Session 類來定義卸夕,另外還有三個方法:

  • withGap:會話時間間隔
  • on:用來分組(按時間間隔)或者排序(按行數(shù))的時間字段
  • as:別名娇哆,必須出現(xiàn)在后面的 groupBy 中實(shí)現(xiàn)案例
  1. 需求描述???????? ?設(shè)置一個session 為10秒鐘 統(tǒng)計id的個數(shù)
  2. 準(zhǔn)備數(shù)據(jù)
sensor_1,1547718199,35.8
sensor_6,1547718201,15.4
sensor_7,1547718202,6.7
sensor_10,1547718205,38.1
sensor_1,1547718206,32
sensor_1,1547718208,36.2
sensor_1,1547718210,29.7
sensor_1,1547718213,30.9
  1. 編寫代碼
package?windows

import?org.apache.flink.streaming.api.TimeCharacteristic
import?org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import?org.apache.flink.streaming.api.scala._
import?org.apache.flink.streaming.api.windowing.time.Time
import?org.apache.flink.table.api.{EnvironmentSettings,?Session,?Table}
import?org.apache.flink.table.api.scala._
import?org.apache.flink.types.Row
import?windows.FlinkSQLTumBlingTie.SensorReading

/**
?*?@Package?windows
?*?@File :FlinkSqlSessionTime.java
?*?@author?大數(shù)據(jù)老哥
?*?@date?2020/12/27?22:52
?*?@version?V1.0?*/
object?FlinkSqlSessionTime?{
??def?main(args:?Array[String]):?Unit?=?{
????//構(gòu)建運(yùn)行環(huán)境
????val?env?=?StreamExecutionEnvironment.getExecutionEnvironment
????env.setParallelism(1)?//?設(shè)置分區(qū)為1?方便后面測試
????env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)?//事件時間

????val?settings?=?EnvironmentSettings.newInstance()
??????.useBlinkPlanner()
??????.inStreamingMode()
??????.build()
????//?創(chuàng)建表env
????val?tableEnv?=?StreamTableEnvironment.create(env,?settings)

????//?讀取數(shù)據(jù)
????val?inputPath?=?"./data/sensor.txt"
????val?inputStream?=?env.readTextFile(inputPath)

????//?先轉(zhuǎn)換成樣例類類型(簡單轉(zhuǎn)換操作)
????val?dataStream?=?inputStream
??????.map(data?=>?{
????????val?arr?=?data.split(",")
????????SensorReading(arr(0),?arr(1).toLong,?arr(2).toDouble)
??????})
??????.assignTimestampsAndWatermarks(new?BoundedOutOfOrdernessTimestampExtractor[SensorReading](Time.seconds(1))?{
????????override?def?extractTimestamp(element:?SensorReading):?Long?=?element.timestamp?*?1000L
??????})

????val?sensorTable:?Table?=?tableEnv.fromDataStream(dataStream,?'id,?'temperature,?'timestamp.rowtime?as?'ts)
????//?注冊表
????tableEnv.createTemporaryView("sensor",?sensorTable)

????val?tableApi?=?sensorTable.
??????window(Session?withGap?10.seconds?on?'ts?as?'w)
??????.groupBy('id,?'w)
??????.select('id,?'id.count,?'w.end)
????val?tableSQL?=?tableEnv.sqlQuery(
??????"""
????????|SELECT
????????|id,
????????|COUNT(id),
????????|SESSION_END(ts,?INTERVAL?'10'?SECOND)?AS?w
????????|FROM?sensor
????????|GROUP?BY
????????|id,
????????|SESSION(ts,?INTERVAL?'10'?SECOND)????????|""".stripMargin)
????tableApi.toAppendStream[Row].print("tableApi")
????tableSQL.toAppendStream[Row].print("tableSQL")

????/**
?????*?.window(Session?withGap?10.minutes?on?'rowtime?as?'w)?事件時間字段?rowtime)
?????*?.window(Session?withGap?10.minutes?on?'proctime?as?'w)?處理時間字段?proctime)?????*/
????env.execute("FlinkSqlSessionTime")
??}
}

二蒙秒、 Over Windows

???????? Over window 聚合是標(biāo)準(zhǔn) SQL 中已有的(Over 子句)晕讲,可以在查詢的 SELECT 子句中定義。Over window 聚合弄息,會針對每個輸入行摹量,計算相鄰行范圍內(nèi)的聚合。Over windows使用.window(w:overwindows*)子句定義凝果,并在 select()方法中通過別名來引用器净。例子:

val?table?=?input
.window([w:?OverWindow]?as?'w)
.select('a,?'b.sum?over?'w,?'c.min?over?'w)

???????? Table API 提供了 Over 類山害,來配置 Over 窗口的屬性沿量。可以在事件時間或處理時間,以及指定為時間間隔佛掖、或行計數(shù)的范圍內(nèi)芥被,定義 Over windows坐榆。?????????

? ? ? ? 無界的 over window 是使用常量指定的。也就是說匹中,時間間隔要指定 UNBOUNDED_RANGE顶捷,或者行計數(shù)間隔要指定 UNBOUNDED_ROW服赎。而有界的 over window 是用間隔的大小指定的交播。

2.1 無界的 over window

//?無界的事件時間?over?window?(時間字段?"rowtime")
.window(Over?partitionBy?'a?orderBy?'rowtime?preceding?UNBOUNDED_RANGE?as?'w)
//無界的處理時間?over?window?(時間字段"proctime")
.window(Over?partitionBy?'a?orderBy?'proctime?preceding?UNBOUNDED_RANGE?as?'w)
//?無界的事件時間?Row-count?over?window?(時間字段?"rowtime")
.window(Over?partitionBy?'a?orderBy?'rowtime?preceding?UNBOUNDED_ROW?as?'w)
//無界的處理時間?Row-count?over?window?(時間字段?"rowtime")
.window(Over?partitionBy?'a?orderBy?'proctime?preceding?UNBOUNDED_ROW?as?'w)

2.2 有界的 over window

//?有界的事件時間?over?window?(時間字段?"rowtime"秦士,之前?1?分鐘)
.window(Over?partitionBy?'a?orderBy?'rowtime?preceding?1.minutes?as?'w)
//?有界的處理時間?over?window?(時間字段?"rowtime",之前?1?分鐘)
.window(Over?partitionBy?'a?orderBy?'proctime?preceding?1.minutes?as?'w)
//?有界的事件時間?Row-count?over?window?(時間字段?"rowtime"乏梁,之前?10?行)
.window(Over?partitionBy?'a?orderBy?'rowtime?preceding?10.rows?as?'w)
//?有界的處理時間?Row-count?over?window?(時間字段?"rowtime"遇骑,之前?10?行)
.window(Over?partitionBy?'a?orderBy?'proctime?preceding?10.rows?as?'w)

2.3 代碼練習(xí)

???????? 我們可以綜合學(xué)習(xí)過的內(nèi)容揖曾,用一段完整的代碼實(shí)現(xiàn)一個具體的需求炭剪。例如,統(tǒng)計每個sensor每條數(shù)據(jù)媒鼓,與之前兩行數(shù)據(jù)的平均溫度绿鸣。

數(shù)據(jù)準(zhǔn)備

sensor_1,1547718199,35.8
sensor_6,1547718201,15.4
sensor_7,1547718202,6.7
sensor_10,1547718205,38.1
sensor_1,1547718206,32
sensor_1,1547718208,36.2
sensor_1,1547718210,29.7
sensor_1,1547718213,30.9

代碼分析:

package?windows

import?org.apache.flink.streaming.api.TimeCharacteristic
import?org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import?org.apache.flink.streaming.api.scala._
import?org.apache.flink.streaming.api.windowing.time.Time
import?org.apache.flink.table.api.{EnvironmentSettings,?Over,?Tumble}
import?org.apache.flink.table.api.scala._
import?org.apache.flink.types.Row

/**
*?@Package?windows
*?@File :FlinkSqlTumBlingOverTime.java
*?@author?大數(shù)據(jù)老哥
*?@date?2020/12/28?21:45
*?@version?V1.0*/
object?FlinkSqlTumBlingOverTime?{
?def?main(args:?Array[String]):?Unit?=?{
???//?構(gòu)建運(yùn)行環(huán)境
???val?env?=?StreamExecutionEnvironment.getExecutionEnvironment
???env.setParallelism(1)?//?設(shè)置并行度為1方便后面進(jìn)行測試
???env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)?//?設(shè)置事件時間

???val?settings?=?EnvironmentSettings.newInstance()
?????.useBlinkPlanner()
?????.inStreamingMode()
?????.build()
???//構(gòu)建table?Env
???val?tableEnv?=?StreamTableEnvironment.create(env,?settings)

???//?讀取數(shù)據(jù)
???val?inputPath?=?"./data/sensor.txt"
???val?inputStream?=?env.readTextFile(inputPath)
???//?先轉(zhuǎn)換成樣例類類型(簡單轉(zhuǎn)換操作)
???//?解析數(shù)據(jù)?封裝成樣例類
???val?dataStream?=?inputStream
?????.map(data?=>?{
???????val?arr?=?data.split(",")
???????SensorReading(arr(0),?arr(1).toLong,?arr(2).toDouble)
?????})
?????.assignTimestampsAndWatermarks(new?BoundedOutOfOrdernessTimestampExtractor[SensorReading](Time.seconds(1))?{
???????override?def?extractTimestamp(element:?SensorReading):?Long?=?element.timestamp?*?1000L
?????})
???//?將數(shù)據(jù)注冊成一張臨時表
???val?dataTable?=?tableEnv.fromDataStream(dataStream,'id,?'temperature,?'timestamp.rowtime?as?'ts)
???tableEnv.createTemporaryView("sensor",dataTable)
???var?tableRes=?dataTable.window(?Over?partitionBy?'id?orderBy??'ts?preceding?2.rows?as?'ow)
????.select('id,'ts,'id.count?over?'ow,?'temperature.avg?over?'ow)

??var?tableSql=?tableEnv.sqlQuery(
?????"""
???????|select
???????|id,
???????|ts,
???????|count(id)?over?ow,
???????|avg(temperature)?over?ow
???????|from?sensor
???????|window?ow?as(
???????|?partition?by?id
???????|?order?by?ts
???????|?rows?between?2?preceding?and?current?row
???????|)???????|""".stripMargin)

???tableRes.toAppendStream[Row].print("tableRes")
???tableSql.toAppendStream[Row].print("tableSql")
???env.execute("FlinkSqlTumBlingOverTime")
?}
?case?class?SensorReading(id:?String,?timestamp:?Long,?temperature:?Double)

}

總結(jié)

???????? 好了到這里FlinkSql中窗口使用到這里就結(jié)束啦,喜歡的可以給了三連擎厢。其中FlinkSql中的窗口的用法還是比較多得动遭,所有還是要多加練習(xí)神得。老話說的好循头,師傅領(lǐng)進(jìn)門,修行在個人国裳。有什么不明白的可以在評論區(qū)留言全跨,也可以加我微信就進(jìn)行一起討論。我是大數(shù)據(jù)老哥蛇数,我們下期見~~~是越。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末倚评,一起剝皮案震驚了整個濱河市天梧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冕香,老刑警劉巖后豫,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異陨收,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)拄衰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門翘悉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妖混,“玉大人轮洋,你說我怎么就攤上這事∠殚梗” “怎么了误褪?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵兽间,是天一觀的道長。 經(jīng)常有香客問我啃洋,道長屎鳍,這世上最難降的妖魔是什么逮壁? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任窥淆,我火速辦了婚禮,結(jié)果婚禮上扛伍,老公的妹妹穿的比我還像新娘词裤。我一直安慰自己,他們只是感情好逆航,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布因俐。 她就那樣靜靜地躺著周偎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吧兔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天纲仍,我揣著相機(jī)與錄音灌侣,去河邊找鬼眉抬。 笑死瞒爬,一個胖子當(dāng)著我的面吹牛侧但,可吹牛的內(nèi)容都是我干的禀横。 我是一名探鬼主播粥血,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼复亏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了抬闷?” 一聲冷哼從身側(cè)響起耕突,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤有勾,失蹤者是張志新(化名)和其女友劉穎古程,沒想到半個月后挣磨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡塘砸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年掉蔬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箭启。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡傅寡,死狀恐怖北救,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情托启,我是刑警寧澤膛壹,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布模聋,位于F島的核電站,受9級特大地震影響持痰,放射性物質(zhì)發(fā)生泄漏工窍。R本人自食惡果不足惜前酿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一罢维、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匀借,春花似錦平窘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萨赁。三九已至兆龙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間慰安,已是汗流浹背聪铺。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工铃剔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凤类。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓谜疤,卻偏偏與公主長得像现诀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子坐桩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

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