nginx详解

Nginx 是一个高性能的Http和反向代理web服务器。它可以作为静态资源服务器,反向代理服务器,也可以用作负载均衡。

一、nginx安装

1、安装依赖包
  • 在安装nginx前需要先安装nginx的依赖包:
//gcc  
//PCRE:一个perl库,包括perl兼容的正则表达式,nginx的http模板需要pcre来解析
//zlib:提供多种压缩和解压缩的方式,nginx使用zlib对http包的内容进行gzip
//openssl:是一个强大的安全套接字层密码库,包括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,nginx不仅支持http协议,还支持https
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
  • 将下载下来的.tar.gz移动到要存放的文件夹,然后使用命令解压:
//tar -zxvf 包名(根据自己包名进行修改)
tar -zxvf nginx-1.16.1.tar.gz

tar -zxvf:用于解压 .tar.gz 后缀结尾的
tar -xvf:用于解压 .tar后缀结尾的

  • 解压后进入解压后的文件夹中,这时需要使用make命令进行编译,但是解压后的文件夹中没有make文件,所以我们需要使用configure来创建make文件:
/** 
--prefix:用于指定nginx安装到哪里
--pid-path:每个进程都有个pid文件,这里指定pid文件存放位置
--lock-path:lock文件存放位置
--error-log-path:错误日志存放位置
--http-log-path:访问日志存放位置
--with-http_gzip_static_module:gzip模块
--http-client-body-temp-path:临时文件保存位置
下面同上,这些temp的目录在nginx启动后都需要存在,否则会报错。
*/
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi
  • 创建好make文件后使用命令编译和安装:
make
make install
  • 安装好后,我们需要在var下创建temp/nginx,否则启动报错:
//-p代表可以创建多层目录
mkdir /var/temp/nginx -p
  • 接下来到安装好的nginx目录下的sbin
cd /usr/local/nginx/sbin
//启动nginx
./nginx
  • 启动成功后通过命令查询是否启动成功
ps aux|grep nginx

上图代表启动成功。

  • 关闭nginx
//可以这样关闭,18705为上面图中的id
kill 18705  
//一般来说在sbin下这样关闭
./nginx -s stop
  • 重新加载配置文件,不用关机
./nginx -s reload

nginx安装完成后如果要添加模块

先找到源码包目录,然后执行下面命令,要添加上以前安装过的模块,因为这相当于是重新安装nginx:

#此处添加--with-http_ssl_module模块
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--with-http_ssl_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi
//具体安装在哪,路径自己定,要加上之前安装的模块

执行:make 编译
注意:不要使用make install,否则会覆盖掉你现在正在使用的nginx

然后备份原来的可执行文件,并将刚刚编译好的nginx可执行文件覆盖掉原有的nginx,覆盖前先停掉nginx:

//备份
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
//覆盖,objs为源码包中的文件夹,里面有nginx的可执行文件
cp ./objs/nginx /usr/local/nginx/sbin/

使用命令:nginx -V来查看是否添加成功,configure arguments后面表示当前已经安装的nginx模块:


二、nginx配置反向代理

一个请求先访问到nginx,然后通过nginx将请求转发到配置的服务器,实现反向代理。

upstream tomcat {
    server www.test.com:8080;
    server ...   #可以设置多个
}
server {
    listen       80;
    server_name  www.test.com;
    location / {
        proxy_pass   http://tomcat;
        index  index.html index.htm;
    }
    #下面配置的是静态资源过滤
    location ~ .*\.(gif|jpg|png|jpeg|ico|bmp|swf|css|js|eot|svg|ttf|woff|woff2|properties|json)$ {
        proxy_pass http://tomcat;
        proxy_read_timeout 600s;
        proxy_set_header ?X-Real-IP ?$remote_addr;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    
    }
    error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
    }
}
1、静态资源过滤中的配置介绍:
- proxy_read_timeout:proxy后端服务器超时时间。连接成功后,等候后端服务器响应时间,其实已经进入后端排队之中等候处理。
- proxy_set_header : proxy反向代理设置请求头,是传递给后端服务器的
- proxy_set_header:
        X-Real-IP:真实IP
            $remote_addr:是前一节点的IP,并不一定是用户的真实IP。
        Host:
            $host:代理服务器本身IP。
            $server_port:nginx监听的端口。
            $proxy_port : 服务器真正访问的端口。
        X-Forwarded-For:后面的$remote_addr与$proxy_add_x_forwarded_for
            当只有一层代理服务器的情况下,两者的X-Forwarded-For值一致,都是用户的真实IP。
            $remote_addr:是前一节点的IP,并不一定是用户的真实IP。
            $http_x_forwarded_for:获取的是前一节点的X-Forwarded-For的值。
            $proxy_add_x_forwarded变量包含:$http_x_forwarded_for与$remote_addr两部分,它们之间用逗号分开。
