MHA+ProxySQL实现Mysql的读写分离+高可用

一、前言

最近在研究完ProxySQL之后发现,当后端主从服务器的Master宕机之后,这个复制架构就需要人工介入重新部署Master。此时想着有没有什么版本能让后端的从服务器自动成为Master来接替宕机的Master的功能。后来百度了一下,发现MHA能实现这种需求。MHA,即Master High Availability Manager and Tools for MySQL,是日本的一位MySQL专家采用Perl语言编写的一个脚本管理工具,该工具仅适用于MySQL Replication(二层)环境,目的在于维持Master主库的高可用性。从架构上来说,MHA分为如下两大部分:

Node:我们知道,MHA是基于MySQL Replication环境的,在该环境中,不管是Master角色,还是Slave角色,都称为Node,是被监控管理的对象节点。 Node服务器上需要安装MHA Node包。
Manager:为MHA架构中的管理者,建议部署在一台独立的服务器上,当然也可部署在某个Slave上,但该Slave永远不要被选择成为新的Master,否则故障切换后的MHA架构就失去了高可用性。 Manager服务器需要安装MHA Manager包,并完善一个主配置文件。 一个Manager可管理多套MySQL Replication环境。

MHA的manager工具包主要包括以下几个工具:

masterha_check_ssh              检查MHA的SSH配置状况
masterha_check_repl             检查MySQL复制状况
masterha_manger                 启动MHA
masterha_check_status           检测当前MHA运行状态
masterha_master_monitor         检测master是否宕机
masterha_master_switch          控制故障转移(自动或者手动)
masterha_conf_host              添加或删除配置的server信息

本次实验我们采取一主两从的数据库复制架构,然后通过proxysql来代理主从服务,接着配置MHA来实现Master的高可用,其配置拓扑图如下:


部署拓扑图

二、配置数据库

此处我们配置数据库为半同步复制的主从架构。

1、构建master

首先配置master 的mariadb-server服务的配置文件:

[root@master ~]# vim /etc/my.cnf
skip-name-resolve=ON  ##取消解析登录主机名
log-bin=master.log    #启动master服务器的log-bin功能
innodb-file-per-table=ON
sync_binlog = 1  #默认,sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系统自己控制它的缓存的刷新。这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。
server_id=1  #mysql的同步的数据中是包含server-id的,用于标识该语句最初是从哪个server写入的,所以server-id一定要有的

然后启动mariadb服务并授权主从同步账号:

[root@master ~]# systemctl start mariadb
[root@master ~]# mysql
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO 'slave'@'192.168.0.%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

查看master服务器上对应的二进制日志名称及日志pos位置:

MariaDB [(none)]> show master status;
+---------------+----------+--------------+------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| master.000003 |      473 |              |                  |
+---------------+----------+--------------+------------------+
1 row in set (0.00 sec)

接着安装半同步复制的插件(非必要,可不配置,此处我纯当练手):

MariaDB [(none)]> install plugin rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.00 sec)

然后修改/etc/my.cnf文件,添加如下配置并重启mariadb服务启动半同步复制功能:

[root@master ~]# vim /etc/my.cnf
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=30000
[root@master ~]# systemctl restart mariadb

2、构建slave1和slave2

首先配置slave主机的配置文件:

skip-name-resolve=ON  #取消解析登录主机名
innodb-file-per-table=ON
relay-log=relay.log  #用于保存master服务器的binlog日志
read-only=ON  #设置从库为只读模式,但仅对非SUPER权限的用户有效
server_id=2    #slave1和slave2的server_id需修改为不一样,如2,3;

接着在slave主机上启动mariadb服务,并执行change master语句:

[root@slave2 ~]# systemctl start mariadb
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.0.82',MASTER_USER='slave',MASTER_PASSWORD='123456',MASTER_LOG_FILE='master.000003',MASTER_LOG_POS=473;
Query OK, 0 rows affected (0.06 sec)
MariaDB [(none)]> start slave;

然后安装slave的半同步插件(非必要,可不配置,此处我纯当练手):

MariaDB [(none)]> install plugin rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.00 sec)

最后修改/etc/my.cnf配置文件,添加下述配置并重启mariadb服务:

[root@slave2 ~]# vim /etc/my.cnf
rpl_semi_sync_slave_enabled=1
[root@slave2 ~]# systemctl restart mariadb

