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

问题描述 投票:0回答:1

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

Netty 有 Boss 线程,用于接受传入连接,但连接的处理将交给工作线程(即 IO 线程)。 EventLoopGroup 使用的线程是“IO 线程”,这些线程 IO 线程将处理 0-n 个通道。 据我了解,Netty 有一个事件周期,因此每当您调用任何异步 IO 函数时,请求都会被推送到操作系统级别,并且它使用 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 并在单独的函数中调用线程,但这会违背目的,因为它不是事件驱动的。

asynchronous io netty
1个回答
0
投票

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

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

当您向

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

但是,需要注意的是,

Future
本身无法控制
Executor
线程的生命周期。仅当关联的异步操作完成时,
Executor
线程才会被释放并可用于其他任务。

这里有一个例子来说明这种行为:

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

在上面的例子中,当异步任务执行时,

Executor
线程被占用。
get()
上的
Future
方法会阻塞,直到任务完成,只有在此之后,
Executor
线程才会被释放并可用于其他任务。

如果您想在不阻塞的情况下释放

Executor
线程,可以使用非阻塞技术,例如回调或将侦听器附加到
Future
对象。通过提供回调或侦听器,您可以异步处理操作的完成,而不会阻塞
Executor
线程。

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()
方法允许您将侦听器附加到
Future
对象,该对象将在操作完成时异步调用。这种方法允许在任务提交后立即释放
Executor
线程,而不会阻塞它直到任务完成。

因此,总而言之,在

Executor
上实例化异步操作并获取
Future
不会自动释放
Executor
线程。该线程将被占用,直到关联的异步操作完成。要释放
Executor
线程而不阻塞,您可以使用非阻塞技术,例如回调或将侦听器附加到
Future
对象。

© www.soinside.com 2019 - 2024. All rights reserved.