V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
fangcan
V2EX  ›  程序员

生产环境代码与开发分支的代码差别很大如何处理?

  •  
  •   fangcan · 2021-11-17 17:55:33 +08:00 · 4040 次点击
    这是一个创建于 1137 天前的主题,其中的信息可能已经有所发展或是发生改变。

    由于历史原因,没有做好分支管理,现在的情况是这样的:

    • 多个公司(我司的服务对象是不同的公司)生产中有不同的代码, 而开发分支是同一份(最近才用同一份代码切不同公司分支, 新的需求在不同的分支上开发)
    • 生产环境的更新都是增量发布的
    • 所以分支的代码跟生产的代码可能差的很多。即可能 a 公司修改了 M1 方法,上线了。但是 b 公司没有更新该方法,b 公司下次上线其他需求的时候也要修改 M1 方法,但是由于已经被修改过了,所以与线上的代码差了一个或多个版本,导致了可能期间的版本使用了其他类或配置,由于本次 b 公司的需求只是修改 M1 方法,所以只上线了 M1 方法而没有上其他类或配置,所以就直接报错了。

    最近在上线的时候由于代码不一致的问题,导致了上线很困难。

    目前我的操作是上线前先把线上的代码 class 拿下来反编译跟要上线的代码比对下, 差距较大的用线上的 class 反编译直接覆盖,但还是免不了有各种问题,少类,少方法等

    请教各位 v 友有没有什么好的解决方法?

    第 1 条附言  ·  2021-11-17 19:10:48 +08:00
    目前我能想到的解决办法就是拿线上代码反编译后作为开发分支的代码,但是反编译后的代码可读性太差了

    有没有什么方案可以反编译 class 后可读性还可以的, 比如哪个工具或者框架可以实现的?
    32 条回复    2021-11-23 15:55:49 +08:00
    Chad0000
        1
    Chad0000  
       2021-11-17 18:09:29 +08:00 via iPhone
    一般不这样使用分支吧,我之前做的平台都是从代码角度让他们功能有所不同。通过适当的设计是可以做到的。
    dqzcwxb
        2
    dqzcwxb  
       2021-11-17 18:19:14 +08:00
    一切以生产环境为准,测试环境是为生产环境服务的
    wolfie
        3
    wolfie  
       2021-11-17 18:20:42 +08:00
    拉一个功能表格做管理。

    公司 B 分支要用 公司 A 某个功能,手动 cherry-pick 特定几个 commit 。
    fangcan
        4
    fangcan  
    OP
       2021-11-17 18:38:40 +08:00
    @dqzcwxb 是要以生产为准,但是问题就是上线太难了,做不到直接把新修改的 class 直接替换就可以。 有想过把生产的代码全量拿下来做开发分支,但是反编译后的代码又没有注释,编译后可读性也很差。
    fangcan
        5
    fangcan  
    OP
       2021-11-17 18:49:03 +08:00
    @wolfie 目前我接手后的代码就是切了分支的代码,但其实是基于原来的同一份代码。 期间什么公司修改了什么功能,什么类是没有记录的。 所以最近遇到的就是 我这次开发 b 公司的需求,然后修改了 b 类。增量上线后发现少了其中引用的 c 类。
    sprite82
        6
    sprite82  
       2021-11-17 18:49:11 +08:00   ❤️ 1
    class 增量 无力吐槽,另外你这一份代码服务多个客户方式,你这代码并没有面向对象思想
    master 主干分支,dev 开发分支,dev-com-a dev-com-b 各个客户的需求分支,
    开发时,dev-com-a ,b 都合并到 dev 分支,
    上线时,比如只要上线 a 那就把 a 合并到 master ,在 master 上打包发布就行了

    至于你的 m1 等业务方法,应该抽一个公共方法和继承的几个 A,B,C 个性化的类,运行时根据客户 id 执行对应的方法,这样,你哪怕几个客户的需求同时开发,也不会影响其他客户的业务。

    class 增量更新 劝你赶紧停止
    bk201
        7
    bk201  
       2021-11-17 18:54:59 +08:00
    重新制定完善的分支方案,不要再接着坑走下去了。
    Tink
        8
    Tink  
       2021-11-17 19:24:32 +08:00 via Android
    从生产环境拉最新分支
    statement
        9
    statement  
       2021-11-17 19:38:13 +08:00
    做开关 分支不是干这个的
    chenxytw
        10
    chenxytw  
       2021-11-17 20:38:44 +08:00   ❤️ 1
    建议离职换家公司,折腾这种事情完全没有意义。
    sagaxu
        11
    sagaxu  
       2021-11-17 21:57:04 +08:00 via Android   ❤️ 2
    有两个大问题要整改,

    1. 引入可重现打包机制和可信任发布,每个人每次 checkout 出相同版本的代码,能一键打出二进制上完全一样的包,线上只能发布来源于某个 tag 打出来的包。

    2. 废弃一个公司一个分支的乱象。合理安排组件,做好分层,底层模块各个公司只能用同一套,且不能出现跟特定公司相关的逻辑,极少修改。中层模块所有公司共享,但可以加入一些开关和特定公司逻辑,不经常改。上层模块,可以玩命定制,甚至搞不同的包或者不同的实现。最好把不同的层拆到不同的仓库,上层只能复用下层发布的 jar/lib 。

    有些公司会搞成不同的服务,划分出相应的平台和中台以及大前端,每个 team 各司其职。不过这不太适合规模较小的业务,jar/lib 级复用比较简单可行,虽然不如服务化那么强大,但是也不必付出服务化的成本。
    TypeError
        12
    TypeError  
       2021-11-17 21:59:12 +08:00
    抽时间全 merge 到 master ,然后发布用专门的 release 分支打 tag ,没时间那就没办法了
    MarioLuo
        13
    MarioLuo  
       2021-11-17 22:01:05 +08:00 via Android   ❤️ 1
    问题是生产环境上运行的包,在分支里没有有一个 commit 能完整对应起来。现在只有人肉处理了
    1. 当前的分支留存一份
    2. 对每个公司或者近期要迭代的找出历史 commit 打包后 class 差异最小的,无论是手工还是找差异文件的源代码补齐
    3.如果差异过大或者无法找到的,保持 class 增量部署
    最后处理这个问题一定要反馈给上级领导,风险和成果要让上面知道
    wingoo
        14
    wingoo  
       2021-11-17 23:23:24 +08:00
    不同公司如果需求不确定, 最好是做开关, 在代码层级区分(或者统一的配置管理), 而不是分支, 特别是对于持续迭代的功能, 没法区分的
    momocraft
        15
    momocraft  
       2021-11-18 00:48:01 +08:00
    为什么会有单个 class 更新这种做法的 难道这样风险更小吗
    wqhui
        16
    wqhui  
       2021-11-18 09:43:04 +08:00
    最好是不同公司都用同一套代码,功能的差异通过配置来控制
    jtacm
        17
    jtacm  
       2021-11-18 09:44:44 +08:00   ❤️ 1
    class 反编译的方法非常不建议。

    如果是我的话,设计开关+配置 config 文件(不同公司 config 不同),同时利用好抽象和继承。

    PS:是停下来进行一次重构了,这是一次必须偿还的技术债。否则以后越滚越大,就更麻烦了,除非你也想跑路。
    lei2j
        18
    lei2j  
       2021-11-18 10:01:36 +08:00   ❤️ 1
    怎么感觉跟我现在公司一样啊,不同的分支服务不同公司
    clf
        19
    clf  
       2021-11-18 10:47:52 +08:00   ❤️ 1
    按 commit 合并?

    另外,建议把定制化功能放在单独的项目 /特定服务里,不要影响通用化的项目代码。如果对通用化的功能有改变,统一以新加页面、新加接口的方式进行,通过权限树管理页面。

    比如 AB 两家公司的同一个功能是两个不同的逻辑,那么前端页面就是两个页面,路由是相同的,整套前后端代码是相同的,唯一不同的就是权限树上同个路由指向了不同页面代码文件。
    libook
        20
    libook  
       2021-11-18 11:28:17 +08:00   ❤️ 1
    核心思路就是能统一的都统一版本,不能统一的彻底分开。

    代码分两个 repo ,核心+应用。
    核心提供底层、基础、通用的接口,尽量向前兼容。
    应用调用核心接口来实现业务,可以针对不同客户的需求分不同分支。
    多个客户在应用方面有交集的话,可以再分出一个中台 repo 出来,只维护通用的应用。
    构建的时候是使用核心+中台+客户分支一起编译。

    一个新的应用功能先在本客户的分支上开发,当具有通用性之后就分离出来放入中台,同样当中台硬用不再具备通用性之后就从中台拿出来放到客户分支上。
    应用开发过程中发现需要某核心不具备的基础能力,则可以向核心提扩展需求,核心维护团队评估合理后进行开发。
    每次发版,按照客户和版本号打 tag ,这样可以通过客户信息来定位到当前服务器上部署的代码版本(历史版本也可以定位)。

    首先得明确,这是个技术债务,不还的话利息越滚越多,还债的成本可能低于不还债未来导致的不必要成本,所以最好尽快解决。

    其次是,要对产品需求进行有效管理,至少每一次的需求内容都要有记录,然后梳理出每个客户的最终需求和产品设计方案,然后根据基础的代码来看缺什么、需要修改什么,最不济的方案就是根据最新需求从一个旧版本重新开发,有时候会比 hack 现有代码要更快。
    SingeeKing
        21
    SingeeKing  
       2021-11-18 12:08:47 +08:00
    build flag 就是解决这个的,一份代码,不同的公司用不同的 flag
    gam2046
        22
    gam2046  
       2021-11-18 16:40:25 +08:00
    这个屁股不好擦,有没有可能性联系各个合作方,先进行一次全量更新,统一环境后再考虑后面的事情。

    如果没法全量的话,尝试一下人工比对各个发行版的区别,增量更新到同一个版本。

    如果依旧保持这种情况,很难解决
    smallpython
        23
    smallpython  
       2021-11-18 17:12:44 +08:00
    把数据导出来, 然后统一安装最新的版本, 然后再导进去
    aguesuka
        24
    aguesuka  
       2021-11-18 17:41:34 +08:00
    所有发布必须携带版本号, 在仓库里冻结二进制文件和源代码. 不做增量更新, 保证现场代码与源码对应
    zjsxwc
        25
    zjsxwc  
       2021-11-18 21:32:45 +08:00 via Android
    定期比如一周都合并到 master 分支呗,从来都不合并的分支有意义吗?
    guanhui07
        26
    guanhui07  
       2021-11-18 22:12:23 +08:00
    测试分支删了把 定期从 master 拉
    kaneg
        27
    kaneg  
       2021-11-18 23:27:48 +08:00
    说明你们公司的客户不多。
    要考虑多客户的设计应该是代码保持同一份,客户的不同需求靠各自的配置来适配。
    byzf
        28
    byzf  
       2021-11-19 10:17:48 +08:00
    这不就是屎山 1.0 吗,比较接近线上环境的开发人员懒得跑开发版本代码,直接在生产环境代码修改了之后又要求开发分支去合并生产环境的代码。

    这样搞很大概率结果就是,同一个功能有来自七八个线上版本的不同实现,然后后续开发时也不知道哪个是主要在用的,这个人依赖这个那个人依赖那个,遇到问题要改就要全改,要么就加份新的,反正也没人愿意去重构以前的,最后就变成屎山。
    fangcan
        29
    fangcan  
    OP
       2021-11-22 15:43:15 +08:00
    @byzf 嗯 大概就是这种情况, 基于这种情况, 如何捋清楚线上的各公司的代码?有没有什么好的建议、方法?
    fangcan
        30
    fangcan  
    OP
       2021-11-22 15:46:15 +08:00
    @kaneg 之前就是同一份,但是配置开关之类的应该是没弄好, 或者不知道什么原因, 反正之前都是增量发布。那即使配置弄好了,也没用啊。 这次我新开发的需求,也要求要用增量的,说全量会有风险。但是就遇到了描述里面的情况
    byzf
        31
    byzf  
       2021-11-23 09:31:32 +08:00
    @fangcan 分 dev 、stable ,让维护线上的人改 stable ,dev 定期从 stable 拉版本。
    fangcan
        32
    fangcan  
    OP
       2021-11-23 15:55:49 +08:00
    @byzf stable 是从线上拿代码么?还是怎么操作? 目前就是无法做到全量发布,所以分不出 stable
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2608 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 03:27 · PVG 11:27 · LAX 19:27 · JFK 22:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.