你的第一个 Netty 程序

关注微信公众号(瓠悠笑软件部落),大家一起学习,一起摸鱼。
huyouxiao.com
本章包括:

  • 开发环境的搭建
  • 编写一个 Echo sever 和 client
  • 构建和测试这个应用程序

在本章中,让我们看下如何基于 Netty 构建一个 client 和 server. 这个应用程很简单: client 发送消息给 server。 然后 server 将消息返回给 client。 这个练习的两个关键点在于:
首先,它将提供一个测试平台,用于设置和验证您的开发工具和环境,如果你计划使用这本书,这是必不可少的, 为您自己的开发工作做准备的代码。
其次,您将获得Netty关键方面的实践经验,在上一章中:使用ChannelHandler构建应用程序逻辑。 这个
将为您准备深入研究我们将在第3章开始的Netty API做好准备。

2.1 Setting up the development environment

要编译和运行本书的示例,您需要的唯一工具是 JDK 和 Apache Maven,都可以免费下载。

我们还假设你想要修改示例代码和很快就开始写自己的了。 虽然您可以使用纯文本编辑器,但我们强烈建议使用Java的集成开发环境(IDE)。

2.1.1 Obtaining and installing the Java Development Kit

您的操作系统可能已经安装了JDK。 要查找,请在命令行上键入以下内容:
javac -version

如果你回到javac 1.7 …或1.8 …你已经完成了设置,可以跳过这一步。

否则,从这里获取JDK的第8版。小心下载JDK而不是Java Runtime Environment(JRE)可以运行Java应用程序但不能编译它们。 提供安装程序可执行文件
对于每个平台。 如果您需要安装说明,您可以在上面找到它们同一个网站。

执行以下操作是个好主意:

  • 设置 JAVA_HOME 环境变量,指向 JDK 的安装路径。
  • 在 Linux 环境下,将 ${JAVA_HOME}/bin 添加到你的执行路径。
2.1.2 Downloading and installing an IDE

以下是最广泛使用的Java IDE,都是免费提供的:

  • Eclipse
  • NetBeans
  • Intellij Idea Community Edition
    这三个都完全支持我们使用的构建工具Apache Maven。 NetBeans 和 Intellij 作为安装程序可执行文件分发。 Eclipse通常以zip形式分发归档,虽然有许多自定义版本具有自安装程序。
2.1.3 Downloading and installing Apache Maven

即使您已经熟悉Maven,我们建议您至少浏览一下部分。Maven是Apache Software开发的一种广泛使用的构建管理工具基金会(ASF)。 Netty项目使用它,本书的例子也是如此。 你没有需要成为Maven专家来构建和运行示例,但是如果要在他们身上扩展的话,我们建议阅读附录中的Maven介绍。

你需要安装Maven吗?
Eclipse和NetBeans附带了一个可以正常工作的嵌入式Maven安装为了我们的目的开箱即用。 如果你将在一个拥有它的环境中工作拥有自己的Maven存储库,您的管理员可能有一个Maven安装包预先配置为使用它。

在本书出版时,最新的Maven版本是3.3.3。 您可以从这里下载适用于您系统的tar.gz或zip文件。安装很简单:将存档的内容提取到任何内容你选择的文件夹(我们称之为<install_dir>)。 这将创建目录<install_dir> \ Apache-maven-3.3.3。
和设置 Java 环境变量一样

  • 设置 M2_HOME 环境变量,并将它指向 <install_dir>\apache-maven-3.3.3.
  • 在Linux环境下,将 ${M2_HOME}/bin 添加到你的执行路径下。
    这将使您能够通过在命令行上执行mvn.bat(或mvn)来运行Maven。
2.1.4 Configuring the toolset

如果您按照建议设置了JAVA_HOME和M2_HOME系统变量,则可以发现当你启动IDE时它已经发现了Java的位置和Maven装置。 如果您需要执行手动配置,所有IDE版本都是我们列出的sions有用于在Preferences或下设置这些变量的菜单项设置。 有关详细信息,请参阅文档。这样就完成了开发环境的设置。 在下一节中我们将介绍您将构建的第一个Netty应用程序的详细信息,我们将获得更深入的框架API。 之后,您将使用刚刚设置的工具构建并运行Echo服务器和客户端。

2.2 Netty client/server overview

