码迷,mamicode.com
首页 > 其他好文 > 详细

HACMP 学习笔记--转载自wangjialiang-csdn博客

时间:2015-02-28 22:57:04      阅读:314      评论:0      收藏:0      [点我收藏+]

标签:

An41 教程:

Ha: 初始阶段的规划最重要

第一部分:概念和模型

Ha 目标:掩盖和消除计划和非计划的宕机

       Eliminate SPOF :消除单节点故障, single point of failuare(SPOF)

Cluster:   node 可要是设备可是分区

              Node 尽量不要在一个机柜

              Node 之间一定要有非 ip 网络,串口,磁盘

RSCT :负责 node 之间的通讯和协调,发送心跳,监控 cluster

clstrmgrES :该工具用来实现 HA 管理

clcomd : cluster nodes 间的通信进程 端口 6191

LAA : local administrated address( 本地管理地址 ) ,可以给它做一个假的 mac 地址来进行管理

存储:应支持热插拔和冗余

光纤:普通 SAN 存储 < 10公里

              HAGU > 10 公里

JFS : journal filesystem 日志系统

PowerHA 支持两种环境:顺序环境:热备,互备,互备是两个应用的热备

                                          并行环境: RAC

       历史上 HA 指的是顺序环境版, CMP 指的是并行环境版

       普通版叫 CM ,并行版叫 EM

powerHA 最多支持的 node 数量为 32 个

       topology :以网络为中心的物理结构

       resource :可以改变的实体

       resource group : resource 集合,可以一起切换到另一个 node

       推荐配置应用监控

       网卡在教程中都叫做 communication interface ,串口、心跳磁盘等叫做 communication device

       HA 每切换一次,系统就要重启一次,典型的宕机时间一般在 3 分钟左右,最短 20S , 6 分钟以上就不能容忍了

       Virtual SCSI : VIO SCSI

       目前常见 ha 版本: 5.4 、 5.4.1 、 5.5 、 6.1

       Ha 的层次结构:

HACMP

RCST

AIX

LVM

TCP/IP

      

 

时间同步的协议: stpd 、 stmp

 

HA 并发卷组:利用锁机制,应用层保证对数据的使用不冲突

Raw :支持数据库的锁机制

FS :不支持锁机制,所以 oracle 使用锁机制对 FS 上的数据库操作

 

共享存储:不是 HA 所必需,而是应用必需

 

Cluster 对其节点的要求:

                                   不要求硬件完全相同

性能支持应用

                                   能安装同样的 HA 版本

                                   安装了同样的 os 版本

powerHA 的 XD 选件用于距离非常远的 HA ,这种 HA 使用异步传输

                     plug-ins 组件需要另外单独花费 200 多美元,其内容是很多脚本

                     Smart-assistant 组件

                     并发是共享的一个特例

HA 要求相关的系统环境不能改变,不能修改环境,否则 HA 不正常

 

实施前一定要画好规划图, an41 侧重于规划和实施,学会规划、安装、管理

Resource group polices :资源组策略包括:

              启动        online on home node only 模式中住 node 不启动 RG 不切换

                            Online on first available node 先到先得,也是镜像模式

分布式     哪个 node 启动,他就拿到 RG ,但是只拿到属于自己的那组 RG ,但是并发 vg 在所有 node 都有效

从 powerHA5.4.1 开始支持多借点磁盘心跳

              Failover   按照节点列表的顺序,指定下一个接管节点

                            动态切换到下一个 node

                            不切换(多 node 并发 - 并行模式中,该模式多节点同时对外服务,单个故障不影响集群)

              回切        回到最高的优先级,首先要定义一个回切时间

                            不回切

       现实中的具体情况一般是 先启动数据库,再启动中间件,因为中间件依赖于数据库

IPAT : ip 地址接管,就是 ip 漂移,需要定义的 ip serviceIP 、 persistIP( 用于管理 )

       同一 vlan 中所有的 ip 的子网掩码必需一样

HA 需要配置同步的资源:

              应用

              心跳        用 RSCT 控制同步

              节点配置 用 clcomd 控制同步

触发同步的事件:

              网卡失败

              网络失败

              节点失败

 

配置 HMC 远程管理时 本地 IE 设置

              选项 - 高级 - 关闭 TLS1.0      

                            开启 SSL2.0

                            开启 SSL3.0

