Java 将netty通道传递到队列并在以后将其用于不同线程上的写入是否有效?
我有以下设置。有一个消息分发服务器,它基于名为appId的唯一标识符(每个连接的客户端),将入站客户端消息分发到配置数量的消息队列(在我的示例中为LinkedBlockingQueues): 此外,还有一个消息使用者,它实现了一个Runnable并从分配的阻塞队列中获取新消息。这家伙执行一些昂贵的/阻塞操作,我希望在主netty事件循环之外执行这些操作,这些操作也不会太多地阻塞其他连接客户端的操作,因此使用了几个队列:Java 将netty通道传递到队列并在以后将其用于不同线程上的写入是否有效?,java,multithreading,netty,message-queue,Java,Multithreading,Netty,Message Queue,我有以下设置。有一个消息分发服务器,它基于名为appId的唯一标识符(每个连接的客户端),将入站客户端消息分发到配置数量的消息队列(在我的示例中为LinkedBlockingQueues): 此外,还有一个消息使用者,它实现了一个Runnable并从分配的阻塞队列中获取新消息。这家伙执行一些昂贵的/阻塞操作,我希望在主netty事件循环之外执行这些操作,这些操作也不会太多地阻塞其他连接客户端的操作,因此使用了几个队列: public class MessageConsumer implement
public class MessageConsumer implements Runnable {
private final BlockingQueue<MessageWrapper> messageQueue;
public MessageConsumer(BlockingQueue<MessageWrapper> messageQueue) {
this.messageQueue = messageQueue;
}
@Override
public void run() {
while (true) {
try {
MessageWrapper msgWrap = messageQueue.take();
Channel channel = msgWrap.getChannel();
Message msg = msgWrap.getMessage();
doSthExepnsiveOrBlocking(channel, msg);
} catch (Exception e) {
// handle exception
}
}
}
public void doSthExepnsiveOrBlocking(Channel channel, Message msg) {
// some expsive/blocking operations
channe.writeAndFlush(someResultObj);
}
}
我使用这种方法的目标是将连接的客户机彼此隔离(不是完全隔离,但至少隔离一点),并在不同的线程上执行昂贵的操作
现在我的问题是:将netty channel对象包装在这个MessageWrapper
中以便以后使用并在其他线程中访问其write方法是否有效
更新
我没有在netty上构建额外的消息分发机制,而是决定为我的阻塞通道处理程序使用一个单独的EventExecutorGroup,看看它是如何工作的 是从其他线程调用
通道。*
方法是有效的。也就是说,当从属于通道的线程本身调用这些方法时,它们的性能最佳
public class MessageWrapper {
private final Channel channel;
private final Message message;
public MessageWrapper(Channel channel, Message message) {
this.channel = channel;
this.message = message;
}
public Channel getChannel() {
return channel;
}
public Message getMessage() {
return message;
}
}
public class MessageConsumer implements Runnable {
private final BlockingQueue<MessageWrapper> messageQueue;
public MessageConsumer(BlockingQueue<MessageWrapper> messageQueue) {
this.messageQueue = messageQueue;
}
@Override
public void run() {
while (true) {
try {
MessageWrapper msgWrap = messageQueue.take();
Channel channel = msgWrap.getChannel();
Message msg = msgWrap.getMessage();
doSthExepnsiveOrBlocking(channel, msg);
} catch (Exception e) {
// handle exception
}
}
}
public void doSthExepnsiveOrBlocking(Channel channel, Message msg) {
// some expsive/blocking operations
channe.writeAndFlush(someResultObj);
}
}
int nrOfWorkers = config.getNumberOfClientMessageQueues();
List<BlockingQueue<MessageWrapper>> messageQueueBuckets = new ArrayList<>(nrOfWorkers);
for (int i = 0; i < nrOfWorkers; i++) {
messageQueueBuckets.add(new LinkedBlockingQueue<>());
}
MessageDistributor distributor = new MessageDistributor(messageQueueBuckets);
List<MessageConsumer> consumers = new ArrayList<>(nrOfWorkers);
for (BlockingQueue<MessageWrapper> messageQueueBucket : messageQueueBuckets) {
MessageConsumer consumer = new MessageConsumer(messageQueueBucket);
consumers.add(consumer);
messageExecutor.submit(consumer);
}