SpringCloud-Eureka服務注冊與發(fā)現(xiàn)組件

Eureka和Zookeeper很類似,它是SpringCloud框架中的服務注冊及發(fā)現(xiàn)組件找筝。所有的微服務在使用過程中會向Eureka進行注冊,而后客戶端利用Eureka獲取服務的信息(即服務的發(fā)現(xiàn))究流。雖然SpringCloud支持Zookeeper予跌,不過官方并不建議使用Zookeeper,而是推薦使用Eureka蒿叠。

為什么要使用Eureka

對于這個問題其實可以引申為:在RPC框架或服務治理框架中明垢,為什么要使用服務發(fā)現(xiàn)組件?
在沒有使用服務注冊和發(fā)現(xiàn)組件情況中市咽,客戶端如果想要調用服務存在以下缺點

  1. 需要記錄大量的真實服務地址痊银;
  2. 客戶端需要實現(xiàn)負載;
  3. 無法確認某一服務是否可用施绎;

而服務注冊和發(fā)現(xiàn)組件可以幫助客戶端解決這些問題溯革。


Eureka服務注冊和發(fā)現(xiàn)

創(chuàng)建Eureka服務

和Zookeeper提供了單獨的安裝包不同,目前還沒發(fā)現(xiàn)Eureka官方提供單獨的安裝包來運行谷醉。我們可以將Eureka的依賴引入單獨的工程中致稀,然后部署運行該工程即可將Eureka的服務啟動起來。另外Eureka即能創(chuàng)建單機版又能創(chuàng)建集群版俱尼,下面分別介紹一下單機版Eureka和集群版Eureka如何搭建抖单。

搭建單機版Eureka

  1. 引入相關依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- SpringCloud是基于SpringBoot的,所以要引入SpringBoot的依賴 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 在配置文件中加入Eureka相關的配置
server:
  port: 7001

eureka:
  instance: # eureak實例定義
    hostname: 127.0.0.1 # 定義Eureka實例所在的主機名稱
  1. 在啟動類中加入@EnableEurekaServer注解
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer   // 啟動Eureka服務
public class Eureka_7001_StartSpringCloudApplication {
    public static void main(String[] args) {
        SpringApplication.run(Eureka_7001_StartSpringCloudApplication.class,args);
    }
}
  1. 啟動應用遇八,打開瀏覽器訪問http://127.0.0.1:7001/


    Eureka控臺

    此時可以看到Eureka已經(jīng)啟動矛绘,但是此時如果觀察后臺會發(fā)現(xiàn)有如下ERROR日志

2018-05-24 21:25:52.500 ERROR 10360 --- [tbeatExecutor-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_UNKNOWN/localhost:7001 - was unable to send heartbeat!

com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
    at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:111) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$3.execute(EurekaHttpClientDecorator.java:92) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.sendHeartBeat(EurekaHttpClientDecorator.java:89) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.DiscoveryClient.renew(DiscoveryClient.java:815) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.DiscoveryClient$HeartbeatThread.run(DiscoveryClient.java:1379) [eureka-client-1.6.2.jar:1.6.2]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_79]
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_79]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_79]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_79]
    at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]

2018-05-24 21:25:53.890  INFO 10360 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_UNKNOWN/localhost:7001: registering service...
2018-05-24 21:25:55.903 ERROR 10360 --- [nfoReplicator-0] c.n.d.s.t.d.RedirectingEurekaHttpClient  : Request execution error

com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
    at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:187) ~[jersey-apache-client4-1.19.1.jar:1.19.1]
    at com.sun.jersey.api.client.filter.GZIPContentEncodingFilter.handle(GZIPContentEncodingFilter.java:123) ~[jersey-client-1.19.1.jar:1.19.1]
    at com.netflix.discovery.EurekaIdentityHeaderFilter.handle(EurekaIdentityHeaderFilter.java:27) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.sun.jersey.api.client.Client.handle(Client.java:652) ~[jersey-client-1.19.1.jar:1.19.1]
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682) ~[jersey-client-1.19.1.jar:1.19.1]
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) ~[jersey-client-1.19.1.jar:1.19.1]
    at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:570) ~[jersey-client-1.19.1.jar:1.19.1]
    at com.netflix.discovery.shared.transport.jersey.AbstractJerseyEurekaHttpClient.register(AbstractJerseyEurekaHttpClient.java:56) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.MetricsCollectingEurekaHttpClient.execute(MetricsCollectingEurekaHttpClient.java:73) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.executeOnNewServer(RedirectingEurekaHttpClient.java:118) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.RedirectingEurekaHttpClient.execute(RedirectingEurekaHttpClient.java:79) ~[eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:119) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$1.execute(EurekaHttpClientDecorator.java:59) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.register(EurekaHttpClientDecorator.java:56) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.DiscoveryClient.register(DiscoveryClient.java:798) [eureka-client-1.6.2.jar:1.6.2]
    at com.netflix.discovery.InstanceInfoReplicator.run(InstanceInfoReplicator.java:104) [eureka-client-1.6.2.jar:1.6.2]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_79]
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_79]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) [na:1.7.0_79]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292) [na:1.7.0_79]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_79]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_79]
    at java.lang.Thread.run(Thread.java:745) [na:1.7.0_79]
