TAF定义引用官方文档:
Transparent Application Failover (TAF) instructs Oracle Net to fail over a failed connection to a different listener.
This enables the user to continue to work using the new connection as if the original connection had never failed.
==》基于basic方式的TAF(Transparent Application Failover)的作用就是会话的重新连接。
当初始连接所在的实例失败后,会在存活的实例新建连接。
TAF 仅对使用 OCI 连接的客户端和连接池有效。TAF可以在客户端配置(通过tnsname.ora),也可以在服务端配置(通过配置service)。
当客户端和服务端同时配置TAF时,服务端优先级于客户端。本文针对客户端和服务端会分别测试。
本次测试环境
数据库服务器:oracle linux7.2 + 12.1.0.2两节点RAC
客户端:oracle linux 6.5 + 12.1.0.2单机
一:配置客户端的taf
在连接描述符中的CONNECT_DATA部分指定FAILOVER_MODE参数
FAILOVER_MODE的参数:
METHOD:
basic 实例失败后,在存活节点建立新的连接。
preconnect 在首次连接时,不仅在指定实例上建立连接,还在备用实例上建立预连接。
BACKUP:指定网络服务名称(tnsnames.ora里的字符串)。当使用preconnect方法时使用该参数。
TYPE:
session:新建会话,旧的会话内容全部丢失。
select:满足一定条件下select查询操作会继续输出,不会因为实例的失败而终止输出。
none:禁用failover的功能。
DELAY:每次尝试连接后等待下次连接的秒数,默认等待间隔1s.
RETRIES:尝试连接到存活实例的次数,默认5次。
1)tnsnames.ora的配置
test =
(DESCRIPTION =
(FAILOVER=ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = scan_ip)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED)
(SERVICE_NAME = test)
(FAILOVER_MODE=
(TYPE= SELECT)
(METHOD=basic)
(RETRIES=5)
(DELAY=1))))
2)测试
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options
SQL> select host_name,instance_name from v$instance;
HOST_NAME INSTANCE_NAME
-------------------- ------------------------------------------------
db1 db1
SQL> SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
2 FROM V$SESSION
3 GROUP BY MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER;
MACHINE FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER COUNT(*)
---------- --------------- --------------- --------------- ----------
ora12c SELECT BASIC NO 1
db1 NONE NONE NO 59
3)新开会话,关闭当前连接所在节点
SQL> show parameter instance_name
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
instance_name string
db1
SQL> shutdown abort
ORACLE instance shut down.
4)taf生效,新建连接
SQL> SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
2 FROM V$SESSION
3 GROUP BY MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER;
MACHINE FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER COUNT(*)
---------- --------------- --------------- --------------- ----------
ora12c SELECT BASIC NO 1
db1 NONE NONE NO 59
SQL> /
SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 29680
Session ID: 282 Serial number: 46184
SQL> /
MACHINE FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER COUNT(*)
---------- --------------- --------------- --------------- ----------
db2 NONE NONE NO 61
ora12c SELECT BASIC YES 1
SQL> show parameter instance_name
NAME TYPE VALUE
------------------------------------ --------------------------------- ------------------------------
instance_name string db2
二:服务端的service测试
1)创建具有taf功能的service
[oracle@db1 ~]$srvctl add service -db db -service test_taf_basic -pdb pdb1 -preferred db1,db2 -failovermethod BASIC -failovertype select
2)启动service
[oracle@db1 ~]$srvctl start service -db db -service test_taf_basic
3)查看service的配置信息
[oracle@db1 ~]$ srvctl config service -db db -service test_taf_basic
Service name: test_taf_basic
Server pool:
Cardinality: 2
Disconnect: false
Service role: PRIMARY
Management policy: AUTOMATIC
DTP transaction: false
AQ HA notifications: false
Global: false
Commit Outcome: false
Failover type: SELECT
Failover method: BASIC
TAF failover retries:
TAF failover delay:
Connection Load Balancing Goal: LONG
Runtime Load Balancing Goal: NONE
TAF policy specification: NONE
Edition:
Pluggable database name: pdb1
Maximum lag time: ANY
SQL Translation Profile:
Retention: 86400 seconds
Replay Initiation Time: 300 seconds
Session State Consistency:
GSM Flags: 0
Service is enabled
Preferred instances: db1,db2
Available instances:
SQL> select name, failover_method, failover_type,failover_retries
2 from dba_services
3 where service_id =
4 (select service_id from dba_services where name = 'test_taf_basic');
NAME FAILOVER_METHOD FAILOVER_TYPE FAILOVER_RETRIES
-------------------- -------------------- -------------------- ----------------
test_taf_basic BASIC SELECT 0
4)tnsnames.ora配置
test_taf_basic =
(DESCRIPTION =
(FAILOVER=ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = scan_ip)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED)
(SERVICE_NAME = test_taf_basic)))
5)测试
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options
SQL> show parameter instance_name
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
instance_name string
db1
SQL> SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
2 FROM V$SESSION
3 GROUP BY MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER;
MACHINE FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER COUNT(*)
-------------------- --------------- --------------- --------------- ----------
ora12c SELECT BASIC NO 1
db1 NONE NONE NO 56
6)新开会话,关闭当前连接所在节点
SQL> show parameter instance_name
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
instance_name string
db1
SQL> shutdown abort;
ORACLE instance shut down.
7)taf生效,新建连接
SQL> SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
2 FROM V$SESSION
3 GROUP BY MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER;
MACHINE FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER COUNT(*)
-------------------- --------------- --------------- --------------- ----------
db2 NONE NONE NO 63
ora12c SELECT BASIC YES 1
SQL> show parameter instance_name
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
instance_name string
db2
对客户端的orace net进行trace,截取输出以下内容
1)初始的连接信息,通过scan_ip连接到节点2的vip
2016-07-11 16:25:08.072786 : niotns:Calling address: (DESCRIPTION=(FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=scan_ip)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=test)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=basic)(RETRIES=5)(DELAY=1))(CID=(PROGRAM=sqlplus@ora12c)(HOST=ora12c)(USER=oracle))))
2016-07-11 16:25:08.152423 : nscall:connecting...
2016-07-11 16:25:08.152443 : nsc2addr:entry
2016-07-11 16:25:08.152454 : nsc2addr:(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.201)(PORT=1521))
2016-07-11 16:25:08.152478 : nttbnd2addr:entry
2016-07-11 16:25:08.152490 : snlinGetAddrInfo:entry
2016-07-11 16:25:08.152539 : snlinGetAddrInfo:exit
2016-07-11 16:25:08.152553 : nttbnd2addr:using host IP address: 192.168.100.201
2)初始化连接完成
2016-07-11 16:25:08.203778 : nscon:connect handshake is complete
3)查询一张表的记录,记录数足够大
2016-07-11 16:27:58.964923 : nsbasic_bsd:00 00 00 00 00 27 73 65 |.....'se|
2016-07-11 16:27:58.964935 : nsbasic_bsd:6C 65 63 74 20 6F 62 6A |lect.obj|
2016-07-11 16:27:58.964947 : nsbasic_bsd:65 63 74 5F 69 64 2C 6F |ect_id,o|
2016-07-11 16:27:58.964958 : nsbasic_bsd:62 6A 65 63 74 5F 74 79 |bject_ty|
2016-07-11 16:27:58.964970 : nsbasic_bsd:70 65 20 66 72 6F 6D 20 |pe.from.|
2016-07-11 16:27:58.964981 : nsbasic_bsd:6A 69 6E 7A 79 01 00 00 |jinzy...|
4)kill掉会话所在实例
2016-07-11 16:28:02.563411 : nserror:entry
2016-07-11 16:28:02.563427 : nserror:nsres: id=0, op=68, ns=12537, ns2=12560; nt[0]=507, nt[1]=0, nt[2]=0; ora[0]=0, ora[1]=0, ora[2]=0
==》
[oracle@ora12c ~]$ oerr ora 12537
12537, 00000, "TNS:connection closed"
[oracle@ora12c ~]$ oerr ora 12560
12560, 00000, "TNS:protocol adapter error"
[oracle@ora12c ~]$ oerr tns 507
00507, 00000, "Connection closed"
5)taf生效,重新连接节点1vip
2016-07-11 16:28:02.574410 : niotns:Calling address: (DESCRIPTION=(FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=scan_ip)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=test)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=basic)(RETRIES=5)(DELAY=1))(CID=(PROGRAM=sqlplus)(HOST=ora12c)(USER=oracle))))
2016-07-11 16:28:02.769597 : nscall:connecting...
2016-07-11 16:28:02.769701 : nsc2addr:entry
2016-07-11 16:28:02.769845 : nsc2addr:(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.200)(PORT=1521))
6)新建连接完成
2016-07-11 16:28:02.927320 : nscon:connect handshake is complete
7)继续之前的查询输出
2016-07-11 16:28:03.803200 : nsbasic_bsd:00 00 00 00 00 27 73 65 |.....'se|
2016-07-11 16:28:03.803284 : nsbasic_bsd:6C 65 63 74 20 6F 62 6A |lect.obj|
2016-07-11 16:28:03.803380 : nsbasic_bsd:65 63 74 5F 69 64 2C 6F |ect_id,o|
2016-07-11 16:28:03.803465 : nsbasic_bsd:62 6A 65 63 74 5F 74 79 |bject_ty|
2016-07-11 16:28:03.803569 : nsbasic_bsd:70 65 20 66 72 6F 6D 20 |pe.from.|
2016-07-11 16:28:03.803658 : nsbasic_bsd:6A 69 6E 7A 79 01 00 00 |jinzy...|
end!
Transparent Application Failover (TAF) instructs Oracle Net to fail over a failed connection to a different listener.
This enables the user to continue to work using the new connection as if the original connection had never failed.
==》基于basic方式的TAF(Transparent Application Failover)的作用就是会话的重新连接。
当初始连接所在的实例失败后,会在存活的实例新建连接。
TAF 仅对使用 OCI 连接的客户端和连接池有效。TAF可以在客户端配置(通过tnsname.ora),也可以在服务端配置(通过配置service)。
当客户端和服务端同时配置TAF时,服务端优先级于客户端。本文针对客户端和服务端会分别测试。
本次测试环境
数据库服务器:oracle linux7.2 + 12.1.0.2两节点RAC
客户端:oracle linux 6.5 + 12.1.0.2单机
一:配置客户端的taf
在连接描述符中的CONNECT_DATA部分指定FAILOVER_MODE参数
FAILOVER_MODE的参数:
METHOD:
basic 实例失败后,在存活节点建立新的连接。
preconnect 在首次连接时,不仅在指定实例上建立连接,还在备用实例上建立预连接。
BACKUP:指定网络服务名称(tnsnames.ora里的字符串)。当使用preconnect方法时使用该参数。
TYPE:
session:新建会话,旧的会话内容全部丢失。
select:满足一定条件下select查询操作会继续输出,不会因为实例的失败而终止输出。
none:禁用failover的功能。
DELAY:每次尝试连接后等待下次连接的秒数,默认等待间隔1s.
RETRIES:尝试连接到存活实例的次数,默认5次。
1)tnsnames.ora的配置
test =
(DESCRIPTION =
(FAILOVER=ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = scan_ip)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED)
(SERVICE_NAME = test)
(FAILOVER_MODE=
(TYPE= SELECT)
(METHOD=basic)
(RETRIES=5)
(DELAY=1))))
2)测试
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options
SQL> select host_name,instance_name from v$instance;
HOST_NAME INSTANCE_NAME
-------------------- ------------------------------------------------
db1 db1
SQL> SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
2 FROM V$SESSION
3 GROUP BY MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER;
MACHINE FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER COUNT(*)
---------- --------------- --------------- --------------- ----------
ora12c SELECT BASIC NO 1
db1 NONE NONE NO 59
3)新开会话,关闭当前连接所在节点
SQL> show parameter instance_name
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
instance_name string
db1
SQL> shutdown abort
ORACLE instance shut down.
4)taf生效,新建连接
SQL> SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
2 FROM V$SESSION
3 GROUP BY MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER;
MACHINE FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER COUNT(*)
---------- --------------- --------------- --------------- ----------
ora12c SELECT BASIC NO 1
db1 NONE NONE NO 59
SQL> /
SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
*
ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 29680
Session ID: 282 Serial number: 46184
SQL> /
MACHINE FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER COUNT(*)
---------- --------------- --------------- --------------- ----------
db2 NONE NONE NO 61
ora12c SELECT BASIC YES 1
SQL> show parameter instance_name
NAME TYPE VALUE
------------------------------------ --------------------------------- ------------------------------
instance_name string db2
二:服务端的service测试
1)创建具有taf功能的service
[oracle@db1 ~]$srvctl add service -db db -service test_taf_basic -pdb pdb1 -preferred db1,db2 -failovermethod BASIC -failovertype select
2)启动service
[oracle@db1 ~]$srvctl start service -db db -service test_taf_basic
3)查看service的配置信息
[oracle@db1 ~]$ srvctl config service -db db -service test_taf_basic
Service name: test_taf_basic
Server pool:
Cardinality: 2
Disconnect: false
Service role: PRIMARY
Management policy: AUTOMATIC
DTP transaction: false
AQ HA notifications: false
Global: false
Commit Outcome: false
Failover type: SELECT
Failover method: BASIC
TAF failover retries:
TAF failover delay:
Connection Load Balancing Goal: LONG
Runtime Load Balancing Goal: NONE
TAF policy specification: NONE
Edition:
Pluggable database name: pdb1
Maximum lag time: ANY
SQL Translation Profile:
Retention: 86400 seconds
Replay Initiation Time: 300 seconds
Session State Consistency:
GSM Flags: 0
Service is enabled
Preferred instances: db1,db2
Available instances:
SQL> select name, failover_method, failover_type,failover_retries
2 from dba_services
3 where service_id =
4 (select service_id from dba_services where name = 'test_taf_basic');
NAME FAILOVER_METHOD FAILOVER_TYPE FAILOVER_RETRIES
-------------------- -------------------- -------------------- ----------------
test_taf_basic BASIC SELECT 0
4)tnsnames.ora配置
test_taf_basic =
(DESCRIPTION =
(FAILOVER=ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = scan_ip)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED)
(SERVICE_NAME = test_taf_basic)))
5)测试
Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options
SQL> show parameter instance_name
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
instance_name string
db1
SQL> SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
2 FROM V$SESSION
3 GROUP BY MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER;
MACHINE FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER COUNT(*)
-------------------- --------------- --------------- --------------- ----------
ora12c SELECT BASIC NO 1
db1 NONE NONE NO 56
6)新开会话,关闭当前连接所在节点
SQL> show parameter instance_name
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
instance_name string
db1
SQL> shutdown abort;
ORACLE instance shut down.
7)taf生效,新建连接
SQL> SELECT MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER, COUNT(*)
2 FROM V$SESSION
3 GROUP BY MACHINE, FAILOVER_TYPE, FAILOVER_METHOD, FAILED_OVER;
MACHINE FAILOVER_TYPE FAILOVER_METHOD FAILED_OVER COUNT(*)
-------------------- --------------- --------------- --------------- ----------
db2 NONE NONE NO 63
ora12c SELECT BASIC YES 1
SQL> show parameter instance_name
NAME TYPE
------------------------------------ ---------------------------------
VALUE
------------------------------
instance_name string
db2
对客户端的orace net进行trace,截取输出以下内容
1)初始的连接信息,通过scan_ip连接到节点2的vip
2016-07-11 16:25:08.072786 : niotns:Calling address: (DESCRIPTION=(FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=scan_ip)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=test)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=basic)(RETRIES=5)(DELAY=1))(CID=(PROGRAM=sqlplus@ora12c)(HOST=ora12c)(USER=oracle))))
2016-07-11 16:25:08.152423 : nscall:connecting...
2016-07-11 16:25:08.152443 : nsc2addr:entry
2016-07-11 16:25:08.152454 : nsc2addr:(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.201)(PORT=1521))
2016-07-11 16:25:08.152478 : nttbnd2addr:entry
2016-07-11 16:25:08.152490 : snlinGetAddrInfo:entry
2016-07-11 16:25:08.152539 : snlinGetAddrInfo:exit
2016-07-11 16:25:08.152553 : nttbnd2addr:using host IP address: 192.168.100.201
2)初始化连接完成
2016-07-11 16:25:08.203778 : nscon:connect handshake is complete
3)查询一张表的记录,记录数足够大
2016-07-11 16:27:58.964923 : nsbasic_bsd:00 00 00 00 00 27 73 65 |.....'se|
2016-07-11 16:27:58.964935 : nsbasic_bsd:6C 65 63 74 20 6F 62 6A |lect.obj|
2016-07-11 16:27:58.964947 : nsbasic_bsd:65 63 74 5F 69 64 2C 6F |ect_id,o|
2016-07-11 16:27:58.964958 : nsbasic_bsd:62 6A 65 63 74 5F 74 79 |bject_ty|
2016-07-11 16:27:58.964970 : nsbasic_bsd:70 65 20 66 72 6F 6D 20 |pe.from.|
2016-07-11 16:27:58.964981 : nsbasic_bsd:6A 69 6E 7A 79 01 00 00 |jinzy...|
4)kill掉会话所在实例
2016-07-11 16:28:02.563411 : nserror:entry
2016-07-11 16:28:02.563427 : nserror:nsres: id=0, op=68, ns=12537, ns2=12560; nt[0]=507, nt[1]=0, nt[2]=0; ora[0]=0, ora[1]=0, ora[2]=0
==》
[oracle@ora12c ~]$ oerr ora 12537
12537, 00000, "TNS:connection closed"
[oracle@ora12c ~]$ oerr ora 12560
12560, 00000, "TNS:protocol adapter error"
[oracle@ora12c ~]$ oerr tns 507
00507, 00000, "Connection closed"
5)taf生效,重新连接节点1vip
2016-07-11 16:28:02.574410 : niotns:Calling address: (DESCRIPTION=(FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=scan_ip)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=test)(FAILOVER_MODE=(TYPE=SELECT)(METHOD=basic)(RETRIES=5)(DELAY=1))(CID=(PROGRAM=sqlplus)(HOST=ora12c)(USER=oracle))))
2016-07-11 16:28:02.769597 : nscall:connecting...
2016-07-11 16:28:02.769701 : nsc2addr:entry
2016-07-11 16:28:02.769845 : nsc2addr:(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.100.200)(PORT=1521))
6)新建连接完成
2016-07-11 16:28:02.927320 : nscon:connect handshake is complete
7)继续之前的查询输出
2016-07-11 16:28:03.803200 : nsbasic_bsd:00 00 00 00 00 27 73 65 |.....'se|
2016-07-11 16:28:03.803284 : nsbasic_bsd:6C 65 63 74 20 6F 62 6A |lect.obj|
2016-07-11 16:28:03.803380 : nsbasic_bsd:65 63 74 5F 69 64 2C 6F |ect_id,o|
2016-07-11 16:28:03.803465 : nsbasic_bsd:62 6A 65 63 74 5F 74 79 |bject_ty|
2016-07-11 16:28:03.803569 : nsbasic_bsd:70 65 20 66 72 6F 6D 20 |pe.from.|
2016-07-11 16:28:03.803658 : nsbasic_bsd:6A 69 6E 7A 79 01 00 00 |jinzy...|
end!
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25923810/viewspace-2131493/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/25923810/viewspace-2131493/