2、配置反向代理是在server中进行配置:
server中:
    lister:这里设置你要监听的端口
    server_name:这里是你的请求名字,例如你的网站名或是ip
    location中:
        proxy_pass:这里配置代理转发的位置,如tomcat就需要在前面加上http://
upstream中:
    upstream后面的tomcat就是下面location中的proxy_pass
    server:这里配置端口号

注意问题:如果location按照^~匹配,则proxy_pass后的url需要加上/,不然转发是会把匹配的路径也加上。
例如:
1、请求是http://aaa.com/前缀/index.html,配置proxy_pass http://aaa.com/,则被代理成:http://aaa.com/index.html
2、请求是http://aaa.com/前缀/index.html,配置proxy_pass http://aaa.com,则被代理成:http://aaa.com/前缀/index.html。

上面这些配完,当你访问www.test.com时就可以访问到你的项目。这里相当于把www.test.com:80的请求转发到你本地的tomcat的8080端口上。
我们可以配置多个,这样你就再复制一个server,然后去配置。

3、关于nginx使用反向代理时静态资源无法加载问题
  • 带项目名的访问路径
    当我们使用nginx作反向代理时,如果是下面的配置:
location ^~ /api/ {
    proxy_pass  http://localhost:8080;
}

这时静态资源可以访问的到。

但是我们有时需要使用nginx的负载均衡,或是需要多个web服务器的时候,我们就需要使用upstream,我们看如下配置:

upstream tomcat {
      server  127.0.0.1:8080;
      #这里可以添加其他sever,然后配置负载均衡
}
location ^~ /api/ {
    proxy_pass  http://tomcat;
}

上面这种配置时,静态资源就无法访问,这时我们看到图片的Request URL是下面的:

Request URL:http://tomcat/project/img/logo.jpg

从这里可以看出,nginx反向代理后,转发的请求网址不对,tomcat处应该是localhost(注:我的nginx和tomcat都在一台服务器)。这时因为nginx没有获取到转发上一层的请求情况,所以我们要加一些东西,下面是完整配置:

