0.麻烦

操作系统提供的网络接口都会令人不爽,要么太接近底层而使用不便,要么层次过高又不提供底层点的接口供设置参数。但是我们不能期望系统API做得很高级,因为没有绝对合适的网络库,必须定制化从而达到适合某业务下的最佳性能。

1.需求

移动app使用网络框架的场景不外乎三个:

  1. 和自家(CS架构的)服务器通信
  2. 下载文件
  3. Web浏览

从方便和可扩展性出发,不少app会选择通信协议为HTTP(S),数据协议则为自定义。为了保护隐私,如果不使用HTTPS,数据都该自行加密。一般而言,除非在TCP上使用自定义的通信协议,自有的功能或业务代码都不会写到网络库内部,而是写在上层。这也要求网络库本身有足够的接口来适应业务需求。这些非协议标准的需求可能有:

  • 自动填充一些必须的header,例如host、accept等。
  • 在关键的流程节点有回调通知,可以在这些时机打Log、记录与统计。或者由网络部内部记录性能数据,通过别的接口输出给上层。
  • 下载:分段,断点续传,FTP支持,多连接下载。
  • 同步&异步,线程池,在合适的线程做回调。
  • 出错自动重试。
  • 预先建立连接,有连接池。
  • 不同网络类型、质量下使用不同的通信策略。
  • 清理缓存
  • 可以流式读写
  • 程序进入后台的处理,按需要可断网、降低优先级、限速等。

2.内部设计

流程:

  1. 产生URL和可选的post body,来自业务模块
  2. 构建请求
    • method
    • header(User-Agent, Cookie,Accept……)
    • post body,文件分段上传(需自动填充标准要求的header)
  3. 正式发起
    • 回调:willSend,最后修改请求的机会
    • 根据scheme创建任务(一般只有HTTP和FTP)
    • 调度:线程(进程)、队列、优先级
  4. 读取缓存或使用代理
    • 若命中规则,尝试读取缓存,如有则返回缓存数据
    • 代理出错的回退
  5. DNS
    • 结果缓存,读取
    • DNS结果优选
    • 回调通知结果
    • (optional)允许设置本地的域名映射表
  6. 连接
    • 连接池(Socket Pool)
    • 长连接(Keep-Alive)
    • 握手和协商,更多协议支持:HTTP/2,QUIC
    • SSL,证书管理
    • 出错或超时,重试
    • 回调通知结果
  7. 发送
    • 加密
    • 回调通知:进度,流量
  8. 接收
    • (optional)限速,限量
    • 解密
    • 解析header
    • 缓存:映射表,容量管理、淘汰策略……
    • 解压,解码
    • 构建响应
    • 回调通知:流量
  9. 结束
    • 回调通知:OK或ERROR(错误码或描述)
  10. 工具
    • 解码
    • URL:parser(得到scheme、port、query、host等), encode & decode
    • base64
    • 网络状态监控:连通性,网络类型,弱网(网络质量评级)
    • 日志输出,打点
    • 下载文件的保存文件名推荐(根据URL、mime type等)
    • 网络(适配器)连接信息获取,含WiFi、蜂窝网络等
    • (optional)Server
    • UDP
    • 枚举所有的状态码和reason、常见的header name……

特殊场景的优化:

  1. 证书缓存
  2. 机器学习,智能预测:例如初始化后,对常访问的域名主动预解析、预连接,预加载
  3. 自家服务器压缩,或支持新的压缩格式
  4. 私有协议优化

运维的因素:

  1. 下发DNS,上传统计数据
  2. 下发指定域名或IP使用某种策略
  3. CDN SDK,迅雷SDK
  4. 模块可选,定制化编译与发布

3.接口设计

核心类:

  1. Request, Callback
  2. Response
  3. Manager, Callback
  4. Utility
  5. Parser、证书、log……

五种风格,差别在于拿哪个类来Start:

  1. URL,java.net库
  2. Request,Chromium网络库
  3. 事务:Transaction,WebKit ; Connection,iOS
  4. 管理器:Controller / Manager
  5. enqueue到任务队列

请求的设置和操作(可以是单个或全局,全局的应在Manager设置):

  1. method,header,body(upload file path),Auth
  2. 连接超时
  3. 获取数据超时
  4. DNS
  5. 跳转策略
  6. 是否(强制)使用或不使用缓存
  7. 是否(强制)使用或不使用代理
  8. 重试次数
  9. 自定义(伪造)响应
  10. 数据保存位置选择(内存或磁盘路径)
  11. 优先级
  12. Cancel

Manager设置与操作:

  1. Debug,包括打印log和其它。可以由外部传入Logger
  2. 清理指定缓存,可以具体到URL或host的DNS、HTTP缓存
  3. 设置缓存路径,容量
  4. 各种功能的开关
  5. 获取整体的负荷(任务数、占内存、缓存量等)

4.指标

(分域名)性能:

  • 总耗时,各阶段耗时
  • 重试次数
  • 最终失败的次数
  • 连接(Keep-Alive和预连接)复用率

空间占用:

  • 事务的整体内存波动
  • 各阶段的模块的内存占用
  • 缓存的淘汰策略,磁盘占用空间