Cgi-bin 中的 cgi 指的是通用网关接口

 

不同类型的心跳 ip ,服务 ip 不能在同一网段,否则干扰心跳

HA 配置成心跳的 ip 网络将自动发送心跳

 

如下图所示:如果 node1 的 1 端口网线断了,该如何判断?

 

现象肯定是两 node 间的 1 端口互相不同,这是该如何判断哪个节点网络出问题?

可以实用 tcpdump 命令

通过 node1 的 2 端口向 node2 的 1 端口发送 arp 包 能收到说明 node2 的 1 口没问题

通过 node2 的 2 端口向 node1 的 1 端口发送 arp 包 不能收到说明 node1 的 1 端口网络问题

说明:

       同一个 vlan 可以包括不同的子网(网段),其中的每台主机都能收到本 vlan 其他 host 发送的 arp/ip 包,但是不同子网的网卡收到包后丢弃不作回应,所以通过查看另一个节点的网卡是否收到 arp 包可以确定网卡网络是否正常

       Os 本身具有路由功能, 127.0.0.1 多网卡同一网段时,会选择本身路由通信。

       同一个 node 的任何两个网卡不能设置成同一个子网,因为如果在同一个 subnet ,发包时会从不同的网卡发出,因为两个网卡的路径不同,如果有一个路径出现问题,该网卡将收不到返回包,会有丢包。

       如果是单网卡可以通过配置第三方网卡或文件 (netmon.cf) 来判断节点失败的原因。

第二部分:存储

共享存储:只允许一个节点修改,其他 node 不能读也不能写。谁 varyonvg 谁能操作该存储。

共享存储有两种保护数据不被同时修改的模式:

       Reserve/release 标签模式,基于硬件保护(普通共享使用的模式)

       Active/passive 模式( HA 使用的模式)

       使用清除磁盘 disk reserve 标记位的命令,该共享存储将得以释放,其他 node 可 varyonvg 改共享 。。。清理锁的标识符: clear ssa

       gsclvmd 进程: lv 改动时负责在各节点间发送广播,为成员间的通讯提供服务

       JFS:

       JFS2 :不支持并发访问,不支持锁机制

多 node 间查看同一个共享存储时可能看到的模式不同:

       Passive varyon :只能读部分信息,但是不能写

       Active varyon :可以读写

Concurrent vg=fast vg

 

For avoid split-brain, ip/non-ip 心跳都应该有冗余

当所有的 vg 都被 varyon 以后才能对 vg 进行操作

ConcurrentVG 既可以被 HA 使用也可以当做普通的 fs 使用

 

跟 bootip 是同一个网段的 ip 是别名 ip ( alias IP )

跟 bootip 不同一个网段的 ip 是 standbyIP

 

磁盘快速接管:接管速度快,需要安装 bos.crvm 软件,如果一个 node 安装了 crvm ,另一个没装就会看不到

 

Gost-disk 概念:普通共享可能会出现“鬼盘”

       当用 reserve/release 使用共享存储时

B 故障, a 接管 b

B 恢复,这时候 A 占着存储, B 找不到属于自己的存储,所以 b 又自己创建了一次

这时看到两份存储

可以在 a 上释放存储在 b 上使用就能解决 b 上执行 mklv –l

第三部分: HA 安装和配置

Pvid :盘序列号最好一致,便于管理

Man rendv 给设备改名

Lazy update :使用 enhanced concurrentVG

 

oslevel –s

lsvg rootvg

lsvg –l rootvg

smitty jfs2 – add enhanced JFS            G/fix/4/yes

mount /fix

lslpp –l |grep x.tar

mirrorvg –s rootvg 为 rootvg 做镜像

 

uncompress x.tar.z

tar –xvf x.tar

 

bosboot –a

cd cdrom

smit updateadd

bootlist –m normal hdisk1 hdisk0

bootlist –m normal –o

 

做 concurrentvg 需要安装 clvm 软件

Lslpp –a | grep clvm

系统软件不能同时安装

 

clstrmgrES 工具在系统启动时自动启动

       more /etc/inittab 可以查看,这个工具修改两个 nodes 之间 /usr/es/sbin/cluster/etc/rhosts 文件,保持一致并同步