Caused by: java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[na:1.7.0_79]
    at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) ~[na:1.7.0_79]
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) ~[na:1.7.0_79]
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) ~[na:1.7.0_79]
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) ~[na:1.7.0_79]
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) ~[na:1.7.0_79]
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.7.0_79]
    at java.net.Socket.connect(Socket.java:579) ~[na:1.7.0_79]
    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121) ~[httpclient-4.5.3.jar:4.5.3]
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180) ~[httpclient-4.5.3.jar:4.5.3]
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144) ~[httpclient-4.5.3.jar:4.5.3]
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:134) ~[httpclient-4.5.3.jar:4.5.3]
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610) ~[httpclient-4.5.3.jar:4.5.3]
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445) ~[httpclient-4.5.3.jar:4.5.3]
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835) ~[httpclient-4.5.3.jar:4.5.3]
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:118) ~[httpclient-4.5.3.jar:4.5.3]
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) ~[httpclient-4.5.3.jar:4.5.3]
    at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:173) ~[jersey-apache-client4-1.19.1.jar:1.19.1]
    ... 29 common frames omitted
  1. 去除Error日志
    當然你可以忽略該錯誤日志,繼續(xù)使用Eureka刃永。但是作為有潔癖的程序員看到報錯信息當然是無法忍受的货矮,那么如何干掉這些錯誤日志中,我們需要將配置文件改成如下內容即可
server:
  port: 7001

eureka:
  client: # 客戶端進行Eureka注冊的配置
    service-url:
      defaultZone: http://127.0.0.1:7001/eureka
    register-with-eureka: false    # 當前的微服務不注冊到eureka之中
    fetch-registry: false     # 不通過eureka獲取注冊信息
  instance: # eureak實例定義
    hostname: 127.0.0.1 # 定義Eureka實例所在的主機名稱

搭建集群版Eureka

在實際應用中斯够,任何服務都不會選擇單實例部署囚玫,因為存在單點故障問題喧锦,線上的服務要想高可用必須要搭建集群。在Eureka當中抓督,任何服務都可以作為服務提供者去Eureka進行注冊裸违,這當然包括Eureka服務端本身。Eureka集群的搭建正是利用了這個特性本昏。


Eureka集群示意圖
  • Eureka-server-1做為服務提供者向Eureka-server-2和Eureka-server-3中進行注冊供汛;
  • Eureka-server-2做為服務提供者向Eureka-server-1和Eureka-server-3中進行注冊;
  • Eureka-server-3做為服務提供者向Eureka-server-1和Eureka-server-2中進行注冊涌穆;

我們用3個節(jié)點搭建集群怔昨,這3個節(jié)點的內容除配置文件之外其余的都和單機版相同。下面我們來看看這3個節(jié)點的具體配置宿稀。
Eureka-server-1節(jié)點的配置

server:
  port: 7001
eureka:
  #server:
  client: # 客戶端進行Eureka注冊的配置
    service-url:
      defaultZone: http://eureka-7002.com:7002/eureka,http://eureka-7003.com:7003/eureka
    register-with-eureka: false    # 當前的微服務不注冊到eureka之中
    fetch-registry: false     # 不通過eureka獲取注冊信息
  instance: # eureak實例定義
    hostname: eureka-7001.com  # 定義Eureka實例所在的主機名稱
spring:
  application:
    name: eureka-7001.com

Eureka-server-2節(jié)點的配置

server:
  port: 7002

eureka:
  client: # 客戶端進行Eureka注冊的配置
      service-url:
        defaultZone: http://eureka-7001.com:7001/eureka,http://eureka-7003.com:7003/eureka
      register-with-eureka: false    # 當前的微服務不注冊到eureka之中
      fetch-registry: false     # 不通過eureka獲取注冊信息
  instance:
    hostname: eureka-7002.com
spring:
  application:
    name: eureka-7002.com

Eureka-server-3節(jié)點的配置

server:
  port: 7003
eureka:
  client:
    defalutZone: http://eureka-7001.com:7001/eureka,http://eureka-7002.com:7002/eureka
    register-with-eureka: false
    fetch-registry: false
  instance:
    hostname: eureka-7003.com
