热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

okhttp服务器性能,okHttp小结

byhzwusibo20190504常见问题一:简述一下OkHttpOkHttp已被谷歌加入到Android的源码中。目前比较流行的Retrofit也是默认使用OkH

by hzwusibo  20190504

常见问题一:简述一下OkHttp

OkHttp已被谷歌加入到Android的源码中。目前比较流行的Retrofit也是默认使用OkHttp的。

支持http2,对一台机器的所有请求共享同一个socket

内置连接池,支持连接复用,减少延迟

支持透明的gzip压缩响应体

通过缓存避免重复的请求

请求失败时自动重试主机的其他ip,自动重定向

好用的API

关于 HTTP2 和 HTTPS,这些你必须要知道

常见问题二:看过OkHttp的源码吗,简单说一下

64a5180c7faf

(一)、总体设计

第一,通过一个构建者模式(Request.Builder)构建所有的request;然后分发到Dispatcher(分发器);

第二,Dispatcher再把request分发到HttpEngine(真正干活的类)中,HttpEngine首先要看一下本次请求有没有cache(缓存),如果有缓存,就从缓存中拿到信息,然后返回给response;如果没有缓存,HttpEngine就把request分发到ConnectionPool(连接池)中;

第三,在ConnectionPool(连接池)中,通过Connection发送请求,通过Route(路由)和Platfrom(平台),到达Server(Socket),获取到Data,然后返回response。

(二)、流程图

64a5180c7faf

上面是OKHttp总体设计图,主要是通过Diapatcher不断从RequestQueue中取出请求(Call),根据是否已缓存调用Cache或Network这两类数据获取接口之一,从内存缓存或是服务器取得请求的数据。该引擎有同步和异步请求,同步请求通过Call.execute()直接返回当前的Response,而异步请求会把当前的请求Call.enqueue添加(AsyncCall)到请求队列中,并通过回调(Callback)的方式来获取最后结果。

OkHttp使用教程

Dispatcher线程池总结

1)调度线程池Disptcher实现了高并发,低阻塞的实现

2)采用Deque作为缓存,先进先出的顺序执行

3)任务在try/finally中调用了finished函数,控制任务队列的执行顺序,而不是采用锁,减少了编码复杂性提高性能。

Android面试题-OkHttp3源码分析

OkHttp通过定义许多拦截器一步一步地对Request进行拦截处理,直到请求返回网络数据,后面又倒过来,一步一步地对Response进行拦截处理,最后拦截的结果就是回调的最终Response。

RealInterceptorChain的proceed方法,通过顺序地传入一个拦截器的集合,创建一个RealInterceptorChain,然后拿到之前OkHttp创建的各种拦截器,并调用其interrupt方法,并返回Response对象。其调用顺序如下:

64a5180c7faf

1)在配置 OkHttpClient 时设置的 interceptors;

2)负责失败重试以及重定向的 RetryAndFollowUpInterceptor;

3)负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应的 BridgeInterceptor;

4)负责读取缓存直接返回、更新缓存的 CacheInterceptor;

5)负责和服务器建立连接的 ConnectInterceptor;

6)配置 OkHttpClient 时设置的 networkInterceptors;

7)负责向服务器发送请求数据、从服务器读取响应数据的 CallServerInterceptor。

OkHttp的这种拦截器链采用的是责任链模式,这样的好处是将请求的发送和处理分开,并且可以动态添加中间的处理方实现对请求的处理、短路等操作

责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

可以看到 OkHttp 的线程池配置如下:

核心线程数:0

最大线程数:Iteger.MAX_VALUE,其实就是不限制

空闲线程保活时间:60s

任务队列:SynchronousQueue,为有界队列,且队列大小为 0,不存 Runnable,只是用来进行生产者和消费者之间的传递任务。

是不是很眼熟?和我们在 Executors 使用的 缓存线程池的配置完全一样,缓存线程池的代码如下:

public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue(),

threadFactory);

}

所以 OkHttp 自己创建的这个线程池,和缓存线程池的区别,仅仅是修改了线程名。

我们简要分析一下缓存线程池的运行机制,进入到 ThreadPoolExecutor 中的execute方法的源码中,假设线程池处于运行状态,会有这样的流程:

新过来一个任务,由于核心线程数为 0,不需要创建核心线程,所以尝试加入任务队列

如果线程池中有线程刚好空闲可以接收任务,因为任务队列的类型是 SynchronousQueue,实际大小为 0,只做消费者和生产者的中转站,所以这时候,就可以入列成功,通过 SynchronousQueue 中转任务给空闲的线程执行。

如果当前线程池所有线程工作饱和,会入列失败。这时候 ThreadPoolExecutor 会调用addWorker(command, false)来创建并且启动新线程。

这样子,就会产生疑问,那么如果一次性同时发起大量的请求,不就会产生大量线程了?比如我一次性发起 100 个请求,那么是不是会发出 100 个线程?

是的,如果直接使用该线程池而没有其他的策略的话,是有这样的问题。

所以在 OkHttp 中线程池只是一个辅助作用,仅仅是用来做线程缓存,便于复用的。真正对这些请求的并发数量限制,执行时机等等都是调度器 Dispatcher 承担的。在 OkHttp 这里,线程池只是个带缓存功能的执行器,而真正的调度是外部包了一个调度策略的。