clcomd 使用标准的连接认证

       找源 ip 时,通过 /usr/es/sbin/cluster/etc/rhosts 文件、找 ODM

       clcomdES 工具如果环境变量设置成中文会有问题

RSCT: 最多支持 32 nodes

RSCT :由 心跳拓扑、 组服务 、 RMC 组成

       无论何种心跳,心跳包都走环状拓扑, ip 、串口心跳都走环状顺序,按照序号循环

snmpinfo 查询 snmp 信息

clinfoES : cluster information daemon ( clinfo )

 

安装完 HA 后 os 本身的 NFS 会出问题, NFS 支持锁协议,但是只支持两个 nodes

Oslevel –s

smit update_all 软件更新后,提示的最下端会出一个 attention 提示重启,最好是将系统重启。

安装完 clvm 以后也需要重启,如果不重启可能出问题

用 vmo 命令可以确定系统是否需要重启:

       1 、 Vmo

       2 、查看安装历史

       3 、查看启动时间

       4 、确定是否重启

HA 的补丁最好都先打上,其他的补丁可以先不考虑

 

Ip 别名方式 
192.168.1.99  p510_boot1

192.168.2.99  p510_boot2

192.168.1.88  p550_boot1

192.168.2.88  p550_boot2

10.1.1 .88 srv1

10.1.1 .99 srv2

10.1.1 .100 srv3

10.1.1 .88 p550

10.1.1 .99 p510

替换 ip 模式只支持 2 个 serviceIP , alias 模式可支持多个 serviceIP

 

克隆系统的命令: man alt_disk_copy

克隆:按文件比较计算

镜像:按文件系统比较计算,两个 os 的 fs 应该一致大小

Lsps –a 查看换页空间 /var 中存放日志, dump 等文件,应该足够大否则有报错就会撑满

/usr/sbin/alt_disk_copy –p all –d hdisk2 hdisk3 –OB ( 可以先终止进程然后用以下命令继续 )

ps –ef |grep alt

nohup –p <pid>

alt_disk_install –x altinst_rootvg 删除镜像

 

HA 和 application 安装顺序可以互换,不一定非要先安装 HACMP ,如果 HA 出问题也可以在安装好的系统上卸载并重新安装 HACMP

Lssrc –ls clstrmgrES

Iostat

镜像之后修改 ip 和 hostname 即可使用

HA 在配置过程中只需要配置一个 node 然后同步到另一个 node 即可

       先配拓扑同步

       再配资源同步

       在配置 enhanced concurrentVG

       以此类推(我们要配置的双机热备 + 并发)

Smit HACMP

       c-spoc 日常管理选项

       problem determination tool 日常问题解决

HA 配置步骤如下:

1、  配置 hostname ip

2、  创建 enhanced concurrentVG

3、  配置通信路径

a)         Cluster à nodes à 发现网络(第一项)

b)        拓扑 à 通信接口 à 自动发现(第五项用于 non-IP )

c)        Show top

d)        同步( interactive )

e)         启动 HA (选中两个 nodes ,单独启动时 node 也可以同时启动 HA 不用有先后顺序)

f)         查看 ha 状态

4、  配置 application server name 最好不要大写字母

5、  配置资源, service_name 、 启停脚本、 service_ip

a)         配置服务名

b)        选择启停脚本位置

c)        配置 serviceIP

6、  配置存储 在 c-spoc 中配(两个 nodes 间的共享 vg )

a)         logicVG à create shared VG à create a concurrent VG (可以实现快速接管)

7、  配置 resource group

a)         选第三个,放在前面的节点是主

b)        启动策略选第 4 个并发,

c)        Failback 都选 never

d)        如果改了 startup 策略也得改第二项选择 bring offline

e)         修改属性,选择 serviceIP 、 APP 、 VG

f)         发现 resource Group

8、  配置服务 (HA 都停掉才能同步 )

a)          

9、  配置 non-IP 网络

a)         磁盘心跳:拓扑 à communication device à discover 磁盘心跳占用 io 很小

b)        查看心跳 clstat 可能会看不到,因为找不到命令路径, /usr/es/sbin/cluster/clstat 才可以; more or vi /etc/snmpd3.conf

c)        Stopsrc –s snmpd

d)        Startsrc –s snmpd

