use of com.weibo.api.motan.exception.MotanServiceException in project motan by weibocom.
the class NettyChannel method open.
@Override
public synchronized boolean open() {
if (isAvailable()) {
LoggerUtil.warn("the channel already open, local: " + localAddress + " remote: " + remoteAddress + " url: " + nettyClient.getUrl().getUri());
return true;
}
try {
ChannelFuture channleFuture = nettyClient.getBootstrap().connect(new InetSocketAddress(nettyClient.getUrl().getHost(), nettyClient.getUrl().getPort()));
long start = System.currentTimeMillis();
int timeout = nettyClient.getUrl().getIntParameter(URLParamType.connectTimeout.getName(), URLParamType.connectTimeout.getIntValue());
if (timeout <= 0) {
throw new MotanFrameworkException("NettyClient init Error: timeout(" + timeout + ") <= 0 is forbid.", MotanErrorMsgConstant.FRAMEWORK_INIT_ERROR);
}
// 不去依赖于connectTimeout
boolean result = channleFuture.awaitUninterruptibly(timeout, TimeUnit.MILLISECONDS);
boolean success = channleFuture.isSuccess();
if (result && success) {
channel = channleFuture.getChannel();
if (channel.getLocalAddress() != null && channel.getLocalAddress() instanceof InetSocketAddress) {
localAddress = (InetSocketAddress) channel.getLocalAddress();
}
state = ChannelState.ALIVE;
return true;
}
boolean connected = false;
if (channleFuture.getChannel() != null) {
connected = channleFuture.getChannel().isConnected();
}
if (channleFuture.getCause() != null) {
channleFuture.cancel();
throw new MotanServiceException("NettyChannel failed to connect to server, url: " + nettyClient.getUrl().getUri() + ", result: " + result + ", success: " + success + ", connected: " + connected, channleFuture.getCause());
} else {
channleFuture.cancel();
throw new MotanServiceException("NettyChannel connect to server timeout url: " + nettyClient.getUrl().getUri() + ", cost: " + (System.currentTimeMillis() - start) + ", result: " + result + ", success: " + success + ", connected: " + connected);
}
} catch (MotanServiceException e) {
throw e;
} catch (Exception e) {
throw new MotanServiceException("NettyChannel failed to connect to server, url: " + nettyClient.getUrl().getUri(), e);
} finally {
if (!state.isAliveState()) {
nettyClient.incrErrorCount();
}
}
}
use of com.weibo.api.motan.exception.MotanServiceException in project motan by weibocom.
the class NettyClient method request.
/**
* 请求remote service
*
* <pre>
* 1) get connection from pool
* 2) async requset
* 3) return connection to pool
* 4) check if async return response, true: return ResponseFuture; false: return result
* </pre>
*
* @param request
* @param async
* @return
* @throws TransportException
*/
private Response request(Request request, boolean async) throws TransportException {
Channel channel = null;
Response response = null;
try {
// return channel or throw exception(timeout or connection_fail)
channel = borrowObject();
if (channel == null) {
LoggerUtil.error("NettyClient borrowObject null: url=" + url.getUri() + " " + MotanFrameworkUtil.toString(request));
return null;
}
// async request
response = channel.request(request);
// return channel to pool
returnObject(channel);
} catch (Exception e) {
LoggerUtil.error("NettyClient request Error: url=" + url.getUri() + " " + MotanFrameworkUtil.toString(request), e);
//TODO 对特定的异常回收channel
invalidateObject(channel);
if (e instanceof MotanAbstractException) {
throw (MotanAbstractException) e;
} else {
throw new MotanServiceException("NettyClient request Error: url=" + url.getUri() + " " + MotanFrameworkUtil.toString(request), e);
}
}
// aysnc or sync result
response = asyncResponse(response, async);
return response;
}
use of com.weibo.api.motan.exception.MotanServiceException in project motan by weibocom.
the class NettyResponseFuture method timeoutSoCancel.
private void timeoutSoCancel() {
this.processTime = System.currentTimeMillis() - createTime;
synchronized (lock) {
if (!isDoing()) {
return;
}
state = FutureState.CANCELLED;
exception = new MotanServiceException("NettyResponseFuture request timeout: serverPort=" + channel.getUrl().getServerPortStr() + " " + MotanFrameworkUtil.toString(request) + " cost=" + (System.currentTimeMillis() - createTime), MotanErrorMsgConstant.SERVICE_TIMEOUT);
lock.notifyAll();
}
notifyListeners();
}
use of com.weibo.api.motan.exception.MotanServiceException in project motan by weibocom.
the class NettyChannelHandler method processRequest.
/**
* <pre>
* request process: 主要来自于client的请求,需要使用threadPoolExecutor进行处理,避免service message处理比较慢导致iothread被阻塞
* </pre>
*
* @param ctx
* @param e
*/
private void processRequest(final ChannelHandlerContext ctx, MessageEvent e) {
final Request request = (Request) e.getMessage();
request.setAttachment(URLParamType.host.getName(), NetUtils.getHostName(ctx.getChannel().getRemoteAddress()));
final long processStartTime = System.currentTimeMillis();
// 使用线程池方式处理
try {
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
try {
RpcContext.init(request);
processRequest(ctx, request, processStartTime);
} finally {
RpcContext.destroy();
}
}
});
} catch (RejectedExecutionException rejectException) {
DefaultResponse response = new DefaultResponse();
response.setRequestId(request.getRequestId());
response.setException(new MotanServiceException("process thread pool is full, reject", MotanErrorMsgConstant.SERVICE_REJECT));
response.setProcessTime(System.currentTimeMillis() - processStartTime);
e.getChannel().write(response);
LoggerUtil.debug("process thread pool is full, reject, active={} poolSize={} corePoolSize={} maxPoolSize={} taskCount={} requestId={}", threadPoolExecutor.getActiveCount(), threadPoolExecutor.getPoolSize(), threadPoolExecutor.getCorePoolSize(), threadPoolExecutor.getMaximumPoolSize(), threadPoolExecutor.getTaskCount(), request.getRequestId());
}
}
use of com.weibo.api.motan.exception.MotanServiceException in project motan by weibocom.
the class NettyDecoder method decode.
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
if (buffer.readableBytes() <= MotanConstants.NETTY_HEADER) {
return null;
}
buffer.markReaderIndex();
short type = buffer.readShort();
if (type != MotanConstants.NETTY_MAGIC_TYPE) {
buffer.resetReaderIndex();
throw new MotanFrameworkException("NettyDecoder transport header not support, type: " + type);
}
byte messageType = (byte) buffer.readShort();
long requestId = buffer.readLong();
int dataLength = buffer.readInt();
// FIXME 如果dataLength过大,可能导致问题
if (buffer.readableBytes() < dataLength) {
buffer.resetReaderIndex();
return null;
}
if (maxContentLength > 0 && dataLength > maxContentLength) {
LoggerUtil.warn("NettyDecoder transport data content length over of limit, size: {} > {}. remote={} local={}", dataLength, maxContentLength, ctx.getChannel().getRemoteAddress(), ctx.getChannel().getLocalAddress());
Exception e = new MotanServiceException("NettyDecoder transport data content length over of limit, size: " + dataLength + " > " + maxContentLength);
if (messageType == MotanConstants.FLAG_REQUEST) {
Response response = buildExceptionResponse(requestId, e);
channel.write(response);
throw e;
} else {
throw e;
}
}
byte[] data = new byte[dataLength];
buffer.readBytes(data);
try {
String remoteIp = getRemoteIp(channel);
return codec.decode(client, remoteIp, data);
} catch (Exception e) {
if (messageType == MotanConstants.FLAG_REQUEST) {
Response resonse = buildExceptionResponse(requestId, e);
channel.write(resonse);
return null;
} else {
Response resonse = buildExceptionResponse(requestId, e);
return resonse;
}
}
}
Aggregations