SuSE11环境下Redis+Keepalived实现高可用技术

1.Redis配置信息
Redis部署使用两台服务器,实现Redis+keepalived,提供redis服务高可用,当主redis进程或服务器宕机之后,备redis进程或服务器继续提供服务。

实现目的:主MASTER宕机后,从BACKUP接管VIP提供服务,升为MASTER,主MASTER恢复后状态变为从BACKUP,不抢占回VIP,待新MASTER宕机后继续接替VIP,重新升为MASTER

                 MASTER-->BACKUP-->MASTER 依次轮询接管服务

服务器配置信息如下所示:

主机名/IP

端口

用途

JZSHPT-APP5/

10.133.214.15

6379

Redis主服务器

JZSHPT-APP6/

10.133.214.16

6379

Redis从服务器

2.Redis主服务器搭建
2.1.安装redis
JZSHPT-APP5:/soft # tar -zxf redis-3.2.1.tar.gz -C /usr/local

JZSHPT-APP5:/soft # cd /usr/local/redis-3.2.1/

JZSHPT-APP5:/usr/local/redis-3.2.1 # make

JZSHPT-APP5:/usr/local/redis-3.2.1 # cd src && make install

JZSHPT-APP5:/usr/local # mv /usr/local/redis-3.2.1/ /usr/local/redis

1)redis配置文件修改

JZSHPT-APP5:/usr/local # vim /usr/local/redis/redis.conf

修改文件相关内容为:

protected-mode no

port 6379

daemonize yes

pidfile /usr/local/redis/redis.pid

logfile "/usr/local/redis/redis.log"

2)redis启动脚本编写(非必须)

JZSHPT-APP5:/usr/local/redis # vim /etc/init.d/redisd

#!/bin/sh

#chkconfig 345 86 14

#description Startup and Shutdown script for Redis-3.2.1

progdir=/usr/local/redis/src

progname=redis-server

daemon=$progdir/$progname

config=/usr/local/redis/redis.conf

pidfile=/usr/local/redis/redis.pid

desc="redis daemon"

scriptname=/etc/init.d/redisd

start()

{

if test -x $daemon;

then

echo -e "Starting $desc:$progname"

    if $daemon $config

    then

        echo -e "Start OK!!!"

    else

         echo -e "Start failed!!!"

    fi  

else

echo -e "Couldn‘t find Redis Server($daemon)"

fi  

}

stop()

{

if test -e $pidfile;

then

    echo -e "Stopping $desc:$progname"

    if kill `cat $pidfile`

    then

        echo -e "stop OK!!!"

    else

        echo -e "Stop failed!!!"

    fi

else

    echo -e "No Redis Server($daemoon) running"

fi

}

restart()

{

echo -e "Restarting $desc:$progname"

stop

    start

}

status()

{

ps aux | grep $progname

}

case $1 in

start)

    start

;;

stop)

    stop

;;

restart)

restart

;;

status)

status

;;

*)

echo "Usage:$scriptnme{start|stop|restart|status}" >&2

exit 1

;;

esac

exit 0

JZSHPT-APP5:/usr/local/redis # chmod +x /etc/init.d/redisd

JZSHPT-APP5:/usr/local/redis # chkconfig --add redisd

2.2.安装Keepalived
安装keepalived前请自行安装解决依赖关系(可能会涉及的软件包为libopenssl-devel、zlib-devel、ipvsadm内核模块等)

JZSHPT-APP5:/soft # tar -zxf keepalived-1.2.23.tar.gz

JZSHPT-APP5:/soft # cd keepalived-1.2.23/

JZSHPT-APP5:/soft/keepalived-1.2.23 # ./configure --prefix=/usr/local/keepalived/

JZSHPT-APP5:/soft/keepalived-1.2.23 # make && make install

1) keepalived配置文件编辑

JZSHPT-APP5:~ # mkdir -p /etc/keepalived/{scripts,log}

JZSHPT-APP5:~ # vim /usr/local/keepalived/etc/keepalived/

! Configuration File for keepalived

global_defs {

router_id Redis1_DEVEL

}

vrrp_script chk_redis {

     script "/etc/keepalived/scripts/redis_check.sh"

     interval 2

     timeout 2

     fall 3

}

vrrp_instance VI_1 {

 state BACKUP

 interface eth0

 virtual_router_id 51

 nopreempt

 priority 200

  advert_int 5

  authentication {

auth_type PASS

    auth_pass redis

 }

 virtual_ipaddress {

     10.133.214.50

 }

 track_script {

     chk_redis

}

    notify_master /etc/keepalived/scripts/redis_master.sh

     notify_backup /etc/keepalived/scripts/redis_backup.sh

     notify_fault  /etc/keepalived/scripts/redis_fault.sh

     notify_stop   /etc/keepalived/scripts/redis_stop.sh

}

