受不了本地调试微服务要推远端了,写了个 Java Agent 搞定 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
zhuzhiqiang

受不了本地调试微服务要推远端了,写了个 Java Agent 搞定

  •  
  •   zhuzhiqiang
    zhuzhiqiang18 10 天前 807 次点击

    最近被微服务本地开发折腾得够呛,吐槽一下顺便分享个解决思路。

    我们组十几个微服务,注册中心在远端 Nacos 。每次本地改了 service-a 的接口,想让 service-b 调到,只能推到预发环境。改一行代码验证一次,提交 → CI → 部署 → 验证,最快也要好几分钟。断点调试?想都别想。

    更离谱的是多人开发同一个服务时,预发环境互相覆盖,经常对着别人的代码 debug 半天。

    试过的方案:

    • 手动改 Nacos 地址指向 localhost → 忘恢复就炸,而且只能调一个服务
    • 加 Profile 区分环境 → 配置侵入,每个项目都要改
    • docker-compose 全家桶 → 机器扛不住,而且和 IDEA 断点调试不搭

    后来想到一个思路:用 Java Agent 在 LoadBalancer 层拦截,本地有的服务走本地,没有的自动穿透到远端注册中心。对业务代码零侵入,加个 JVM 参数就行,删掉参数一切恢复原样。

    折腾了一阵,写了个工具,两个 jar:

    • 一个本地注册中心( Netty 实现,带 Web 面板)
    • 一个 Java Agent ( ByteBuddy 字节码增强)

    用法就一行:

    -javaagent:local-discovery-agent-1.0.0.jar

    本地同时启动的服务自动互相发现,没启动的自动走远端,Feign / Gateway / WebClient 都支持。

    实际体验下来最爽的是:本地改完代码直接 Feign 调到,断点能打通,不用推远端了。停用某个实例也是即时生效,不受 Spring Cloud 那个 35 秒缓存的影响。

    项目开源了: https://github.com/zhuzhiqiang18/local-discovery

    技术上比较有意思的点是 ClassLoader 隔离问题Agent 类和 Spring Cloud 类在不同 ClassLoader ,ByteBuddy Advice 内联后直接引用会 ClassNotFoundException ,用了个 Bridge 模式只暴露 JDK 类型来解决。有兴趣的可以看看代码。

    有类似痛点的兄弟可以试试,也欢迎提 issue / PR 。

    4 条回复    2026-04-15 10:03:50 +08:00
    iqiuyu0821
        1
    iqiuyu0821  
       9 天前
    支持服务运行在 K8s 环境吗?
    Edward4074
        2
    Edward4074  
       9 天前 via iPhone
    我实现的方案是全链路打通的路由染色,让运维把开发环境的 k8s 和企业内网打通,请求带上和本地服务一样的 tag ,不管微服务之间怎么跳,都能路由到本地
    zhuzhiqiang
        3
    zhuzhiqiang  
    OP
       9 天前
    @Edward4074 也不错
    zhuzhiqiang
        4
    zhuzhiqiang  
    OP
       9 天前
    @iqiuyu0821 你本地启动的模块能掉通 k8s 里的服务 就可以用啊
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4801 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 48ms UTC 09:42 PVG 17:42 LAX 02:42 JFK 05:42
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86