client优化
This commit is contained in:
@@ -31,14 +31,6 @@ public abstract class AsyncGroup {
|
|||||||
return new AsyncIOGroup(threadNameFormat, workExecutor, safeBufferPool);
|
return new AsyncIOGroup(threadNameFormat, workExecutor, safeBufferPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AsyncGroup create(String threadNameFormat, int threads, ExecutorService workExecutor, final int bufferCapacity, final int bufferPoolSize) {
|
|
||||||
return new AsyncIOGroup(threadNameFormat, threads, workExecutor, bufferCapacity, bufferPoolSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AsyncGroup create(String threadNameFormat, int threads, ExecutorService workExecutor, ByteBufferPool safeBufferPool) {
|
|
||||||
return new AsyncIOGroup(threadNameFormat, threads, workExecutor, safeBufferPool);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CompletableFuture<AsyncConnection> createTCPClient(final SocketAddress address) {
|
public CompletableFuture<AsyncConnection> createTCPClient(final SocketAddress address) {
|
||||||
return createTCPClient(address, 0, 0);
|
return createTCPClient(address, 0, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,41 +57,33 @@ public class AsyncIOGroup extends AsyncGroup {
|
|||||||
//关闭数
|
//关闭数
|
||||||
protected final LongAdder connClosedCounter = new LongAdder();
|
protected final LongAdder connClosedCounter = new LongAdder();
|
||||||
|
|
||||||
protected final ScheduledThreadPoolExecutor timeoutExecutor;
|
//超时器
|
||||||
|
protected final ScheduledExecutorService timeoutExecutor;
|
||||||
|
|
||||||
public AsyncIOGroup(final int bufferCapacity, final int bufferPoolSize) {
|
public AsyncIOGroup(final int bufferCapacity, final int bufferPoolSize) {
|
||||||
this("Redkale-AnonymousClient-IOThread-%s", Utility.cpus(), null, bufferCapacity, bufferPoolSize);
|
this("Redkale-AnonymousClient-IOThread-%s", null, bufferCapacity, bufferPoolSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AsyncIOGroup(String threadNameFormat, final ExecutorService workExecutor, final int bufferCapacity, final int bufferPoolSize) {
|
public AsyncIOGroup(String threadNameFormat, final ExecutorService workExecutor, final int bufferCapacity, final int bufferPoolSize) {
|
||||||
this(threadNameFormat, Utility.cpus(), workExecutor, bufferCapacity, bufferPoolSize);
|
this(threadNameFormat, workExecutor, ByteBufferPool.createSafePool(bufferPoolSize, bufferCapacity));
|
||||||
}
|
|
||||||
|
|
||||||
public AsyncIOGroup(String threadNameFormat, int threads, final ExecutorService workExecutor, final int bufferCapacity, final int bufferPoolSize) {
|
|
||||||
this(threadNameFormat, threads, workExecutor, ByteBufferPool.createSafePool(bufferPoolSize, bufferCapacity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("OverridableMethodCallInConstructor")
|
@SuppressWarnings("OverridableMethodCallInConstructor")
|
||||||
public AsyncIOGroup(String threadNameFormat, ExecutorService workExecutor, final ByteBufferPool safeBufferPool) {
|
public AsyncIOGroup(String threadNameFormat, ExecutorService workExecutor, final ByteBufferPool safeBufferPool) {
|
||||||
this(threadNameFormat, Utility.cpus(), workExecutor, safeBufferPool);
|
final int threads = Utility.cpus(); //固定值,不可改
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("OverridableMethodCallInConstructor")
|
|
||||||
public AsyncIOGroup(String threadNameFormat, int threads, ExecutorService workExecutor, final ByteBufferPool safeBufferPool) {
|
|
||||||
this.bufferCapacity = safeBufferPool.getBufferCapacity();
|
this.bufferCapacity = safeBufferPool.getBufferCapacity();
|
||||||
this.ioReadThreads = new AsyncIOThread[threads];
|
this.ioReadThreads = new AsyncIOThread[threads];
|
||||||
this.ioWriteThreads = new AsyncIOThread[threads];
|
this.ioWriteThreads = new AsyncIOThread[threads];
|
||||||
final ThreadGroup g = new ThreadGroup(String.format(threadNameFormat, "Group"));
|
final ThreadGroup g = new ThreadGroup(String.format(threadNameFormat, "Group"));
|
||||||
|
this.timeoutExecutor = Executors.newScheduledThreadPool(1, (Runnable r) -> {
|
||||||
this.timeoutExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1, (Runnable r) -> {
|
|
||||||
Thread t = new Thread(r, String.format(threadNameFormat, "Timeout"));
|
Thread t = new Thread(r, String.format(threadNameFormat, "Timeout"));
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < threads; i++) {
|
for (int i = 0; i < threads; i++) {
|
||||||
String indexfix = WorkThread.formatIndex(threads, i + 1);
|
String indexFix = WorkThread.formatIndex(threads, i + 1);
|
||||||
this.ioReadThreads[i] = createAsyncIOThread(g, String.format(threadNameFormat, indexfix), i, threads, workExecutor, safeBufferPool);
|
this.ioReadThreads[i] = createAsyncIOThread(g, String.format(threadNameFormat, indexFix), i, threads, workExecutor, safeBufferPool);
|
||||||
this.ioWriteThreads[i] = this.ioReadThreads[i];
|
this.ioWriteThreads[i] = this.ioReadThreads[i];
|
||||||
}
|
}
|
||||||
this.connectThread = createConnectIOThread(g, String.format(threadNameFormat, "Connect"), 0, 0, workExecutor, safeBufferPool);
|
this.connectThread = createConnectIOThread(g, String.format(threadNameFormat, "Connect"), 0, 0, workExecutor, safeBufferPool);
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ public abstract class Client<C extends ClientConnection<R, P>, R extends ClientR
|
|||||||
|
|
||||||
public static final int DEFAULT_MAX_PIPELINES = 128;
|
public static final int DEFAULT_MAX_PIPELINES = 128;
|
||||||
|
|
||||||
|
protected boolean debug;
|
||||||
|
|
||||||
protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
|
protected final Logger logger = Logger.getLogger(this.getClass().getSimpleName());
|
||||||
|
|
||||||
protected final String name;
|
protected final String name;
|
||||||
|
|||||||
@@ -99,39 +99,37 @@ public abstract class ClientCodec<R extends ClientRequest, P> implements Complet
|
|||||||
void responseComplete(boolean halfCompleted, ClientFuture<R, P> respFuture, P message, Throwable exc) {
|
void responseComplete(boolean halfCompleted, ClientFuture<R, P> respFuture, P message, Throwable exc) {
|
||||||
if (respFuture != null) {
|
if (respFuture != null) {
|
||||||
R request = respFuture.request;
|
R request = respFuture.request;
|
||||||
WorkThread workThread = null;
|
AsyncIOThread readThread = connection.channel.getReadIOThread();
|
||||||
|
final WorkThread workThread = request == null ? readThread : request.removeWorkThread(readThread);
|
||||||
try {
|
try {
|
||||||
if (!halfCompleted && request != null && !request.isCompleted()) {
|
if (!halfCompleted && request != null && !request.isCompleted()) {
|
||||||
if (exc == null) {
|
if (exc == null) {
|
||||||
connection.sendHalfWrite(request, exc);
|
connection.sendHalfWrite(request, exc);
|
||||||
//request没有发送完,respFuture需要再次接收
|
//request没有发送完,respFuture需要再次接收
|
||||||
return;
|
return;
|
||||||
} else { //异常了需要清掉半包
|
} else {
|
||||||
connection.sendHalfWrite(request, exc);
|
connection.sendHalfWrite(request, exc);
|
||||||
|
//异常了需要清掉半包
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (request != null) {
|
|
||||||
workThread = request.workThread;
|
|
||||||
request.workThread = null;
|
|
||||||
}
|
|
||||||
connection.respWaitingCounter.decrement();
|
connection.respWaitingCounter.decrement();
|
||||||
if (connection.isAuthenticated()) {
|
if (connection.isAuthenticated()) {
|
||||||
connection.client.incrRespDoneCounter();
|
connection.client.incrRespDoneCounter();
|
||||||
}
|
}
|
||||||
respFuture.cancelTimeout();
|
respFuture.cancelTimeout();
|
||||||
//if (client.finest) client.logger.log(Level.FINEST, Utility.nowMillis() + ": " + Thread.currentThread().getName() + ": " + ClientConnection.this + ", 回调处理, req=" + request + ", message=" + rs.message);
|
// if (connection.client.debug) {
|
||||||
|
// connection.client.logger.log(Level.FINEST, Utility.nowMillis() + ": " + Thread.currentThread().getName() + ": " + connection + ", 回调处理, req=" + request + ", message=" + message, exc);
|
||||||
|
// }
|
||||||
connection.preComplete(message, (R) request, exc);
|
connection.preComplete(message, (R) request, exc);
|
||||||
boolean reqInIO = workThread != null && workThread.inIO();
|
|
||||||
|
|
||||||
if (workThread == null || workThread.getWorkExecutor() == null) {
|
|
||||||
workThread = connection.channel.getReadIOThread();
|
|
||||||
}
|
|
||||||
if (exc != null) {
|
if (exc != null) {
|
||||||
if (reqInIO) { //request在IO线程中发送请求,说明request是在异步模式中
|
if (workThread.inIO()) {
|
||||||
|
workThread.execute(() -> {
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
Traces.currTraceid(request.traceid);
|
Traces.currTraceid(request.traceid);
|
||||||
}
|
}
|
||||||
respFuture.completeExceptionally(exc);
|
respFuture.completeExceptionally(exc);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
workThread.runWork(() -> {
|
workThread.runWork(() -> {
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
@@ -142,11 +140,13 @@ public abstract class ClientCodec<R extends ClientRequest, P> implements Complet
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final Object rs = request == null || request.respTransfer == null ? message : request.respTransfer.apply(message);
|
final Object rs = request == null || request.respTransfer == null ? message : request.respTransfer.apply(message);
|
||||||
if (reqInIO) { //request在IO线程中发送请求,说明request是在异步模式中
|
if (workThread.inIO()) {
|
||||||
|
workThread.execute(() -> {
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
Traces.currTraceid(request.traceid);
|
Traces.currTraceid(request.traceid);
|
||||||
}
|
}
|
||||||
((ClientFuture) respFuture).complete(rs);
|
((ClientFuture) respFuture).complete(rs);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
workThread.runWork(() -> {
|
workThread.runWork(() -> {
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
@@ -157,11 +157,13 @@ public abstract class ClientCodec<R extends ClientRequest, P> implements Complet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
if (workThread == null || workThread.inIO()) {
|
if (workThread.inIO()) {
|
||||||
|
workThread.execute(() -> {
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
Traces.currTraceid(request.traceid);
|
Traces.currTraceid(request.traceid);
|
||||||
}
|
}
|
||||||
respFuture.completeExceptionally(t);
|
respFuture.completeExceptionally(t);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
workThread.runWork(() -> {
|
workThread.runWork(() -> {
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
|
|||||||
@@ -32,6 +32,12 @@ public abstract class ClientRequest {
|
|||||||
|
|
||||||
public abstract void writeTo(ClientConnection conn, ByteArray array);
|
public abstract void writeTo(ClientConnection conn, ByteArray array);
|
||||||
|
|
||||||
|
WorkThread removeWorkThread(WorkThread defaultValue) {
|
||||||
|
WorkThread t = this.workThread;
|
||||||
|
this.workThread = null;
|
||||||
|
return t == null ? defaultValue : t;
|
||||||
|
}
|
||||||
|
|
||||||
public Serializable getRequestid() {
|
public Serializable getRequestid() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ import org.redkale.util.*;
|
|||||||
@Deprecated(since = "2.8.0")
|
@Deprecated(since = "2.8.0")
|
||||||
public class WebSocketWriteIOThread extends AsyncIOThread {
|
public class WebSocketWriteIOThread extends AsyncIOThread {
|
||||||
|
|
||||||
private final ScheduledThreadPoolExecutor timeoutExecutor;
|
private final ScheduledExecutorService timeoutExecutor;
|
||||||
|
|
||||||
private final BlockingDeque<WebSocketFuture> requestQueue = new LinkedBlockingDeque<>();
|
private final BlockingDeque<WebSocketFuture> requestQueue = new LinkedBlockingDeque<>();
|
||||||
|
|
||||||
public WebSocketWriteIOThread(ScheduledThreadPoolExecutor timeoutExecutor, ThreadGroup g, String name, int index, int threads,
|
public WebSocketWriteIOThread(ScheduledExecutorService timeoutExecutor, ThreadGroup g, String name, int index, int threads,
|
||||||
ExecutorService workExecutor, ByteBufferPool safeBufferPool) throws IOException {
|
ExecutorService workExecutor, ByteBufferPool safeBufferPool) throws IOException {
|
||||||
super(g, name, index, threads, workExecutor, safeBufferPool);
|
super(g, name, index, threads, workExecutor, safeBufferPool);
|
||||||
Objects.requireNonNull(timeoutExecutor);
|
Objects.requireNonNull(timeoutExecutor);
|
||||||
|
|||||||
Reference in New Issue
Block a user