slave1 和slave2的配置雷同,可参考上述模板进行配置。

至此数据库相关的配置就配置完了。

三、配置ProxySQL

在proxysql主机上安装proxysql服务:

[root@proxysql ~]# yum install -y https://www.percona.com/downloads/proxysql/proxysql-1.4.8/binary/redhat/7/x86_64/proxysql-1.4.8-1.1.el7.x86_64.rpm
[root@proxysql ~]# systemctl start proxysql

在配置proxySQL服务之前,首先在后端数据库中添加相应的proxysql授权账号:

MariaDB [(none)]> grant all on *.* to 'proxysql'@'192.168.0.%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

接着在proxysql主机的本地连接proxysql的管理接口,然后配置proxysql服务:

[root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032
#添加proxysql用于访问后端数据库
MySQL [(none)]> insert into mysql_users(username,password,default_hostgroup,transaction_persistent) values('proxysql','123456',0,1);
Query OK, 1 row affected (0.00 sec)

#添加做健康检测的账号
MySQL [(none)]> set mysql-monitor_username='proxysql';
Query OK, 1 row affected (0.00 sec)
MySQL [(none)]> set mysql-monitor_password='123456';
Query OK, 1 row affected (0.00 sec)

#添加后端数据库主机,hostgroup_id 0表示写组,1表示读组
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(0,'192.168.0.82',3306,1,'Write Group');
Query OK, 1 row affected (0.00 sec)
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.0.87',3306,1,'Read Group');
Query OK, 1 row affected (0.00 sec)

#将insert这样的修改语句路由到0组(写组)
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port,weight,comment) values(1,'192.168.0.89',3306,1,'Read Group');
Query OK, 1 row affected (0.00 sec)

#将select语句全部路由至hostgroup_id=1的组(也就是读组)
MySQL [(none)]>  insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(1,1,'^INSERT.*',0,0);
Query OK, 1 row affected (0.00 sec)

#将select语句全部路由至hostgroup_id=1的组(也就是读组)
MySQL [(none)]> insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(2,1,'^SELECT',1,0);
Query OK, 1 row affected (0.00 sec)

#将show语句全部路由至hostgroup_id=1的组(也就是读组)
MySQL [(none)]> insert into mysql_query_rules(rule_id,active,match_digest,destination_hostgroup,apply)values(3,1,'^SHOW',1,0);
Query OK, 1 row affected (0.00 sec)

MySQL [(none)]> select rule_id,active,match_digest,destination_hostgroup,apply from mysql_query_rules;
+---------+--------+--------------+-----------------------+-------+
| rule_id | active | match_digest | destination_hostgroup | apply |
+---------+--------+--------------+-----------------------+-------+
| 1       | 1      | ^INSERT.*    | 0                     | 0     |
| 2       | 1      | ^SELECT      | 1                     | 0     |
| 3       | 1      | ^SHOW        | 1                     | 0     |
+---------+--------+--------------+-----------------------+-------+
3 rows in set (0.00 sec)

#添加mysql_replication_groups,此配置用于与MHA结合实现高可用
MySQL [(none)]> insert into  mysql_replication_hostgroups (writer_hostgroup,reader_hostgroup,comment)values(0,1,'test with proxysql and MHA');
Query OK, 1 row affected (0.00 sec)
MySQL [(none)]>  select * from runtime_mysql_replication_hostgroups;
+------------------+------------------+----------------------------+
| writer_hostgroup | reader_hostgroup | comment                    |
+------------------+------------------+----------------------------+
| 0                | 1                | test with proxysql and MHA |
+------------------+------------------+----------------------------+
1 row in set (0.01 sec)


#加载刚才添加的配置
MySQL [(none)]> load mysql users to runtime;
Query OK, 0 rows affected (0.00 sec)
MySQL [(none)]> load mysql servers to runtime;
Query OK, 0 rows affected (0.01 sec)
MySQL [(none)]> load mysql variables to runtime;
Query OK, 0 rows affected (0.00 sec)
MySQL [(none)]> load admin variables to runtime;
Query OK, 0 rows affected (0.00 sec)
MySQL [(none)]> load mysql query rules to runtime;
Query OK, 0 rows affected (0.00 sec)