e)         查看心跳: cldump  /usr/es/sbin/utilities/cldump, 可以把要用的文件路径放到 path 里;cldump=HACMP 里面检测中的第二项

f)         Ls –l | grep ^d (ctrl_d)

10、              同步(启动)

11、              校验配置对不对

a)         cltopinfo :/usr/es/sbin/cluster/cltopinfo

b)        clshowres 查看资源

c)        cldisp 显示动态 vip

d)        /usr/bin/snmpinfo/ -n next –v risc

e)        /usr/es/sbin/cluster/utilities/clcheck_server grpsvcs|echo $        0 表示没启, 表示已启动

f)         lssrc –ls clstrmgrES(vrmf 是版本的意思 )

g)        clRGinfo

h)        lssrc –a |grep cl

i)          不要使用 HA 自带的 test 工具,日志 cluster.log hacmp.out , hacmp 停掉 aix 会重启

j)          Lssrc –ls clstrmgrES , current state : ST_INIT 正在执行, ST_STABLE 状态稳定

k)        elf 、 mount 查看 FS

12、              如果 HA 有问题, HA 从活动向非活动同步, stable 代表状态稳定

删除 HA 的步骤:

1、  停 HA

2、  删除 nodes(persistIP 可以不删 )

3、  删除 vg

a)         Varyoffvg vg00

b)        Exportvg vg00

c)        Reducevg bvg hdisk2

d)        Lsvg –o

e)         Ls –l /etc/vg

4、  Odm 方法删除 vg

a)         Odmget –q name=bvg CuDv

b)        Odmdelete –o CuDv –q name=bvg

c)        Odmget –o CuAt –q name=bvg

d)        Odmget –o CuDvDr

5、   

 

Aix 各种忘记密码的办法:

       Root :用光盘重新引导

       Asmi :

       Sms :抠出电池放电

       串口管理、 simi :找到小开关 拨弄一下

       HMC(CA/CE login) :重装 HMC 、恢复出厂设置、等 14 天以后自动重设

通过串口可以获得 HMC IP , HMC 先开机再插网线, ip 会变成默认,并发资源组不能带 IP 。最好使用串口连接安装 AIX

smit hostname 修改主机名

smit tcp/ip à fuuther configuration( 好像是配置 persistIP)

lssrc –s sshd

cfgmgr –l scsi2

cfgmgr

lsdev –Cc disk

bootinfo –s hdisk2 查看磁盘的大小

rmdev –dl hdisk2 删除磁盘

HA 中 node 名可以和 host 名不一样,但最好是一样

HA 在 smit 建立节点连接的时候,选一个网卡资源就行

       Add interface/device à add discovered 连接接口和设备

persistIP 用来管理: ( 主要用于平时的管理,路由配置、 ip 不能漂移到另一个 node 、校验同步,在“ interactive”选择中配置 )

       ssa

       disk 心跳( enhanced concurrentVG )

       串口心跳

       校验和同步

persistIP 可路由,监控程序、监视目前是安全的 cluster

gsclvmd : 随着 HA 启动而启动,单独停止再启动启不来

grpglsm : 用来监控, sp 做切换时使用,平时不启动

netstat –i 查看启动端口

chmod 700 *

 

报错 HACMPsiteinfo

/etc/es/objrepos/HACMPsiteinfo 这是没有 pvid 的原因

授予 pvid       chdev –l hdisk2 –a pv=yes

Machinfo 查看 cpu

 

改变 0,0 à 33,24

同步频率 60 à 10

改变 ssa 节点号 0 à 1,

à 2

 

Smit clstart 启动 ha

Lssrc –ls clstrmgrES

Netstat –i

查看路由: netstat –rn

              Ping –R

Cllsif 查看接口

Crfindres

Clshowsrv –v 、 -a

Odmget HACMPlogs 查看日志菜单

查看历史操作: history|   .sh_history | wtmp

Ifconfig en1 10.1.1.1 delete

Lqueryvg –p hdisk4 –At | more

Redefinevg –d hdisk4 bvg     Redefinevg –d hdisk4

Cd /dev/         ls –l | grep vg

Odmget CuDvDr |grep –p bvg

Ls –l |grep 48,

Odmget CuAt | grep pvid

Odmget CuAt|grep –p pvid

Shutdown –Fr

Odmdelete –o CuDvDr –q value=bvg

 

