Download - 实现轻型服务器的 Java TM 方法
![Page 1: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/1.jpg)
‹#›
![Page 2: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/2.jpg)
< 在此处插入图片 >
实现轻型服务器的 JavaTM 方法
![Page 3: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/3.jpg)
‹#›
< 在此处插入图片 >
议题
• 背景• Java NIO 和 NIO.2• JSSE 和 SSLEngine• 结论
![Page 4: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/4.jpg)
‹#›
背景
• C10K 问题• 轻型 Web 服务器 (Nginx、 Lighttpd)• NIO 架构 (Netty、 Apache MINA)• Grizzly
![Page 5: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/5.jpg)
‹#›
目标
• 改善延迟• 提高可伸缩性• 最大限度提高吞吐量• 最大限度提高性能• 可重用性
![Page 6: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/6.jpg)
‹#›
< 在此处插入图片 >
议题
• 背景• Java NIO 和 NIO.2• JSSE 和 SSLEngine• 结论
![Page 7: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/7.jpg)
‹#›
Java I/O
• 阻塞 I/O (Java SE 1.4 之前 )– 调用者被阻塞
• 非阻塞 I/O (NIO) (Java SE 1.4)– 调用者即时获得数据或错误代码
• 异步 I/O (NIO.2) (Java SE 1.7)– 调用者获得通知
![Page 8: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/8.jpg)
‹#›
• ServerSocket/Socket• InputStream/OutputStream• 线程 (1:1)
传统服务模式
服务器
![Page 9: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/9.jpg)
‹#›
• ServerSocket/Socket• InputStream/OutputStream• ExecutorService (JDK 1.5)• 线程池 (M:N)
传统服务模式
服务器
线程池
![Page 10: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/10.jpg)
‹#›
• 操作系统的线程数限制• 线程上下文切换是一种“高负载”操作• 工作线程是 I/O 绑定的
传统服务模式
服务器
线程池
![Page 11: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/11.jpg)
‹#›
• Selector/SelectionKey• Channel/Buffer• 线程 (1:N)
NIO 反应器模式
服务器
. 线程反应器
接收器
分派器
读取 | 写入
读取 | 写入
读取 | 写入
![Page 12: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/12.jpg)
‹#›
• Selector/SelectionKey• Channel/Buffer• 工作线程池• 线程 (1:X:N)
NIO 反应器模式
服务器
. 线程反应器
接收器
分派器
读取 | 写入
读取 | 写入
读取 | 写入
![Page 13: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/13.jpg)
‹#›
• Selector/SelectionKey• Channel/Buffer• 工作线程池 /多个反应器• 线程 (K:X:N)
NIO 反应器模式
服务器
反应器
接收器
分派器
读取 | 写入
读取 | 写入
读取 | 写入
![Page 14: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/14.jpg)
‹#›
NIO.2 前摄器模式
![Page 15: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/15.jpg)
‹#›
NIO.2 前摄器模式
![Page 16: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/16.jpg)
‹#›
• AsynchronousChannel/Buffer• AsynchronousChannelGroup• CompletionHandler• 线程 (M:N)
NIO.2 前摄器模式
服务器
前摄器
处理器
分派器
读取 | 写入
接受
![Page 17: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/17.jpg)
‹#›
• 充分利用操作系统 I/O 功能
NIO.2 前摄器模式
服务器
前摄器
处理器
分派器
读取 | 写入
接受
![Page 18: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/18.jpg)
‹#›
• 发起非阻塞 I/O 操作• 在 I/O 完成时发出通知
NIO.2 概念
![Page 19: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/19.jpg)
‹#›
interface CompletionHandler<V,A> {
void completed(V result, A attachment);
void failed(Throwable exc, A attachment);
}
V = 结果值的类型A = 附加到 I/O 操作中的对象的类型
用于传递上下文通常封装连接上下文
若成功则会调用 completed 方法若 I/O 操作失败则会调用 failed 方法
CompletionHandler
![Page 20: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/20.jpg)
‹#›
class Connection { … } class Handler implements CompletionHandler<Integer, Connection> { public void completed(Integer result, Connection conn) { // handle result }
public void failed(Throwable exc, Connection conn) { // error handling }}
AsynchronousSocketChannel ch = ...ByteBuffer buf = ...Connection conn = ...Handler handler = ...
ch.read(buf, conn, handler);
CompletionHandler
![Page 21: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/21.jpg)
‹#›
• 异步连接• 异步读取 / 写入• 异步分散 / 集中(多个缓冲区)• 读取 / 写入操作支持超时设置– 出现超时异常时调用 failed 方法
• 实现 NetworkChannel– 用于绑定、设置套接字选项等
AsynchronousSocketChannel
![Page 22: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/22.jpg)
‹#›
• 哪些线程调用 completion 处理器?• 面向网络的通道与一个组绑定– AsynchronousChannelGroup
• 组封装线程池和其他共享资源• 创建含线程池的组• 较为简单的应用程序的默认组• 由池线程调用 Completion 处理器• AsynchronousFileChannel 可以使用自己的线程池
(单一组)来创建
ChannelGroup
![Page 23: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/23.jpg)
‹#›
// custom thread poolExecutorService pool = ...
AsynchronousChannelGroup group = AsynchronousChannelGroup .withThreadPool(pool);
AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(group);
创建一个组
![Page 24: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/24.jpg)
‹#›
Buffer 和 ByteBuffer
![Page 25: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/25.jpg)
‹#›
Buffer 和 ByteBuffer
• 直接和非直接 Buffer– ByteBuffer.allocateDirect()– MappedByteBuffer
![Page 26: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/26.jpg)
‹#›
ByteBuffer 的问题
• 问题:– 假设接受了 10000 个连接– 因此会创建 10000 个 ByteBuffer 并调用读取操作– 现在,我们等待、等待、再等待,等待远程客户端向我们发送
字节(客户端 / 网络非常慢)– 这时接收到另外 10000 个请求,我们再一次创建 10000 个
ByteBuffer 并调用 read() operations.ByteBuffer.allocateDirect() MappedByteBuffer
• 系统不堪重负!
![Page 27: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/27.jpg)
‹#›
使用 ByteBuffer 池和限制
• 我们不必过于消极。目前为止,我们对超过 20000 个客户端进行了测试,均未出现任何问题• 但您仍然需要谨记上面的问题!!• 您可能希望对 read() 操作进行限制,以避免创建过多
的 ByteBuffer• 我们强烈建议使用 ByteBuffer 池,特别是在使用堆时
。在调用 read() 方法之前获取一个 ByteBuffer ,并在读取操作完成后立即将其返回给池。
![Page 28: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/28.jpg)
‹#›
< 在此处插入图片 >
议题
• 背景• Java NIO and NIO.2• JSSE 和 SSLEngine• 结论
![Page 29: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/29.jpg)
‹#›
SSL/TLS 和 JSSE
• TLS/SSL 协议• HTTPS 协议• JavaTM 安全套接字扩展• SSLEngine 与非阻塞 I/O
![Page 30: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/30.jpg)
‹#›
SSLEngine
![Page 31: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/31.jpg)
‹#›
NIO 和 NIO.2 的 SSLEngine
ByteBuffer
![Page 32: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/32.jpg)
‹#›
SSLEngine 操作
• SSLEngine.wrap(ByteBuffer src, ByteBuffer dst)• SSLEngine.unwrap(ByteBuffer src, ByteBuffer dst)• SSLEngine.getDelegatedTask()
![Page 33: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/33.jpg)
‹#›
SSLEngineResult.HandshakeStatus
• NEED_UNWRAP– SSLEngine 需要先从远端接收数据,然后才能继续握手。
• NEED_WRAP– SSLEngine 必须先将数据发送给远端,然后才能继续握手,
因此应调用 SSLEngine.wrap() 。
![Page 34: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/34.jpg)
‹#›
SSLEngineResult.HandshakeStatus
• FINISHED– SSLEngine 刚完成握手。
• NEED_TASK– SSLEngine 需要一个(或多个)委托任务的结果,然后才能
继续握手。• NOT_HANDSHAKING– SSLEngine 当前未进行握手。
![Page 35: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/35.jpg)
‹#›
SSLEngineResult.Status
• OK– SSLEngine 已完成该操作。
![Page 36: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/36.jpg)
‹#›
SSLEngineResult.Status
• BUFFER_OVERFLOW– SSLEngine 无法处理操作,因为目标缓冲区中没有足够的空间来保存结果。
• BUFFER_UNDERFLOW– SSLEngine 无法解包传入数据,因为源空间没有足够的可用
数据来建立完整有效的协议包。• CLOSED– SSLEngine 已经关闭,操作无法完成。
![Page 37: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/37.jpg)
‹#›
NIO.2 前摄器模式中的 SSLEngine
服务器
线程池
前摄器
处理器
分派器
读取 | 写入
接受
SS
LE
NG
INE
状态
分派器
![Page 38: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/38.jpg)
‹#›
< 在此处插入图片 >
议题
• 背景• Java NIO and NIO.2• JSSE 和 SSL 引擎• 结论
![Page 39: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/39.jpg)
‹#›
总结
• NIO.2 和 SSLEngine 非常适于构建安全轻型服务器。• NIO.2 已在 JDK7 试用版中提供,赶快体验它吧!
![Page 40: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/40.jpg)
‹#›
更多信息 — NIO.2
• OpenJDK NIO.2 页面:– http://openjdk.java.net/projects/nio/
• NIO.2 文档– http://openjdk.java.net/projects/nio/javadoc/
• NIO.2 邮件列表– [email protected]
• Alan 的博客– http://blogs.sun.com/alanb/
![Page 41: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/41.jpg)
‹#›
更多信息 — JSSE
• JSSE 参考指南:– http://download.oracle.com/javase/7/docs/technotes/guides/
security/jsse/JSSERefGuide.html
• 安全开发邮件列表– [email protected]
![Page 42: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/42.jpg)
‹#›
更多信息 — Grizzly
• Grizzly 项目:– http://grizzly.dev.java.net
• Grizzly 的 Twitter– http://twitter.com/project_grizzly
![Page 43: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/43.jpg)
‹#›
问答
![Page 44: 实现轻型服务器的 Java TM 方法](https://reader033.vdocuments.pub/reader033/viewer/2022061409/5681592f550346895dc65ef1/html5/thumbnails/44.jpg)
‹#›