任务说明 — 服务依赖与边界梳理

本文是任务工作笔记(背景/参考/方法/进展/已采集数据)。重启会话从本文接续即可

背景与目的

13-现金贷业务时序 已从业务流视角梳理了每个服务的核心接口。本任务换服务边界视角,对每个服务单独梳理:

  • 出向依赖:我依赖哪些外部服务的接口(Feign 客户端 + 外部三方)
  • 入向被依赖:哪些外部服务依赖我(= 全量出向的逆映射)
  • 边界洞察:强耦合点、枢纽服务、单点、形同虚设的死依赖

目的:对外/对内理解整个系统拓扑如何运转,便于各服务 owner 认领核对。

必读参考

  • 00-总览 — 服务名映射(仓库↔简称↔Eureka名)、两层网关、TxnType 全集、三缺口模块(agg/crs/res)
  • README梳理教训必读:标 ✓ 前读实现体;注释/TODO 即事实;call_graph 仅单 reactor 内、跨服务 Feign 追不到;blueprint 是权威源不写”被某某印证”
  • 代码源:gitlab/backend-cashloan/(12 服务,master 已 pull);依赖声明在各服务 */facility/outgoing/I*Client.java@FeignClient(name=...)

方法

  1. 逐服务枚举 outgoing 全部 Feign 客户端 → @FeignClient(name=) 得目标服务 + 接口
  2. 每条依赖标状态:活跃 / 注释 / 空壳(空接口或 extends 注释)——须读实现体确认,不能只看声明(沿用 13 的严谨度)
  3. 标外部三方依赖(bridge-service / 通道 / Smile,及 env 变量)
  4. 聚合全量出向 → 反推每服务入向被依赖(仅得仓库内的入向
  5. 被调面扫描(入向必做的独立第二步):逆映射看不到调用方在仓库外的边。逐服务枚举 service-api @RequestMapping 端点 + 事件消费端(Sink/Handler) + 回调入口(callback/notify/sync/inner),交叉出向全表,无对应出向者 = 外部/缺失方依赖的入口。入向分两类呈现:① 仓库内调用方 ② 外部/缺失方入口。
  6. 工具:code-toolset(code_search def/ref、call_graph 单 reactor 内、repo_overview/file_outline

依赖模型:三种边(关键修正 — Feign 全表只是其一)

服务依赖不止 Feign。 经验证本系统服务间依赖有三种边,依赖图必须三种全画,否则会漏掉资金主链路:

边类型机制现状典型
① 同步 RPC@FeignClient已扫(见下表)查询/校验类
② 异步事件Kafka/Stream Publisher→Consumer未配对,且是资金主链路fcs↔pmt 放款/还款、ims 绑卡、→mdut 触达
③ 非 Feign HTTPRestTemplate/OkHttp/HttpExecutor已定位未展开ims/pmt 调通道三方、fds 调 bas/大数据

⚠ Feign-only 全表恰好漏掉资金派发主链路(②)——本会话已查实:fcs→pmt 放款走 PlutusLoanApplyPublisher、还款走 BeforePaymentPlutusPublisher,均 MQ 非 Feign

② 事件 Publisher(已扫出向,待配对 topic+consumer)

  • fcsPlutusLoanApplyPublisher(放款)、BeforePaymentPlutusPublisher(还款)、PlutusDoRepayBatchChargePublisherRefundDataPublisher(退款)、PaidOffSendBigDataPublisherBeforePaymentPublisher(注释死)
  • pmtBatchDeductOutputPublisher/DoAccountRepayOutPutPublisher/DoAccountRepayToThirdPublisher/DoApRepayForBusiOutPutPublisher/DoBatchRepay*(回流/批扣一批)+ dopayment 包下约 48 个 Publisher
  • imsDoBindAccountPayPublisher/DoBindCardQueryPublisher/DoBindCardSendMonnifyPublisher/DoNoticeChannelPublisher/DoPushMdutPublisher(→触达 mdut)/DoRepaySinglePublisher

③ 非 Feign HTTP(已定位)

  • imsims-facility/util/http/HttpExecutor(调支付通道三方)
  • pmtpmt-facility/util/http/HttpExecutor(调通道 Paystack/Monnify/…)
  • fdsOkHttpClientUtils / DxaClient(→bas) / BigDataIvUserInfoRequsetTask(大数据)
  • middle-gatewayOKHttpUtil + RestTemplate

① Feign 补充

  • pmt 出向确认只有 1 个 Feign:→ plutus-ims-service(未截断)

用户决策(已定)

  • 输出:目录拆分——00-总览 + 每服务一文(12 个)+ 本 README
  • 范围:全部 12 个已拉取服务(含空壳 agg/crs,如实标空)
  • 深度:每条依赖标活跃/注释/空壳

输出结构(计划)

14-服务依赖与边界/
├── README.md           ← 本文
├── 00-总览.md           ← 全局依赖有向图(Mermaid,标活跃/注释/外部) + N×N 依赖矩阵 + 外部三方依赖表 + 图例
├── 01-bns.md           (business-system 业务编排)
├── 02-bns-gateway.md   (business-gateway 业务网关)
├── 03-fcs.md           (fund-control 账务)
├── 04-pfs.md           (product-factory 产品工厂)
├── 05-fds.md           (fraud-detection 反欺诈)
├── 06-ims.md           (cardbind-middle 绑卡中台)
├── 07-pmt.md           (payment-middle 支付中台)
├── 08-crs.md           (credit-reporting 资信,空壳)
├── 09-agg.md           (agg-vars 聚合/风控变量,空壳)
├── 10-middle-gateway.md(infrgateway 中台网关,RouteLocator/Eureka 非 Feign)
├── 11-comet.md         (dynamic-serial 序列号)
└── 12-base.md          (business-base 共享基础库)

每服务文件统一结构(「方向 × 内/外」两维对称,边类型作表内列):

  • 一句话职责
  • 出向依赖(我依赖谁)### 仓库内服务 + ### 外部三方
  • 入向被依赖(谁依赖我)### 仓库内调用方 + ### 外部 / 缺失方入口
  • 边界洞察

表列统一为:目标/调用方 · 客户端/Publisher · 接口/事件 · 边类型(Feign/事件/HTTP/路由) · 状态。

已采集原始数据(Feign 依赖边全表,已扫描)

格式:归属服务 →(Feign 客户端)→ 目标 Eureka 名。状态栏据 13 复核已知者标注,其余待逐条核。

bns(business-system)出向

客户端→ 目标状态
IFcsAdjustClient / IFcsCustomerClient / IFcsFinancialClient / IFcsLoanClient / IFcsNonfinancialClient / IFcsPlatformClient / IFcsPlutusClientfcs-service多数活跃(IFcsFinancialClient.checkLoanApply、IFcsNonfinancialClient.loanCalculate/isFirstLoan 等已验活跃)
IFdsServiceClientfds-service活跃(queryAccountIsFreeze 冻结校验)
IImsServiceClientims-service部分注释(bankBvnMatch 注释;routeRedirect 活跃)
IPfsServiceClientpfs-service活跃(queryProductByProductFeeId)
IPmtServiceClientpmt-service活跃(queryBvnByAccount 等)

fcs(fund-control)出向

客户端→ 目标状态
IBankClientbns-service待核
ICommonClient / IProductClientpfs-service活跃(IProductClient.queryOffsetConfig 销账规则)
ILokiClientfds-service待核
IPlutusClientcardbind-service(ims)空接口extends IPlutusService 注释,方法体空)
IBigdataClient / ICouponClient / IPublishClient / IRiskClientbridge-service(外部 Transsnet)唯一活跃 IPublishClient.saveEventLog;IRiskClient/ICouponClient 整文件注释、IBigdataClient 空接口(getAvailableLimit/getMarketingUrl/queryBigdataBvn/applyExclusionRule 调用全注释)
IInversionInviteClienttank-agg-invite-service(外部)邀请返现(用户定不做)

ims(cardbind-middle)出向

客户端→ 目标状态
IPmtBankServiceClient / IPmtBudpayClient / IPmtFlutterwaveClient / IPmtFlutterwaveV3Client / IPmtInnerService / IPmtInterSwitchClient / IPmtMonnifyClient / IPmtOrderClient / IPmtPayStackClient / IPmtRemitaClient / IPmtSeerbitClient / IPmtZestpayClientplutus-pmt-service(pmt)一批通道客户端(Paystack/Monnify/Flutterwave/InterSwitch/Remita/Seerbit/Zestpay/Budpay),待核活跃度
IUserInfoClient(ims-job)plutus-ims-service(自身?)待核

pmt(payment-middle)出向

客户端→ 目标状态
IImsCustClientplutus-ims-service(ims)待核(扫描在此被截断,pmt 可能还有更多 outgoing 客户端,重启后需补扫 payment-middle

fds(fraud-detection)出向

客户端→ 目标状态
IBasUserClient / IGroupUserClientbas-service待核(bas-service = 用户/鉴权服务,疑似登录认证 Afmobi,不在 12 仓库内

base(business-base)出向

客户端→ 目标状态
IIdgClientidg-service(comet)序列号,活跃

无 Feign 出向(扫描结果)

bns-gateway(仅路由)、pfs、crs(空壳)、agg(空壳)、middle-gateway(RouteLocator/Eureka 非 Feign)、comet —— 扫描未见 outgoing Feign 客户端(重启后逐一确认,尤其 pfs 是否真无下游)。

重要发现:外部/额外服务(不在 12 仓库内)

  • bridge-service(Transsnet 外部):fcs 4 个 Feign(风控/优惠券/大数据/发布),唯一活跃 IPublishClient.saveEventLog(放款/还款事件日志),其余注释或空壳;bns 不接 bridge
  • tank-agg-invite-service(外部):邀请返现
  • bas-service:fds 依赖,疑似用户/鉴权服务(登录认证)——需确认是否=Afmobi 登录认证
  • 这些是 12 服务依赖图的”外部边界节点”,应在 00-总览的依赖图中作为外部节点画出

进展

  • 用户决策确认(结构/范围/深度)
  • ① Feign 边扫描(基本全;pmt 确认仅 1 个 →ims)
  • ② 事件 Publisher 出向扫描(已列 fcs/pmt/ims)
  • ③ 非 Feign HTTP 位置扫描(已列 ims/pmt/fds/middle-gateway)
  • ② 事件边配对(publisher→consumer):fcs↔pmt 资金链闭合(fcs event/afterpayment/in 消费 pmt 回流)、pmt/ims/fcs→mdut 触达、pmt→ims 绑卡回调;bns 无事件消费端,pmt→bns / ims 通道通知消费端不在仓库
  • 三种边逐条核状态(活跃/注释/空壳,读实现体确认)
  • 确认 bas-service 身份:内部用户/组织(员工目录),非 C 端登录认证;Feign 注释停用 → DXA HTTP 替代
  • 写 00-总览(三种边依赖图 + N×N 矩阵 + 外部节点表 + 边界洞察)
  • 写 01–12 各服务文件

待办下一步(重启后从这里开始)

  1. ② 事件维度配对(核心):对每个 Publisher 找其 topic(StreamBridge/binding 配置)+ 哪个服务 @StreamListener/@KafkaListener 消费——连成事件边。重点 fcs↔pmt 资金链路、→mdut 触达
  2. ③ HTTP 维度:列 ims/pmt HttpExecutor 调的外部三方(通道清单)、fds DxaClient→bas
  3. ① 状态核:逐条确认 fcs/ims 各 Feign client 活跃/注释/空壳(沿用 13 严谨度)
  4. 确认 bas-service 身份(grep IBasUserClient/DxaClient 的 url/用途,是否 = Afmobi 登录认证)
  5. 00-总览:依赖图区分三种边(实线 Feign / 虚线事件 / 点线 HTTP),外部节点 bridge/tank-agg/bas/通道/mdut;附 N×N 矩阵
  6. 逐服务成文(01–12),每条依赖标状态,每文末写边界洞察

验收与自检方法(任务收尾时逐项过)

完成后用这些开放性检查确认”评估完整且确信”,结果记录在本节末尾的”验收记录”。

完整性 check

  • 三种边都画了?随机抽 3 个服务,确认 Feign + 事件 + HTTP 三类出向都未漏(反例:只画 Feign 会漏 fcs→pmt 资金链路)
  • 入向=出向逆映射自洽?对每个服务,其”入向被依赖”应能在别的服务”出向”里找到对应边;矩阵行列对称核对,无悬挂边
  • 外部节点齐全?bridge-service / tank-agg-invite / bas-service / 各支付通道 / mdut 触达 都作为外部节点出现
  • 12 服务无遗漏,每个都有独立文档 + 在总览图里有节点(含空壳 agg/crs,如实标)

正确性 check(沿用 13 教训)

  • 每条依赖标了状态,且状态经实现体核实(非只看声明)——抽查注释/空壳依赖(如 fcs IPlutusClient/IRiskClient)确为 ✗
  • 不靠命名猜:依赖的”活跃”判断有 call_graph/code_search 证据,不是看类名
  • 跨服务边有两端:事件边能指出 publisher 端和 consumer 端(topic 对得上)

边界洞察 check(价值)

  • 标出枢纽服务(入向最多,如 fcs/pmt)——改动影响面大
  • 标出死依赖(声明但注释/空壳,如 fcs→bridge 风控)——形同虚设、改造重点
  • 标出单点/外部强耦合(如全系统资金出口 pmt;判断/核验缺口归 res/crs/大数据,非 bridge)

对外可用性 check

  • 一个不懂代码的人能否凭 00-总览图看懂”系统由哪些服务、怎么连”?
  • 各服务 owner 能否凭自己那篇认领核对(出/入向是否符合其认知)?

交叉验证手段(可选,增信)

  • dependency_graph 工具对 bns/fcs 跑文件级依赖,与手工 Feign 边对照
  • 与 13-时序文档交叉核对:时序里出现的每条跨服务调用,应在依赖图里有对应边

验收记录(完成时填)

完成日期:2026-06-03。产出:00-总览 + 0112 十二服务文件 + 本 README。

完整性 check

  • ✓ 三种边都画了:抽查 fcs(Feign→pfs/fds/bridge + 事件→pmt/mdut)、pmt(Feign→ims + 事件→fcs/ims/mdut + HTTP→通道/大数据)、ims(Feign→pmt + 事件→pmt/mdut + HTTP→通道),三类出向均覆盖。只画 Feign 会漏 fcs↔pmt 资金链,已补。
  • ✓ 入向=出向逆映射自洽 + 被调面补扫(用户质疑后修正):逆映射只能得「12 仓库彼此」的入向,看不到调用方不在仓库内的边。故每服务入向改为两类——① 仓库内调用方(逆映射)② 外部/缺失方入口(被调面扫描:service-api 端点 + 事件消费端 + 回调入口,交叉出向全表后无对应出向者)。新挖出:支付通道/中台平台/虚拟子账户回调进 fcs/pmt/ims(IPaystackservice/IPlatFormPayService/IOutCallbackPaymentService/IInnerService,已读实现体核实活跃)、外部名单系统推送 fds、运营台调 pfs-web。并修正一条仓库内被漏边 ims→bns(HTTP BindCardResultNotify→bns /inner/bindCardCallBack,非 Feign,藏在 outgoing/bussiness/notify/)。
  • ✓ 外部节点齐全:bridge / tank-agg / bas(→DXA) / 11 家支付通道 / 大数据 / mdut 均作为外部节点出现在 00-总览图与外部节点表。
  • ✓ 12 服务无遗漏:每个独立成文且在总览图有节点;crs/agg 如实标空壳。

正确性 check

  • ✓ 每条依赖标状态且经实现体核实:fcs IRiskClient/ICouponClient(整文件注释)、IBankClient(BankBusiness:67-91 注释返空)、IFcsPlutusClient/IPlutusClient(空接口 extends 注释)、fds IBasUserClient(全文注释)均确认为 ✗。
  • ✓ 不靠命名猜:fcs IBigdataClient 经调用点核出「getAvailableLimit/getMarketingUrl 活跃、queryBigdataBvn/applyExclusionRule 注释」的 ◐ 部分态;bns IImsServiceClient 经 BankBusiness:244 核出 routeRedirect 活跃、bankBvnMatch(BvnBusiness:275) 注释。修正了子代理「IPublishClient 全活跃/IBigdataClient 全活跃」的过度声称。
  • ✓ 跨服务事件边有两端:fcs→pmt 放款(PlutusLoanApplyPublisher)、pmt→fcs 回流(DoPaySucToFundOutPublisher source.output().send 已核) → fcs event/afterpayment/in 消费;pmt→ims 绑卡回调 → ims DoBindCardQueryHandler 消费。消费机制为 Transsnet @InputSimpleEvent+@EnableBinding(XxxSink),topic 多在 Apollo(代码内仅见部分),已在总览注明。

边界洞察 check

  • ✓ 枢纽:fcs(账务+事件交汇)、pmt(资金出口)标出。
  • ✓ 死依赖清单:fcs→bns/ims 空壳、fcs→bridge 风控/优惠券、bns→ims bankBvnMatch、fds→bas、批量还款/旧放款 publisher 注释,均列入 00-总览「死依赖」。
  • ✓ 单点/外部强耦合:pmt 资金出口单点已标;判断/核验缺口归 res/crs/大数据(fcs 的 bridge 对应 Feign 多死,唯 saveEventLog 活)已标。

对外可用性 check

  • ✓ 00-总览以分组 flowchart + 三种边图例 + N×N 矩阵 + 外部节点表呈现,非技术读者可看懂「哪些服务、怎么连」。
  • ✓ 各服务单文含出向/入向/外部/洞察,owner 可据本篇认领核对。

与 13-时序交叉核对

  • 一致:13 的 fcs→pmt 事件桥(放款/还款)、bns→fcs/fds/ims/pfs/pmt Feign、bridge 外挂风控/大数据/优惠券(注释)、crs/agg 空壳,在本篇依赖图均有对应边,结论同源(采集+资金完整、判断+核验断裂)。
  • 本篇新增(13 未展开):pmt→fcs 资金回流事件、pmt 全部支付通道 HTTP 出口清单、fds→DXA 与 bas 身份定论、fcs→bridge 活/死方法级拆分。

非 Feign 外部边穷扫(用户要求 SoT 完整确信,2026-06-03 补)

  • 方法:grep 全仓库穷举外部边载体(第三方 SDK import + 各类 HTTP 客户端 OkHttp/RestTemplate/CXF/HttpURLConnection/Apache + 外部 URL 配置),命中读实现核实;再用 code-toolset code_search 交叉验证
  • 修正/新增的外部边:bns→华为云 OBS(客户上传文件,ObsClient);fds/pmt→华为云 OBS(案件附件/对账合同凭证,经 Transsnet 共享库 S3FileUtil,类名/amazonaws 为迁移前残留)——对象存储后端统一华为 OBS(早期 AWS S3 已整体迁移,「S3」命名/SDK 未清理是技术债,非两套并存);pmt→NIBSS SOAP/CXF 双向(出向 CxfClient 调 + 入向 /DXWS 被回调),原误当 OkHttp 通道;pmt→SMTP 邮件;ims/fds/pmt→飞书告警 webhook。
  • code-toolset 交叉验证结果:code_search @FeignClient 返回 38 处,4 处自动标 [comment](ICouponClient/IRiskClient/IBasUserClient/IGroupUserClient)——印证 4 条注释死依赖;并揪出遗漏 ims→pmt 实为 12 个 IPmt*Client(原列 9,漏 Budpay/Order/InnerService),已补;确认 IUserInfoClient = ims-job 自调。
  • 排除(非外部服务):com.xinye.bank=分布式批处理框架、aspose.words/deepoove.poi=本地文档生成、bns 的 Smileidentity=活体渠道参数值、base okhttp=日志工具。
  • 通用基础设施(总览统一记不逐服务):Apollo/Eureka/Redis/MySQL/ShardingSphere/XXL-Job。

遗留问题(需后端 owner 确认)

  1. pmt→bns 业务通知(DoPayToBusinessNoticeOutPublisher)、ims 通道通知(DoNoticeChannelPublisher)消费端在仓库内未定位——疑 Apollo binding 或外部业务系统。
  2. fds 黑灰名单同步入口(syncBlackGreyList)的上游调用方不在本仓库——疑外部风控/名单推送。
  3. ims IUserInfoClient(ims-job → 自身 plutus-ims-service)用途待核。
  4. 事件 topic↔binding 精确映射多在 Apollo,本篇以 publisher/consumer 双端实现体确认为准,topic 名以代码内可见者为限。