#保存配置至db文件中
MySQL [(none)]> save mysql users to disk;
Query OK, 0 rows affected (0.01 sec)
MySQL [(none)]> save mysql servers to disk;
Query OK, 0 rows affected (0.01 sec)
MySQL [(none)]>  save mysql query rules to disk;
Query OK, 0 rows affected (0.02 sec)
MySQL [(none)]> save mysql variables to disk;
Query OK, 94 rows affected (0.01 sec)
MySQL [(none)]> save admin variables to disk;
Query OK, 31 rows affected (0.00 sec)

配置完成后,应能够通过192.168.0.81的6033端口访问后端的数据库服务,如:

[root@proxysql ~]# mysql -uproxysql -p123456 -h192.168.0.81 -P6033
MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hellodb            |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)

MySQL [(none)]> 
MySQL [(none)]> select * from hellodb.students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name          | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
|     1 | Shi Zhongyu   |  22 | M      |       2 |         3 |
|     2 | Shi Potian    |  22 | M      |       1 |         7 |
|     3 | Xie Yanke     |  53 | M      |       2 |        16 |
|     4 | Ding Dian     |  32 | M      |       4 |         4 |
|     5 | Yu Yutong     |  26 | M      |       3 |         1 |
|     6 | Shi Qing      |  46 | M      |       5 |      NULL |
|     7 | Xi Ren        |  19 | F      |       3 |      NULL |
|     8 | Lin Daiyu     |  17 | F      |       7 |      NULL |
|     9 | Ren Yingying  |  20 | F      |       6 |      NULL |
|    10 | Yue Lingshan  |  19 | F      |       3 |      NULL |
|    11 | Yuan Chengzhi |  23 | M      |       6 |      NULL |
|    12 | Wen Qingqing  |  19 | F      |       1 |      NULL |
|    13 | Tian Boguang  |  33 | M      |       2 |      NULL |
|    14 | Lu Wushuang   |  17 | F      |       3 |      NULL |
|    15 | Duan Yu       |  19 | M      |       4 |      NULL |
|    16 | Xu Zhu        |  21 | M      |       1 |      NULL |
|    17 | Lin Chong     |  25 | M      |       4 |      NULL |
|    18 | Hua Rong      |  23 | M      |       7 |      NULL |
|    19 | Xue Baochai   |  18 | F      |       6 |      NULL |
|    20 | Diao Chan     |  19 | F      |       7 |      NULL |
|    21 | Huang Yueying |  22 | F      |       6 |      NULL |
|    22 | Xiao Qiao     |  20 | F      |       1 |      NULL |
|    23 | Ma Chao       |  23 | M      |       4 |      NULL |
|    24 | Xu Xian       |  27 | M      |    NULL |      NULL |
|    25 | Sun Dasheng   | 100 | M      |    NULL |      NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.01 sec)
MySQL [(none)]> insert into hellodb.students values (26,'Jin Yong',75,'M',2,3);
Query OK, 1 row affected (0.01 sec)

此时在proxysql的管理接口中,通过下述命令可以查看proxysql的工作情况:

[root@proxysql ~]# mysql -uadmin -padmin -h127.0.0.1 -P6032

MySQL [(none)]> select * from stats_mysql_query_digest;
+-----------+--------------------+----------+--------------------+---------------------------------------------------+------------+------------+------------+----------+----------+----------+
| hostgroup | schemaname         | username | digest             | digest_text                                       | count_star | first_seen | last_seen  | sum_time | min_time | max_time |
+-----------+--------------------+----------+--------------------+---------------------------------------------------+------------+------------+------------+----------+----------+----------+
| 0         | information_schema | proxysql | 0xF705DF6D769FEE0D | insert into hellodb.students values (?,?,?,?,?,?) | 1          | 1530285228 | 1530285228 | 6063     | 6063     | 6063     |
| 0         | information_schema | proxysql | 0x65E26382DB42BC29 | insert into hellodb.students values (?,?,?,M,?,?) | 1          | 1530285224 | 1530285224 | 4176     | 4176     | 4176     |
| 1         | information_schema | proxysql | 0x234E67CE83C9D8AD | select * from hellodb.students                    | 1          | 1530285184 | 1530285184 | 5992     | 5992     | 5992     |
| 1         | information_schema | proxysql | 0x02033E45904D3DF0 | show databases                                    | 1          | 1530285175 | 1530285175 | 3938     | 3938     | 3938     |
+-----------+--------------------+----------+--------------------+---------------------------------------------------+------------+------------+------------+----------+----------+----------+
5 rows in set (0.00 sec)

