PC客户端软件升级方式简史

  • 在windows8之前,微软的Windows平台一直没有提供一个想苹果的AppStore或者Linux的包管理这样的统一软件管理工具。所以Windows下的软件安装、升级、卸载的事情一般都是软件自己去负责。这样导致Windows下的软件安装、升级、卸载的方式五花八门,但总体上来说方法都大同小异。安装程序主要分两种,下载器的安装包和离线安装包,这个不赘述。
  • 今天重点聊一下升级,升级功能看似简单,但对于一个想持续经营的客户端软件来说却是一个重要的生命线。开发团队辛苦修改的bug、做的新功能都希望用户能马上通过升级新版本体验到。
  • 在互联网还没普及的蛮荒年代,很多软件公司升级都是发布离线升级包,一般这种包就是一个安装程序,它只负责安装程序需要更新的部分,然后做一些修改注册表之类的系统配置以适应新版本的功能。
  • 现在互联网普及后,所有的PC客户端软件基本上都是使用的在线升级。

    • 最简单的在线升级方式是首先客户端发送检测更新的消息到服务器,服务器给返回是否有新版本,最新版本号以及下载地址等信息,客户端就根据这些信息处理。如果有更新就去刚刚获取到的地址下载最新的安装程序,然后执行安装程序更新。
    • 后来大家觉得每次都重新安装太麻烦,而且安装包也特别大,下载也非常耗时。于是这个下载的程序被替换成了一个压缩包,里面装的是程序需要更新的文件。升级程序下载好压缩包后再解压到安装目录中就完成了软件的升级。
  • 随着敏捷开发方式的普及,软件的升级就变得越来越频繁了。对于PC客户端软件每次升级时主程序以及一些重要的动态库都有可能更新,所以下载的压缩包也会比较大。于是就产生了比较文件二进制差异的算法BsDiff,以及Google基于其进一步改进的Courgette(小胡瓜)。这些算法的加入可以让补丁包缩小了n个数量级。这样需要客户端去下载的压缩包就会很小了,下载耗时也会大大缩短。
  • 另外值得一提的是,随着软件升级包大小越来越大,用户下载更新文件的等待时间也越来越长,于是有些软件就采用了后台静默下载的方式。这种方式虽然流氓,但可能对于用户来说体验要好一些。那么这种情况下主程序一般都还在运行,而升级程序下载完成后想要更新文件立即升级就必须关闭主程序然后进行文件替换,以免文件被占用,导致升级失败。于是Google的chorme搞出一个双目录更新的方法来应对这种情况。所谓双目录更新就是把原来的文件先复制到另一个目录下,更新程序的时候就更新这个文件目录,升级完成后就直接从新的目录中启动新版本。
  • chrome的目录结构是这样的:
Chorme
    +Application
        +57.0.2987.110
        +57.0.2987.88
            chrome.exe
  • 可以看到,他是以版本号做目录名。以后启动chrome.exe时去加载最新版本就可以了。当然它能这样做主要因为chrome.exe本身是个很小的程序,基本它自身是不需要升级的,它主要负责的就是检测版本号然后加载新版本的dll。
  • 当然现在的客户端升级程序还涉及一些入灰度,md5完整性检测断点续传等技术这里也不在赘述。下面我简单介绍一下BsDiff和Courgette。
BsDiff: Linux中的一个开源工具,致力于快速和轻量的更新Linux的操作系统漏洞(跟微软的安全补丁类似),其算法的核心思想是基于统计学规律进行近似匹配,然后通过一系列的变化(比如BWT变换)提高“近似段”的压缩率。
Courgette: Google Chrome升级系统的核心模块,基于BsDiff,但对其进行了一系列的改进,将平台相关的信息(即x86汇编指令)融入其中,以期望更精确的定位指针,从而避免统计算法在差异明显时候的错误率。
  • Google官方给了一个10M的升级包例子使用bsdiff可以看到包小了不少,用Courgette更是少了几个数量级。

  • 使用bsdiff算法我们的升级过程是这样的:
server:
    diff = bsdiff(original, update)
    transmit diff

