Haproxy

haproxy简介

HAProxy是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件。暂时不支持UDP协议

主要版本

版本1.8:多线程,HTTP / 2,缓存,动态服务器添加/删除,无缝重新加载,DNS SRV,硬件SSL引擎,...
版本1.7:增加了服务器热重新配置,内容处理代理,多种证书,... -
版本1.6:添加DNS解析支持,HTTP连接复用,完整的粘贴表复制,无状态压缩,...
版本1.5:添加SSL,IPv6,保持活着,DDoS保护,... -
1.4版:不需要SSL的人最稳定的版本。仍然提供客户端连接包活

高性能

  • 单进程事件驱动的模型大大降低了上下文切换 和内存使用的成本 。在几毫秒内处理数百个任务是可能的,并且内存使用量是每个会话几千字节的数量级,而预先执行的或线程化的服务器中消耗的内存更多是每个进程的兆字节数量级。
  • O(1)事件检查系统,允许它(Linux和FreeBSD),允许瞬间检测任何事件在成千上万的任何连接。
  • 使用延迟事件缓存延迟对事件检查器的更新可确保我们绝不会在事件绝对需要的情况下更新事件。这节省了很多系统调用。
  • 只要可能,在读写之间没有任何数据拷贝的单缓冲。这节省了大量的CPU周期和有用的内存带宽。通常,瓶颈将是CPU和网络接口之间的I / O总线。在10-100 Gbps时,内存带宽也可能成为瓶颈。
  • 使用Linux下的splice()系统调用可以实现零拷贝转发,并且从Linux 3.5开始实现零拷贝。这允许一个小型3瓦设备(如希捷Dockstar)以千兆/秒的速度转发HTTP流量。
  • MRU 内存分配器使用固定大小的内存池进行即时内存分配,有利于冷高速缓存中的热缓存区域。这大大缩短了创建新会话所需的时间。
  • 工作分解(例如同时接受多个accept)以及在多进程模式下运行时限制每次迭代accept()的次数的能力,以便负载在进程间平均分配。
  • 在多进程模式下运行时支持CPU亲和性,或者仅适应硬件,并尽可能靠近管理NIC的CPU内核,而不与其冲突。
  • 基于树的存储,大量使用弹性二叉树我已经开发了好几年了。这用于保持定时器的有序性,以保持runqueue的有序性,以管理循环和最少连接队列,仅在O(log(N))成本中查找表中的ACL或密钥。
  • 优化的定时器队列:如果定时器被推迟,定时器不会在树中移动,因为它们被满足的可能性接近于零,因为它们主要用于超时处理。这进一步优化了ebtree的使用。
  • 优化的HTTP头分析:头文件被解析和动态解析,解析被优化以避免重新读取任何先前读取的内存区域。检查点用于当一个不完整的头部达到缓冲区的末端时,以便当更多的数据被读取时解析不会从头再次开始。在快速Xeon E5上解析平均HTTP请求通常需要半微秒。
  • 仔细减少昂贵的系统调用的次数。大部分工作是在用户空间默认完成的,如时间读取,缓冲区聚合,文件描述符启用/禁用。
  • 内容分析被优化为只携带指向原始数据的指针,并且除非数据需要被转换,否则不会复制。这确保了非常小的结构被转移,并且当不是绝对必要时内容不会被复制。

衡量负载平衡器性能有三个重要因素:
会话速率
会话并发性
数据转发速率

安全

建议使用root用户启动,因为可以使用chroot()提高提高系统安全性。
使用upd方式发送日志,提供较多排查信息。

配置文件格式

  • 配置文件一行总是优先
  • global,设置全过程参数
  • 代理部分可以采取“default”,“listen”,
    “frontend”和“backend”的形式。
    测试配置命令:

$ haproxy -f configuration.conf -c