2)keepalived启动脚本配置

JZSHPT-APP5:~ # cp /soft/keepalived-1.2.23/keepalived/etc/init.d/keepalived.suse.init /etc/init.d/keepalived.suse

JZSHPT-APP5:~ # cp /usr/local/keepalived/sbin/keepalived /usr/local/sbin/

JZSHPT-APP5:~ # cp /usr/local/keepalived/etc/keepalived/ /etc/keepalived/

3)定义监控脚本

JZSHPT-APP5:~ # vim /etc/keepalived/scripts/redis_check.sh

#!/bin/sh

###/etc/keepalived/scripts/redis_check.sh

ALIVE=/usr/local/bin/redis-cli PING

if [ "$ALIVE" == "PONG" ]; then

echo $ALIVE

exit 0

else

echo $ALIVE

exit 1

fi

4)定义状态切换为master时执行的脚本

JZSHPT-APP5:~ # vim /etc/keepalived/scripts/redis_master.sh

#!/bin/sh

###/etc/keepalived/scripts/redis_master.sh

REDISCLI="redis-cli"

LOGFILE="/etc/keepalived/log/redis-state.log"

pid=$$

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver]" >> $LOGFILE

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver] Run ‘SLAVEOF 10.133.214.16 6379‘" >> $LOGFILE

$REDISCLI SLAVEOF 10.133.214.16 6379 >> $LOGFILE 2>&1

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver] wait 10 sec for data sync from old master" >> $LOGFILE

sleep 10

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver] data rsync from old mater ok..." >> $LOGFILE

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master] Run slaveof no one,close master/slave" >> $LOGFILE

$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master] wait other slave connect...." >> $LOGFILE

5)定义状态切换为backups时执行的脚本

JZSHPT-APP5:~ # vim /etc/keepalived/scripts/redis_backup.sh

#!/bin/bash

###/etc/keepalived/scripts/redis_backup.sh

REDISCLI="redis-cli"

LOGFILE="/etc/keepalived/log/redis-state.log"

pid=$$

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master]" >> $LOGFILE

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master] Being slave state..." >> $LOGFILE 2>&1

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master] wait 10 sec for data sync from old master" >> $LOGFILE

sleep 10

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master] data rsync from old mater ok..." >> $LOGFILE

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver] Run ‘SLAVEOF 10.133.214.16 6379‘" >> $LOGFILE

$REDISCLI SLAVEOF 10.133.214.16 6379 >> $LOGFILE 2>&1

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver] slave connect to 192.18.3.21 ok..." >> $LOGFILE

6) 定义状态切换为stop时执行的脚本

JZSHPT-APP5:~ # cp /etc/keepalived/scripts/redis_backup.sh /etc/keepalived/scripts/redis_stop.sh

7) 定义状态切换为fault时执行的脚本

JZSHPT-APP5:~ # cp /etc/keepalived/scripts/redis_backup.sh /etc/keepalived/scripts/redis_fault.sh

2.2.安装rsyslog实现keepalived日志分离
1)安装rsyslog软件包

JZSHPT-APP5:/soft # rpm -ivh rsyslog-5.10.1-0.7.49.x86_64.rpm

2)修改rsyslog配置文件

JZSHPT-APP5:/soft # vim /etc/rsyslog.conf

140 #.;mail.none;news.none -/var/log/messages

141 .;mail.none;news.none;local0.none -/var/log/messages

153 #local0,local1.* -/var/log/localmessages

154 local0.* -/var/log/keepalived.log

155 local1.* -/var/log/localmessages

156 local2,local3.* -/var/log/localmessages

157 local4,local5.* -/var/log/localmessages

158 cal6,local7.* -/var/log/localmessages

3)修改rsyslog启动脚本配置文件

根据/etc/init.d/syslog中的三个启动选项,修改该文件内的”SYSLOG_DAEMON”选项

JZSHPT-APP5:/soft # vim /etc/sysconfig/syslog

40 #SYSLOG_DAEMON="syslog-ng"

41 SYSLOG_DAEMON="rsyslogd"

4)修改Keepalived启动脚本选项

JZSHPT-APP5:/soft # vim /etc/init.d/keepalived.suse

17 DAEMON_OPT="-d "

18 DAEMON_OPT="-d -D -S 0"

5)启动rsyslog服务