第四部分: ip 替换方式配置 HA

相比于别名方式, ip 替换方式支持 mac 接管,这是 ip 替换方式的唯一优点

serviceIP 启动以后替换 bootIP

一个网卡只能有一个 ServiceIP

一个网卡对应一个 ip ,有多少个网卡就有多少个 iP

所有 serviceIP 和 bootip 都应该在同一个子网

最多只支持 2 个 serviceIP ,且必须在同一个子网

当网卡的 HA 故障检测需要配置第三方节点,即 netmountcf 文件

 

常见的 ip 配置错误:

       子网掩码不同

       一个 node 上的 ip 都在同一 subnet

       放在同一 subnet

       网口速率最好指定,不要自动

       /etc/host 文件不同

 

Ip 地址漂移对 client 的影响:

       同一 node 上的 en1 飘到了 en2

       Gratuitous app 广发消息包,但是有些路由不支持,因为一旦是欺骗包将导致以后不能正常通信

      

Ip –d 删除 ip (在客户端执行)

Arp –d ip

Ping –c 4 ip ( ip 表里没有)

       这时可以更新 ip 列表

如果遇到 ipcache 问题可以实用假 mac 方式解决

Smit à device à communication à add à 合并

 

有多种检测方式可以检测总体情况:

规划应用监控:进程监控、定制监控

Hacmp es cluster manage 包含

       Run_clappmond

       Clappmond

定制监控:服务可用、不可用

Ps –l <process_name>

Ps –e 显示其他

一个 app 可以有多个 monitor ,一个 cluster 最多有 48 个 monitor

 

Ip 别名方式换成 ip 替换方式, persistIP 需要先删掉

Snapshot 用来备份 ha 配置信息,还原配置信息,也可以存储配置信息

 

DARE :动态重分配

       Cluster toplogy

       运行 DARE 需要三种 odm copies : DCD/SCD/ACD 在同步过程中使用

单节点控制:

       做改变之前,建议先做 snapshot ,改变 vgda 其实是改变 odm , gpfs 需要单独买软件

Esc+9 切换到另一个 node

配置 ha 过程中一定要把 vg 加入到 resourceVG 中

Snap –e

Netmon –cf

Clsnap –a

Lvm 问题原因,基本上是改变和 odm 不一致造成,手工改变 lvm 就行

在 a 上改口令,突然切到了 b 上, b 上还是老口令

Link to 。。。

Home 目录下不妨共享文件

使用集群修改口令,如果 A 改动,那么自动同步到 b ,如果某 node 关闭,就需要将 cluster 改成 single 模式

如果 HA 版本不一致,包括补丁,可以校验但不要同步,否则 odm 会垮掉

如果某个 node 非活,那么该节点不能发起同步

 

每日巡检:

       校验:配置和 env 是否匹配

       先不要同步,先校验

       如果想回滚操作可以用 snapshot 还原

测试串口心跳:

       两个节点都执行 stty</dev/tty0

       也可以在一个节点执行 cal>/dev/tty0 另一个执行 cat</dev/tty0

       测心跳应该双方向

c-spoc 选项用来添加删除可以,但是改变不可以

home node 模式不是并发

netmon.cf 用来配置单网卡 cluster 第三方校验

ls –l |grep ^d

事件目录: /usr/es/sbin/cluster/events

       Ls|grep –v rp|wc –l

       Ls –l |grep –v rp|grep down

网络故障是 fail 不是 down

使用 smit 中的文件名最好不带空格

打完补丁就会自动改脚本,所以打完补丁需要改动脚本

添加事件实际就是启用

停掉 cluster 服务, clmond 先是停掉在重启,修改事件记录再重启 cluster

建立资源时不应该让 vg 自动 varyon

模拟错误日志:

       Errpt|head

Detail send data 什么都没有说明是模拟

       如果有二进制数说明有问题

Ha 的自动校验是默认每晚 12 点,生产环境中 testtool 不要用

 

Led 显示 888,

原因:可能是 dms 超时( dead man swich 死人开关)

       Cluster 在每个 node 都有心跳的计数,达到一定数值会自动复位,如果磁盘 io 太大, cluster 不让计数及时复位,不复位 node 就不能发出心跳,节点间会互相认为对方故障,出现 split-brain

       DGSP 原理:一个节点正在正常运行资源,另一个资源来接管(抢), cluster 会中断资源数少的 node ,保证数据完整,网络不混乱