图2.1显示了您将要编写的Echo客户端和服务器的高级视图。虽然您的主要关注点可能是编写基于Web的应用程序以供浏览器访问,但通过实现客户端和服务器,您肯定可以更全面地了解Netty API。虽然我们已经谈到客户端,但该图显示了多个客户端已连接同时到服务器。 可支持的客户端数量有限,理论上,只有可用的系统资源(以及可能存在的任何约束)由JDK版本强制使用。

Echo客户端和服务器之间的交互非常简单; 在客户端建立连接之后,它会向服务器发送一条或多条消息,然后服务器将每条消息回送给客户端。 虽然这本身似乎并不十分有用,但它本身举例说明了典型的客户端/服务器系统的请求 - 响应交互。我们将通过检查服务器端代码来开始这个项目。
Echo client and server

2.3 Writing the Echo server

所有Netty服务器都需要以下内容:

  • 至少有一个ChannelHandler - 这个组件实现了服务器的进程 - 从客户端收到的数据 - 其业务逻辑。
  • Bootstrapping-这是配置服务器的启动代码。 最低限度,它将服务器绑定到它将侦听连接请求的端口。

在本节的其余部分,我们将看看如何写 Echo server 的 logic code 和 bootstrapping code。

2.3.1 ChannelHandlers and business logic

在第1章中,我们介绍了 Future 和 callbacks,并说明了它们的事件驱动设计用法。 我们还讨论了ChannelHandler,它是一个家族的父母接口,其实现接收并响应事件通知。 在Netty应用程序,所有数据处理逻辑都包含在这些核心的实现中抽象。

因为您的Echo服务器将响应传入的消息,所以它需要实现接口 ChannelInboundHandler ,它定义了对入站事件进行操作的方法。 这个简单的应用程序只需要这些方法中的一小部分,因此继承 ChannelInboundHandlerAdapter 就足够了,它提供了 ChannelInboundHandler 的默认实现。

以下方法让我们感兴趣:

  • channelRead() 被每一个 incoming message 所调用
  • channelReadComplete() 通知处理程序最后一次调用 ChannelRead(), 是当前批次中的最后一条消息
  • exceptionCaught() 如果在读取操作期间抛出异常,则调用此方法

Echo服务器的ChannelHandler实现是EchoServerHandler,代码如下:

package com.huyouxiao.study.echo;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
  @Override
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    ByteBuf in = (ByteBuf) msg;
    System.out.println("Server received:" + in.toString(CharsetUtil.UTF_8));
    ctx.write(msg);
  }

  @Override
  public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
  }

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception              {
    cause.printStackTrace();
    ctx.close();
  }
}

EchoServerHandler

ChannelInboundHandlerAdapter 有一个简单的API及其每个方法可以重写以在适当的点挂钩到事件生命周期。 因为你需要处理所有收到的数据,你覆盖 channelRead()。 在这个服务器你只需将数据回显给远程的端点。

覆盖 exceptionCaught() 允许您对任何Throwable子类型做出反应,在此处记录异常并关闭连接。 更精细的应用程序可能会尝试从异常中恢复,但在这种情况下只需关闭连接向远程对等方发出错误信号。

如果未捕获异常会发生什么?
每个频道都有一个关联的ChannelPipeline,它拥有一系列 ChannelHandler 实例。 默认情况下,处理程序将转发处理程序的调用方法到链中的下一个。 因此,如果在链的某处未实现 exceptionCaught(),则收到的异常将传递到该链的末尾 ChannelPipeline 将被记录。 因此,您的应用程序应该提供至少有一个实现exceptionCaught() 的 ChannelHandler 。 (第6.4节详细讨论了异常处理。)

除了 ChannelInboundHandlerAdapter 之外,还有很多ChannelHandler子要了解的类型和实现,我们将在第6章详细介绍这些内容.现在,请记住以下要点:

  • ChannelHandlers 为不同类型的事件调用。
  • 应用程序 实现 或扩展 ChannelHandlers, 以挂钩(hook)到事件生命周期并提供自定义应用程序逻辑。
  • 在架构上,ChannelHandler有助于保持业务逻辑的分离来自网络代码。 随着代码的发展,这简化了开发过程, 响应不断变化的要求。

2.3.2 Bootstrapping the server

在讨论了 EchoServerHandler 实现的核心业务逻辑之后,我们可以现在检查服务器本身的引导,包括以下内容:

  • 将侦听的端口绑定到服务器并接受传入的连接请求
  • 配置通道以通知EchoServerHandler实例有关入站的信息消息(inbound messages)