client:
    receive diff
    update = bspatch(original, diff)
  • 大致流程就是这使用bsdiff算法比较不同版本的二进制文件制作补丁包,客户端下载补丁包后调用bspatch生成新的二进制文件。
  • 使用Courgette的升级过程是这样的:
server:
    asm_old = disassemble(original)
    asm_new = disassemble(update)
    asm_new_adjusted = adjust(asm_new, asm_old)
    asm_diff = bsdiff(asm_old, asm_new_adjusted)
    transmit asm_diff

client:
    receive asm_diff
    asm_old = disassemble(original)
    asm_new_adjusted = bspatch(asm_old, asm_diff)
    update = assemble(asm_new_adjusted)
  • Courgette对于bsdiff的优化主要就是在adjust这一步上,具体可以参考Courgette官方说明
  • 最后,Google还开源了一套Windows下的升级协议,大家有兴趣也可以研究下omaha
Image placeholder
qiuchous15
未设置
  60人点赞

没有讨论,发表一下自己的看法吧

推荐文章
Git教程_1.2 起步 - Git 简史

同生活中的许多伟大事物一样,Git诞生于一个极富纷争大举创新的年代。 Linux内核开源项目有着为数众多的参与者。绝大多数的Linux内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-20

一个大型互联网公司后台基础设施发展简史

笔者在某大厂后台从事后台研发工作多年,亲历了后台基础设施随着业务的发展一步步演进,如果代码也有生命,整个过程堪称一部精彩的进化史。下面通过一张时间轴思维导图将整个过程呈现出来,后续将不定期分享其中的专

svn服务端安装、权限修改以及客户端的使用

欢迎加入前端交流群交流知识获取视频资料:749539640svn服务端安装、权限修改以及客户端的使用svn服务端、客户端、汉化包:下载地址1.安装服务器端程序(傻瓜式下一步。。下一步)选择服务器和管理

php 获取客户端ip