64a5180c7faf

Retrofit

64a5180c7faf

OkHttp和Retrofit的联系

Retrofit负责请求的数据和请求的结果,使用接口的方式呈现(注解)。

OkHttp负责请求的过程。

RxJava负责异步,各种线程之间的切换。

Retrofit是Square开源的一款适用于Android网络请求的框架。Retrofit底层是基于OkHttp实现的,与其他网络框架不同的是,它更多使用运行时注解的方式提供功能。

1.Retrofit优缺点

优点:

•  可以配置不同HTTP client来实现网络请求,如okhttp、httpclient等;

•  请求的方法参数注解都可以定制;

•  支持同步、异步和RxJava;

•  解耦;

•  可以配置不同的反序列化工具来解析数据,如json、xml等;

•  使用非常方便灵活;

2.Retrofit注解

64a5180c7faf

Retrofit注解分为三大类,分别是HTTP请求方法注解(8种)、标记类注解(3种)和参数类注解(11种)。

• HTTP请求方法注解:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、HTTP

• 标记类注解:FormUrlEncoded、Multipart、Streaming

• 参数类注解:Headers、Header、Body、Field、FieldMap、Part、PartMap、Path、Query、QueryMap、Url

Retrofit底层对网络的访问默认是基于okhttp,不过Retrofit非常适合于restful url格式的请求,更多使用注解的方式提供功能。

Retrofit框架网络请求流程图

网络请求:APP发起网络请求,Retrofit通过注解配置请求参数、Header、Url之后,通过OkHttp发生网络请求给服务器。

服务器响应:服务器返回响应数据,OkHttp将数据传递给Retrofit,再把数据直接传递给APP,界面刷新反馈结果给用户。

OkHttp和Retrofit都是网络开源框架,但是他们之间的区别请不要混淆:

职责不同:

• Retrofit主要负责应用层面的封装,就是说主要面向开发者,方便使用,比如请求参数,响应数据的处理,错误处理等等。

• OkHttp主要负责socket部分的优化,比如多路复用,buffer缓存,数据压缩等等。

封装不同:

• Retrofit封装了具体的请求,线程切换以及数据转换。

• OkHttp 是基于Http协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟HttpClient, HttpUrlConnection的职责是一样的。

网上一般都推荐RxJava+Retrofit+OkHttp框架。



推荐阅读
  • C++ 异步编程中获取线程执行结果的方法与技巧及其在前端开发中的应用探讨
    本文探讨了C++异步编程中获取线程执行结果的方法与技巧,并深入分析了这些技术在前端开发中的应用。通过对比不同的异步编程模型,本文详细介绍了如何高效地处理多线程任务,确保程序的稳定性和性能。同时,文章还结合实际案例,展示了这些方法在前端异步编程中的具体实现和优化策略。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 在2015年1月的MySQL内核报告中,我们详细探讨了性能优化和Group Commit机制的改进。尽管网上已有大量关于Group Commit的资料,本文将简要回顾其发展,并重点分析MySQL 5.6及之前版本中引入的二进制日志(Binlog)对性能的影响。此外,我们还将深入讨论最新的优化措施,如何通过改进Group Commit机制显著提升系统的整体性能和稳定性。 ... [详细]
  • JUC(三):深入解析AQS
    本文详细介绍了Java并发工具包中的核心类AQS(AbstractQueuedSynchronizer),包括其基本概念、数据结构、源码分析及核心方法的实现。 ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • 本文总结了一些开发中常见的问题及其解决方案,包括特性过滤器的使用、NuGet程序集版本冲突、线程存储、溢出检查、ThreadPool的最大线程数设置、Redis使用中的问题以及Task.Result和Task.GetAwaiter().GetResult()的区别。 ... [详细]
  • 本文深入解析了 Kubernetes 控制平面(特别是 API 服务器)与集群节点之间的通信机制,并对其通信路径进行了详细分类。旨在帮助用户更好地理解和定制其安装配置,从而增强网络安全性,确保集群的稳定运行。 ... [详细]
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
  • 在配置Nginx的SSL证书后,虽然HTTPS访问能够正常工作,但HTTP请求却会遇到400错误。本文详细解析了这一问题,并提供了Nginx配置的具体示例。此外,还深入探讨了DNS服务器证书、SSL证书的申请与安装流程,以及域名注册、查询方法和CDN加速技术的应用,帮助读者全面了解相关技术细节。 ... [详细]
  • 为了在Hadoop 2.7.2中实现对Snappy压缩和解压功能的原生支持,本文详细介绍了如何重新编译Hadoop源代码,并优化其Native编译过程。通过这一优化,可以显著提升数据处理的效率和性能。此外,还探讨了编译过程中可能遇到的问题及其解决方案,为用户提供了一套完整的操作指南。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • 在优化Nginx与PHP的高效配置过程中,许多教程提供的配置方法存在诸多问题或不良实践。本文将深入探讨这些常见错误,并详细介绍如何正确配置Nginx和PHP,以实现更高的性能和稳定性。我们将从Nginx配置文件的基本指令入手,逐步解析每个关键参数的最优设置,帮助读者理解其背后的原理和实际应用效果。 ... [详细]
author-avatar
停止离开静悄悄
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有