Transports
在本节中,您将遇到术语“传输(Transports)”。 在标准的多层视图中网络协议,传输层是为终端提供服务的传输层到端或主机到主机的通信。Internet通信基于TCP传输。 NIO运输是指除了服务器端性能增强外,与TCP大致相同的传输 - Java NIO实现提供的功能。Transports 将在第4章详细讨论。

以下清单显示了EchoServer类的完整代码。

package com.huyouxiao.study.echo;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.net.InetSocketAddress;

public class EchoServer {
  private final int port;

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

  public void start() throws Exception {
    final EchoServerHandler serverHandler = new EchoServerHandler();
    EventLoopGroup group = new NioEventLoopGroup();

    try {
      ServerBootstrap serverBootstrap = new ServerBootstrap();
      serverBootstrap.group(group)
          .channel(NioServerSocketChannel.class)
          .localAddress(new InetSocketAddress(port))
          .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
              socketChannel.pipeline().addLast(serverHandler);
            }
          });

      ChannelFuture channelFuture = serverBootstrap.bind().sync();
      channelFuture.channel().closeFuture().sync();
    } finally {
      group.shutdownGracefully().sync();
    }

  }

  public static void main(String[] args) throws Exception {
    int port;
    if(args.length != 1) {
      System.out.println("Usage:" + EchoServer.class.getSimpleName() + "  <port>");
      System.out.println("use port  12121 by default");
      port = 12121;
    } else {
      port = Integer.parseInt(args[0]);
    }
    new EchoServer(port).start();
  }
}

原图如下(注意看,有个排版错误 Exceptio3n):
EchoServer class
你创建了一个 ServerBootstrap 实例,因为你使用的是 NIO transport, 你指定了 NioEventLoopGroup 去接受和处理新的 connections. NioServerSocketChannel 作为一个 channel type. 之后你用选择的端口号创建 InetSocketAddress, 并作为本地地址。服务端讲绑定这个地址,并侦听所有的新链接请求。

你使用了一个特殊类 ChannelInitializer. 这很关键。当一个新的链接被接受后,将会创建一个新的 child Channel. 并且这个 ChannelInitializer 将会把 EchoServerHandler 的一个实例添加到这个 Channel 的 ChannelPipeline. 就像我们早先描述的那样。这个 Handler 将会接收 inbound messages 相关的 notifications.

尽管NIO具有可扩展性,但其正确的配置,尤其是多线程配置,并非易事。 Netty的设计封装了大部分复杂性,我们将在第3章中更详细地讨论相关的抽象(EventLoopGroup,SocketChannel和ChannelInitializer)。

接下来,绑定服务器并等待绑定完成。 (对 sync() 的调用导致当前Thread阻塞直到那时。)应用程序将等到服务器的 Channel 关闭(因为你在 Channel 的 CloseFuture 上调用 sync() )。然后你可以关闭 EventLoopGroup 并释放 所有资源,包括所有创建的线程。

NIO在此示例中使用,因为它具有可扩展性和彻底的异步性,因此它是目前使用最广泛的传输。 但也可以使用不同的传输实现。 如果您希望在服务器中使用OIO(旧IO)传输,则需要指定 OioServerSocketChannel 和 OioEventLoopGroup 。 我们将在第4章中更详细地探讨运输。

与此同时,让我们回顾一下刚刚完成服务器实现中的重要步骤。 这些是服务器的主要代码组件:

  • EchoServerHandler实现业务逻辑。
  • main() 方法启动服务器。

引导中需要以下步骤:

  • 创建 ServerBootstrap 实例以引导和绑定服务器。
  • 创建并分配 NioEventLoopGroup 实例来处理事件处理,例如接受新连接和读/写数据。
  • 指定服务器绑定的本地 InetSocketAddress 。
  • 使用 EchoServerHandler 实例初始化每个新 Channel 。
  • 调用 ServerBootstrap.bind() 来绑定服务器。

此时,服务器已初始化并准备好使用。 在下一节我们将会检查客户端应用程序的代码。

2.4 Writing an Echo client

Echo client 将会

  • 链接服务器
  • 发送一条或者多条 messages
  • 每发一条下息,等待服务器端发送同样的消息回来。
  • 关闭链接
    编写客户端涉及您在服务器中看到的两个主要代码区域:业务逻辑(business logic) 和 引导(bootstrapping)。
2.4.1 Implementing the client logic with ChannelHandlers

与服务器一样,客户端将使用 ChannelInboundHandler 来处理数据。 在这种情况下,您将扩展SimpleChannelInboundHandler 类来处理所有要的任务,如下所示。 这需要覆盖以下方法:

  • channelActive() 在与服务器的连接建立后调用
  • channelRead0() 从服务器收到消息时调用
  • exceptionCaught() 如果在处理期间引发异常,则调用