JZSHPT-APP5:/soft # /etc/init.d/syslog start

2.3.启动Redis和Keepalived
JZSHPT-APP5:~ # /etc/init.d/redisd start

JZSHPT-APP5:~ # /etc/init.d/keepalived.suse start

3.Redis从服务器搭建
3.1.安装redis
JZSHPT-APP6:/soft # tar -zxf redis-3.2.1.tar.gz -C /usr/local

JZSHPT-APP6:/soft # cd /usr/local/redis-3.2.1/

JZSHPT-APP6:/usr/local/redis-3.2.1 # make

JZSHPT-APP6:/usr/local/redis-3.2.1 # cd src && make install

JZSHPT-APP6:/usr/local # mv /usr/local/redis-3.2.1/ /usr/local/redis

1)redis配置文件修改

JZSHPT-APP6:/usr/local # vim /usr/local/redis/redis.conf

修改文件相关内容为:

protected-mode no

port 6379

daemonize yes

pidfile /usr/local/redis/redis.pid

logfile "/usr/local/redis/redis.log"

2)redis启动脚本编写(非必须)

JZSHPT-APP6:/usr/local/redis # vim /etc/init.d/redisd

#!/bin/sh

#chkconfig 345 86 14

#description Startup and Shutdown script for Redis-3.2.1

progdir=/usr/local/redis/src

progname=redis-server

daemon=$progdir/$progname

config=/usr/local/redis/redis.conf

pidfile=/usr/local/redis/redis.pid

desc="redis daemon"

scriptname=/etc/init.d/redisd

start()

{

if test -x $daemon;

then

echo -e "Starting $desc:$progname"

    if $daemon $config

    then

        echo -e "Start OK!!!"

    else

         echo -e "Start failed!!!"

    fi  

else

echo -e "Couldn‘t find Redis Server($daemon)"

fi  

}

stop()

{

if test -e $pidfile;

then

    echo -e "Stopping $desc:$progname"

    if kill `cat $pidfile`

    then

        echo -e "stop OK!!!"

    else

        echo -e "Stop failed!!!"

    fi

else

    echo -e "No Redis Server($daemoon) running"

fi

}

restart()

{

echo -e "Restarting $desc:$progname"

stop

    start

}

status()

{

ps aux | grep $progname

}

case $1 in

start)

    start

;;

stop)

    stop

;;

restart)

restart

;;

status)

status

;;

*)

echo "Usage:$scriptnme{start|stop|restart|status}" >&2

exit 1

;;

esac

exit 0

JZSHPT-APP6:/usr/local/redis # chmod +x /etc/init.d/redisd

JZSHPT-APP6:/usr/local/redis # chkconfig --add redisd

3.2.安装Keepalived
安装keepalived前请自行安装解决依赖关系(可能会涉及的软件包为libopenssl-devel、zlib-devel、ipvsadm内核模块等)

JZSHPT-APP6:/soft # tar -zxf keepalived-1.2.23.tar.gz

JZSHPT-APP6:/soft # cd keepalived-1.2.23/

JZSHPT-APP6:/soft/keepalived-1.2.23 # ./configure --prefix=/usr/local/keepalived/

JZSHPT-APP6:/soft/keepalived-1.2.23 # make && make install

1)keepalived配置文件编辑

JZSHPT-APP6:~ # mkdir -p /etc/keepalived/{scripts,log}

JZSHPT-APP6:~ # vim /usr/local/keepalived/etc/keepalived/

! Configuration File for keepalived

global_defs {

router_id Redis2_DEVEL

}

vrrp_script chk_redis {

     script "/etc/keepalived/scripts/redis_check.sh"

     interval 2

     timeout 2

     fall 3

}

vrrp_instance VI_1 {

 state BACKUP

 interface eth0

 virtual_router_id 51

 priority 150

  advert_int 5

  authentication {

auth_type PASS

    auth_pass redis

 }

 virtual_ipaddress {

     10.133.214.50

 }

 track_script {

     chk_redis

}

    notify_master /etc/keepalived/scripts/redis_master.sh

     notify_backup /etc/keepalived/scripts/redis_backup.sh

     notify_fault  /etc/keepalived/scripts/redis_fault.sh

     notify_stop   /etc/keepalived/scripts/redis_stop.sh

}

2)keepalived启动脚本配置

JZSHPT-APP6:~ # cp /soft/keepalived-1.2.23/keepalived/etc/init.d/keepalived.suse.init /etc/init.d/keepalived.suse

JZSHPT-APP6:~ # cp /usr/local/keepalived/sbin/keepalived /usr/local/sbin/

