use of com.alibaba.otter.canal.protocol.exception.CanalClientException in project canal by alibaba.
the class SimpleCanalConnector method waitClientRunning.
private void waitClientRunning() {
try {
if (zkClientx != null) {
if (!connected) {
// 未调用connect
throw new CanalClientException("should connect first");
}
running = true;
// 阻塞等待
mutex.get();
} else {
// 单机模式直接设置为running
running = true;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new CanalClientException(e);
}
}
use of com.alibaba.otter.canal.protocol.exception.CanalClientException in project canal by alibaba.
the class SimpleCanalConnector method doConnect.
private InetSocketAddress doConnect() throws CanalClientException {
try {
channel = SocketChannel.open();
channel.socket().setSoTimeout(soTimeout);
SocketAddress address = getAddress();
if (address == null) {
address = getNextAddress();
}
channel.connect(address);
readableChannel = Channels.newChannel(channel.socket().getInputStream());
writableChannel = Channels.newChannel(channel.socket().getOutputStream());
Packet p = Packet.parseFrom(readNextPacket());
if (p.getVersion() != 1) {
throw new CanalClientException("unsupported version at this client.");
}
if (p.getType() != PacketType.HANDSHAKE) {
throw new CanalClientException("expect handshake but found other type.");
}
//
Handshake handshake = Handshake.parseFrom(p.getBody());
supportedCompressions.add(handshake.getSupportedCompressions());
//
// seed for auth
ByteString seed = handshake.getSeeds();
String newPasswd = password;
if (password != null) {
// encode passwd
newPasswd = SecurityUtil.byte2HexStr(SecurityUtil.scramble411(password.getBytes(), seed.toByteArray()));
}
ClientAuth ca = ClientAuth.newBuilder().setUsername(username != null ? username : "").setPassword(ByteString.copyFromUtf8(newPasswd != null ? newPasswd : "")).setNetReadTimeout(idleTimeout).setNetWriteTimeout(idleTimeout).build();
writeWithHeader(Packet.newBuilder().setType(PacketType.CLIENTAUTHENTICATION).setBody(ca.toByteString()).build().toByteArray());
//
Packet ack = Packet.parseFrom(readNextPacket());
if (ack.getType() != PacketType.ACK) {
throw new CanalClientException("unexpected packet type when ack is expected");
}
Ack ackBody = Ack.parseFrom(ack.getBody());
if (ackBody.getErrorCode() > 0) {
throw new CanalClientException("something goes wrong when doing authentication: " + ackBody.getErrorMessage());
}
connected = true;
return new InetSocketAddress(channel.socket().getLocalAddress(), channel.socket().getLocalPort());
} catch (IOException | NoSuchAlgorithmException e) {
throw new CanalClientException(e);
}
}
use of com.alibaba.otter.canal.protocol.exception.CanalClientException in project canal by alibaba.
the class SimpleCanalConnector method rollback.
@Override
public void rollback(long batchId) throws CanalClientException {
waitClientRunning();
ClientRollback ca = ClientRollback.newBuilder().setDestination(clientIdentity.getDestination()).setClientId(String.valueOf(clientIdentity.getClientId())).setBatchId(batchId).build();
try {
writeWithHeader(Packet.newBuilder().setType(PacketType.CLIENTROLLBACK).setBody(ca.toByteString()).build().toByteArray());
} catch (IOException e) {
throw new CanalClientException(e);
}
}
use of com.alibaba.otter.canal.protocol.exception.CanalClientException in project canal by alibaba.
the class ClientRunningMonitor method initRunning.
// 改动记录:
// 1,在方法上加synchronized关键字,保证同步顺序执行;
// 2,判断Zk上已经存在的activeData是否是本机,是的话把mutex重置为true,否则会导致死锁
// 3,增加异常处理,保证出现异常时,running节点能被删除,否则会导致死锁
public synchronized void initRunning() {
if (!isStart()) {
return;
}
String path = ZookeeperPathUtils.getDestinationClientRunning(this.destination, clientData.getClientId());
// 序列化
byte[] bytes = JsonUtils.marshalToByte(clientData);
try {
mutex.set(false);
zkClient.create(path, bytes, CreateMode.EPHEMERAL);
// 触发一下事件
processActiveEnter();
activeData = clientData;
mutex.set(true);
} catch (ZkNodeExistsException e) {
bytes = zkClient.readData(path, true);
if (bytes == null) {
// 如果不存在节点,立即尝试一次
initRunning();
} else {
activeData = JsonUtils.unmarshalFromByte(bytes, ClientRunningData.class);
// 如果发现已经存在,判断一下是否自己,避免活锁
if (activeData.getAddress().contains(":") && isMine(activeData.getAddress())) {
mutex.set(true);
}
}
} catch (ZkNoNodeException e) {
zkClient.createPersistent(ZookeeperPathUtils.getClientIdNodePath(this.destination, clientData.getClientId()), // 尝试创建父节点
true);
initRunning();
} catch (Throwable t) {
logger.error(MessageFormat.format("There is an error when execute initRunning method, with destination [{0}].", destination), t);
// fixed issue 1220, 针对server节点不工作避免死循环
if (t instanceof ServerNotFoundException) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
// 出现任何异常尝试release
releaseRunning();
throw new CanalClientException("something goes wrong in initRunning method. ", t);
}
}
use of com.alibaba.otter.canal.protocol.exception.CanalClientException in project canal by alibaba.
the class ClusterCanalConnector method connect.
@Override
public void connect() throws CanalClientException {
while (currentConnector == null) {
int times = 0;
while (true) {
try {
currentConnector = new SimpleCanalConnector(null, username, password, destination) {
@Override
public SocketAddress getNextAddress() {
return accessStrategy.nextNode();
}
};
currentConnector.setSoTimeout(soTimeout);
currentConnector.setIdleTimeout(idleTimeout);
if (filter != null) {
currentConnector.setFilter(filter);
}
if (accessStrategy instanceof ClusterNodeAccessStrategy) {
currentConnector.setZkClientx(((ClusterNodeAccessStrategy) accessStrategy).getZkClient());
}
currentConnector.connect();
break;
} catch (Exception e) {
logger.warn("failed to connect to:{} after retry {} times", accessStrategy.currentNode(), times);
currentConnector.disconnect();
currentConnector = null;
// retry for #retryTimes for each node when trying to
// connect to it.
times = times + 1;
if (times >= retryTimes) {
throw new CanalClientException(e);
} else {
// fixed issue #55,增加sleep控制,避免重试connect时cpu使用过高
try {
Thread.sleep(retryInterval);
} catch (InterruptedException e1) {
throw new CanalClientException(e1);
}
}
}
}
}
}
Aggregations