<pre name="code" class="html">如果在连接时候zk服务器宕机 To create a client session the application code must provide a connection string containing a comma separated list of host:port pairs, each corresponding to a ZooKeeper server (e.g. "127.0.0.1:4545" or "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"). The ZooKeeper client library will pick an arbitrary server and try to connect to it. If this connection fails, or if the client becomes disconnected from the server for any reason, the client will automatically try the next server in the list, until a connection is (re-)established. 创建一个client session 应用代码必须提供一个连接字符串包含一个逗号分隔的主机:端口 列表, 每个对应到一个ZooKeeper server (e.g. "127.0.0.1:4545" or "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"). ZooKeeper 客户端库 会选择一个任意的server 和尝试连接到它。 如果这个连接失败,或者 如果客户端变的不能连接,客户端会自动 尝试下一个server 在列表里,知道一个连接重新创建。 如果已经连接之后服务器宕机 SessionMovedException. There is an internal exception that is generally not seen by clients called the SessionMovedException. This exception occurs because a request was received on a connection for a session which has been reestablished on a different server. The normal cause of this error is a client that sends a request to a server, but the network packet gets delayed, so the client times out and connects to a new server. When the delayed packet arrives at the first server, the old server detects that the session has moved, and closes the client connection. Clients normally do not see this error since they do not read from those old connections. (Old connections are usually closed.) One situation in which this condition can be seen is when two clients try to reestablish the same connection using a saved session id and password. One of the clients will reestablish the connection and the second client will be disconnected (causing the pair to attempt to re-establish its connection/session indefinitely). SessionMovedException. 有一个内部的异常,那是通常不被客户端请求SessionMovedException 看到。 这个exception 因为 一个请求被接收在一个连接对于一个会话 精被重新建立到一个不同的zk server. 这个错误的通常情况是一个客户端发送一个请求到一个服务器, 但是网络包延时了,因此客户端超时 ,连接到一个新的服务器.当延迟的packet 到达第一个server, old server 检测倒 session 已经移动了,关闭客户端连接。 客户端通常不会看到这个错误 因为它们不会从老的连接读取(老的连接通常是被关闭的) 一种情况是这个状况可以被看到当 2个客户端尝试重建建立相同的连接使用一个保存的会话id和密码。 demo: zjtest7-redis:/root/zk# cat test_zk.pl use ZooKeeper; use AnyEvent; use AE; use Data::Dumper; use IO::Socket; sub check_port { ( $server, $port ) = ('127.0.0.1','3306'); $sock = IO::Socket::INET->new(PeerAddr => $server, PeerPort => $port, Proto => 'tcp'); if ($sock) {return 1} else {return 0 }; }; my @ip_list=(); my $zk = ZooKeeper->new(hosts => '1.1.1.1:2181,1.1.1.1:2182,1.1.1.1:2183') ; #my $zk = ZooKeeper->new(hosts => '1.1.1.1:2182,1.1.1.1:2183') ; print Dumper($zk); eval { my $stat = $zk->exists('/mysql/0001'); if ($stat){ $mysql_ip = $zk->get('/mysql/0001'); print $mysql_ip." "; } else{ $mysql_ip = $zk->get('/mysql/0002'); print $mysql_ip." "; }; use DBI; my $database='zjzc'; my $user="zjzc_app"; my $passwd="1234567"; my @arr2=(); my $dbh = DBI->connect("dbi:mysql:database=$database;host=$mysql_ip;port=3306",$user,$passwd,{ RaiseError => 1, AutoCommit => 0 } ) or die "can't connect to database ". DBI-errstr; my $hostSql = qq{select id,name from scan; }; my ($a1, $a2, $a3,$a4,$a5,$a6,$a7,$a8,$a9); my $selStmt = $dbh->prepare($hostSql); $selStmt->execute(); $selStmt->bind_columns(undef, $a1, $a2); $selStmt->execute(); while( $selStmt->fetch() ) { push (@arr2, "$a1 $a2 $a3 " ); }; print "@arr2 is @arr2 "; $dbh->disconnect; }; 默认连接3个zk server '1.1.1.1:2181,1.1.1.1:2182,1.1.1.1:2183 测试1 关闭 2181 服务器: zjtest7-redis:/root/zk# perl test_zk.pl $VAR1 = bless( { 'buffer_length' => 2048, 'default_acl' => [ { 'scheme' => 'world', 'id' => 'anyone', 'perms' => 31 } ], 'dispatcher' => bless( { 'ignore_session_events' => 1, 'dispatch_cb' => sub { "DUMMY" }, 'channel' => bless( {}, 'ZooKeeper::Channel' ), 'ae_watcher' => bless( do{(my $o = '¸`ÿpᅡþ欁ᄋ')}, 'EV::IO' ), 'watchers' => {} }, 'ZooKeeper::Dispatcher::AnyEvent' ), 'timeout' => 10000, 'hosts' => '1.1.1.1:2181,1.1.1.1:2182,1.1.1.1:2183' }, 'ZooKeeper' ); 192.168.32.6 @arr2 is 1 aaabbb 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe 2 cccddeqe zjtest7-redis:/root/zk# perl test_zk.pl $VAR1 = bless( { 'hosts' => '1.1.1.1:2181,1.1.1.1:2182,1.1.1.1:2183', 'default_acl' => [ { 'perms' => 31, 'id' => 'anyone', 'scheme' => 'world' } ], 'timeout' => 10000, 'buffer_length' => 2048, 'dispatcher' => bless( { 'watchers' => {}, 'dispatch_cb' => sub { "DUMMY" }, 'ae_watcher' => bless( do{(my $o = ' ʂˎྋ샀')}, 'EV::IO' ), 'channel' => bless( {}, 'ZooKeeper::Channel' ), 'ignore_session_events' => 1 }, 'ZooKeeper::Dispatcher::AnyEvent' ) }, 'ZooKeeper' ); 此时有可能连接不上,原因为连接到了1.1.1.1:2181 测试2: #my $zk = ZooKeeper->new(hosts => '1.1.1.1:2181,1.1.1.1:2182,1.1.1.1:2183') ; my $zk = ZooKeeper->new(hosts => '1.1.1.1:2182,1.1.1.1:2183') ; 此时一切正常