全局参数

  • Process management and security

    • ca-base SSL CA证书目录,“ca-file”和“crl-file”指定的绝对位置为准
    • chroot chroot目录
    • crt-base 和ca-base类似
    • daemon 守护进程方式
    • gid 指定gid
    • group
    • log <ip>
    • log-send-hostname
    • nbproc <num> 守护进程数量默认为1
    • pidfile
    • uid
    • ulimit-n
    • user
    • stats
    • ssl-server-verify
    • node 此语句在两个或更多进程或服务器共享相同IP地址的HA配置中非常有用。通过在所有节点上设置不同的节点名称,很容易立即发现哪个服务器正在处理流量。
    • description
    • unix-bind
  • 性能调整

    • max-spread-checks
    • maxconn 最大连接数
    • maxconnrate
    • maxcomprate
    • maxcompcpuusage
    • maxpipes
    • maxsessrate
    • maxsslconn
    • maxsslrate
    • noepoll 禁止在BSD上使用“kqueue”事件轮询系统。
    • nokqueue
    • nopoll 禁用在Linux上使用“epoll”事件轮询系统。
    • nosplice 禁止在Linux上的套接字之间使用内核tcp连接。
    • nogetaddrinfo
    • spread-checks
    • tune.bufsize
    • tune.chksize
    • tune.comp.maxlevel
    • tune.http.cookielen
    • tune.http.maxhdr
    • tune.idletimer
    • tune.maxaccept
    • tune.maxpollevents
    • tune.maxrewrite
    • tune.pipesize
    • tune.rcvbuf.client
    • tune.rcvbuf.server
    • tune.sndbuf.client
    • tune.sndbuf.server
    • tune.ssl.cachesize
    • tune.ssl.lifetime
    • tune.ssl.force-private-cache
    • tune.ssl.maxrecord
    • tune.ssl.default-dh-param
    • tune.zlib.memlevel
    • tune.zlib.windowsize
  • Debugging

后端配置

“defaults”段用于为所有其它配置段提供默认参数,这配置默认配置参数可由下一个“defaults”所重新设定。
“frontend”段用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接。
“backend”段用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器。
“listen”段通过关联“frontend”和“backend”定义了一个完整的代理,通常只对TCP流量有用。

关键字段解析

1, balance
balance url_param [check_post []]

定义负载均衡算法,可用于“defaults”、“listen”和“backend”。用于在负载均衡场景中挑选一个server,其仅应用于持久信息不可用的条件下或需要将一个连接重新派发至另一个服务器时。支持的算法有:

roundrobin:基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,这表示其权重可以在运行时进行调整,不过,在设计上,每个后端服务器仅能最多接受4128个连接;并支持慢启动。

static-rr:基于权重进行轮叫,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效;不过,其在后端服务器连接数上没有限制;不支持慢启动,在高负荷的情况下,服务器重新上线时会立即被分配大量连接。

leastconn(WLC):适用于长连接的会话,新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,可以在运行时调整其权重;

source:将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可以使得同一个客户端IP的请求始终被派发至某特定的服务器;不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;常用于负载均衡无cookie功能的基于TCP的协议;其默认为静态,不过也可以使用hash-type修改此特性;

对原地址hash,第一次调度时使用WLC

source:IP层,位于同一个NAT服务器背后的多个请求都会定向至同一个upstream server,不利于负载均衡,一般只有不支持使用cookie插入又需要保持会话时使用 cookie:应用层,有更好的负载均衡效果;