Dms 产生的原因:

       没有心跳网络和通信网络

       切换太快

Dms 是不允许停掉的。要想改变 dms 报错,

只能扩展配置,

把心跳率变低

Syncd 每 60 秒把磁盘上的东西写到磁盘,如果时间变短一点 io 也会变得少一点,就能减少 dms 几率

把系统级别的改成 33 、 24

Src 中断会导致死机

Src 意外中断、 kill -9 等原因

没打补丁修复 bug

会导致关机或死机

Src 不能意外终止否则会死机

两个节点,拔掉线之后马上插上,节点也会 down (有丢包了认为对方 down ,又通了说明有未知问题,为了保护数据 down 掉自己)

问题定位采用少数节点服从多数节点原则

2 节点可能是名字顺序

如果意外宕机将先记录关机日志,在记录错误日志,注意时间顺序

RG 事件再加 180 秒,错误往前推

Snap –c 收集 ha 日志

http://www.aixchina.net/home/space.php?uid=6880&do=blog&id=24175

Death man swich

The DGSP message
A Diagnostic Group Shutdown Partition (DGSP) message is sent when a node loses communication with the cluster and then tries to re-establish communication.
214 IBM ^ Certification Study Guide - pSeries HACMP for AIX
For example, if a cluster node becomes unable to communicate with other nodes, yet it continues to work through its process table, the other nodes conclude that the “missing” node has failed because they no longer are receiving keepalive messages from it. The remaining nodes then process the necessary events to acquire the disks, IP addresses, and other resources from the “missing” node. This attempt to take over resources results in the dual-attached disks receiving resets to release them from the “missing” node and the start of IP address takeover scripts.
As the disks are being acquired by the takeover node (or after the disks have been acquired and applications are running), the “missing” node completes its process table (or clears an application problem) and attempts to resend keepalive messages and rejoin the cluster. Since the disks and IP addresses are in the process of being successfully taken over, it becomes possible to have a duplicate IP address on the network and the disks may start to experience extraneous traffic on the data bus.
Because the reason for the “missing” node remains undetermined, you can assume that the problem may repeat itself later, causing additional down time of not only the node but also the cluster and its applications. Thus, to ensure the highest cluster availability, a DGSP message is sent to all nodes in one of the partitions. Any node receiving a DGSP message halts immediately, in order to not cause any damage on disks or confusion on the networks.

In a partitioned cluster situation, the smaller partition (lesser number of nodes) is shut down, with each of its nodes getting a DGSP message. If the partitions are of equal size, the one with the node name beginning in the lowest name in the alphabet gets shut down. For example, in a cluster where one partition has NodeA and the other has NodeB, NodeB will be shut down.

 

Deadman switch

To ensure a clean takeover, HACMP provides a Deadman Switch, which is configured to halt the unresponsive node one second before the other nodes begin processing a node failure event. The Deadman Switch uses the Failure Detection Parameters of the slowest network to determine at what point to halt the node. Thus, by increasing the amount of time before a failure is detected, you give a node more time in which to give HACMP CPU cycles. This can be critical if the node experiences saturation at times. 
To help eliminate node saturation, modify AIX 5L tuning parameters. For information about these tuning parameters, see the following sections in the Administration Guide: 
•Configuring Cluster Performance Tuning in Chapter 18: Troubleshooting HACMP Clusters 
•Changing the Failure Detection Rate of a Network Module in Chapter 12: Managing the Cluster Topology. 
Change Failure Detection Parameters only after these other measures have been implemented.

Syncd Frequency 
The syncd setting determines the frequency with which the I/O disk-write buffers are flushed. Frequent flushing of these buffers reduces the chance of deadman switch time-outs. 
The AIX 5L default value for syncd as set in /sbin/rc.boot is 60. Change this value to 10. Note that the I/O pacing parameter setting should be changed first. You do not need to adjust this parameter again unless time-outs frequently occur.

 

Ha 非常重要的几个概念:

     Gost-disk

     Split-brain

     Deadman swich

     DGSP

HACMP 学习笔记--转载自wangjialiang-csdn博客

标签:

原文地址:http://www.cnblogs.com/TDlemon/p/4306292.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!