Netty 将第三方库的异步调用卸载到操作系统

Netty offload Async calls of Third-Party Libs to OS

提问人:Vipresh 提问时间:8/28/2023 最后编辑:Vipresh 更新时间:9/4/2023 访问量:54

问:

试图弄清楚我对第三方库的异步调用将如何卸载到操作系统,

Netty 具有用于接受传入连接的 Boss 线程,但连接的处理被移交给工作线程(即 IO 线程)。EventLoopGroup 使用的线程是“IO 线程”,这些线程 IO 线程将处理 0-n 个通道。 据我了解,Netty 有一个事件周期,因此每当您调用任何异步 IO 函数时,请求都会被推送到 o/s 级别,并且它使用 epoll 并等待事件发送回 netty,并且 IO 线程可以自由地在其他通道上提供请求,当操作系统生成 netty 订阅的事件时, 然后,Netty 有一个触发的事件循环。 此外,您不应阻止(休眠)这些 IO 线程,否则您的客户端将等待响应,并且您还将浪费一个可用于处理另一个请求的线程,如果要确保 ChannelHandler 将从 IO 线程中卸载,您通常会创建一个 DefaultEventExecutorGroup 并在添加 ChannelHandler 时指定它。

现在根据我的理解,每次服务器收到请求时,都会使用 channelPipelineFactory 来创建 ChannelPipeline。ChannelPipeline 包含一系列处理请求的 ChannelHandler。现在我的问题是,如果我的管道中的一些处理程序需要从 Redis 和 Aerospike 等缓存中获取数据,这就是阻止 IO。该 IOThread 会阻止请求的处理,直到 IO 完成。 我对来自 NodeJS 的事件驱动的异步 I/O 的理解是,有一个事件循环,并且有一系列注册用于阻止 I/O 操作的回调函数,每当 I/O 完成时,这些函数就会被调用。如何在 Netty 中实现相同的目标?在 NodeJs 中,我可以调用 Redis 和 Aerospike 客户端库的异步函数。异步函数返回 promise,当 IO 完成(即从缓存中获取数据)时,将调用异步调用中传递的回调函数。NodeJs 知道一些 IO 正在运行,因此它释放了请求处理管道并处理其他请求。我如何向 Netty 发出信号释放 IO 线程,以便它们可以处理我的 HTTP 服务器的其他请求并将请求向下推送到操作系统级别并等待来自操作系统的事件,我可以使用 ExecutorGroup 并在单独的线程中执行函数调用,但这会破坏目的,因为它不是 EventDriven。

异步 IO netty

评论

0赞 Vipresh 9/4/2023
这是 ChatGTP 建议的可能解决方案,不确定它是否正确,poe.com/s/Qz4wveDQV6NnAEAiVpxm

答:

0赞 Vipresh 9/4/2023 #1

这是我从 Chat GPT 得到的,不确定这是否正确

在 上实例化异步操作并获取 不会自动释放线程。线程将继续被占用,直到与 关联的异步操作完成。ExecutorFutureExecutorExecutorFuture

当您将异步任务提交到 时,它通常会在单独的线程中执行该任务。线程负责执行任务并监视其进度。当您获得表示任务结果的 a 时,它允许您检查完成状态、检索结果或根据任务的完成情况执行其他操作。ExecutorExecutorFuture

但是,需要注意的是,它本身无法控制线程的生命周期。只有当关联的异步操作完成时,线程才会被释放并可用于其他任务。FutureExecutorExecutor

下面是一个示例来说明此行为:

Executor executor = ...; // Get an Executor

Future<String> future = executor.submit(() -> {
    // Perform asynchronous task
    return "Result";
});

// The Executor thread is still occupied until the task completes

// Wait for the task to complete and retrieve the result
String result = future.get();

// The Executor thread is released at this point

在上面的示例中,在执行异步任务时,线程被占用。块上的方法,直到任务完成,只有在那之后,线程才会被释放并可用于其他任务。Executorget()FutureExecutor

如果要在不阻塞的情况下释放线程,可以使用非阻塞技术,例如回调或将侦听器附加到对象。通过提供回调或侦听器,可以在不阻塞线程的情况下异步处理操作的完成。ExecutorFutureExecutor

executor.submit(() -> {
    // Perform asynchronous task
    return "Result";
}).addListener((FutureListener<String>) future -> {
    // Handle completion asynchronously
    if (future.isSuccess()) {
        String result = future.get();
        // Process the result
    } else {
        Throwable cause = future.cause();
        // Handle the failure
    }
});

在这种情况下,该方法允许您将侦听器附加到对象,该侦听器将在操作完成时异步调用。此方法允许在提交任务后立即释放线程,而不会在任务完成之前阻止它。addListener()FutureExecutor

因此,总而言之,在 上实例化异步操作并获取 不会自动释放线程。线程将被占用,直到关联的异步操作完成。要在不阻塞的情况下释放线程,可以使用非阻塞技术,例如回调或将侦听器附加到对象。ExecutorFutureExecutorExecutorFuture