hash/weight%ip :除以权重取模
uri:对URI的左半部分(“问题”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器;这可以使得对同一个URI的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法常用于代理缓存或反病毒代理以提高缓存的命中率;需要注意的是,此算法仅应用于HTTP后端服务器场景;其默认为静态算法,不过也可以使用hash-type修改此特性;

url_param:通过<argument>为URL指定的参数在每个HTTP GET请求中将会被检索;如果找到了指定的参数且其通过等于号“=”被赋予了一个值,那么此值将被执行hash运算并被服务器的总权重相除后派发至某匹配的服务器;此算法可以通过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一个特定的服务器,除非服务器的总权重发生了变化;如果某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度;此算法默认为静态的,不过其也可以使用hash-type修改此特性;

hdr(<name>):对于每个HTTP请求,通过<name>指定的HTTP首部将会被检索;如果相应的首部没有出现或其没有有效值,则使用轮叫算法对相应请求进行调度;其有一个可选选项“use_domain_only”,可在指定检索类似Host类的首部时仅计算域名部分以降低hash算法的运算量;此算法默认为静态的,不过其也可以使用hash-type修改此特性;

2, mode
tcp:实例运行于纯TCP模式,在客户端和服务器端之间将建立一个全双工的连接,且不会对7层报文做任何类型的检查;通常用于SSL、SSH、SMTP等应用;

http:实例运行于HTTP模式,客户端请求在转发至后端服务器之前将被深度分析,所有不与RFC格式兼容的请求都会被拒绝;此为默认模式;

3, hash-type
map-based:hash表是一个包含了所有在线服务器的静态数组。其hash值将会非常平滑,会将权重考虑在列,但其为静态方法,对在线服务器的权重进行调整将不会生效,这意味着其不支持慢速启动。此外,挑选服务器是根据其在数组中的位置进行的,因此,当一台服务器宕机或添加了一台新的服务器时,大多数连接将会被重新派发至一个与此前不同的服务器上,对于缓存服务器的工作场景来说,此方法不甚适用。

consistent:“一致性哈希算法”,hash表是一个由各服务器填充而成的树状结构,将服务器散列在hash环上;基于hash键在hash树中查找相应的服务器时,最近的服务器将被选中。此方法是动态的,支持在运行时修改服务器权重,因此兼容慢速启动的特性。添加一个新的服务器时,仅会对一小部分请求产生影响,因此,尤其适用于后端服务器为cache的场景。不过,此算法不甚平滑,派发至各服务器的请求未必能达到理想的均衡效果,因此,可能需要不时的调整服务器的权重以获得更好的均衡性。

4,log address facility level
global:当前实例的日志系统参数同”global”段中的定义时,将使用此格式;每个实例仅能定义一次“log global”语句,且其没有任何额外参数;

<address>:定义日志发往的位置,其格式之一可以为<IPv4_address:PORT>,其中的port为UDP协议端口,默认为514;格式之二为Unix套接字文件路径,但需要留心chroot应用及用户的读写权限;

<facility>:可以为syslog系统的标准facility之一;

<level>:定义日志级别,即输出信息过滤器,默认为所有信息;指定级别时,所有等于或高于此级别的日志信息将会被发送;

5,maxconn
设定一个前端的最大并发连接数,因此,其不能用于backend区段。对于大型站点来说,可以尽可能提高此值以便让haproxy管理连接队列,从而避免无法应答用户请求。当然,此最大值不能超出“global”段中的定义。此外,需要留心的是,haproxy会为每个连接维持两个缓冲,每个缓冲的大小为8KB,再加上其它的数据,每个连接将大约占用17KB的RAM空间。这意味着经过适当优化后,有着1GB的可用RAM空间时将能维护40000-50000并发连接。

如果为<conns>指定了一个过大值,极端场景下,其最终占据的空间可能会超出当前主机的可用内存,这可能会带来意想不到的结果;因此,将其设定了一个可接受值方为明智决定。其默认为2000。

6,server
后端声明一个server,因此,不能用于defaults和frontend区段。
<name>:为此服务器指定的内部名称,其将出现在日志及警告信息中;如果设定了”http-send-server-name”,它还将被添加至发往此服务器的请求首部中;
<address>:此服务器的的IPv4地址,也支持使用可解析的主机名,只不过在启动时需要解析主机名至相应的IPv4地址;
[:port]:指定将连接请求所发往的此服务器时的目标端口,其为可选项;未设定时,将使用客户端请求时的同一相端口;
[param*]:为此服务器设定的一系参数;其可用的参数非常多,具体请参考官方文档中的说明,下面仅说明几个常用的参数;

服务器或默认服务器参数:

backup:设定为备用服务器,仅在负载均衡场景中的其它server均不可用于启用此server;

check:启动对此server执行健康状态检查,其可以借助于额外的其它参数完成更精细的设定,如:

inter <delay>:设定健康状态检查的时间间隔,单位为毫秒,默认为2000;也可以使用fastinter和downinter来根据服务器端状态优化此时间延迟;

rise <count>:设定健康状态检查中,某离线的server从离线状态转换至正常状态需要成功检查的次数;

fall <count>:确认server从正常状态转换为不可用状态需要检查的次数;

cookie <value>:为指定server设定cookie值,此处指定的值将在请求入站时被检查,第一次为此值挑选的server将在后续的请求中被选中,其目的在于实现持久连接的功能;

maxconn <maxconn>:指定此服务器接受的最大并发连接数;如果发往此服务器的连接数目高于此处指定的值,其将被放置于请求队列,以等待其它连接被释放;

haproxy 有n个进程,每个支持m个连接,后端有x个服务器,每个最大支持y个连接,则 nm <= xy,如果后端服务器支持排队,则nm <= x(y+z),z为每个服务器的排队队列

maxqueue <maxqueue>:设定请求队列的最大长度;

observe <mode>:通过观察服务器的通信状况来判定其健康状态,默认为禁用,其支持的类型有“layer4”和“layer7”,“layer7”仅能用于http代理场景;

redir <prefix>:启用重定向功能,将发往此服务器的GET和HEAD请求均以302状态码响应;需要注意的是,在prefix后面不能使用/,且不能使用相对地址,以免造成循环;

weight <weight>:权重,默认为1,最大值为256,0表示不参与负载均衡;

7,capture request header
capture request header <name> len <length>
捕获并记录指定的请求首部最近一次出现时的第一个值,仅能用于frontend和listen区段。捕获的首部值使用花括号{}括起来后添加进日志中。如果需要捕获多个首部值,它们将以指定的次序出现在日志文件中,并以竖线“|”作为分隔符。不存在的首部记录为空字符串,最常需要捕获的首部包括在虚拟主机环境中使用的“Host”、上传请求首部中的“Content-length”、快速区别真实用户和网络机器人的“User-agent”,以及代理环境中记录真实请求来源的X-Forward-For。

<name>:要捕获的首部的名称,此名称不区分字符大小写,但建议与它们出现在首部中的格式相同,比如大写首字母。需要注意的是,记录在日志中的是首部对应的值,而非首部名称。

<length>:指定记录首部值时所记录的精确长度,超出的部分将会被忽略。

可以捕获的请求首部的个数没有限制,但每个捕获最多只能记录64个字符。为了保证同一个frontend中日志格式的统一性,首部捕获仅能在frontend中定义。
8, capture response header
capture response header <name> len <length>
捕获并记录响应首部,其格式和要点同请求首部。

9,stats enable
示例:

stats enable
stats hide-version
stats scope .
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth statsadmin:password
stats auth statsmaster:password

10,option httplog
默认情况下,日志输入格式非常简陋,因为其仅包括源地址、目标地址和实例名称,而“option httplog”参数将会使得日志格式变得丰富许多,其通常包括但不限于HTTP请求、连接计时器、会话状态、连接数、捕获的首部cookie、frontend、backend及服务器名称,当然也包括源地址和端口号等。

11,option forwardfor 添加X-forward-for,客户的真实IP地址。
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
<network>:可选参数,当指定时,源地址为匹配至此网络中的请求都禁用此功能。
<name>:可选参数,可使用一个自定义的首部。
if-none:仅在此首部不存在时才将其添加至请求报文问道中。

12,errorfile
在用户请求不存在的页面时,返回一个页面文件给客户端而非由haproxy生成的错误代码;可用于所有段中。

<code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504;
<file>:指定用于响应的页面文件;

13,ACL
haproxy的ACL用于实现基于请求报文的首部、响应报文的内容或其它的环境状态信息来做出转发决策,这大大增强了其配置弹性。其配置法则通常分为两步,首先去定义ACL,譬如用来做动静分离,定义ACL的语法格式如下。

acl <aclname> <criterion> [flags] [operator] <value> ...
<aclname>:ACL名称,区分字符大小写,且其只能包含大小写字母、数字、-(连接线)、_(下划线)、.(点号)和:(冒号);haproxy中,acl可以重名,这可以把多个测试条件定义为一个共同的acl;

<criterion>:测试标准,即对什么信息发起测试;测试方式可以由[flags]指定的标志进行调整;而有些测试标准也可以需要为其在<value>之前指定一个操作符[operator];

[flags]:目前haproxy的acl支持的标志位有3个:

-i:不区分<value>中模式字符的大小写;

-f:从指定的文件中加载模式;

--:标志符的强制结束标记,在模式中的字符串像标记符时使用;

<value>:acl测试条件支持的值有以下四类:

整数或整数范围:如1024:65535表示从1024至65535;仅支持使用正整数(如果出现类似小数的标识,其为通常为版本测试),且支持使用的操作符有5个,分别为eq、ge、gt、le和lt;

字符串:支持使用“-i”以忽略字符大小写,支持使用“\”进行转义;如果在模式首部出现了-i,可以在其之前使用“–”标志位;

正则表达式:其机制类同字符串匹配;

IP地址及网络地址

同一个acl中可以指定多个测试条件,这些测试条件需要由逻辑操作符指定其关系。条件间的组合测试关系有三种:与(默认即为与操作)、或(使用||操作符)以及非(使用“!”操作符)。
hdr <string>

hdr(header) <string>
用于测试请求报文中的所有首部或指定首部是否满足指定的条件;指定首部时,其名称不区分大小写,且在括号“()”中不能有任何多余的空白字符。测试服务器端的响应报文时可以使用shdr()。例如下面的例子用于测试首部Connection的值是否为close。
hdr(Connection) -i close

method <string>

method <string>
测试HTTP请求报文中使用的方法。

path_beg <string>

用于测试请求的URL是否以<string>指定的模式开头。下面的例子用于测试URL是否以/static、/images、/javascript或/stylesheets头。

acl url_static path_beg -i /static /images /javascript /stylesheets

path_end <string>

用于测试请求的URL是否以<string>指定的模式结尾。例如,下面的例子用户测试URL是否以jpg、gif、png、css或js结尾。

acl url_static path_end -i .jpg .gif .png .css .js

hdr_beg <string>

用于测试请求报文的指定首部的开头部分是否符合<string>指定的模式。例如,下面的例子用记测试请求是否为提供静态内容的主机img、video、download或ftp。

acl host_static hdr_beg(host) -i img. video. download. ftp.

hdr_end <string>

用于测试请求报文的指定首部的结尾部分是否符合<string>指定的模式。

定义独立日志

[root@hadoop01 haproxy]# vim /etc/sysconfig/rsyslog

SYSLOGD_OPTIONS="-r -c 2"
[root@hadoop01 haproxy]# vim /etc/rsyslog.conf 
$ModLoad imudp
$UDPServerRun 514 
$ModLoad imtcp
$InputTCPServerRun 514
local2.* /var/log/haproxy.log

Http代理示例:

global
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
frontend web:
    bind *:80
    acl url_static       path_beg        -i /img
    acl url_static       path_end        -i .jpg
    use_backend web_static      if url_static
    default_backend      webserver
backend web_static
    balance     roundrobin
    server  web_static  172.16.10.53:80 check maxconn 20000
backend webserver
    balance     roundrobin
    server  app1    172.16.10.53:80 check  maxconn 20000
    server  app2    172.16.10.54:80 check  maxconn 20000
listen statistics
    bind *:8009
    stats auth admin:admin # 统计页面用户名和密码设置
    stats uri /admin?stats # 自定义统计页面的URL,默认为/haproxy?stats
    stats hide-version # 隐藏统计页面上HAProxy的版本信息
    stats refresh 30s # 统计页面自动刷新时间
    stats admin if TRUE #如果认证通过就做管理功能,可以管理后端的服务器
    stats realm Hapadmin # 统计页面密码框上提示文本,默认为Haproxy\ Statistics

MySQL代理示例:

global
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats

defaults
    mode                    tcp
    log                     global
    option                  tcplog
    option                  dontlognull
    option http-server-close
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend mysql
    bind *:3306
    mode tcp
    log global
    default_backend      mysqlservers
backend mysqlservers
    balance     roundrobin
    server  ms1  172.16.10.53:3306 check inter 2 rise 1 fall 2 maxconn 400
    server  ms2  172.16.10.54:3306 check inter 2 rise 1 fall 2 maxconn 400
listen statistics
    bind *:8009
    mode http
    stats auth admin:admin # 统计页面用户名和密码设置
    stats uri /admin?stats # 自定义统计页面的URL,默认为/haproxy?stats
    stats hide-version # 隐藏统计页面上HAProxy的版本信息
    stats refresh 30s # 统计页面自动刷新时间
    stats admin if TRUE #如果认证通过就做管理功能,可以管理后端的服务器
    stats realm Hapadmin # 统计页面密码框上提示文本,默认为Haproxy\ Statistics

参考链接:
http://www.tianfeiyu.com/?p=1061
https://www.haproxy.org/download/1.5/doc/configuration.txt

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