spring:
  application:
    name: eureka-7003.com

啟動3個節(jié)點的Eureka服務趁舀,登錄http://eureka-7001.com:7001/查看7001的Eureka控臺,在集群信息中可以看到集群中的另外兩個節(jié)點信息祝沸。

eureka-7001.com:7001

Eureka服務詳解

Eureka可以分為Eureka服務端和Eureka客戶端矮烹,Eureka服務端即服務注冊中心,Eureka客戶端包含兩個角色:服務提供者和服務消費者罩锐。Eureka的主要功能是服務治理


圖片源自《SpringCloud微服務實戰(zhàn)》

服務提供者的功能

  • 注冊服務
  • 續(xù)約
  • 服務下線通知

服務消費者的功能

  • 獲取服務列表
  • 調用服務

服務注冊中心的功能

  • 服務提供者信息同步
  • 失效剔除
  • 自我保護

這里我們先重點看看服務注冊中心的功能奉狈。

自我保護

在Eureka的控臺中,我們可能會經(jīng)成螅看到以下信息仁期,該信息表明Eureka的自我保護機制被觸發(fā)了。
觸發(fā)了Eureka自我保護的提示信息

默認情況下竭恬,如果Eureka Server在一定時間內沒有接收到某個微服務實例的心跳跛蛋,Eureka Server將會注銷該實例(默認90秒)。但是當網(wǎng)絡分區(qū)故障發(fā)生時痊硕,微服務與Eureka Server之間無法正常通信赊级,以上行為可能變得非常危險了——因為微服務本身其實是健康的,此時本不應該注銷這個微服務岔绸。

Eureka通過“自我保護模式”來解決這個問題——當Eureka Server節(jié)點在短時間內丟失過多客戶端時(可能發(fā)生了網(wǎng)絡分區(qū)故障)理逊,那么這個節(jié)點就會進入自我保護模式。一旦進入該模式亭螟,Eureka Server就會保護服務注冊表中的信息挡鞍,不再刪除服務注冊表中的數(shù)據(jù)(也就是不會注銷任何微服務)骑歹。當網(wǎng)絡故障恢復后预烙,該Eureka Server節(jié)點會自動退出自我保護模式。

可以通過eureka: server:enable-self-preservation: false將自我保護機制關閉道媚,但一般不建議將其關閉扁掸。

失效剔除

正常下線時翘县,服務提供者會發(fā)送下線通知給注冊中心,注冊中心能正常處理這種情況谴分。如果服務非正常下線的話锈麸,注冊中心又該如何處理呢?Eureka Server在啟動的時候會創(chuàng)建一個定時任務每分鐘掃描一篇服務清單牺蹄,如果發(fā)現(xiàn)有服務超過90秒沒有發(fā)送過心跳就將該服務信息剔除出去忘伞。

服務信息同步

當服務提供者將自己的信息注冊給某個注冊中心,該注冊中心就會將此服務信息同步到集群中的其他注冊中心上沙兰,從而實現(xiàn)注冊中心間的服務同步氓奈。

服務提供者

我們知道服務提供者有三個主要功能

  • 注冊服務
  • 續(xù)約
  • 服務下線通知

注冊服務

  1. 引入相關依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
  1. 在application.yml文件中對Eureka客戶端進行配置
eureka:
 client: # 客戶端進行Eureka注冊的配置
   service-url:
     defaultZone: http://127.0.0.1:7001/eureka
  1. 在啟動類上追加Eureka客戶端啟用的注解@EnableEurekaClient
@SpringBootApplication
@EnableEurekaClient
public class Dept_8001_StartSpringCloudApplication {
    public static void main(String[] args) {
        SpringApplication.run(Dept_8001_StartSpringCloudApplication.class, args);
    }
}
  1. 啟動服務提供者,由于加入了@EnableEurekaClient注解及配置了Eureka服務的連接地址鼎天,所以會自動向Eureka注冊中心進行服務的注冊舀奶。此時訪問Eureka的控臺,可以看到以下信息
    注冊的服務

    最左側的Application表示服務的標記符斋射,服務的調用方正是通過該標識符對服務發(fā)起調用育勺。此時它的值為UNKNOWN這顯然不符合我們的要求,該值的內容取自application.yml文件中的spring.application.name罗岖,所以我們可以通過設置spring.application.name對其進行修改涧至。最右邊UP表示當前服務是活著的(DOWN表示服務不可用),UP邊上有個超鏈接桑包,點擊這個鏈接我們可以看到該服務提供者的詳細信息化借。這個詳細信息是在服務提供者的配置文件中進行配置的。
  2. 配置詳細的服務信息