相关的语句均都proxysql代理到指定的hostgroup中,说明proxysql工作正常。

四、配置MHA

在配置完成proxysql+mysql半同步主从后,最后我们来配置MHA提供Mysql的高可用。因此MHA架构分为Manger和node,因此我需要在各监控的节点上安装mha4mysql-node,然后在MHA节点上安装mha4mysql-node和mha4mysql-manager。

1、安装mha4mysql-node

在各数据库节点及MHA主机上安装mha4mysql-node的rpm包:

[root@slave2 ~]# yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm 

2、安装mha4mysql-manager

另外还需要在MHA管理节点上安装mha4mysql-manager:

#部分依赖包需要安装epel-release来提供
[root@MHA ~]# yum install -y mha4mysql-manager-0.56-0.el6.noarch.rpm

3、修改各数据库节点的配置文件并授权MHA管理账号

在两个slave节点上编辑/etc/my.cnf,添加下述配置后重启mariadb服务:

[root@slave2 ~]# vim /etc/my.cnf
relay_log_purge=0    #关闭中继日志自动修剪功能,因为中继日志默认会自动修剪,此时为了以后各从服务器之间的执行过的操作对比
log-bin=master.log    #因为slave有可能会变成master ,因此需要开启binlog日志
[root@slave2 ~]# systemctl restart mariadb

在Master节点的/etc/my.cnf文件上,添加下述配置并重启mariadb服务:

[root@master ~]# vim /etc/my.cnf
relay-log=relay-bin    #因为master有可能会变成slave,所以需要开启中继日志
[root@master ~]# systemctl restart mariadb

授权MHA管理账号:

MariaDB [(none)]> GRANT ALL ON *.* TO 'mhauser'@'192.168.0.%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

4、配置MHA各节点之间的SSH免密钥登录

在MHA管理节点上输入下述命令:

[root@MHA ~]# ssh-keygen -t rsa -P ""
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:NwX89jz5FtOyaeeQe9Ik1nfwWDTBFE7Uf45DjdCPxgM root@MHA
The key's randomart image is:
+---[RSA 2048]----+
|         ..  .+*+|
|          ..E +oo|
|           ..+ Bo|
|           .o O *|
|        S o. = @o|
|         . .  %+O|
|             .o@=|
|              =o*|
|             ..*.|
+----[SHA256]-----+
[root@MHA ~]# cat .ssh/id_rsa.pub >> .ssh/authorized_keys
[root@MHA ~]# chmod go= .ssh/authorized_keys 
[root@MHA ~]# scp -p .ssh/id_rsa .ssh/authorized_keys root@192.168.0.82:/root/.ssh/
[root@MHA ~]# scp -p .ssh/id_rsa .ssh/authorized_keys root@192.168.0.87:/root/.ssh/
[root@MHA ~]# scp -p .ssh/id_rsa .ssh/authorized_keys root@192.168.0.89:/root/.ssh/
#注意:请事先确保各节点上/root/.ssh目录存在

5、配置MHA

首先创建MHA的配置文件:

[root@MHA ~]# vim /etc/masterha/app.cnf

[server default]
user=mhauser  # MySQL 管理员,用来管理各个节点
password=123456
manager_workdir=/data/masterha/app1  #这个目录/data/masterha/app1不需要创建,不存在时会自动创建
manager_log=/data/masterha/app1/manager.log
remote_workdir=/data/masterha/app1   #指各个node节点的工作目录,自动创建
ssh_user=root
ssh_port=22
repl_user=slave    #此处使用此前做mysql 主从时的repl账号,注意需确保此账号在master和slave中都存在
repl_password=123456
ping_interval=1  #多长时间检测一次

[server1]
hostname=192.168.0.82
candidate_master=1

[server2]
hostname=192.168.0.87
candidate_master=1  #将来是否可以成为主节点,如果不定义,就不能成为候选的主节点

[server3]
hostname=192.168.0.89
candidate_master=1
#no_master=1 #如果定义no_master就不能成为主节点

创建配置完配置文件后,可以使用命令masterha_check_ssh来检查各节点的ssh连通性:

[root@MHA ~]# masterha_check_ssh --conf=/etc/masterha/app.cnf 
.....
MySQL Replication Health is OK.
#若最后一行出现上述信息,说明检查成功;如有报错,请根据报错进行排查。