课程推荐:PHP开发工程师--学习猿地精品课程 1functiongetRealIp(){2if(getenv("HTTP_CLIENT_IP")&&strcasecmp(getenv("HTTP_C

TPC-C解析系列03_TPC-C基准测试之SQL优化

TPC-C是一个非常严苛的基准测试模型,考验的是一个完备的关系数据库系统全链路的能力。这也是为什么在TPC-C的榜单前列,出现的永远只是大家熟知的那几家在业界有着几十年积累、从关系数据库理论开始发展就

TPC-C解析系列05_TPC-C基准测试之存储优化

TPC-C规范要求被测数据库的性能(tpmC)与数据量成正比。TPC-C的基本数据单元是仓库(warehouse),每个仓库的数据量通常在70MB左右(与具体实现有关)。TPC-C规定每个仓库所获得的

TPC-C解析系列01_TPC-C benchmark测试介绍

作者:阳振坤2019.10导语:自从蚂蚁金服自研数据库OceanBase获得TPC-C测试第一名后,引起了行业内外大量关注,我们衷心的感谢大家对OceanBase的支持与厚爱,也虚心听取外界的意见和建

TPC-C解析系列02_OceanBase如何做TPC-C测试

导语:蚂蚁金服自研数据库OceanBase登顶TPC-C引起业内广泛关注,为了更清楚的展示其中的技术细节,我们特意邀请OceanBase核心研发人员对本次测试进行技术解读,共包括五篇:1)TPC-C基

TPC-C解析系列04_TPC-C基准测试之数据库事务引擎的挑战

OceanBase这次TPC-C测试与榜单上Oracle和DB2等其他数据库在硬件使用上有非常大的不同,OceanBase的数据库服务器使用的是204+3台型号是ecs.i2.16xlarge阿里云E

HPC CHINA 2019:面向E级计算时代的HPC/AI协同设计

蓝天飘白云,牧场奶茶香。蒙古大营雄风在,琴声传远方。骑马又滑沙,豪饮河套王。敖包相会歌一曲,笑发少年狂。中国一年一度高性能计算领域的盛会——全国高性能计算学术年会(HPCCHINA2019)在内蒙古呼

企业级RPC框架zRPC

课程推荐:GO开发工程师--学习猿地精品课程 近期比较火的开源项目go-zero是一个集成了各种工程实践的包含了Web和RPC协议的功能完善的微服务框架,今天我们就一起来分析一下其中的RPC部分zRP

十年软件通胀率:从 2009 到 2019 年,软件越来越昂贵

过去十年,软件定价逐渐上升。在我们调查的一百个商业应用程序中,价格平均上涨了62%,其中包括一些比较便宜的应用程序。如果用户现在花钱购买一款应用程序,那么它很可能比十多年前的价格贵98%以上。

软件工程学习笔记(一):软件工程

1计算机软件1.1软件计算机软件是指计算机系统中的程序以及文档,程序是计算任务处理对象和处理规则的描述.1.2软件特点 一种逻辑实体. 维护工作量大. 维护软件过程中会引入副作用. 1.3软件分类1.

到2022年,全球客户体验的支出将达到6410亿美元

根据IDC最新发布的《全球半年度客户体验支出指南》报告显示,2019年全球客户体验(CX)技术支出总额将达到5080亿美元,比2018年增长了7.9%。由于公司专注于满足客户的期望并提供差异化的客户体

付费客户突破10000家 帆软的不凡

在笔者眼中,帆软一直是一家”特立独行”的ToB公司,但活的很滋润。其与众不同之处有很多:2018年销售额超过4.6亿,早已达到了上市标准,却效仿华为并未上市。坚持不融资,在如今的市场环境下看,似乎很难

号称以客户为中心的保险行业如何做到真正的“按需”服务?

随着客户消费模式的改变和对服务要求的不断提高,当前保险行业正经历深刻变化。虽然保险行业已经积累了大量的客户数据,但由于其业务的复杂性及缺少系统的建设,大多数数据都是孤立的。而在数字化浪潮的推进下,许多

opcode 操作数 5 中不同的类型

zend_op_array.opcodes指向指令列表,具体每条指令的结构如下: struct_zend_op{//*opline*opcodes constvoid*handler;//指令执行ha

GoWeb教程_08.4. RPC

前面几个小节我们介绍了如何基于Socket和HTTP来编写网络应用,通过学习我们了解了Socket和HTTP采用的是类似"信息交换"模式,即客户端发送一条信息到服务端,然后(一般来说)服务器端都会返回

gRPC-Go 和 Java 的一次 HelloWorld(十)

都说grpc是跨语言的一个rpc框架,当团队内部有多种流行编程语言时,那么grpc可以为他们提供通信,今天我们就通过一个HelloWorld来看看Java和Go是怎么通信的,一起实践吧,只有亲身实践才

PHP Opcache 注意事项以及调优

从PHP5.5开始,Opcache扩展是核心的一部分,增加了对PHP脚本的字节码缓存的支持。对于动态语言(例如PHP),字节码缓存可以显著的提高性能,因为它可以确保脚本仅被编译一次。 Opcache扩

Go语言高级编程_ 4.1 RPC入门

4.1RPC入门 RPC是远程过程调用的简称,是分布式系统中不同节点间流行的通信方式。在互联网时代,RPC已经和IPC一样成为一个不可或缺的基础构件。因此Go语言的标准库也提供了一个简单的RPC实现,

Go语言高级编程_4.3 玩转RPC

4.3玩转RPC 在不同的场景中RPC有着不同的需求,因此开源的社区就诞生了各种RPC框架。本节我们将尝试Go内置RPC框架在一些比较特殊场景的用法。 4.3.1客户端RPC的实现原理 Go语言的RP

Go语言高级编程_4.4 gRPC入门

4.4gRPC入门 gRPC是Google公司基于Protobuf开发的跨语言的开源RPC框架。gRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多个服务,对于移动设备更加友好。本节将

Go语言高级编程_4.5 gRPC进阶

4.5gRPC进阶 作为一个基础的RPC框架,安全和扩展是经常遇到的问题。本节将简单介绍如何对gRPC进行安全认证。然后介绍通过gRPC的截取器特性,以及如何通过截取器优雅地实现Token认证、调用跟

Go语言高级编程_4.6 gRPC和Protobuf扩展

4.6gRPC和Protobuf扩展 目前开源社区已经围绕Protobuf和gRPC开发出众多扩展,形成了庞大的生态。本节我们将简单介绍验证器和REST接口扩展。 4.6.1验证器 到目前为止,我们接