V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
seedhk
V2EX  ›  程序员

求指教后端项目迁移方案

  •  
  •   seedhk · 85 天前 · 2113 次点击
    这是一个创建于 85 天前的主题,其中的信息可能已经有所发展或是发生改变。

    公司原有项目是使用某个国产框架的,现在这框架已经很久没维护了,论坛也没啥人更新,于是要求迁移到 springboot 上

    其实是我主动提的

    前端是若干个小程序,项目架构是小程序通过 nginx 访问后端服务,没有网关,没有中间层;

    梳理完业务和功能后,发现工作量巨大,700 多个接口。几乎所有接口都要手动改一遍。

    目前正在确定发布方案和回滚方案,我思考的方案如下:

    发布方案

    • 方案一: 渐进式发布方案
    1. 后端服务隔一定周期(比如一周),或若干个模块,完成开发和测试后,先行上线一部分接口;
    2. 新老项目同时并存,线上重新发布一个服务,端口待定,老的小程序访问老的项目,新的小程序访问新的项目;
    3. 小程序端修改这部分接口的访问域名为新项目,并发布体验版进行内部测试;
    4. 内部测试完成后上线;
    5. 优点:
      1. 上线范围可控,数量可控,能减少一次性大规模部署带来的风险;
    6. 缺点:
      1. 接口出现问题,因为小程序端修改了 URL ,无法快速回滚;
    • 方案二: 整体迁移发布方案
    1. 项目迁移完成且测试完毕后一起上线;
    2. 新服务,或通过权重配置,切换一部分流量到新项目;
    3. 新老项目同时并存,线上重新发布一个服务,端口待定,将 nginx 流量切换到新项目;
    4. 内部测试完成后上线;
    5. 优点:
      1. 接口出现大范围问题,可以快速切换回原项目;
    6. 缺点:
      1. 接口多,出现问题几率大;

    请问大佬们,有什么好的补充点以及方案吗? 谢谢!

    第 1 条附言  ·  85 天前

    容我解释一句,这次项目重构并不是我发起的。

    我在去年年底入职的时候提了一句:项目框架有点老了,且看论坛上一直都没人维护,可以考虑换成其他框架。而后很长一段时间内都没有消息;

    直到年后前段时间,领导在定今年工作计划的时候把这部分内容加进来了。

    29 条回复    2024-04-29 11:53:55 +08:00
    macaodoll
        1
    macaodoll  
       85 天前 via Android
    某国产是啥?
    seedhk
        2
    seedhk  
    OP
       85 天前
    @macaodoll nutz
    flyqie
        3
    flyqie  
       85 天前 via Android
    为啥要主动提,是没办法维护了吗
    seedhk
        4
    seedhk  
    OP
       85 天前
    @flyqie 确实不好维护,一是官方已经不管更新了,全靠爱好者和使用者推送更新,他们再 merge 。
    二是框架太老,很多东西都没有,很多东西也没法接。
    lsk569937453
        5
    lsk569937453  
       85 天前
    结论:大聪明。你完蛋了,准备提桶跑路吧。

    如果我的老大给我提个需求要换个框架重构,我都要自己跑路。你还自己提出来,这就是挖坑给自己跳。我自己碰到现实中不得不重构的原因:
    1.新来的领导换技术栈,招自己心腹来,把老员工排挤走。
    2.公司合并,老的组离职了,老代码维护不了,线上频繁出问题,需要重构。

    说下为啥不推荐超大项目重构的原因:
    1.重构期间还接新需求吗,你这 700 个接口大概率半年是搞不完的。这半年期间,你不接新需求了吗?如果一边接新需求一半重构肯定对重构进度/接新需求进度有影响(否则就需要招人来做,你和老板说我自己干不过来,那你提重构搞毛啊)。
    2.越大的项目需要的回归测试周期越长,有的代码单元测试都没有,就是黑盒。只要这 700 个接口有一个重要接口重构有问题,你就得负责背锅。
    3.腾讯的 QQ 重构的时候都会出问题,你是不是觉得你比腾讯的工程师还 6 。

    再说下重构的方案:
    1.先把当前受影响的接口重构(你生产环境跑的好好的,没有问题。重构就是自己找罪受)
    2.不重构,新需求直接上 springboot 那一套。
    frank1256
        6
    frank1256  
       85 天前
    方案 1 就行了,用同一个域名,请求头或者请求体加个参数例如 x-new:true ,nginx 之类的根据参数反向代理到不同新旧就行了
    seedhk
        7
    seedhk  
    OP
       85 天前
    @lsk569937453
    1.小公司没那么严格,没有绩效考核,半年内不接新需求问题也不大
    2.领导只是有这个想法,如果把时间节点列给他看(比如超过半年,是否要做看他意见);
    3.我只是提过建议,没说一定要做,是领导说要换框架,我才开始做技术方案;
    4.测试确实是个大问题,怎么测试还没想好;
    seedhk
        8
    seedhk  
    OP
       85 天前
    @frank1256 谢谢
    ruiyinjinqu
        9
    ruiyinjinqu  
       85 天前 via iPhone
    方案一比较靠谱,风险小,对于已经稳定的服务没必要管,毕竟又不是啥非得迁,对于不适合用老框架的接口用 springboot ,然后用微服务一套,可以用 gateway 作为中间层转发请求,可以慢慢迁移,接口有问题了切回老接口就行了,当然要是想迁移的顺利,新的一套东西要好好考虑兼容性,如果是国企,考虑好国产化合规方面,然后想说的这个完全吃力不讨好
    seedhk
        10
    seedhk  
    OP
       85 天前
    @lsk569937453 谢谢大佬提醒。补充下,这个重构不涉及业务重构,只是单纯把代码迁过去,能保证访问通,数据对得上就行了。理论上只要传参、返回值不出问题,应该没问题。
    seedhk
        11
    seedhk  
    OP
       85 天前
    @ruiyinjinqu 提这个主要是原有框架确实太恶心 之前也想过新接口走新的一套框架,老接口如果涉及业务改动再迁移。奈何领导今年想直接把框架还掉。
    thevita
        12
    thevita  
       85 天前
    看具体签约什么东西, 如果整体架构不动,仅迁移 web 层(也就是 controller ),可以搞个自动转换一步到位,再手动改改,当然,前提是 web 这层得薄,但你提到维护性有问题,所有这个假设概率不成立,框架并不能帮你解决维护问题
    seedhk
        13
    seedhk  
    OP
       85 天前
    @thevita 框架会变,但是业务逻辑和代码逻辑不动。目前正在开发一个工具,支持将原有代码分层(原有代码没有分层的概念,所有代码都写在 controller 上)。这个工具有两个目的:
    1.进行分层(controller 、service 、dao);
    2.将原有框架中的一些自定义的类(主要是一些工具类,比如 NutMap 等)进行转换
    sagaxu
        14
    sagaxu  
       85 天前 via Android
    单元测试覆盖率有没有 90%?接口测试覆盖率有没有 90%?两样都没有,人力测试的工作量是巨大的,且一定会出错。

    700 个接口了,且半年不接新需求都 OK ,换句话说基本上功能稳定不做改动了,一个养老项目而已,那换框架的意义何在?

    能多盈利还是能降低成本?在管理层看来,做成了你等于啥也没做,出问题了全怪你。

    这种高投入高风险且无收益的事情,就是领导要推进也得劝他三思啊。
    seedhk
        15
    seedhk  
    OP
       85 天前
    @sagaxu
    1.原有项目没有任何的单元测试和接口测试;
    2.项目是核心项目,半年不接新需求都 OK 指的是我个人可以半年都投在这个项目里面而不需要担心因为没接新需求导致绩效很差。其他同事会在新项目上继续开发。
    seedhk
        16
    seedhk  
    OP
       85 天前
    @sagaxu
    补充:
    3.从公司层面看,确实是如此

    我会把这些内容和领导说清楚,具体弄不弄看他的意见。
    yrj
        17
    yrj  
       85 天前
    方案一吧,还能看到点成果。方案二我怕还没等重构完,公司都黄了 :)
    amon
        18
    amon  
       85 天前   ❤️ 3
    作为一个有着丰富大重构和迁移经验(踩坑)的人,友情提示几句:

    重构的前提条件:
    1. 业务在持续增长,甚至增长迅速,原有的系统无法满足
    2. 领导层和业务方对这个事情知悉,并且是不反对的态度
    3. 你准备在这家公司长久地呆下去
    hui9000
        19
    hui9000  
       85 天前
    太天真了,刚开始都想着只迁移业务代码,迁过去后,哪哪都飘红,改完还得测。
    能不动就别动。
    hui9000
        20
    hui9000  
       85 天前
    我就没见过这种迁移能顺利的。真的。
    dlmy
        21
    dlmy  
       85 天前
    我司把一个 20 年前的 php 项目用 Java 重构了一遍,2 年过去了,换了一个又一个的负责人,现在还没完全迁移成功。

    主要原因如下:
    1 、项目代码量 30w 行,接口上千个,以前开发不太规范,也没有注释,理解起来很困难
    2 、项目存在时间久远,换了一波又一波的人,很多历史遗留问题跟业务问题没人能说得清
    3 、与其他系统存在大量的交互,跨部门协调效率差,责任边界划分不明确,每天都在扯皮
    4 、工作量巨大,每天都在无休止的加班赶进度,导致人心涣散,干好了没功劳,出问题得背锅
    timethinker
        22
    timethinker  
       85 天前
    你以为的重构,是使用新语言新框架重新写一遍已经存在的接口。但实际上这不叫重构,顶多算是用另一种语言重新翻译了一遍相同的东西。比如你提到的 700 多个接口,如果重构完毕之后还是有 700 个,那么意义何在呢?纯粹技术上的重构,不涉及业务改动真没必要。从成本收益上来考虑,如果不成正比,成功的可能性不大,当然你要为爱发电主动加班,领导何乐而不为呢?
    xuanbg
        23
    xuanbg  
       85 天前
    你看,这个时候要是微服务的话,一个个服务慢慢换就是了。当然,现在要换也可以按微服务的方法来。就是旧服务当作微服务中一个特别大的服务,然后拆解一个上一个,直到拆完再下掉这个巨石服务就好了。
    8355
        24
    8355  
       84 天前
    这种相当于全部重构,整体流程不是这样的,这种项目对公司没有产出,现有功能是正常运行的,随时可能停止。
    类似的活我干过,主要是为了性能优化,原来项目也是类似的需求,只不过原始版本太老了,性能差。
    1.先用写一个代理工具,先收集一下请求流量的多少和接口的响应速度以及请求的高低峰。
    2.了解现有项目接口的串行调用逻辑,按照业务系统操作流形成接口脑图同时制定重构计划(方便测试和定位问题)。
    3.了解老系统用了哪些中间件,比如缓存/阿波罗/队列消费之类的,这里需要做好迁移方案尽量一起动。
    4.根据因为前期有了代理工具可以收集入参出参可以进行数据对比检查和测试。
    5.上线后的调用逻辑是
    客户端请求 -> springboot 重构系统 -> 老系统
    未重构的接口走老系统返回的数据直接返回
    重构的上线前期对比自己的数据结果和老系统的结果是否一致,一致正常返回,不一致返回老系统的值并告警排查,稳定一段时间后减少老系统的请求转发(也可以等项目整体上线全部稳定以后再整体切换)。

    整体切换对中间件的依赖连贯性更好,但是会产生双倍流量负载,包括数据库和缓存需要考虑扩容
    veapon
        25
    veapon  
       84 天前
    如果真要搞,感觉方案一的缺点也可以克服啊,就是麻烦点,接口地址不变,新的接口地址通过 nginx 来代理到新项目,回滚时,把这部分配置注释掉就行。
    muyiluop
        26
    muyiluop  
       84 天前
    看标题我就猜是不是 nutz 。因为我们之前也用,好多东西得自己接
    lizy0329
        27
    lizy0329  
       84 天前
    改好就有由头辞退你了,你好生想想。上线之日就是你 fire 之时:)
    seedhk
        28
    seedhk  
    OP
       83 天前
    @yrj @veapon 我也倾向于方案一
    @amon 感谢大佬的分享,我也会把这些东西跟领导说清楚
    @hui9000 @dlmy @timethinker 就算顺利,估计时间上也要半年至少,加班是不可能加班的
    @xuanbg 别说微服务了,,,之前连日志都没记下来
    @8355 感谢大佬,我也打算写一个代理工具,收集原有项目的接口、参数、返回值,调用频率等,不过不是为了做代理,而是为了拿来做接口测试
    @muyiluop 哈哈哈哈,这框架性能上可能比 spring 好(没经过测试,体感),就是社区生态不够
    @lizy0329 哈哈哈哈,说的我有点慌
    flmn
        29
    flmn  
       83 天前
    700 多个接口的项目,这边不推荐重构呢。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1243 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 23:37 · PVG 07:37 · LAX 16:37 · JFK 19:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.