最后启动MHA,需注意的是,masterha_manager没有启动程序,需手动启动服务:

[root@MHA ~]# nohup masterha_manager --conf=/etc/masterha/app.cnf > /data/masterha/app1/manager.log 2>& 1 &
[1] 11941
[root@MHA ~]# ps aux | grep masterha_manager | grep -v grep
root      11941  3.1  2.1 297132 21592 pts/1    S    13:13   0:00 perl /usr/bin/masterha_manager --conf=/etc/masterha/app.cnf

启动成功后,可通过如下命令来查看 master 节点的状态。

[root@MHA ~]# masterha_check_status --conf=/etc/masterha/app.cnf
app (pid:11429) is running(0:PING_OK), master:192.168.0.82

上述信息表示MHA服务运行正常,否则会显示为类似于“app is stopped”类似的字眼。

若需要停止MHA,需要使用masterha_stop命令:

[root@MHA ~]# masterha_stop --conf=/etc/masterha/app.cnf 
Stopped app successfully.
[1]+  Exit 1                  nohup masterha_manager --conf=/etc/masterha/app.cnf > /data/masterha/app1/mnager.log 2>&1

6、测试故障转移

在master 节点关闭mariadb服务:

[root@master ~]# systemctl stop mariadb

在MHA管理节点上如果能在/data/masterha/app1/manager.log日志文件中查看到如下信息,说明manager检查到192.168.0.82节点故障,并自动执行故障转移了,将192.168.0.87提升为主节点:

----- Failover Report -----

app: MySQL Master failover 192.168.0.82(192.168.0.82:3306) to 192.168.0.87(192.168.0.87:3306) succeeded

Master 192.168.0.82(192.168.0.82:3306) is down!

Check MHA Manager logs at MHA:/data/masterha/app1/manager.log for details.

Started automated(non-interactive) failover.
The latest slave 192.168.0.87(192.168.0.87:3306) has all relay logs for recovery.
Selected 192.168.0.87(192.168.0.87:3306) as a new master.
192.168.0.87(192.168.0.87:3306): OK: Applying all logs succeeded.
192.168.0.89(192.168.0.89:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
192.168.0.89(192.168.0.89:3306): OK: Applying all logs succeeded. Slave started, replicating from 192.168.0.87(192.168.0.87:3306)
192.168.0.87(192.168.0.87:3306): Resetting slave info succeeded.
Master failover to 192.168.0.87(192.168.0.87:3306) completed successfully.

此时登录Proxysql的管理接口查看相应的servers状态:

MySQL [(none)]> select * from mysql_servers;
+--------------+--------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| hostgroup_id | hostname     | port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment     |
+--------------+--------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
| 0            | 192.168.0.87 | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Read Group  |
| 1            | 192.168.0.82 | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Write Group |
| 1            | 192.168.0.89 | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Read Group  |
| 1            | 192.168.0.87 | 3306 | ONLINE | 1      | 0           | 1000            | 0                   | 0       | 0              | Read Group  |
+--------------+--------------+------+--------+--------+-------------+-----------------+---------------------+---------+----------------+-------------+
4 rows in set (0.00 sec)

从上述信息发现,192.168.0.87被提升为hostgroup 0(写组),而192.168.0.82则变成hostgroup 1(读组)。这是因为proxysql的mysql_replication_hostgroups表配置的原因,mysql_replication_hostgroups 表的主要作用是监视指定主机组中所有服务器的read_only值,并且根据read_only的值将服务器分配给写入器或读取器主机组,从而定义 hostgroup 的主从关系。ProxySQL monitor 模块会监控后端所有servers 的 read_only 变量,如果发现从库的 read_only 变为0、主库变为1,则认为角色互换了,自动改写 mysql_servers 表里面 hostgroup 的数值,达到自动 Failover 效果。因此当MHA把后端的Master更改为192.168.0.87的时候,ProxySQL也能够将相应的192.168.0.87调整为写组。

结尾

最后配置完做冗余切换的时候发现,mysql主从的半同步在MHA高可用切换后就失效了(因为master变更了),新的master上也没有启动相关的master插件,那估计还得重启新master的mariadb服务才能重做,这时候相当于数据库要停机了,后面我再研究下看看是否有其他解决办法。

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

推荐阅读更多精彩内容