首页 > 试题广场 >

微服务架构下的深层依赖链路漏洞影响面分析

[编程题]微服务架构下的深层依赖链路漏洞影响面分析
  • 热度指数:67 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解


背景
在现代大型互联网公司的微服务架构中,服务之间的调用关系错综复杂,往往会形成庞大的调用网(有向图)。近期安全团队发现核心的“支付网关(Payment_Gateway)”服务存在一个底层安全漏洞。为了评估漏洞的影响面,我们需要查出所有直接或间接调用过该服务的下游微服务。为了排除历史废弃链路的干扰,我们仅关注在2025年内新建立的活跃依赖关系。

表结构和字段说明

  • 表名:services(微服务信息表)
    • service_id:整数类型,微服务的唯一标识ID,主键
    • service_name:字符串类型,微服务的英文名称
    • owner_team:字符串类型,微服务所属的研发团队名称
  • 表名:service_dependencies(微服务依赖关系表)
    • caller_service_id:整数类型,主调服务ID(即发起调用的服务/依赖方)
    • callee_service_id:整数类型,被调服务ID(即接收调用的服务/被依赖方)
    • first_call_date:日期类型,这两项服务首次建立调用关系并产生流量的日期

3. 问题

请编写一条 MySQL 查询语句,查询所有直接或间接依赖于服务名为'Payment_Gateway'的微服务,仅统计依赖建立日期(first_call_date)在2025年(包含2025全年)的调用关系

要求返回以下字段:

  • service_id:主调服务ID
  • service_name:主调服务名称
  • dependency_depth:依赖深度(直接调用Payment_Gateway的深度为1,间接调用依次递增)
  • dependency_path:依赖路径(格式为Payment_Gateway->中间服务名->...->主调服务名)

排序规则

结果须按依赖深度(dependency_depth)升序排列;若深度相同,则按主调服务ID(service_id)升序排列;若主调服务ID也相同(说明该服务通过多条不同路径依赖了目标服务),则按依赖路径(dependency_path)的字典序升序排列。

4. 示例数据表

services(微服务信息表)

service_id service_name owner_team
100 Payment_Gateway Core_Pay
101 Order_Service Trade_Biz
102 User_Wallet_Service Asset_Biz
103 E_Commerce_BFF Frontend_Arch
104 Analytics_Job Data_Tech
105 Legacy_Report Data_Tech

service_dependencies(微服务依赖关系表)

caller_service_id callee_service_id first_call_date
101 100 2025-01-15
102 100 2025-02-20
103 101 2025-03-10
104 102 2025-04-05
105 103 2024-12-01

5. 示例数据查询结果表

(注意:主调服务 Legacy_Report (105) 因为依赖建立日期是 2024 年,所以该分支的递归被截断,不出现在结果中)

service_id service_name dependency_depth dependency_path
101 Order_Service 1 Payment_Gateway->Order_Service
102 User_Wallet_Service 1 Payment_Gateway->User_Wallet_Service
103 E_Commerce_BFF 2 Payment_Gateway->Order_Service->E_Commerce_BFF
104 Analytics_Job 2 Payment_Gateway->User_Wallet_Service->Analytics_Job


示例1

输入

-- 创建表结构(仅保留逻辑关联,无强制外键约束)
DROP TABLE IF EXISTS service_dependencies;
DROP TABLE IF EXISTS services;

CREATE TABLE services (
    service_id INT PRIMARY KEY,
    service_name VARCHAR(100),
    owner_team VARCHAR(50)
);

CREATE TABLE service_dependencies (
    caller_service_id INT,
    callee_service_id INT,
    first_call_date DATE
);

-- 插入示例数据
INSERT INTO services (service_id, service_name, owner_team) VALUES
(100, 'Payment_Gateway', 'Core_Pay'),
(101, 'Order_Service', 'Trade_Biz'),
(102, 'User_Wallet_Service', 'Asset_Biz'),
(103, 'E_Commerce_BFF', 'Frontend_Arch'),
(104, 'Analytics_Job', 'Data_Tech'),
(105, 'Legacy_Report', 'Data_Tech');

INSERT INTO service_dependencies (caller_service_id, callee_service_id, first_call_date) VALUES
(101, 100, '2025-01-15'),  -- Order 直接调用 Payment (深度1)
(102, 100, '2025-02-20'),  -- Wallet 直接调用 Payment (深度1)
(103, 101, '2025-03-10'),  -- BFF 调用 Order (深度2)
(104, 102, '2025-04-05'),  -- Analytics 调用 Wallet (深度2)
(105, 103, '2024-12-01');  -- Legacy 调用 BFF,但在2024年,不应计入

输出

service_id|service_name|dependency_depth|dependency_path
101|Order_Service|1|Payment_Gateway->Order_Service
102|User_Wallet_Service|1|Payment_Gateway->User_Wallet_Service
103|E_Commerce_BFF|2|Payment_Gateway->Order_Service->E_Commerce_BFF
104|Analytics_Job|2|Payment_Gateway->User_Wallet_Service->Analytics_Job
# 错误代码
select caller_service_id service_id,s1.service_name,
if(s2.service_name='Payment_Gateway',1,2) dependency_depth,
if(if(s2.service_name='Payment_Gateway',1,2)=1,concat('Payment_Gateway','->',s1.service_name),concat('Payment_Gateway','->',s2.service_name,'->',s1.service_name)) dependency_path
from service_dependencies sd left join services s1 on sd.caller_service_id = s1.service_id
left join services s2 on sd.callee_service_id = s2.service_id 
where year(first_call_date)=2025
order by dependency_depth,s1.service_id,dependency_path

# 抄的大佬正确代码
with RECURSIVE temp as (
    # 1、Payment_Gateway作为被调用,找到主调服务
    select
    s2.service_id,
    s2.service_name,
    1 as dependency_depth,
    concat('Payment_Gateway->', s2.service_name) as dependency_path
    from service_dependencies sp
    join services s on sp.callee_service_id = s.service_id # 关联被调用方(Payment_Gateway
    join services s2 on sp.caller_service_id = s2.service_id # 关联主调用方(直接依赖)
    where year(first_call_date) = 2025
    and s.service_name = 'Payment_Gateway' # 被调用方是 Payment_Gateway

    union all 

    # 上层作为被调服务,找到本层的主调服务
    select 
    s2.service_id as service_id,
    s2.service_name,
    t.dependency_depth + 1,
    concat(t.dependency_path, '->', s2.service_name)
    from temp t 
    join service_dependencies sp on sp.callee_service_id = t.service_id # 上一层的主调用服务 → 本层的被调用服务
    join services s2 on sp.caller_service_id = s2.service_id # 关联本层的主调用服务
    where year(first_call_date) = 2025
)

select * from temp
order by dependency_depth,service_id,dependency_path
;

发表于 2026-03-02 15:05:57 回复(0)