Micro Service Architecture — Timeout

1 Overview

常見的微服務(wù)架構(gòu):


微服務(wù)架構(gòu)

做好超時(shí)時(shí)間的限定,用于判定超時(shí)后資源能夠及時(shí)被釋放,用于處理其它的請求筷频,從而提升的性能熏挎。

  • 前端:Ajax速勇、Node
  • 代理層:DNS、LB(SLB坎拐、F5烦磁、Keepalived+LVS、Haproxy哼勇、A10等)都伪、Ngixn、Gateway
  • 服務(wù)容器:Tomcat积担、Jetty
  • 中間件:Feign陨晶、Dubbo、HTTPClient帝璧、ES先誉、MongoDB、Redis
  • 數(shù)據(jù)庫:MySQL聋溜、Oracle

2 Solution

2.1 Front-end Timeout

2.1.1 ajax Timeout

? ajax底層使用的是XMLHttpRequest谆膳,其超時(shí)參數(shù)可以設(shè)置:連接超時(shí)、讀超時(shí)和寫超時(shí)撮躁。但對于包裝后的ajax漱病,我們通常只需要設(shè)置請求超時(shí)時(shí)間(timeout)即可,具體案例如下:

var ajaxTimeoutTest = $.ajax({
  url:'/demo',
    // 設(shè)置請求超時(shí)時(shí)間(毫秒)把曼,此設(shè)置將覆蓋全局設(shè)置
  timeout : 1000,
  type : 'get',
  data :{},
  dataType:'json',
  success:function(data){
    alert("成功");
  },
  complete : function(XMLHttpRequest,status){
      // 超時(shí)處理: status還有success,error等值的情況
      if(status=='timeout'){
       ajaxTimeoutTest.abort();
       alert("超時(shí)");
    }
  }
});

2.1.2 Node.js Timeout

  • Server Timeout
const http = require("http");
const server = http.createServer( function(req, res){
    // ......
});

// 設(shè)置服務(wù)端請求處理的超時(shí)時(shí)間
server.setTimeout(30 * 1000);
server.listen(3000, "localhost", function(){
    console.log("開始監(jiān)聽"+server.address().port+"......");
});
  • Client Timeout
const http = require('http');

const options = {host: 'localhost', method: 'GET', port: 8080, path: '/test'}
var req = http.request(options);

// 設(shè)置客戶端每個(gè)外調(diào)的超時(shí)時(shí)間
req.setTimeout(20 * 1000);
req.on('response', (res) => {
  res.setEncoding('utf8');
  res.on('data', function(chunk){
    console.log('收到數(shù)據(jù):%s', chunk);
  });
  res.on('end', function(){
    console.log(res.trailers);
  });
});
req.end();

2.2 Ngixn Timeout

2.2.1 keepalive_timeout

? HTTP是一種無狀態(tài)協(xié)議杨帽,其客戶端底層向服務(wù)器發(fā)送一個(gè)TCP請求,服務(wù)端響應(yīng)完畢后就會斷開連接嗤军。如果客戶端向服務(wù)器發(fā)送多個(gè)請求注盈,每個(gè)請求都要建立各自獨(dú)立的連接以傳輸數(shù)據(jù)。

? HTTP的KeepAlive就用于告訴服務(wù)器在處理完請求后保持一段這個(gè)TCP連接的打開狀態(tài)叙赚。若接收到來自客戶端的其它請求老客,服務(wù)端會利用這個(gè)未被關(guān)閉的連接僚饭,而不需要再建立一個(gè)連接。KeepAlive在一段時(shí)間內(nèi)保持打開狀態(tài)胧砰,它們會在這段時(shí)間內(nèi)占用資源鳍鸵,但占用過多就會影響性能。

? 因此尉间,Nginx使用 keepalive_timeout 來指定KeepAlive的超時(shí)時(shí)間偿乖,用于指定每個(gè)TCP 連接最多可以保持多長時(shí)間。Nginx的默認(rèn)值是75 秒哲嘲,然而有些瀏覽器最多只保持 60秒贪薪,所以可以設(shè)定為 60 秒 更安全。若將它設(shè)置為 0眠副,就禁止了 keepalive 連接画切。

# 配置段: http、server侦啸、location, 默認(rèn)值是75秒
keepalive_timeout 60s;

2.2.2 client_body_timeout

