比较Http框架
框架介绍
目前项目中,使用的HTTP框架种类太多,加上自己基本功不扎实,现总结一下各个框架。
- HttpURLConnection
- apache HttpClient
- OKhttp
- jersey client
- netty
BIO、NIO、AIO
在了解框架之前,我们必须先知道NIO,AIO,BIO之间的区别。
BIO:同步阻塞。JDK1.4版本之前,我们建立网络链接时,先在服务器端建立ServerSocket,然后客户端起服务,与服务器端建立连接。默认情况下,服务器端会建立起一堆线程等待请求,等客户端发送请求,先咨询服务器端是否有线程响应,如果没有,则一直等待或等待。
NIO:同步非阻塞。实现基于React.当Socket有流可以读或者可以写的时候,操作系统会通知相应的流程来处理。
HTTP/1.1出现后,有了Http长连接,这样除了超时和指明特定关闭的http header外,这个链接是一直打开的状态的,这样在NIO处理中可以进一步的进化,在后端资源中可以实现资源池或者队列,当请求来的话,开启的线程把请求和请求数据传送给后端资源池或者队列里面就返回,并且在全局的地方保持住这个现场(哪个连接的哪个请求等),这样前面的线程还是可以去接受其他的请求,而后端的应用的处理只需要执行队列里面的就可以了,这样请求处理和后端应用是异步的.当后端处理完,到全局地方得到现场,产生响应,这个就实现了异步处理。
Netty就是NIO的流行框架。以后有机会研究一下源码。
BIO与NIO.pngAIO:异步非阻塞。当有读写操作时,只需要操作API提供的read/write接口。这两个方式都是异步的。当进行读操作时,将数据写入read的缓冲区,并通知应用程序。写操作亦然。在JDK1.7中,这部分内容被称作NIO.2,主要在java.nio.channels包下增加了下面四个异步通道:
- AsynchronousSocketChannel
- AsynchronousServerSocketChannel
- AsynchronousFileChannel
- AsynchronousDatagramChannel
适用场景
- BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
- NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
- AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
HttpURLConnection
由Java标准库实现的Http通讯,但是API使用复杂,功能也比较有限,一般项目中不使用。
HttpClient
由Apache的开源项目HttpClient项目。功能强大,使用率也很高。
OKHttp
由Square公司开发,以易用性以及性能著称。
OkHttp 提供了对最新的 HTTP 协议版本 HTTP/2 和 SPDY 的支持,这使得对同一个主机发出的所有请求都可以共享相同的套接字连接。如果 HTTP/2 和 SPDY 不可用,OkHttp 会使用连接池来复用连接以提高效率。OkHttp 提供了对 GZIP 的默认支持来降低传输内容的大小。OkHttp 也提供了对 HTTP 响应的缓存机制,可以避免不必要的网络请求。当网络出现问题时,OkHttp 会自动重试一个主机的多个 IP 地址。
Netty
序列化方式问题
- Java序列化机制是Java内部的一种对象编解码技术,无法跨语言使用;例如对于异构系统之间的对接,Java序列化后的码流需要能够通过其它语言反序列化成原始对象(副本),目前很难支持。
- 相比于其它开源的序列化框架,Java序列化后的码流太大,无论是网络传输还是持久化到磁盘,都会导致额外的资源占用。
- 序列化性能差(CPU资源占用高)。
http高性能的三个方向
- 传输:用什么样的通道将数据发送给对方,BIO、NIO或者AIO,IO模型在很大程度上决定了框架的性能。
- 协议:采用什么样的通信协议,HTTP或者内部私有协议。协议的选择不同,性能模型也不同。相比于公有协议,内部私有协议的性能通常可以被设计的更优。
- 线程:数据报如何读取?读取之后的编解码在哪个线程进行,编解码后的消息如何派发,Reactor线程模型的不同,对性能的影响也非常大。
netty是如何实现高性能的?
- 异步非阻塞通信
- Zero拷贝
- 内存池
随着JVM虚拟机和JIT即时编译技术的发展,对象的分配和回收是个非常轻量级的工作。但是对于缓冲区Buffer,情况却稍有不同,特别是对于堆外直接内存的分配和回收,是一件耗时的操作。为了尽量重用缓冲区,Netty提供了基于内存池的缓冲区重用机制。
- Reactor线程模型
- 无锁化的串行设计
- 高效的并发编程
- 高性能序列化框架
- 灵活TCP参数配置能力
看了这么多资料,感觉任重道远。
未完待续
参考文献
https://www.ibm.com/developerworks/cn/java/j-lo-okhttp/index.html#_%E6%B8%85%E5%8D%95%202.%20OkHttp%20%E6%9C%80%E5%9F%BA%E6%9C%AC%E7%9A%84%20HTTP%20%E8%AF%B7%E6%B1%82
https://blog.csdn.net/gaowenhui2008/article/details/55044704
https://blog.csdn.net/skiof007/article/details/52873421
https://blog.csdn.net/a417930422/article/details/52585862