server:
  port: 8001

eureka:
  client:
    service-url:
      defaultZone: http://eureka-7001.com:7001/eureka
  instance:
    instance-id: dept-8001.com    # 在信息列表時顯示主機名稱
    prefer-ip-address: true      # 訪問的路徑變?yōu)?IP 地址

info:
  app.name: spring-cloud-demo
  company.name: zgc
  build.artifactId: $project.artifactId$
  build.version: $project.verson$

如果現(xiàn)在要想查看所有的微服務詳細信息捡多,還需要修改 pom.xml 文件蓖康,追加監(jiān)控配置:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot- starter-actuator</artifactId>
</dependency>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven- resources-plugin</artifactId>
  <configuration>
    <delimiters>
      <delimiter>$</delimiter>
    </delimiters>
  </configuration>
</plugin>

此時再點擊查看服務詳情的info信息,可以看到如下信息


續(xù)約

服務注冊完之后垒手,服務提供者和Eureka注冊中心之間會維持心跳來告知注冊中心蒜焊,服務還活著。我們把該操作稱為服務續(xù)約(Renew)科贬,下列兩個配置和續(xù)約有關

eureka:
  instance:
    lease-renewal-interval-in-seconds: 30     #每30秒會向Eureka Server發(fā)起Renew操作
    lease-expiration-duration-in-seconds: 90  #服務失效時間泳梆。默認是90秒,也就是如果Eureka Server在90秒內沒有接收到來自Service Provider的Renew操作榜掌,就會把Service Provider剔除优妙。

服務下線

當服務提供者進行正常的關閉操作時,會觸發(fā)一個服務下線的REST請求給Eureka注冊中心憎账。Eureka服務端在收到請求之后套硼,將該服務狀態(tài)設置為下線(DOWN),并把該線下通知廣播出去。

服務消費者

服務消費者的主要功能

  • 獲取服務列表
  • 調用服務

服務發(fā)現(xiàn)

服務發(fā)現(xiàn)不僅能應用在服務消費者中還能應用在服務提供者中胞皱。

  1. 在Eureka的客戶端程序中注入DiscoveryClient類邪意,借助該類可以幫助我們自動獲取服務的列表信息
    @Autowired
    private DiscoveryClient client ;    // 進行Eureka的發(fā)現(xiàn)服務
    @RequestMapping("/discover")
    public Object discover() {  // 直接返回發(fā)現(xiàn)服務信息
        return this.client ;
    }
  1. 在啟動類中加入@EnableDiscoveryClient注解九妈。(貌似不加入也能夠生效)

調用服務

服務消費者通過服務標識符獲取具體的服務提供者信息,由服務消費者自己決定具體調用哪個服務提供者雾鬼。所以服務消費者通常要維護負載均衡算法萌朱,在SpringCloud中提供了Ribbon組件進行客戶端的負載調度。

參考連接
Eureka 客戶端和服務端間的交互

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末策菜,一起剝皮案震驚了整個濱河市晶疼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌又憨,老刑警劉巖冒晰,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異竟块,居然都是意外死亡壶运,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門浪秘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒋情,“玉大人,你說我怎么就攤上這事耸携】醚ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵夺衍,是天一觀的道長狈谊。 經(jīng)常有香客問我,道長沟沙,這世上最難降的妖魔是什么河劝? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮矛紫,結果婚禮上赎瞎,老公的妹妹穿的比我還像新娘。我一直安慰自己颊咬,他們只是感情好务甥,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著喳篇,像睡著了一般敞临。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上麸澜,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天挺尿,我揣著相機與錄音,去河邊找鬼。 笑死票髓,一個胖子當著我的面吹牛,可吹牛的內容都是我干的铣耘。 我是一名探鬼主播洽沟,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蜗细!你這毒婦竟也來了裆操?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤炉媒,失蹤者是張志新(化名)和其女友劉穎踪区,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吊骤,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡缎岗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了白粉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片传泊。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鸭巴,靈堂內的尸體忽然破棺而出眷细,到底是詐尸還是另有隱情,我是刑警寧澤鹃祖,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布溪椎,位于F島的核電站,受9級特大地震影響恬口,放射性物質發(fā)生泄漏校读。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一祖能、第九天 我趴在偏房一處隱蔽的房頂上張望地熄。 院中可真熱鬧,春花似錦芯杀、人聲如沸端考。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽却特。三九已至,卻和暖如春筛圆,著一層夾襖步出監(jiān)牢的瞬間裂明,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工太援, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留闽晦,地道東北人扳碍。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像仙蛉,于是被迫代替她去往敵國和親笋敞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內容