Nacos 入门学习指南

Nacos 是什么?

https://nacos.io/zh-cn/docs/what-is-nacos.html

  • 本文基于: Nacos 1.4.0

  • 官方介绍

    Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

    Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

  • 核心特点: 既可以是注册中心也可以是配置中心

  • 服务是一等公民

    • 服务(Service)是 Nacos 世界的一等公民。Nacos 支持几乎所有主流类型的“服务”的发现、配置和管理:

      • Kubernetes Service

      • gRPC & Dubbo RPC Service

      • Spring Cloud RESTful Service

  • Nacos 的关键特性包括:

    • 服务发现

      • 默认支持服务健康监测
      • Nacos 支持基于 DNS 和基于 RPC 的服务发现
    • 配置中心

      • 默认支持动态配置刷新功能,无需额外配置

        • 在Nacos控制台修改了配置后,点击发布时,会自动通知Nacos客户端更新本地缓存的配置文件。如果客户端的某个变量值就来自配置文件那么可以结合 @RefreshScope 注解实现变量值的更新。
      • 动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。

      • 动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。

      • 配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。

      • Nacos 提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。

      • Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助您更安全地在生产环境中管理配置变更和降低配置变更带来的风险。

        • NACOS server 会记录配置文件的历史版本,保留30天,同时还贴心的提供了一键回滚功能,回滚操作将会触发配置更新。
      • 配置快照(本地)

        Nacos 的客户端 SDK 会在本地生成配置的快照。当客户端无法连接到 Nacos Server 时,可以使用配置快照显示系统的整体容灾能力。

    • 动态 DNS 服务

      动态 DNS 服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以 DNS 协议为基础的服务发现,以帮助您消除耦合到厂商私有服务发现 API 上的风险。

      Nacos 提供了一些简单的 DNS APIs TODO 帮助您管理服务的关联域名和可用的 IP:PORT 列表.

    • 服务及其元数据管理

      Nacos 能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。

  • Nacos 地图

    https://nacos.io/img/nacosMap.jpg

  • Nacos 概念

    https://nacos.io/zh-cn/docs/concepts.html

  • Nacos 架构

    https://nacos.io/zh-cn/docs/architecture.html

怎么用?

2.1 快速开始 - 安装 Nacos Server

https://nacos.io/zh-cn/docs/quick-start.html

下载源码或者安装包

你可以通过源码和发行包两种方式来获取 Nacos。

  • 从 Github 上下载源码方式

    git clone https://github.com/alibaba/nacos.git
    cd nacos/
    mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U
    ls -al distribution/target/

    // change the version to your actual path cd distribution/target/nacos-server-version/nacos/bin

  • 下载编译后的压缩包方式

    • 您可以从 最新稳定版本 下载 nacos-server-$version.zip 包。

      unzip nacos-server-version.zip 或者 tar -xvf nacos-server-version.tar.gz
      cd nacos/bin

    • 解压后可以发现,其实是个 SpringBoot 工程

启动服务器

  • Linux/Unix/Mac
    启动命令(standalone代表着单机模式运行,非集群模式):

    sh startup.sh -m standalone

  • 如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行:

    bash startup.sh -m standalone

  • Windows

    启动命令:

    cmd startup.cmd

    或者双击startup.cmd运行文件。

启动后可以在日志文件后看到

:   |   \ | :  ,--.--.     ,---.  /   /   | /  /    '   Pid: 2423
|   : '  '; | /       \   /     \.   ; ,. :|  :  /`./   Console: http://169.254.212.54:8848/nacos/index.html
'   ' ;.    ;.--.  .-. | /    / ''   | |: :|  :  ;_
|   | | \   | \__\/: . ..    ' / '   | .; : \  \    `.      https://nacos.io
'   : |  ; .' ," .--.; |'   ; :__|   :    |  `----.   \
|   | '`--'  /  /  ,.  |'   | '.'|\   \  /  /  /`--'  /
'   : |     ;  :   .'   \   :    : `----'  '--'.     /
;   |.'     |  ,     .-./\   \  /            `--'---'


* 默认用户名密码: nacos/nacos
  • Tips:

    1. 如果想修改JVM参数,那么直接修改 startup.sh 文件即可。
    2. 如果想修改 Nacos 的端口: 安装目录: /nacos/conf/application.properties 文件中修改即可

进入控制台

  • Nacos有几个基础概念,我们只有先了解清楚之后才能更好的结合到业务场景:

    • namespace 命名空间

    • Group 配置分组

    • DataID 具体的配置文件名称,例如: application-dev.yml

    • 一般我们使用namespace来区分不同的项目或环境。

    • 不同的 namespace 或者不同的 Group 之间的配置与服务都是隔离的

    • Group 区分配置的差异系比如A业务获取的配置和B团队的有一些细微的差别可以通过Group来区分。

      • 配置分组,建议填写产品名:模块名(Nacos:Test)保证唯一性,只允许英文字符和4种特殊字符("."、":"、"-"、"_"),不超过128字节。

      • 需要在客户端的bootstrap.properties来添加分组信息才能取到非默认组的文件

    • 最后使用DataId来区分具体的配置文件。

    • 一个 DataID 就对应一个配置文件。

  • 如果需要使用 Nacos 的配置中心功能

    1. 首先新建一个命名空间 - 不创建则会使用默认的命名空间(public)

      • 比如: 先创建一个 sms-dev 表示短信平台项目 Dev 环境

      • 目前一个命名空间下最多可以配置 200 个配置文件。

    2. 在配置管理页面新建一个配置

      * DataID :  sms-api-service-dev.yaml
      
      * Group  :        DEFAULT_GROUP
      
      * 配置格式:        YAML
      
      * 配置内容:        user.name: sms-api-service-dev-yaml
                        user.age: 68
      
      • 注意:注意dataid是以 properties(默认的文件扩展名方式)为扩展名。如果要使用 yml 或者 yaml

        • 在应用的 bootstrap.properties 配置文件中显示的声明 dataid 文件扩展名。如下所示

          • bootstrap.properties

            spring.cloud.nacos.config.file-extension=yaml

      • 注意: 如果不使用 DEFAULT_GROUP , 则需要在客户端的bootstrap.properties来添加分组信息才能取到非默认组的文件

        spring.cloud.nacos.config.group=myGroup1
        
      • 新建完成后,也有对应的JAVA系的示例代码

2.2 Nacos Spring Cloud 快速开始

https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html