upstream ...
location ^~ /api/ {
    proxy_pass  http://tomcat;
    proxy_set_header ?X-Real-IP ?$remote_addr;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
---------------------------------------------------------------------------------------------
访问的网址为:www.aaa.com/api/toIndex;
location前缀api后面加了/,即为精确匹配。
在proxy_pass后面tomcat后面是不是加/,作用于区别本文中有解释,这里不做介绍。

上面的配置我们就可以正常访问了。

三、server中location的配置

1、location中root和alias的区别
location /i/ {
    root /data/w3/images/;
}
当请求是/i/top.gif时,nginx将会请求/data/w3/images/i/top.gif
root处理结果:root路径+location路径
使用root时,目录后面的"/"可有可无。
location /i/ {
    alias /data/w3/images/;
}
当请求/i/top.gif时,nginx将会请求/data/w3/images/top.gif
alias处理结果:使用alias路径替换location路径
注意:
    使用alias时,目录名后面一定要加"/"。
    alias只能位于location块中。

root和alias主要区别在于nginx如何解释location后面的uri。

2、location后面的uri
location语法:location [=|~|~*|^~|@] /uri/ { … }

location分为两类:一类是普通location,一类是正则location

普通location是以:= 或 ^~ 为前缀或者没有任何前缀的uri
注:普通location都是以 / 开始的uri请求
正则location是以:~ 或 ~* 为前缀的uri
  • 普通location
前缀 作用 说明
/ 匹配任何请求。 因为所有请求都是以"/"开始,但是更长字符匹配或者正则表达式匹配会优先匹配,如果是location =/ {},则只响应/请求。
/* 最大前缀匹配。 例如/uri/api/*,普通location最长字符匹配,与location在配置文件中的顺序无关,是按照匹配的长短来取匹配结果。若完全匹配,就停止匹配。
= 前缀精确匹配。 必须严格等于,匹配到则立即停止,不会去执行“最大前缀”匹配结果。
^~ 非正则匹配。 与普通匹配的差别是,告诉nginx不继续正则匹配。请求/images/,那么/images/、/images/a、/images/a/b/index.html这三个都会在/images/这停止,后面的location和这三个一样也不会匹配到。
@ nginx内部跳转 用于定义一个location块,且该块不能被外部client访问,只能被nginx内部配置指令所访问。
  • 正则location
    正则匹配顺序则为location在配置文件中出现的顺序,从上到下进行匹配,如果符合则停止。
前缀 说明
~ 表示区分大小写的正则匹配
~* 表示不区分大小写的正则匹配
!~ 表示区分大小写不匹配的正则
!~* 表示不区分大小写不匹配的正则
  • location匹配优先级:
//优先级
#精确匹配(=) > 最大前缀匹配(/ *,需完全匹配) > 非正则匹配(^~) > 正则匹配(|~|~*|!~|!~*|) > 最大前缀匹配(/ *,不完全匹配) > location通配(/)
解释:
1、先查找是否有=开头的精确匹配,如果没有继续查找。
2、再查找普通匹配,以最大前缀为原则。例如:/a/和/a/a,则匹配到后一项。如果没有继续查找。
3、匹配到一个普通格式后,并没有结束,而是暂存当前匹配结果并继续。
如果找到非正则匹配(^~)项,则终止搜索,将以此项为最终匹配结果;如果没有将继续查找。
4、接着匹配正则,将第一个匹配项作为最终结果,也覆盖了前面缓存的匹配结果,并终止搜索。正则受在配置文件中配置的前后顺序影响,普通匹配不会。
5、如果没有找到正则匹配项,则以3中缓存的结果为最终结果。
6、如果一个都没有匹配到,返回404。

看下面例子:

//配置示例
#location / {  config A  }
请求为:/aaa/index.html  匹配到:cofig A  ------通用匹配,如果匹配到A以后,往后没有任何匹配,则使用config A

#location =/ {  config B  }
请求为:/  匹配到:cofig B  ------精确匹配,即使/index.html也匹配不了

#location /api/ {  config C  }
请求为:/api/index.html  匹配到:cofig  C ------先匹配到C,往下没有任何匹配项,使用config C
请求为:/api/1.jpg 匹配到:config E  ------先匹配到C,往下找到正则匹配项,所以使用config E

#location ~ /api/Abc {  config CC  }
请求为:/api/Abc.jpg  匹配到:cofig CC  ------最长前缀先匹配到C,继续往下找到正则CC,终止搜索,不会往下到E。

#location ^~ /images/ {  config D  }
请求为:/images/abc.jpg  匹配到:cofig D  ------先匹配到F,继续搜索找到D,然后停止,不会再去查找正则。

#location /images/ {  config F  }
请求为:/images/1.jpg  匹配到:cofig D  ------先匹配到F,因为普通匹配不受顺序影响,然后有非正则项,所以使用config D,不会再查找正则。

#location /images/abc {  config G  }
请求为:/images/abc/1.jpg或/images/abc.jpg  匹配到:cofig D  ------先匹配到G,然后有非正则,所以使用D。

#location ~ /images/abc/ {  config H ] }
请求为:/images/abc/1.jpg  匹配到:cofig D  ------如果没有非正则项,此配置最长会匹配到H,正则第一个匹配项会被作为最终项。

#location ~* \.(gif|jpg|jpeg)$ {  config E  }
请求为:/1.jpg  匹配到:cofig E  ------此项为关于图片后缀的正则,不区分大小写。
  • location中以@开头的uri
    用于定义一个location块,且该块不能被外部client访问,只能被nginx内部配置指令所访问。
//示例:
location /img/ {
    error_page 404 @img_err;
}
location @img_err {
    config A
}
#以 /img/ 开头的请求,如果连接的状态为 404。则会匹配到 @img_err 这条规则上。
  • location前缀后面的 / 加与不加的区别
//示例:
location /images/pic { config A }
location /images/pic/ { config A }

location进行的是模糊匹配,如上面示例:

  • 当没有 / 时,/images/pic可以匹配/images/picabc请求,也可以匹配/images/pic/abc请求
  • 当有 / 时,/images/pic/不可以匹配/images/picabc请求,只可以匹配/images/pic/anything这样的请求

四、Rewrite地址重写

参考:https://blog.csdn.net/qq_41475058/article/details/89516051

Nginx的rewrite的主要功能是实现URL地址重写。Nginx的rewrite规则需要PCRE软件的支持,即通过Perl兼容正则表达式语法进行规则匹配。

rewrite和location的功能有点相像,都能实现跳转,主要区别在于rewrite常用于同一域名内更改获取资源的路径,而location是对一类路径做控制访问和反向代理,可以proxy_pass到其他服务器。

rewrite功能就是使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。

地址重写和地址转发的含义:
地址重写是为了实现地址的标准化,比如在地址栏中中输入 www.baidu.com. 我们也可以输入 www.baidu.cn. 最后都会被重写到 www.baidu.com 上。浏览器的地址栏也会显示www.baidu.com。会产生两次请求。
地址转发它是指在网络数据传输过程中数据分组到达路由器或桥接器后,该设备通过检查分组地址并将数据转发到最近的局域网的过程。只会有一次请求。

rewrite只能放在 server{}, location{}, if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用。
例如:www.baidu.com/a/b/index.html?id=1,则只对/a/b/index.html重写。

1、rewrite相关指令
指令 默认值 使用范围
break none if,server,location
if ( condition ) { … } none server,location
return none server,if,location
rewrite regex replacement flag server,location,if
uninitialized_variable_warn on/off on http,server,location,if
set variable value none

指令作用见下:

break:
    完成当前的规则集,不再处理rewrite指令(属于rewrite的指令),需要和last加以区分。
if ( condition ) { … }:
    用于检测一个条件是否符合,符合则执行大括号内的语句。不支持嵌套,不支持多个条件&&或处理
return:
    用于结束规则的执行和返回状态码给客户端。
    状态码的值可以是:204,400,402,406,408,410,411,413,416以及500~504,
    另外非标准状态码444,表示以不发送任何的Header头来结束连接。
rewrite regex replacement flag:
    该指令根据表达式来重定向URI,或者修改字符串。
    指令根据配置文件中的顺序来执行。注意重写表达式只对相对路径有效。
    该指令根据表达式来重定向URI,或者修改字符串。
    指令根据配置文件中的顺序来执行。注意重写表达式只对相对路径有效。
uninitialized_variable_warn on/off:
    该指令用于开启和关闭未初始化变量的警告信息,默认值为开启。
set variable value:
    该指令用于定义一个变量,并且给变量进行赋值。变量的值可以是文本、一个变量或者变量和文本的联合,文本需要用引号引起来。
2、rewrite常用全局变量
变量 说明
$args 该变量中存放了请求URL中的请求指令。
比如aaa.com?arg1=value1&arg2=value2 中的
"arg1=value1&arg2=value2"
$content_length 该变量中存放了请求头中的Content-length字段
$content_type 该变量中存放了请求头中的 Content-type字段
$document_root 该变量中存放了针对当前请求的根路径
$document_uri 该变量中存放了请求的当前URI, 但是不包括请求指令。
比如aaa.com/aaa/1?arg1=value1&arg2=value2; 中的 "/aaa/1"
$host 变量中存放了请求的URL中的主机部分字段,比如aaa.com/home中的 aaa.com。
如果请求中的主机部分字段不可用或者为空,
则存放Nginx配置中server块中的server_name指令的配置值
$http_host 该变量与$host唯一区别带有端口号:比如上面的是 aaa.com:8080
$http_user_agent 变量中存放客户端的代理信息
$http_cookie 该变量中存放客户端的cookie信息
$limit_rate 变量中存放Nginx服务器对网络连接速率的限制,也就是Nginx配置中的limit_rate指令的配置值
$remote_addr 该变量中存放客户端的地址。
$remote_port 该变量中存放了客户端与服务器建立连接的端口号
$remote_user 变量中存放客户端的用户名。
$request_body_file 变量中存放了发给后端服务器的本地文件资源的名称
$request_method 变量中存放了客户端的请求方式,比如 'GET'、'POST'等
$request_filename 变量中存放了当前请求的资源文件的路径名
$request_uri 变量中存放了当前请求的URI,并且带请求指令
$query_string 和变量$args含义一样
$scheme 变量中存放了客户端请求使用的协议,比如 'http', 'https'和'ftp'等
$server_protocol 变量中存放了客户端请求协议的版本, 比如 'HTTP/1.0'、'HTTP/1.1' 等
$server_addr 变量中存放了服务器的地址
$server_name 变量中存放了客户端请求到达的服务器的名称
$server_port 变量中存放了客户端请求到达的服务器的端口号
$uri 与变量$document_uri含义相同
3、rewrite语法
  • rewrite regex replacement [flag];
rewrite:为固定关键字,表示开始进行rewrite匹配规则。
regex:用于匹配URI的正则表达式。
replacement :将regex正则匹配到的内容替换成 replacement。
flag:flag标记。
        flag有如下值:
        last: 本条规则匹配完成后,继续向下匹配新的location URI 规则。(不常用)last一般写在server和if中。
        break: 本条规则匹配完成即终止,不再匹配后面的任何规则(不常用)。break一般使用在location中。
        redirect: 返回302临时重定向,浏览器地址会显示跳转新的URL地址。
        permanent: 返回301永久重定向。浏览器地址会显示跳转新的URL地址。
rewrite ^/(.*) http://www.baidu.com permanent;
当请求过来会重写,然后重定向到www.baidu.com
  • set和return
    使用 $ 来引用变量。
location / {
    #set赋值,可以直接赋字符串,或是变量,或是变量和字符串的组合
    set $set_value_uri “111 $request_uri”;
    return 200 $set_value_uri;
}
www.aaa.com/aaa请求后,将返回200的status,还有111 
  • if
    if中的判断条件condition为空或为0,都为false,不支持嵌套,不支持多个条件&&或处理。
相关判断表达式:
- 变量与字符串比较,= 为等于,!= 为不等
- 变量与正则表达式匹配,~ 为区分大小写匹配,~* 为不区分大小写匹配,!~ 和 !~* 前面两者的非操作,即区分和不区分大小写不匹配。
- 检查文件是否存在,-f 存在即为true,!-f 不存在即为true
- 检查目录是否存在,-d 存在即为true,!-d 不存在即为true
- 检查文件或目录是否存在,-e 存在即为true,!-e 不存在即为true
- 检查文件是否可执行,-x 可执行即为true,!-x 不可执行即为true
如果/usr/local文件或文件夹存在,则返回200
if(-e /usr/local){
      return 200;
}

五、防盗链配置

防盗链及实现原理:别人直接拿我们的图片链接用在自己的服务器上,为了防止这种行为,就出现了防盗链。要实现防盗链先了解下图片的加载,客户端向服务器请求资源时,为了减少网络带宽和提高响应时间,服务器会分开加载资源。比如请求一个网页,先传回文本,解析中发现网页中有图片,浏览器再次请求图片资源。但是如果别人拿到你的图片链接直接放到自己的网页上,那么别人在请求他的服务器后,网页中有你的图片,则浏览器会直接向你的服务器请求,这种会增加你服务器的负担,消耗你的带宽,这个就是盗链行为。因此我们要实现防盗链。

实现防盗链:使用http协议中请求头部的Referer头域来判断当前访问的网页或文件的源地址。通过该头域的值,我们可以检测访问目标资源的源地址。如果目标源地址不是我们自己站内的URL的话,那么这种情况下,我们采取阻止措施,实现防盗链。但是注意的是:Referer头域中的值是可以被更改的。因此该方法也不能完全安全阻止防盗链。

nginx服务器的rewrite功能实现防盗链

Nginx中有一个指令valid_referers。该指令可以用来获取Referer头域中的值,并且根据该值的情况给Nginx全局变量invalidreferer赋值。如果Referer头域中没有符合validreferers指令的值的话invalid_referer变量将会赋值为1.。

  • valid_referers 指令基本语法如下:
valid_referers  none | blocked | server_names | arbitrary_string | regular experssion
  • valid_referers后面参数的意思:
none:代表请求头中没有referer信息,这一般是直接在浏览器输入图片网址。
blocked:代表Referer头域的值被防火墙或者代理服务器删除或伪装的情况。那么在这种情况下,该头域的值不以"http://" 或 "https://" 开头。
server_names:当设置一个或多个URL,即nginx监听的server_name 。检测Referer头域的值是否是URL中的某个。
arbitrary_string:自定义指定字符串,但使用作通配符 
regular experssion:被指定的正则表达式模式匹配到的字符串,需要使用~开头,如:~ aaa.com
示例:
根据请求文件类型实现防盗链配置
location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ {
    valid_referers none blocked www.aaa.com *.bbb.com;
    if($invalid_referer){
        rewrite ^/ http://www.aaa.com/images/aaa.png;
    }
}
根据请求目录实现防盗链配置
location /images/ {
    valid_referers none blocked www.aaa.com *.bbb.com;
    if($invalid_referer){
        rewrite ^/ http://www.aaa.com/images/aaa.png;
    }
}

示例中,blocked后面的地址就相当于白名单,如果请求的资源文件不是以这些域名开头的话,就说明请求的资源文件不是该域下的请求,可以判断它是盗链。然后invalid_referer被赋值为1,而1代表是true,就进入if代码块,然后把它重定向到aaa.png这个图片。

六、其他

1、设置过期时间(expires [time])
根据文件类型设置过期时间
location ~* \.(js|css|jpg|jpeg|gif|png|swf)$
if(-f $request_filename){
      expires 30d;
      break;
}
设置图片缓存时间
location ~ \.(gif|jpg|png)${
     expires 1h; 
}
2、禁止访问某个目录(deny all)
location ~* \.(txt|doc)${
     root /data/images;  #所有用户都禁止访问这个目录
    deny all;
}
3、隐藏版本号

在http中添加:server_tokens off;


写在最后:

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