5.如果有钱

  1. 动态网络策略:收集用户的网络使用习惯,并根据当前网络类型、质量来设置各类参数。
  2. 使用中间件进行数据传输
  3. 恶意URL检测
  4. 性能数据收集统计:

    RT,出错次数,出错率,请求次数,来源方……
  5. 针对特定业务优化,如视频
  6. 支持按视频协议下载,支持p2p下载

HTTP(S)网络框架的设计的更多相关文章

  1. 《android开发进阶从小工到专家》读书笔记--网络框架的设计与实现

    第一步: 第一层:Request--请求类型,JSON,字符串,文件 第二层:消息队列--维护了提交给网络框架的请求列表,并且根据响应的规则进行排序.默认情况下按照优先级和进入队列的顺序来执行,该队列 ...

  2. [连载]《C#通讯(串口和网络)框架的设计与实现》- 0.前言

                                  目       录 前言 前言 刚参加工作,使用过VB.VC开发软件,随着C#的崛起,听说是C++++,公司决定以后开发软件使用C#,凭借在 ...

  3. [连载]《C#通讯(串口和网络)框架的设计与实现》- 6.通讯控制器的设计

    目       录 第六章           通讯控制器的设计... 2 6.1           控制器接口... 2 6.2           串口控制器... 3 6.3          ...

  4. [连载]《C#通讯(串口和网络)框架的设计与实现》-1.通讯框架介绍

    [连载]<C#通讯(串口和网络)框架的设计与实现>- 0.前言 目       录 第一章           通讯框架介绍... 2 1.1           通讯的本质... 2 1 ...

  5. [连载]《C#通讯(串口和网络)框架的设计与实现》-2.框架的总体设计

    目       录 C#通讯(串口和网络)框架的设计与实现... 1 (SuperIO)- 框架的总体设计... 1 第二章           框架总体的设计... 2 2.1           ...

  6. [连载]《C#通讯(串口和网络)框架的设计与实现》- 5.串口和网络统一IO设计

    目       录 第五章           串口和网络统一IO设计... 2 5.1           统一IO接口... 2 5.1.1    串口IO.. 4 5.1.2    网络IO.. ...

  7. [连载]《C#通讯(串口和网络)框架的设计与实现》-4.设备驱动管理器的设计

    目       录 第四章           设备驱动管理器的设计... 2 4.1           接口定义... 2 4.2           设备容器... 7 4.3          ...

  8. [连载]《C#通讯(串口和网络)框架的设计与实现》- 11.调试器的设计

    目       录 第十一章     调试器设计... 2 11.1         调试接口... 2 11.2         界面方式调试... 3 11.3         命令行方式调试.. ...

  9. 事件驱动之Twsited异步网络框架

    在这之前先了解下什么是事件驱动编程 传统的编程是如下线性模式的: 开始--->代码块A--->代码块B--->代码块C--->代码块D--->......--->结 ...

随机推荐

  1. 【JavaScript】类继承(对象冒充)和原型继承__深入理解原型和原型链

    JavaScript里的继承方式在很多书上分了很多类型和实现方式,大体上就是两种:类继承(对象冒充)和原型继承. 类继承(对象冒充):在函数内部定义自身的属性的方法,子类继承时,用call或apply ...

  2. C#(同步调用、异步调用、异步回调)

    Review: 原作者虽然使用了汉字的类名,看起来十分蹩脚,但是,还是把同步调用.异步调用.异步回调的使用讲解的很详细的.原理讲解的很清晰. ------ 本文将主要通过“同步调用”.“异步调用”.“ ...

  3. p1164 小A点菜 题解——背包初步

    传送门 除去花里胡哨的表层题干,其实可以简化为: 若有m个东西,每取一个要K个代价,问若要求取出数据的代价为n的方案数是多少 其实是01背包的一种变式(反正我就是这么认为的,不对又怎样,打我啊). 我 ...

  4. 洛谷 P2014 选课(树形背包)

    洛谷 P2014 选课(树形背包) 思路 题面:洛谷 P2014 如题这种有依赖性的任务可以用一棵树表示,因为一个儿子要访问到就必须先访问到父亲.然后,本来本题所有树是森林(没有共同祖先),但是题中的 ...

  5. SqlServer索引、优化、约束、连接

    索引的创建和删除 create index in_name on person(name) --创建索引 drop index person.in_name --删除索引 create index i ...

  6. Sublime Text 3插件收集

    0.Package Control 这个是必须装的,就不多解释了 1.ConvertToUTF8 支持 GBK, BIG5, EUC-KR, EUC-JP, Shift_JIS 等编码的插件. 2.B ...

  7. 【Vim】Vim学习

    1. 三种模式 (1)命令模式:刚启动vim便进入命令模式,此时敲击键盘会被当做命令来处理 以下是常用的几个命令: i 切换到插入模式,以输入字符.x 删除当前光标所在处的字符.: 切换到底线命令模式 ...

  8. ubuntu关闭时间同步与centos更改时间

    环境:ubuntu 源于一次项目需要修改系统时间,但是每次修改后又被同步回网络时间,找了好久发现是这个原因: NTP即Network Time Protocol(网络时间协议),是一个互联网协议,用于 ...

  9. Hibernate 查询语句基本用法

    转发: http://459104018-qq-com.iteye.com/blog/720538

  10. UVM序列篇之一:新手上路

          声明:本人所有权属路科验证,本人仅为个人学习方便将文章整理至此. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 有了UVM的世界观,知道这座城市的建 ...