9

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

 2 years ago
source link: https://www.v2ex.com/t/816109
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  程序员

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

  fangcan · 1 天前 · 2636 次点击

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

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

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

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

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

第 1 条附言  ·  1 天前

目前我能想到的解决办法就是拿线上代码反编译后作为开发分支的代码,但是反编译后的代码可读性太差了

有没有什么方案可以反编译 class 后可读性还可以的, 比如哪个工具或者框架可以实现的?
28 条回复    2021-11-19 10:17:48 +08:00

Chad0000

Chad0000   1 天前 via iPhone

一般不这样使用分支吧,我之前做的平台都是从代码角度让他们功能有所不同。通过适当的设计是可以做到的。

dqzcwxb

dqzcwxb   1 天前

一切以生产环境为准,测试环境是为生产环境服务的

wolfie

wolfie   1 天前

拉一个功能表格做管理。

公司 B 分支要用 公司 A 某个功能,手动 cherry-pick 特定几个 commit 。

fangcan

fangcan   1 天前

@dqzcwxb 是要以生产为准,但是问题就是上线太难了,做不到直接把新修改的 class 直接替换就可以。 有想过把生产的代码全量拿下来做开发分支,但是反编译后的代码又没有注释,编译后可读性也很差。

fangcan

fangcan   1 天前

@wolfie 目前我接手后的代码就是切了分支的代码,但其实是基于原来的同一份代码。 期间什么公司修改了什么功能,什么类是没有记录的。 所以最近遇到的就是 我这次开发 b 公司的需求,然后修改了 b 类。增量上线后发现少了其中引用的 c 类。

sprite82

sprite82   1 天前   ❤️ 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

bk201   1 天前

重新制定完善的分支方案,不要再接着坑走下去了。

Tink

Tink   1 天前 via Android

从生产环境拉最新分支

statement

statement   1 天前

做开关 分支不是干这个的

chenxytw

chenxytw   1 天前   ❤️ 1

建议离职换家公司,折腾这种事情完全没有意义。

sagaxu

sagaxu   1 天前 via Android   ❤️ 2

有两个大问题要整改,

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

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

有些公司会搞成不同的服务,划分出相应的平台和中台以及大前端,每个 team 各司其职。不过这不太适合规模较小的业务,jar/lib 级复用比较简单可行,虽然不如服务化那么强大,但是也不必付出服务化的成本。

TypeError

TypeError   1 天前

抽时间全 merge 到 master ,然后发布用专门的 release 分支打 tag ,没时间那就没办法了

MarioLuo

MarioLuo   1 天前 via Android   ❤️ 1

问题是生产环境上运行的包,在分支里没有有一个 commit 能完整对应起来。现在只有人肉处理了
1. 当前的分支留存一份
2. 对每个公司或者近期要迭代的找出历史 commit 打包后 class 差异最小的,无论是手工还是找差异文件的源代码补齐
3.如果差异过大或者无法找到的,保持 class 增量部署
最后处理这个问题一定要反馈给上级领导,风险和成果要让上面知道

wingoo

wingoo   1 天前

不同公司如果需求不确定, 最好是做开关, 在代码层级区分(或者统一的配置管理), 而不是分支, 特别是对于持续迭代的功能, 没法区分的

momocraft

momocraft   1 天前

为什么会有单个 class 更新这种做法的 难道这样风险更小吗

wqhui

wqhui   1 天前

最好是不同公司都用同一套代码,功能的差异通过配置来控制

jtacm

jtacm   1 天前   ❤️ 1

class 反编译的方法非常不建议。

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

PS:是停下来进行一次重构了,这是一次必须偿还的技术债。否则以后越滚越大,就更麻烦了,除非你也想跑路。

lei2j

lei2j   1 天前   ❤️ 1

怎么感觉跟我现在公司一样啊,不同的分支服务不同公司

clf

clf   1 天前   ❤️ 1

按 commit 合并?

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

比如 AB 两家公司的同一个功能是两个不同的逻辑,那么前端页面就是两个页面,路由是相同的,整套前后端代码是相同的,唯一不同的就是权限树上同个路由指向了不同页面代码文件。

libook

libook   1 天前   ❤️ 1

核心思路就是能统一的都统一版本,不能统一的彻底分开。

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

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

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

其次是,要对产品需求进行有效管理,至少每一次的需求内容都要有记录,然后梳理出每个客户的最终需求和产品设计方案,然后根据基础的代码来看缺什么、需要修改什么,最不济的方案就是根据最新需求从一个旧版本重新开发,有时候会比 hack 现有代码要更快。

SingeeKing

SingeeKing   23 小时 36 分钟前

build flag 就是解决这个的,一份代码,不同的公司用不同的 flag

gam2046

gam2046   19 小时 4 分钟前

这个屁股不好擦,有没有可能性联系各个合作方,先进行一次全量更新,统一环境后再考虑后面的事情。

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

如果依旧保持这种情况,很难解决

smallpython

smallpython   18 小时 32 分钟前

把数据导出来, 然后统一安装最新的版本, 然后再导进去

aguesuka

aguesuka   18 小时 3 分钟前

所有发布必须携带版本号, 在仓库里冻结二进制文件和源代码. 不做增量更新, 保证现场代码与源码对应

zjsxwc

zjsxwc   14 小时 12 分钟前 via Android

定期比如一周都合并到 master 分支呗,从来都不合并的分支有意义吗?

guanhui07

guanhui07   13 小时 32 分钟前

测试分支删了把 定期从 master 拉

kaneg

kaneg   12 小时 17 分钟前

说明你们公司的客户不多。
要考虑多客户的设计应该是代码保持同一份,客户的不同需求靠各自的配置来适配。

byzfbyzf   1 小时 27 分钟前

这不就是屎山 1.0 吗,比较接近线上环境的开发人员懒得跑开发版本代码,直接在生产环境代码修改了之后又要求开发分支去合并生产环境的代码。

这样搞很大概率结果就是,同一个功能有来自七八个线上版本的不同实现,然后后续开发时也不知道哪个是主要在用的,这个人依赖这个那个人依赖那个,遇到问题要改就要全改,要么就加份新的,反正也没人愿意去重构以前的,最后就变成屎山。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK