gpt4 book ai didi

netty - Akka HTTP 和 Netty 的区别

转载 作者:行者123 更新时间:2023-12-03 22:36:31 28 4
gpt4 key购买 nike

有人可以解释Akka HTTP之间的主要区别吗?和 Netty ? Netty 也提供其他协议(protocol),如 FTP。 Akka HTTP 可用于 Scala 和 Java,是 build on the actor model .但除此之外,两者都是异步的。我什么时候使用 Akka HTTP,什么时候使用 Netty?两者的典型用例是什么?

最佳答案

以下是我认为的主要可对比区域:

编码风格

拿netty的discard server example这大概是最简单的例子,因为它是文档中的第一个。

对于 akka-http这相对简单:

object WebServer {
def main(args: Array[String]) {

implicit val system = ActorSystem("my-system")
implicit val materializer = ActorMaterializer()

val route =
extractRequestEntity { entity =>
onComplete(entity.discardBytes(materializer)) { _ =>
case _ => complete(StatusCodes.Ok)
}
}

val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
}

对于 netty,这要详细得多:
public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1)

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2)
// Discard the received data silently.
((ByteBuf) msg).release(); // (3)
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
// Close the connection when an exception is raised.
cause.printStackTrace();
ctx.close();
}
}

public class DiscardServer {

private int port;

public DiscardServer(int port) {
this.port = port;
}

public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // (3)
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new DiscardServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128) // (5)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)

// Bind and start to accept incoming connections.
ChannelFuture f = b.bind(port).sync(); // (7)

// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}

public static void main(String[] args) throws Exception {
new DiscardServer(8080).run();
}
}

指令

在我看来,akka-http 的最大优势之一是 Directives ,它为复杂的请求处理逻辑提供了 DSL。例如,假设我们想用一条消息响应 GET。和 PUT requests 和所有其他请求方法的另一条消息。这很容易使用指令:
val route = 
(get | put) {
complete("You sent a GET or PUT")
} ~
complete("Shame shame")

如果您想从请求路径中获取订单项目和数量:
val route = 
path("order" / Segment / IntNumber) { (item, qty) =>
complete(s"Your order: item: $item quantity: $qty")
}

netty 中不存在此功能。

流媒体

我要注意的最后一项是关于流媒体。 akka-http 基于 akka-stream .因此,akka-http 很好地处理了请求实体的流式传输特性。拿netty的 Looking Into the Received Data例如,对于 akka,这看起来像
//a stream with a Source, intermediate processing steps, and a Sink
val entityToConsole : (RequestEntity) => Future[Done] =
(_ : RequestEntity)
.getDataBytes()
.map(_.utf8String)
.to(Sink.foreach[String](println))
.run()

val route =
extractRequestEntity { entity =>
onComplete(entityToConsole(entity)) { _ =>
case Success(_) => complete(200, "all data written to console")
case Failure(_) => complete(404, "problem writing to console)
}
}

Netty 必须处理字节缓冲区和 while 循环的相同问题:
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
try {
while (in.isReadable()) { // (1)
System.out.print((char) in.readByte());
System.out.flush();
}
} finally {
ReferenceCountUtil.release(msg); // (2)
}
}

关于netty - Akka HTTP 和 Netty 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44549074/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com