package com.huyouxiao.study.echo;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;

@ChannelHandler.Sharable
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {

  @Override
  public void channelActive(ChannelHandlerContext channelHandlerContext) {
    channelHandlerContext.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8));
  }

  @Override
  protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
    System.out.println("Client received: " + byteBuf.toString(CharsetUtil.UTF_8));
  }

  @Override
  public void exceptionCaught(ChannelHandlerContext channelHandlerContext, Throwable cause) {
    cause.printStackTrace();
    channelHandlerContext.close();
  }
}

ChannelHandler for the client

首先,覆盖channelActive(),在建立连接时调用。 这可以确保尽快将某些内容写入服务器
在这种情况下是一个字节缓冲区,编码字符串“Netty rocks!”。

接下来,您将覆盖方法channelRead0()。 无论何时调用此方法收到数据。 注意,服务器发送的消息可以以块的形式接收。也就是说,如果服务器发送5个字节,则无法保证将接收所有5个字节
立刻。 即使对于如此少量的数据,channelRead0() 方法也可以调用两次,首先使用 ByteBuf(Netty的字节容器)保存3个字节,然后调用第二个ByteBuf保存2个字节。 作为面向流的协议,TCP保证了这一点:字节将按服务器发送的顺序接收。

您覆盖的第三种方法是 exceptionCaught()。 就像在EchoServerHandler中一样,记录Throwable并关闭 channel,在这种情况下终止与服务器的连接。

SimpleChannelInboundHandler vs. ChannelInboundHandler
您可能想知道为什么我们在客户端中使用 SimpleChannelInboundHandler 而不是EchoServerHandler 中使用的 ChannelInboundHandlerAdapter。这与两个因素的相互作用有关:业务逻辑如何处理消息以及Netty如何管理资源。
在客户端,当channelRead0() 完成时,您有传入的消息和你完成了它。当方法返回时SimpleChannelInboundHandler 采用小心释放保存消息的 ByteBuf 的内存引用。
在 EchoServerHandler 中,您仍然必须将传入的消息回显给发送者,并且 write() 操作是异步的,直到之后才可能完成 channelRead() 返回(如清单2.1所示)。出于这个原因 EchoServerHandler
扩展 ChannelInboundHandlerAdapter,它不会释放消息这点。消息在 EchoServerHandler 中的channelReadComplete() 中释放当调用 writeAndFlush() 时(列出2.1)。第5章和第6章将详细介绍消息资源管理。

2.4.2 Bootstrapping the client

正如您将在下一个清单中看到的,引导客户端类似于引导服务器,区别在于不是绑定到客户端使用的侦听端口. 而是连接到远程地址的主机和端口参数,这里是Echo服务器的地址。

package com.huxing.study.echo;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.InetSocketAddress;

public class EchoClient {
  private final String host;
  private final int port;

  public EchoClient(String host, int port) {
    this.host = host;
    this.port = port;
  }

  public void start() throws Exception {
    EventLoopGroup group = new NioEventLoopGroup();

    try {
      Bootstrap bootstrap = new Bootstrap();
      bootstrap.group(group)
          .channel(NioSocketChannel.class)
          .remoteAddress(new InetSocketAddress(host, port))
          .handler(new ChannelInitializer<SocketChannel>() {

            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
              ch.pipeline().addLast(new EchoClientHandler());
            }
          });
      ChannelFuture channelFuture = bootstrap.connect().sync();
      channelFuture.channel().closeFuture().sync();

    } finally {
      group.shutdownGracefully().sync();
    }
  }

  public static void main(String[] args) throws Exception {
    String host;
    int port;
    if (args.length != 2) {
      System.out.println("Usage: " + EchoClient.class.getSimpleName() + " <host> <port>");
       host = "10.8.10.28";
       port = 12121;
    } else {
      host = args[0];
      port = Integer.parseInt(args[1]);
    }

    new EchoClient(host, port).start();
  }
}