JZSHPT-APP6:~ # cp /usr/local/keepalived/etc/keepalived/ /etc/keepalived/

3)定义监控脚本

JZSHPT-APP6:~ # vim /etc/keepalived/scripts/redis_check.sh

#!/bin/sh

###/etc/keepalived/scripts/redis_check.sh

ALIVE=/usr/local/bin/redis-cli PING

if [ "$ALIVE" == "PONG" ]; then

echo $ALIVE

exit 0

else

echo $ALIVE

exit 1

fi

4)定义状态切换为master时执行的脚本

JZSHPT-APP6:~ # vim /etc/keepalived/scripts/redis_master.sh

#!/bin/sh

###/etc/keepalived/scripts/redis_master.sh

REDISCLI="redis-cli"

LOGFILE="/etc/keepalived/log/redis-state.log"

pid=$$

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver]" >> $LOGFILE

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver] Run ‘SLAVEOF 10.133.214.15 6379‘" >> $LOGFILE

$REDISCLI SLAVEOF 10.133.214.15 6379 >> $LOGFILE 2>&1

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver] wait 10 sec for data sync from old master" >> $LOGFILE

sleep 10

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver] data rsync from old mater ok..." >> $LOGFILE

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master] Run slaveof no one,close master/slave" >> $LOGFILE

$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master] wait other slave connect...." >> $LOGFILE

5)定义状态切换为backups时执行的脚本

JZSHPT-APP6:~ # vim /etc/keepalived/scripts/redis_backup.sh

#!/bin/bash

###/etc/keepalived/scripts/redis_backup.sh

REDISCLI="redis-cli"

LOGFILE="/etc/keepalived/log/redis-state.log"

pid=$$

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master]" >> $LOGFILE

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master] Being slave state..." >> $LOGFILE 2>&1

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master] wait 10 sec for data sync from old master" >> $LOGFILE

sleep 10

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[master] data rsync from old mater ok..." >> $LOGFILE

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver] Run ‘SLAVEOF 10.133.214.15 6379‘" >> $LOGFILE

$REDISCLI SLAVEOF 10.133.214.15 6379 >> $LOGFILE 2>&1

echo "date +‘%Y-%m-%d:%H:%M:%S‘|$pid|state:[slaver] slave connect to 10.133.214.15 ok..." >> $LOGFILE

6) 定义状态切换为stop时执行的脚本

JZSHPT-APP6:~ # cp /etc/keepalived/scripts/redis_backup.sh /etc/keepalived/scripts/redis_stop.sh

7) 定义状态切换为fault时执行的脚本

JZSHPT-APP6:~ # cp /etc/keepalived/scripts/redis_backup.sh /etc/keepalived/scripts/redis_fault.sh

3.3.安装rsyslog实现keepalived日志分离
1)安装rsyslog软件包

JZSHPT-APP5:/soft # rpm -ivh rsyslog-5.10.1-0.7.49.x86_64.rpm

2)修改rsyslog配置文件

JZSHPT-APP5:/soft # vim /etc/rsyslog.conf

140 #.;mail.none;news.none -/var/log/messages

141 .;mail.none;news.none;local0.none -/var/log/messages

153 #local0,local1.* -/var/log/localmessages

154 local0.* -/var/log/keepalived.log

155 local1.* -/var/log/localmessages

156 local2,local3.* -/var/log/localmessages

157 local4,local5.* -/var/log/localmessages

159 cal6,local7.* -/var/log/localmessages

3)修改rsyslog启动脚本配置文件

根据/etc/init.d/syslog中的三个启动选项,修改该文件内的”SYSLOG_DAEMON”选项

JZSHPT-APP5:/soft # vim /etc/sysconfig/syslog

40 #SYSLOG_DAEMON="syslog-ng"

41 SYSLOG_DAEMON="rsyslogd"

4)修改Keepalived启动脚本选项

JZSHPT-APP5:/soft # vim /etc/init.d/keepalived.suse

17 DAEMON_OPT="-d "

18 DAEMON_OPT="-d -D -S 0"

5)启动rsyslog服务

JZSHPT-APP5:/soft # /etc/init.d/syslog start

3.4.启动Redis和Keepalived
JZSHPT-APP6:~ # /etc/init.d/redisd start

JZSHPT-APP6:~ # /etc/init.d/keepalived.suse start

测试结果可通过依次停Redis主从单节点来观测vip漂移

原文地址:http://blog.51cto.com/11612019/2156425

时间: 2024-10-10 20:54:42

SuSE11环境下Redis+Keepalived实现高可用技术的相关文章