? 用于指定客戶端與服務(wù)端建立連接后發(fā)送 request body 的超時(shí)時(shí)間槽唾,如果客戶端在指定時(shí)間內(nèi)沒有發(fā)送一個(gè)完整的 request body,Nginx就會返回 HTTP 408(Request Timed Out)光涂。

# 配置段: http庞萍、server、location
client_body_timeout 20s;

2.2.3 client_header_timeout

? 客戶端向服務(wù)端發(fā)送一個(gè)完整的 request header 的超時(shí)時(shí)間忘闻,如果客戶端在指定時(shí)間內(nèi)沒有發(fā)送一個(gè)完整的 request header钝计,Nginx 返回 HTTP 408(Request Timed Out)

# 配置段: http齐佳、server私恬、location
client_header_timeout 10s;

2.2.4 proxy_upstream_fail_timeout

? fail_timeout通常是配合max_fails一起來使用的,實(shí)現(xiàn)熔斷隔離的功能炼吴。其作用主要是指在 30 秒內(nèi)請求某一應(yīng)用失敗 3 次本鸣,則認(rèn)為該應(yīng)用宕機(jī),之后會等待 30 秒硅蹦,這期間內(nèi)不會再把新請求發(fā)送到宕機(jī)應(yīng)用荣德,而是直接發(fā)到正常的那一臺。時(shí)間到后再有請求進(jìn)來童芹,則繼續(xù)嘗試連接宕機(jī)應(yīng)用且僅嘗試 1 次涮瞻,如果還是失敗,則繼續(xù)等待 30 秒…...以此循環(huán)假褪,直到恢復(fù)署咽。

# 配置段: upstream, fail_timeout默認(rèn)為10s, max_fails默認(rèn)為1
upstream  web_tomcat {
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
}

2.2.5 proxy_connect_timeout

? 用于設(shè)置Nginx向后端服務(wù)器的連接超時(shí)時(shí)間,即為發(fā)起TCP握手等候響應(yīng)的超時(shí)時(shí)間生音。

# 配置段: http宁否、server窒升、location, 默認(rèn)為60s
location / {
    proxy_connect_timeout 500s;
    proxy_pass http://web_tomcat;
 }

2.2.6 proxy_read_timeout

? 連接成功后,等候后端服務(wù)器響應(yīng)時(shí)間家淤,其實(shí)已經(jīng)進(jìn)入后端的排隊(duì)之中等候處理异剥,也可以說是后端服務(wù)器處理請求的 時(shí)間。

# 配置段: http絮重、server、location, 默認(rèn)為60s
location / {
    proxy_read_timeout 500s;
    proxy_pass http://web_tomcat;
 }

2.2.7 proxy_send_timeout

? 用于設(shè)置后端服務(wù)器數(shù)據(jù)回傳時(shí)間歹苦,就是在規(guī)定時(shí)間之內(nèi)后端服務(wù)器必須傳完所有的數(shù)據(jù)青伤。

# 配置段: http、server殴瘦、location, 默認(rèn)為60s
location / {
    proxy_send_timeout 500s;
    proxy_pass http://web_tomcat;
 }

2.2.8 Others

  • resolver_timeout:域名解析超時(shí)狠角,默認(rèn)30s。配置段:http蚪腋、server丰歌、location
  • lingering_timeout:設(shè)置TCP連接關(guān)閉時(shí)的SO_LINGER延時(shí),默認(rèn)為5s屉凯。配置段:http立帖、server、location
  • tcp_nodelay:默認(rèn)情況下悠砚,當(dāng)數(shù)據(jù)發(fā)送時(shí)晓勇,內(nèi)核并不會馬上發(fā)送,可能會等待更多的字節(jié)組成一個(gè)數(shù)據(jù)包灌旧,這樣可以提高 I/O 性能绑咱,但是在每次只發(fā)送很少字節(jié)的業(yè)務(wù)場景中,等待時(shí)間會比較長

注意事項(xiàng)

  • 客戶端連接Nginx超時(shí)枢泰,建議5s內(nèi)
  • proxy_connect_timeout的值不能超過75s
  • 通常client_body_timeout應(yīng)該比keepalive_timeout小

擴(kuò)展:tcp_nodelay與tcp_nopush

  • tcp_nodelay:開啟或關(guān)閉Nginx使用TCP_NODELAY選項(xiàng)的功能
  • tcp_nopush:開啟或者關(guān)閉Nginx在FreeBSD上使用TCP_NOPUSH套接字選項(xiàng)的功能