本文主要面向 Spring Cloud 的使用者,通过两个示例来介绍如何使用 Nacos 来实现分布式环境下的配置管理和服务注册发现。

  • 关于 Nacos Spring Cloud 的详细文档请参看:Nacos Config 和 Nacos Discovery。

    通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 实现配置的动态变更。
    通过 Nacos Server 和 spring-cloud-starter-alibaba-nacos-discovery 实现服务的注册与发现。

  1. 前提

    您需要先下载 Nacos 并启动 Nacos server。

  2. 使用配置中心

    1. 客户端依赖

      1. parent.xml - 采用公共版本依赖管理的方式

         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.SR4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        
        <dependencyManagement>
            <dependencies>
        
                <!--spring cloud alibaba-->
                <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                    <version>2.0.2.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
        
            <dependencies>
        
        <dependencyManagement>
        
      2. my-demo.xml

         <!--配置中心客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        
    2. 然后必须配置下面这两个配置项

      spring.application.name=nacos-demo
      # spring.cloud.nacos.config.server-addr :Nacos 服务器的地址和端口
      spring.cloud.nacos.config.server-addr=127.0.0.1:8848
      
      • server-addr 属性

        • 代码位置: com.alibaba.nacos.client.config.impl.ServerListManager#ServerListManager(java.util.Properties)

          if (StringUtils.isNotEmpty(serverAddrsStr)) {
              isFixed = true;
              List<String> serverAddrs = new ArrayList<String>();
              String[] serverAddrsArr = serverAddrsStr.split(",");
              for (String serverAddr: serverAddrsArr) {
                  if (serverAddr.startsWith(HTTPS) || serverAddr.startsWith(HTTP)) {
                      serverAddrs.add(serverAddr);
                  } else {
                      String[] serverAddrArr = serverAddr.split(":");
                      if (serverAddrArr.length == 1) {
                          serverAddrs.add(HTTP + serverAddrArr[0] + ":" + ParamUtil.getDefaultServerPort());
                      } else {
                          serverAddrs.add(HTTP + serverAddr);
                      }
                  }
              }
              serverUrls = serverAddrs;
              if (StringUtils.isBlank(namespace)) {
                  name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()]));
              } else {
                  this.namespace = namespace;
                  this.tenant = namespace;
                  name = FIXED_NAME + "-" + getFixedNameSuffix(serverUrls.toArray(new String[serverUrls.size()])) + "-"
                      + namespace;
              }
          }
          
        • 从源码可知

          • 实际上是支持配置多个地址的,只需要用 ; 分割。 不具有客户端负载均衡的效果,但是有高可用的效果。

          • 如果配置的某个地址没有带上 ":port" 部分,那么默认会把 8848 作为端口号来拼接。因此在你搭建了NacosVip的情况下,建议让Nginx也监听 8848 端口,或者在你的vip后面补充一个 :80 即可。

      • 说明:之所以需要配置 spring.application.name ,是因为它是构成 Nacos 配置管理 dataId字段的一部分。

        • 在 Nacos Spring Cloud 中,dataId 的完整格式如下:

          {prefix}-{spring.profile.active}.${file-extension}

          • prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix 来配置。

          • spring.profile.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profile.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成
            {prefix}.{file-extension}

          • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。

        • 以上面的例两行配置为例: 此时将会加载 nacos 中 默认(public) 命名空间下的, DEFAULT_GROUP 分组下的 DataID 为 nacos-demo.properties 文件。

        • 如果需要加载指定命名空间(sms-dev)下非默认分组(MY_GROUP1)下的DataID 为 sms-api-service-dev.yaml 的配置文件

          1. bootstrap.yml

            spring:
              application:
                name: @artifactId@
              cloud:
                nacos:
                  discovery:
                    server-addr: 127.0.0.1:8848
                  config:
                    server-addr: ${spring.cloud.nacos.discovery.server-addr}
                    file-extension: yaml
                    namespace: sms-dev
                    group: MY_GROUP1
              profiles:
                active: @profiles.active@
            
          2. pom.xml 中配置的 artifactId 为 sms-api-service, rofiles.active 为 dev

            • 当然也可以不引用 pom.xml 中的配置。直接在 bootstrap.yml 中写入这两个值。
      • 注意

        当你使用域名的方式来访问 Nacos 时,spring.cloud.nacos.config.server-addr 配置的方式为 域名:port。 例如 Nacos 的域名为abc.com.nacos,监听的端口为 80,则 spring.cloud.nacos.config.server-addr=abc.com.nacos:80。 注意 80 端口不能省略。

      • 示例: 在SpringBoot中打印配置

        public static void main(String[] args) {
            ConfigurableApplicationContext applicationContext = SpringApplication.run(ProviderApplication.class, args);
            String userName = applicationContext.getEnvironment().getProperty("user.name");
            String userAge = applicationContext.getEnvironment().getProperty("user.age");
            System.err.println("user name :"+userName+"; age: "+userAge);
        }
        
    3. 完全关闭配置

      通过设置 spring.cloud.nacos.config.enabled = false 来完全关闭 Spring Cloud Nacos Config

  1. 使用注册中心 - Nacos discovery

    1. 依赖配置

      <dependency>
         <groupId>com.alibaba.cloud</groupId>
         <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
      </dependency>
      
      • pom.xml的配置。一个完整的 pom.xml 配置如下所示:

        <?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>
        
            <groupId>open.source.test</groupId>
            <artifactId>nacos-discovery-test</artifactId>
            <version>1.0-SNAPSHOT</version>
            <name>nacos-discovery-test</name>
        
            <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>${spring.boot.version}</version>
                <relativePath/>
            </parent>
        
            <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
                <java.version>1.8</java.version>
            </properties>
        
            <dependencyManagement>
                <dependencies>
                    <dependency>
                        <groupId>org.springframework.cloud</groupId>
                        <artifactId>spring-cloud-dependencies</artifactId>
                        <version>${spring.cloud.version}</version>
                        <type>pom</type>
                        <scope>import</scope>
                    </dependency>
                    <dependency>
                        <groupId>com.alibaba.cloud</groupId>
                        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                        <version>${spring.cloud.alibaba.version}</version>
                        <type>pom</type>
                        <scope>import</scope>
                    </dependency>
                </dependencies>
            </dependencyManagement>
        
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </dependency>
        
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-actuator</artifactId>
                </dependency>
        
                <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
                </dependency>
            </dependencies>
        
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                    </plugin>
                </plugins>
            </build>
        </project>
        
    2. 启动一个 Provider 应用

      1. 在 bootstrap.properties 中或者 application.properties 中配置

        server.port=8081
        spring.application.name=nacos-producer
        
        spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
        
        # management.endpoints.web.exposure.include=*
        
      2. 应用程序启动类添加 @EnableDiscoveryClient 注解。

        @SpringBootApplication
        @EnableDiscoveryClient
        public class NacosProviderDemoApplication {

         public static void main(String[] args) {
             SpringApplication.run(NacosProducerDemoApplication.class, args);
         }
        
         @RestController
         public class EchoController {
             @GetMapping(value = "/echo/{string}")
             public String echo(@PathVariable String string) {
                 return "Hello Nacos Discovery " + string;
             }
         }
        

        }

    3. 服务的 EndPoint

      spring-cloud-starter-alibaba-nacos-discovery 在实现的时候提供了一个EndPoint,EndPoint的访问地址为 http://ip:port/actuator/nacos-discovery。 EndPoint 的信息主要提供了两类:

      1. subscribe: 显示了当前有哪些服务订阅者
      2. NacosDiscoveryProperties: 显示了当前服务实例关于 Nacos 的基础配置
    4. 启动一个 Consumer 应用

      Consumer 的应用可能还没像启动一个 Provider 应用那么简单。因为在 Consumer 端需要去调用 Provider 端提供的REST 服务。例子中我们使用最原始的一种方式, 即显示的使用 LoadBalanceClient 和 RestTemolate 结合的方式来访问。

      Note
      通过带有负载均衡的RestTemplate 和 FeignClient 也是可以访问的。

      @SpringBootApplication
      @EnableDiscoveryClient
      public class NacosConsumerApp {
      
          @RestController
          public class NacosController{
      
              @Autowired
              private LoadBalancerClient loadBalancerClient;
              @Autowired
              private RestTemplate restTemplate;
      
              @Value("${spring.application.name}")
              private String appName;
      
              @GetMapping("/echo/app-name")
              public String echoAppName(){
                  //使用 LoadBalanceClient 和 RestTemolate 结合的方式来访问
                  ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-provider");
                  String url = String.format("http://%s:%s/echo/%s",serviceInstance.getHost(),serviceInstance.getPort(),appName);
                  System.out.println("request url:"+url);
                  return restTemplate.getForObject(url,String.class);
              }
      
          }
      
          //实例化 RestTemplate 实例
          @Bean
          public RestTemplate restTemplate(){
      
              return new RestTemplate();
          }
      
          public static void main(String[] args) {
      
              SpringApplication.run(NacosConsumerApp.class,args);
          }
      }
      

      这个例子中我们注入了一个 LoadBalancerClient 的实例,并且手动的实例化一个 RestTemplate,同时将 spring.application.name 的配置值 注入到应用中来, 目的是调用 Provider 提供的服务时,希望将当前配置的应用名给显示出来。

      • Note
        在启动 Consumer 应用之前请先将 Nacos 服务启动好。具体启动方式可参考 Nacos 官网。

      启动后,访问 Consumer 提供出来的 http://ip:port/echo/app-name 接口。我这里测试启动的 port是 8082。访问结果如下所示:

       访问地址:http://127.0.0.1:8082/echo/app-name
       访问结果:Hello Nacos Discovery nacos-consumer
      
    5. 关于 Nacos Starter 更多的配置项信息

      https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery#%E5%85%B3%E4%BA%8E-nacos-starter-%E6%9B%B4%E5%A4%9A%E7%9A%84%E9%85%8D%E7%BD%AE%E9%A1%B9%E4%BF%A1%E6%81%AF

      • 例如:

        集群 spring.cloud.nacos.discovery.cluster-name DEFAULT 配置成Nacos集群名称
        AccessKey spring.cloud.nacos.discovery.access-key 无 当要上阿里云时,阿里云上面的一个云账号名
        是否开启Nacos Watch spring.cloud.nacos.discovery.watch.enabled true 可以设置成false来关闭 watch
        命名空间 spring.cloud.nacos.discovery.namespace 无 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等

    6. Note

      • 如果不想使用 Nacos 作为您的服务注册与发现,可以将 spring.cloud.nacos.discovery.enabled 设置为 false。
    • 官方参考
    * 示例:  https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example

    * 详细:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-discovery