原图如下:
Main class for the client
Main class for the client2
和以前一样,使用NIO传输。 请注意,在客户端和服务器您可以使用不同的传输方式; 例如,服务器端的NIO传输,在客户端使用OIO传输。 在第4章中,我们将研究那些因素和情景引导您为特定用例选择特定传输。
让我们回顾一下本节介绍的重点:

  • 创建 Bootstrap 实例以初始化客户端。
  • 分配 NioEventLoopGroup 实例来处理事件处理,其中包括创建新的连接和处理入站和出站
    绑定数据。
  • 为连接到服务器创建 InetSocketAddress。
  • 连接时,将在管道中安装 EchoClientHandler 成立。
  • 设置完所有内容后,调用 Bootstrap.connect() 连接到远程同伴。
    完成客户端后,您可以继续构建系统并对其进行测试。

2.5 Building and running the Echo server and client

在本节中,我们将介绍编译和运行Echo服务器所需的所有步骤和客户。

The Echo client/server Maven project
本书的附录使用Echo客户端/服务器项目的配置详细解释如何组织多模块Maven项目。 这不是必需的阅读建立和运行应用程序,但建议获得一个更好地理解本书的例子以及Netty项目本身。

2.5.1 Running the build

要构建Echo客户端和服务器,请转到代码示例根目录下的第2章目录,然后执行以下命令:

mvn clean package

这应该产生的东西非常类似于清单2.5中所示的输出(我们已经在编译中编辑了一些不必要的步骤)

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building echo 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ echo ---
[INFO] Deleting /home/huyouxiao/free-repo/echo/target
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ echo ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.2:compile (default-compile) @ echo ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 4 source files to /home/huxing/free-repo/echo/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ echo ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.2:testCompile (default-testCompile) @ echo ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.17:test (default-test) @ echo ---
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ echo ---
[INFO] Building jar: /home/huyouxiao/free-repo/echo/target/echo-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.693 s
[INFO] Finished at: 2019-05-07T14:10:24+08:00
[INFO] Final Memory: 18M/300M
[INFO] ------------------------------------------------------------------------

我的项目没有安装书中的项目那样组织。
Building jar
以下是上一个构建日志中记录的主要步骤:

  • Maven确定构建顺序:首先是父pom.xml,然后是模块(子项目)。
  • 如果在用户的本地存储库中找不到Netty工件,Maven将会从公共Maven存储库下载它们(此处未显示)。
  • 运行构建生命周期的 clean 和 compile 阶段
  • 执行 maven-jar-plugin.

Maven Reactor Summary显示所有项目都已成功构建。 一个现在,两个子项目中目标目录的列表应该类似于下面部分。

Build artifacts

2.5.2 Running the Echo server and client

要运行应用程序组件,可以直接使用Java命令。 但在POM文件中,exec-maven-plugin配置为你这样做(参见附录详情)。并排打开两个控制台窗口,一个登录到chapter2 \ Server 目录,另一个进入chapter2 \ Client。

在服务器的控制台中,执行以下命令:

mvn exec:java

您应该看到如下内容:
Execute Echo Server

服务器已启动并准备接受连接。 现在客户端控制台中执行相同的操作命令:

mvn exec:java

您应该看到如下内容:
Building Echo Client
在服务器控制台中,您应该看到:

Server received: Netty rocks!

每次运行客户端时,您都会在服务器的控制台中看到此日志语句。
这是发生的事情:

  1. 一旦客户端连接,它就会发送消息:Netty rock!
  2. 服务器报告收到的消息并将其回显给客户端。
  3. 客户端报告返回的消息并退出。

你所看到的是预期的行为; 现在让我们看看如何处理故障。服务器仍应运行,因此在服务器控制台中键入Ctrl-C以停止进程。 终止后,再次启动客户端
Exception handling in the Echo client

发生了什么? 客户端尝试连接到它希望找到的服务器在localhost:9999运行。 这失败了(正如预期的那样),因为服务器已经存在先前已停止,导致客户端中出现 java.net.ConnectException。 此异常触发了 EchoClientHandler 的 exceptionCaught() 方法,其中打印出堆栈跟踪并关闭通道。

2.6 Summary

在本章中,您将设置开发环境并构建并运行第一个环境 Netty 客户端和服务器。 虽然这是一个简单的应用程序,但它可以扩展到几个千位并发连接 - 每秒多于平面的消息基于vanilla socket的Java应用程序将能够处理。在接下来的章节中,您将看到更多关于Netty如何简化的示例可伸缩性和并发性。 我们还将深入研究 Netty 对分离关注点的架构原则的支持。 通过提供正确的抽象 Netty 将业务逻辑与网络逻辑分离,使其易于跟上步伐,在不损害系统稳定性的情况下快速发展的需求。在下一章中,我们将概述Netty的架构。 这会给您将深入全面地研究Netty的内部结构请参阅后续章节。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值