【OGG】 RAC环境下管理OGG的高可用 (五)

[OGG] RAC环境下管理OGG的高可用 (五) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① RAC环境下管理OGG的高可用 注意:本篇BLOG中代码部分需要特别关注的地方我都用黄色背景和红色字体来表示,比如下边的例子中,thread 1的最大归档日志号为33,thread 2的最大归档日志号为43是需要特别关注的地方. List of Archived L

redis+keepalived实现高可用

Redis简介: Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发工作由VMware主持. redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set –有序集合)和hash(哈希类型).这些数据类型都支持push/pop.ad

Centos6下nginx+keepalived构建高可用web集群

1)拓扑描述: 2) nginx的安装准备 pcre:兼容的正则表达式,nginx也要支持伪静态 # yum -y install pcre pcre-devel # yum -y install openssl* # mkdir -p /application/nginx1.6.2 # ln -s /application/nginx1.6.2 /application/nginx 3) 安装nginx # cd /usr/local/src # tar xf nginx-1.6.2.tar.

Linux下HAProxy+keepalived双机高可用方案

Keepalived 的作用是检测web服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到,并将有故障的web服务器从系统中剔除, 当web服务器工作正常后Keepalived自动将web服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的 web服务器. HAProxy 提供高可用性.负载均衡以及基于 TCP 和 HTTP 应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy 特别适用于那些负载特

redis主从配置及通过keepalived实现redis自动切换高可用

一:环境介绍: Master: 192.168.1.4 Slave: 192.168.1.5 Virtural IP Address (VIP): 192.168.1.253 二:设计思路: 当 Master 与 Slave 均运作正常时, Master负责服务,Slave负责Standby: 当 Master 挂掉,Slave 正时, Slave接管服务,同时关闭主从复制功能: 当 Master 恢复正常,则从Slave同步数据,同步数据之后关闭主从复制功能,恢复Master身份,于此同时Sl

18.1 集群介绍;18.2 keepalived介绍;18.3,18.4,18.5 用keepalived配置高可用集群(上,中,下);

18.1 集群介绍 1. 根据功能划分为两大类:高可用和负载均衡 2. 高可用集群通常为两台服务器,一台工作,另外一台作为冗余,当提供服务的机器宕机,冗余将接替继续提供服务 3. 实现高可用的开源软件有:heartbeat.keepalived 负载均衡集群,需要有一台服务器作为分发器,它负责把用户的请求分发给后端的服务器处理,在这个集群里,除了分发器外,就是给用户提供服务的服务器了,这些服务器数量至少为2 4. 实现负载均衡的开源软件有LVS.keepalived.haproxy.nginx,

Redis 之 主从复制 + Keepalived 实现高可用

一.Redis 主从复制 + Keepalived 实现高可用 作用:保证Redis高可用,首先搭建Redis 主从复制,然后在主从两台机器上分别安装keepalived服务,把VIP定位在主Redis上,以供对外提供服务,然后在主服务机器上,添加守护进程,判断redis进程是否正常,如不正常,把keepalived服务停止,使VIP漂移到从服务器上,并且在从服务器上添加相应的守护进程,实时判断VIP是否在本机上,如在,立刻执行从库提升为主库. 二.网络拓扑图 三.分别在两台机器安装Redis

基于Keepalived构建高可用集群配置实例(HA Cluster)

什么是集群 简单的讲集群(cluster)就是一组计算机,它们作为一个整体向用户提供一组网络资源.这些单个的计算机系统就是集群的节点(node).一个理想的集群是,用户从来不会意识到集群系统底层的节点,在他/她们看来,集群是一个系统,而非多个计算机系统.并且集群系统的管理员可以随意增加和删改集群系统的节点. 关于更详细的高可用集群我们在后面再做详解,先来说说Keepalived Keepalived是什么 Keepalived是集群管理中保证集群高可用的一个服务软件,其功能类似于heartbea

Redis+Keeplived实现高可用

博文说明[前言]: 本文将通过个人口吻介绍Redis+Keeplived实现高可用的相关知识,在目前时间点[2017年6月23号]下,所掌握的技术水平有限,可能会存在不少知识理解不够深入或全面,望大家指出问题共同交流,在后续工作及学习中如发现本文内容与实际情况有所偏差,将会完善该博文内容. 本文为我编写的部署文档(word格式)中关于redis部分的内容复制粘贴而来,因此会存在一些格式问题,因不影响阅读和理解,也没有改的必要了,这样反而便于大家慢下来理解.发表此处,一来是有方便自己查看,二来是给