zoukankan      html  css  js  c++  java
  • 代码热更新

    代码热更新

    有支持ios的热更方案都有个共同点:更新后代码都是解析执行。如果按其更新前是否解析执行,可以分为两大类:

    一类是某些模块甚至整个游戏都采用解析执行。这是最传统的方式,目前市面上所有主流方案(xLua,slua,tolua,ILRuntime,jsb等等)都支持这种方式。

    这种方式:

    1. 或多或少都会有些侵入性;

    2. 基于性能、实现便利性等的考虑,一般在游戏中要以原生的方式跑,这些原生跑的代码出了bug时,在这种方式下是无能为力的;

    3. 如果使用的脚本是动态类型语言,还会带来代码维护困难的问题;

    4. 可以新增功能,有的游戏甚至可以做到一次下载,后续不用整包更新。

    另外一类是原生方式,如果有bug,把逻辑重定向到新的,解析执行的逻辑。

    这种方式:

    1. 侵入性低,后期项目也可以使用;

    2. 正常逻辑是原生方式运行,有问题只是局部切换到解析执行,所以性能比较好;

    3. 会导致代码段增大,增大正比于注入的类的数量;

    4. 这种方式往往难以新增功能。

    第二种方式是接下来讨论的重点,方便起见,我们称之为“热修复”,热修复最早的成熟方案是xLua提供,经过两年来的使用已经逐渐被接受,tolua#后来也加入了这功能,也有一些网友基于ILRuntime做了热修复功能。

    InjectFix

    https://mp.weixin.qq.com/s/-J7zxnh-_H6kRH3G_LyMxw

    InjectFix就是一个热修复的实现。那它和其它热修复方案又有什么不同呢?

    设想这么个场景,我们有一个一千行代码的函数,其中有一行有问题,我们需要修复它。如果用xLua,需要用lua去重新实现一遍这个函数,工作量大。而基于ILRuntime的热修复,由于其补丁是另一个程序集,它无法直接访问原类的私有成员,所以那999行正常代码一般也不能直接使用,需要做较多修改。而InjectFix不需要用lua,也不需要像ILRuntime热修复那样另外建一个工程把那一千行逻辑重实现。只需要在Unity原工程直接改掉这行代码,然后标注这函数要更新即可。

    InjectFix还有其它优势:

    1. 运行时非常小巧,仅100K左右,比各lua方案,ILRuntime都要小很多,而且不依赖第三方库,纯C#实现;

    2. 支持每个游戏生成一份自己私有的补丁格式,私有的指令定义。这样相比通用的lua原代码,lua字节码,clr程序集都更安全些。

    3. 支持Assembly-CSharp.dll之外的dll的修复。

    4. 免代码生成,更干净。

    它也有缺点,不支持新增类,也不支持在已有类新增字段,修bug还是够用的,但难以通过热更为游戏增加新功能。InjectFix就一个纯粹的修bug工具而已。

    各热更方案群提问频率最高的问题之一:这方案会不会导致我游戏苹果审核不通过。让我们看看苹果的热更新条款:

    可以看到最新条款允许下载代码解析执行,但前提是不能通过新增特性和功能来把程序改得(和审核时相比)面目全非。再看看通常被拒时的理由中的Guideline 2.5.2里的一句:Your app, extension, or linked framework appears to contain code designed explicitly with the capability to change your app’s behavior or functionality after App Review approval。有“新增特性和功能”能力的热更新方案的尴尬之处在于有“改得面目全非”的能力。而InjectFix从它提供的能力(只能修改已有函数)来看,并不具备“新增特性和功能”的能力,这本来是弱点,放在这里却成为合规性的保证了。

    作者:车雄生
    链接:https://www.zhihu.com/question/345639690/answer/825301379

    InjectFix的作者,同时也是xLua的作者来答一波。

    先回题主的问题:其实这问题在腾讯开源公众号发布的公告那也描述得挺清楚的,简而言之,InjectFix是xLua的hotfix功能(公告那称之为“热修复”)的升级版。

    和ILRuntime的区别从用户视角看,ILRuntime要更新的整个模块要挪到一个dll里头,“整个模块”解析执行。而InjectFix不需要对工程重构,当工程不需要更新时,全部代码都以原生方式运行,有更新的话,仅仅待更新那少数几个函数切换到解析执行。

    而CSHotfix,XIL,也是“热修复”方案,据我所知,它们访问原类的私有变量之类是要特殊的写法,一个类成员方法往往避免不了这些写法,因此你要修复一个很大的函数,对原来逻辑的重新实现往往是无可避免的。而InjectFix在原工程哪行错误改哪里即可。

    ET好像是个使用了ILRuntime的一个C#框架吧。和InjectFix关系不大,属于两类东西没可比性。

    如果仅仅修C# bug,目前方案中,InjectFix应该是最好用的。缺点嘛,公告也说了,不能新增功能。其实这“不能”,更多是人为的设定,InjectFix在对Unity协程,闭包的支持中其实是包含了对新增class的支持,只不过人为约束了仅这些场合使用。公告也分析了,这样更符合苹果的热更新条款。

    至于某层提到的产品化问题,这里也答一下:

    InjectFix(内部叫iFix,因外部商标被注册被迫改名,打听的时候记得说iFix)项目在xLua对外开源不久后就有想法了做了,在2017年下半部开始研发,2018年初对内发布。目前“已知”有9个项目在用,其中4个已经正式上线,没上线的也用于他们平时体验版本的修复,第一个使用iFix的项目至今已经使用了1年多。9个说多也不多,但新项目用ue的居多,所以说少其实也不少。

    至于“多年脱产”嘛,也是,但前面也说了,InjectFix和xLua同一个作者,xLua在2015年研发,作者在热更新方面领域也默默耕耘了4年多了,期间和很多内部项目交流相关需求,在外部xLua的两个千人+的群,前期也有很多交流。iFix从设计之初就考虑了很多项目的痛点。脱产也有脱产的好处,不会优先考虑自家的问题,在一个公共组件中做了很多私有特性,脱产不可怕,脱产+闭塞才可怕。然而个人还是蛮喜欢和项目交流的,开源也是为了和更多的人交流。

  • 相关阅读:
    尚硅谷Docker笔记(6) DockerFile解析
    注意防踩坑系列
    尚硅谷Docker笔记(1) Docker简介
    尚硅谷Docker笔记(4) Docker 镜像
    尚硅谷Docker笔记(8) 本地镜像发布到阿里云
    尚硅谷Docker笔记(2) Docker安装
    SQL中join连接查询时条件放在on后与where后的区别
    尚硅谷Docker笔记(3) Docker常用命令
    尚硅谷Docker笔记(7) Docker常用软件安装
    关于存储过程的几个sql
  • 原文地址:https://www.cnblogs.com/heweiwei/p/12554627.html
Copyright © 2011-2022 走看看