3. 示例-客户端配置Nacos注册中心与配置中心

  • pom.xml

      ```xml
      <!--注册中心客户端-->
      <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
      </dependency>
      <!--配置中心客户端-->
      <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
      </dependency>
      ```
    
    • bootstrap.yml

      server:
        port: 7002
      
      spring:
        application:
          name: @artifactId@
        cloud:
          nacos:
            discovery:
              server-addr: 127.0.0.1:8848
              namespace: sms-dev
              # 设置 nacos client 使用这个 ip 注册到 nacos server , 若不配置则会自动探测。
              #ip: 192.160.22.22
      
            config:
              server-addr: ${spring.cloud.nacos.discovery.server-addr}
              file-extension: yaml
              namespace: sms-dev
              group: DEFAULT_GROUP
              shared-configs:
                - data-id: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
                  group: @nacos.group@
                  refresh: false
        profiles:
          active: @profiles.active@
      
  • 注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。

  • 注意: 关于 Nacos 的配置需要在 bootstrap.yaml 中配置。

  • 注意: @RefreshScope与数据源之间存在冲突!!

    因为项目是多数据源,所以使用的是自定义数据源配置的DataSource,用@Bean注入。

    在SpringBoot 2.0以上默认使用Hikari连接池,一旦连接池启动,就无法再修改HikariDataSource,所以刷新配置时连带数据源一起刷新,于是会报错。

    Caused by: java.lang.IllegalStateException: The configuration of the pool is sealed once started. Use HikariConfigMXBean for runtime changes.

    解决方法: 在自定义的DataSource上加入注解@RefreshScope,或者使用spring.scloud.refresh.extra-refreshable配置指定classname列表即可。

      查看Hikari的默认配置即可发现,这个与刷新配置之间是存在冲突的。
    
      因此在数据源配置类中加入注释,这样每次刷新配置的时候会重新刷新这个Bean,那么就可以保证不会报错,这样的spring的刷新机制就可以顺利执行下去了。
    

4. 常见问题

用户指南

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容