# tcp_nodelay配置段: http描融、server、location, 默認(rèn)值為 tcp_nodelay on;
# tcp_nopush配置段: http衡蚂、server窿克、location, 默認(rèn)值為 tcp_nopush off;
http {
    tcp_nodelay on;
}

2.3 Gateway Timeout

2.3.1 Zuul Timeout

  • 使用Ribbon路由
    Zuul的超時(shí)與Ribbon、Hystrix相關(guān)(RibbonRoutingFilter整合了Hystrix和Ribbon)讳窟,此時(shí)Zuul的超時(shí)可以配置如下:

    # Hystrix,設(shè)置調(diào)用者等待命令執(zhí)行的超時(shí)限制,超過此時(shí)間,HystrixCommand被標(biāo)記為TIMEOUT让歼,并執(zhí)行回退邏輯
    hystrix.command.xxx.execution.isolation.thread.timeoutInMilliseconds: 1000
    
    # Ribbon
    ribbon:
     read-timeout: 1000
     connect-timeout: 1000
    
  • 未使用Ribbo路由(SimpleHostRoutingFilter整合了Apache HttpClient)

    zuul.routes.xxx.path: /user/**
    zuul.routes.xxx.url: http://localhost:8000/
    # TCP連接超時(shí)時(shí)間
    zuul.host.connect-timeout-millis: 2000
    # Socket超時(shí),即數(shù)據(jù)傳輸?shù)某瑫r(shí)時(shí)間
    zuul.host.socket-timeout-millis: 10000
    

2.4 Middleware Timeout

2.4.1 Ribbon Timeout

全局配置:

ribbon:
    read-timeout: 60000
    connect-timeout: 60000

局部配置:

service-id:
    ribbon:
        read-timeout: 1000
        connect-timeout: 1000

2.4.2 Feign Timeout

? 從Spring Cloud Edgware開始,F(xiàn)eign支持使用屬性配置超時(shí)(對于老版本丽啡,可以寫個(gè)feign.Request.Options 即可):

feign.client.config:
    feign-name:
    connect-timeout: 5000
    read-timeout: 5000

2.4.3 RestTemplate Timeout

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    factory.setConnectTimeout(1000);
    factory.setReadTimeout(1000);
    return new RestTemplate(factory);
}

2.4.4 Hystrix Timeout

# 默認(rèn)開啟超時(shí)機(jī)制
hystrix.command.default|xxx.execution.timeout.enabled: true
# 是否打開超時(shí)線程中斷, Thread模式有效
hystrix.command.default|xxx.execution.isolation.thread.interruptOnTimeout: true
# 超時(shí)時(shí)間, 默認(rèn)為1秒:
# 1.在THREAD模式下,達(dá)到超時(shí)時(shí)間,可以中斷
# 2.在SEMAPHORE模式下,會等待執(zhí)行完成后,再去判斷是否超時(shí)
hystrix.command.default|xxx.execution.isolation.thread.timeoutInMilliseconds: 1000

2.4.5 Tomcat Timeout

? tomcat對每個(gè)請求的超時(shí)時(shí)間是通過connectionTimeout參數(shù)設(shè)置的谋右。默認(rèn)的server.xml里的設(shè)置是20秒,如果不設(shè)置這個(gè)參數(shù)代碼里會使用60秒补箍。這個(gè)參數(shù)也會對POST請求有影響改执,但并不是指上傳完的時(shí)間限制啸蜜,而是指兩次數(shù)據(jù)發(fā)送中間的間隔超過connectionTimeout會被服務(wù)器斷開。

<Connector port="7001" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

? 如果connectionTimeout配置為20000辈挂,這個(gè)配置導(dǎo)致建立一個(gè)socket連接后衬横,如果一直沒有收到客戶端的FIN,也沒有數(shù)據(jù)過來终蒂,那么此連接也必須等到20s后蜂林,才能被超時(shí)釋放。

2.4.6 Dubbo Timeout

? Dubbo協(xié)議超時(shí)實(shí)現(xiàn)使用了Future模式拇泣。ResponseFuture.get()在請求還未處理完或未到超時(shí)前一直是wait狀態(tài)噪叙;響應(yīng)達(dá)到后,設(shè)置請求狀態(tài)霉翔,并進(jìn)行notify喚醒睁蕾。即使用了Object的 await-notify-notifyAll 機(jī)制。

Dubbo Architecture

Dubbo消費(fèi)端

  • 全局超時(shí)配置
    <dubbo:consumer timeout="5000" />
    
  • 指定接口以及特定方法超時(shí)配置
    <dubbo:reference interface="com.foo.BarService" timeout="2000">
        <dubbo:method name="sayHello" timeout="3000" />
    </dubbo:reference>
    

Dubbo服務(wù)端

  • 全局超時(shí)配置
    <dubbo:provider timeout="5000" />
    
  • 指定接口以及特定方法超時(shí)配置
    <dubbo:provider interface="com.foo.BarService" timeout="2000">
        <dubbo:method name="sayHello" timeout="3000" />
    </dubbo:provider>
    

2.5 DB Timeout

以下是應(yīng)用(WAS/BLOC)债朵、連接池(DBCP)子眶、Timeout層級和DBMS直接的關(guān)系圖:


應(yīng)用&數(shù)據(jù)庫間 — Timeout架構(gòu)

解釋說明

  • statement timeout無法處理網(wǎng)絡(luò)連接失敗時(shí)的超時(shí),它能做的僅僅是限制statement的操作時(shí)間
  • 網(wǎng)絡(luò)連接失敗時(shí)的timeout必須交由JDBC來處理
  • JDBC的socket timeout會受到操作系統(tǒng)socket timeout設(shè)置的影響
  • timeout層級與DBCP是相互獨(dú)立序芦,DBCP負(fù)責(zé)的是數(shù)據(jù)庫連接的創(chuàng)建和管理臭杰,并不干涉timeout的處理
  • 在應(yīng)用中調(diào)用DBCP的getConnection()時(shí),你可以設(shè)置獲取數(shù)據(jù)庫連接的超時(shí)時(shí)間芝加,但是這和JDBC的timeout無關(guān)

案例:JDBC連接會在網(wǎng)絡(luò)出錯(cuò)后阻塞30分鐘硅卢,然后又奇跡般恢復(fù),即使并沒有對JDBC的socket timeout進(jìn)行設(shè)置

2.5.1 Transaction Timeout

? 一般存在于框架或應(yīng)用級藏杖,用于設(shè)置是一個(gè)事務(wù)的執(zhí)行總時(shí)間将塑,其中可能包含多個(gè)statement。在Spring中可以使用XML或在源碼中使用@Transactional注解來進(jìn)行設(shè)置蝌麸。

  • 1個(gè)statement ~ 0.1s点寥,10w個(gè)statement ~ 1w秒(約7個(gè)小時(shí))
  • 1個(gè)statement × 1個(gè)statement執(zhí)行200ms,則transaction timeout至少應(yīng)該設(shè)置為:1100ms(200×5+100)

2.5.2 Statement Timeout

? 用于設(shè)置單個(gè)statement的執(zhí)行超時(shí)時(shí)間来吩,即Driver等待statement執(zhí)行完成敢辩,接收到數(shù)據(jù)的超時(shí)時(shí)間。timeout的值通過調(diào)用JDBC的java.sql.Statement.setQueryTimeout(int timeout) API進(jìn)行設(shè)置弟疆,但更多的是是通過框架來進(jìn)行設(shè)置戚长。

注意

  • statement timeout的具體值需要依據(jù)應(yīng)用本身的特性而定,并沒有可供推薦的配置
  • statement的timeout不是整個(gè)查詢的timeout怠苔,只是statement執(zhí)行完成并拉取數(shù)據(jù)返回的超時(shí)時(shí)間

MySQL JDBC Statement的QueryTimeout處理過程

MySQL JDBC Statement的QueryTimeout處理過程

解釋說明

  • statement創(chuàng)建一個(gè)新的timeout-execution線程用于超時(shí)處理同廉,5.1版本后改為每個(gè)connection分配一個(gè)timeout-execution線程
  • 達(dá)到超時(shí)時(shí)間,TimerThread調(diào)用JtdsStatement實(shí)例中的TsdCore.cancel()方法,timeout-execution線程創(chuàng)建一個(gè)和statement配置相同的connection迫肖,向超時(shí)query發(fā)送:cancel query(KILL QUERY “connectionId”)

2.5.3 JDBC socket timeout

? 用于設(shè)置jdbc I/O socket read and write operations的超時(shí)時(shí)間锅劝,防止因網(wǎng)絡(luò)問題或數(shù)據(jù)庫問題,導(dǎo)致Driver會一直阻塞等待蟆湖。(建議比statement timeout的時(shí)間長)

  • mysql(單位為毫秒)

    jdbc:mysql://localhost:3306/ag_admin?useUnicode=true&characterEncoding=UTF8&connectTimeout=60000&socketTimeout=60000
    
  • pg(單位為秒)

    jdbc:postgresql://localhost/test?user=fred&password=secret&&connectTimeout=60&socketTimeout=60
    
  • oracle
    ? oracle需要通過oracle.jdbc.ReadTimeout參數(shù)來設(shè)置故爵,連接超時(shí)參數(shù)是oracle.net.CONNECT_TIMEOUT∮缃颍可以通過以下兩種方式進(jìn)行設(shè)置:

    通過properties設(shè)置

    Class.forName("oracle.jdbc.driver.OracleDriver");
    Properties props = new Properties() ;
    props.put( "user" , "test_schema") ;
    props.put( "password" , "pwd") ;
    props.put( "oracle.net.CONNECT_TIMEOUT" , "10000000") ;
    props.put( "oracle.jdbc.ReadTimeout" , "2000" ) ;
    Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@127.0.0.1:1521:orcl" , props ) ;
    

    通過環(huán)境變量設(shè)置 —— 注意需要在connection連接之前設(shè)置環(huán)境變量

    String readTimeout = "10000"; // ms
    System.setProperty("oracle.jdbc.ReadTimeout", readTimeout);
    Class.forName("oracle.jdbc.OracleDriver");
    Connection conn = DriverManager.getConnection(jdbcUrl, user, pwd);
    

2.5.4 OS socket timeout

? 這是操作系統(tǒng)級別的socket設(shè)置诬垂,用來檢測壞死socket連接,Linux一般默認(rèn)2小時(shí)饥瓷。如果jdbc socket timeout沒有設(shè)置剥纷,而OS級別的socket timeout有設(shè)置,則使用系統(tǒng)的socket timeout值呢铆。

# 查看OS的keepalive配置信息
sudo sysctl -a|grep keepalive

# 修改OS的keepalive配置信息,并修改以下配置信息
vim /etc/sysctl.conf

# 表示TCP連接在多少秒之后沒有數(shù)據(jù)報(bào)文傳輸時(shí)啟動(dòng)探測報(bào)文(發(fā)送空的報(bào)文),單位為秒(s)
net.ipv4.tcp_keepalive_time = 7200
# 表示前一個(gè)探測報(bào)文和后一個(gè)探測報(bào)文之間的時(shí)間間隔,單位為秒(s)
net.ipv4.tcp_keepalive_intvl = 75
# 表示探測的次數(shù)
net.ipv4.tcp_keepalive_probes = 9

# 讓修改的參數(shù)即時(shí)生效
sysctl -p

總結(jié)
? jdbc的socketTimeout值的設(shè)置要非常小心,不同數(shù)據(jù)庫的jdbc driver設(shè)置不一樣蹲缠,特別是使用不同連接池的話棺克,設(shè)置也可能不盡相同。對于嚴(yán)重依賴數(shù)據(jù)庫操作的服務(wù)來說线定,非常有必要設(shè)置這個(gè)值娜谊,否則萬一網(wǎng)絡(luò)或數(shù)據(jù)庫異常,會導(dǎo)致服務(wù)線程一直阻塞在java.net.SocketInputStream.socketRead0斤讥。

  • 如果查詢數(shù)據(jù)多纱皆,則會導(dǎo)致該線程持有的data list不能釋放,相當(dāng)于內(nèi)存泄露芭商,最后導(dǎo)致OOM
  • 如果請求數(shù)據(jù)庫操作很多且阻塞住了派草,會導(dǎo)致服務(wù)器可用的woker線程變少,嚴(yán)重則會導(dǎo)致服務(wù)不可用

3 Practice

3.1 Focus

各層組件的超時(shí)時(shí)間铛楣,主要是設(shè)置以下兩個(gè)參數(shù):

  • connectTimeout
  • socketTimeout

當(dāng)然針對特殊的場景近迁,則可以設(shè)置更詳細(xì)的超時(shí)參數(shù),如:

  • readTimeout
  • writeTimeout

3.2 Suggest

ajax —— 5s ~ 60s

  • 建議全局設(shè)置一個(gè)統(tǒng)一的超時(shí)時(shí)間簸州,如60s
    • 從使用的互聯(lián)網(wǎng)產(chǎn)品來看鉴竭,一般網(wǎng)絡(luò)較差時(shí),加載網(wǎng)頁可能需要等待30秒或1分鐘左右后才出現(xiàn)網(wǎng)絡(luò)異常等的情況
  • 特殊場景自定義設(shè)置超時(shí)時(shí)間岸浑,從而覆蓋全局超時(shí)時(shí)間
    • 如上傳較大文件時(shí)搏存,則可以設(shè)置時(shí)間更長(當(dāng)然太大的文件,則建議單獨(dú)考慮矢洲,如分塊處理等)
    • 如實(shí)時(shí)性要求較高的場景璧眠,則可以設(shè)置更短,如5s等

Ngixn

  • 建議設(shè)置 keepalived_time 來提高Ngixn支持的并發(fā)能力與復(fù)用HTTP建立的TCP連接,如設(shè)置為5s
  • 建議設(shè)置 client_body_timeoutclient_header_timeout蛆橡,用于防止客戶攻擊Dos攻擊舌界,如分別20s、10s
  • 建議設(shè)置 max_failsfail_timeout 泰演,解決每次請求宕機(jī)服務(wù)端時(shí)呻拌,都需要等待超時(shí)問題,如分別為3次睦焕、30s
  • 建議設(shè)置 proxy_connect_timeout藐握、proxy_send_timeoutproxy_read_timeout 參數(shù),用于控制Ngixn轉(zhuǎn)發(fā)到后臺的超時(shí)控制

Node
使用Node作為網(wǎng)關(guān)代理轉(zhuǎn)發(fā)請求時(shí):

  • Server —— 60s
    • 如果代理層有一定的功能邏輯垃喊,則建議加上Server的處理超時(shí)時(shí)間
    • 如果代理層幾乎沒有邏輯猾普,則Server層的超時(shí)可以不配置
  • Client
    Client用于代理轉(zhuǎn)發(fā),而后端業(yè)務(wù)場景不同本谜,要求也有所不同初家,所以建議設(shè)置較長的默認(rèn)值,并支持請求自定義

Middleware
Ribbon乌助、Zuul(Apache HTTPClient)溜在、Feign、RestTemplate和Netty等他托,都建議必須設(shè)置以下兩個(gè)參數(shù):

  • connectTimeout
  • socketTimeout

Hystrix
使用Hystrix時(shí)掖肋,建議設(shè)置提交線程后的等待超時(shí)時(shí)間:thread.timeoutInMilliseconds ,默認(rèn)為1000ms

DB

  • Transaction Timeout
  • connectTimeout
  • socketTimeout
  • OS socket timeout

3.3 Timeout Architecture

微服務(wù)超時(shí)架構(gòu)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赏参,一起剝皮案震驚了整個(gè)濱河市志笼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌把篓,老刑警劉巖纫溃,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異纸俭,居然都是意外死亡皇耗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門揍很,熙熙樓的掌柜王于貴愁眉苦臉地迎上來郎楼,“玉大人,你說我怎么就攤上這事窒悔∥卦” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵简珠,是天一觀的道長阶界。 經(jīng)常有香客問我虹钮,道長,這世上最難降的妖魔是什么膘融? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任芙粱,我火速辦了婚禮,結(jié)果婚禮上氧映,老公的妹妹穿的比我還像新娘春畔。我一直安慰自己,他們只是感情好岛都,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布律姨。 她就那樣靜靜地躺著,像睡著了一般臼疫。 火紅的嫁衣襯著肌膚如雪择份。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天烫堤,我揣著相機(jī)與錄音荣赶,去河邊找鬼。 笑死鸽斟,一個(gè)胖子當(dāng)著我的面吹牛讯壶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播湾盗,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼立轧!你這毒婦竟也來了格粪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤氛改,失蹤者是張志新(化名)和其女友劉穎帐萎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胜卤,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疆导,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了葛躏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片澈段。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖舰攒,靈堂內(nèi)的尸體忽然破棺而出败富,到底是詐尸還是另有隱情,我是刑警寧澤摩窃,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布兽叮,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鹦聪。R本人自食惡果不足惜账阻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泽本。 院中可真熱鬧淘太,春花似錦、人聲如沸观挎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘁捷。三九已至造成,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雄嚣,已是汗流浹背晒屎。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缓升,地道東北人鼓鲁。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像港谊,于是被迫代替她去往敵國和親骇吭。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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