16 KiB
16 KiB
网关域架构与跨域调用实现详解
🌐 网关域的职责与架构
网关域的核心职责
网关域 (Gateway Domain) = API网关 + 路由管理 + 协议转换
主要功能:
- 统一入口 - 所有外部请求的唯一入口点
- 路由分发 - 根据路径将请求分发到对应的域服务
- 协议转换 - HTTP ↔ gRPC 转换
- 横切关注点 - 认证、限流、监控、日志
- 服务发现 - 动态发现后端服务
网关域架构图
┌─────────────────────────────────────────────────────────────┐
│ Gateway Domain │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ Gateway Service ││
│ │ ││
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││
│ │ │ HTTP │ │ Router │ │ gRPC │ ││
│ │ │ Handlers │ │ Engine │ │ Clients │ ││
│ │ └─────────────┘ └─────────────┘ └─────────────┘ ││
│ │ ││
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││
│ │ │ Auth │ │ Rate Limit │ │ Monitor │ ││
│ │ │ Middleware │ │ Middleware │ │ Middleware │ ││
│ │ └─────────────┘ └─────────────┘ └─────────────┘ ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ User Domain │ │ Data Domain │ │ Billing Domain │
│ (User Service) │ │ (Data Service) │ │(Billing Service)│
└─────────────────┘ └─────────────────┘ └─────────────────┘
🏗️ 网关域的目录结构
domains/gateway-domain/
└── gateway-service/
├── cmd/
│ └── server/
│ └── main.go # 网关服务启动入口
│
├── api/
│ └── http/
│ └── gateway.api # 网关API定义
│
├── internal/
│ ├── application/ # 应用层
│ │ └── service/
│ │ └── gateway_orchestrator.go # 🔥 核心协调器
│ │
│ ├── domain/ # 领域层
│ │ ├── entity/
│ │ │ ├── route.go # 路由实体
│ │ │ └── service_endpoint.go # 服务端点
│ │ └── service/
│ │ ├── router_service.go # 路由服务
│ │ └── discovery_service.go # 服务发现
│ │
│ ├── infrastructure/ # 基础设施层
│ │ ├── client/ # gRPC客户端
│ │ │ ├── user_client.go
│ │ │ ├── data_client.go
│ │ │ ├── security_client.go
│ │ │ ├── billing_client.go
│ │ │ └── product_client.go
│ │ ├── discovery/ # 服务发现
│ │ │ └── etcd_discovery.go
│ │ └── config/
│ │ └── service_config.go # 服务配置
│ │
│ └── interfaces/ # 接口适配器层
│ ├── http/ # HTTP处理器
│ │ ├── data_handler.go # 数据服务API处理
│ │ ├── user_handler.go # 用户服务API处理
│ │ └── billing_handler.go # 计费服务API处理
│ ├── middleware/ # 中间件
│ │ ├── auth_middleware.go # 认证中间件
│ │ ├── rate_limit_middleware.go # 限流中间件
│ │ ├── audit_middleware.go # 审计中间件
│ │ └── cors_middleware.go # CORS中间件
│ └── router/
│ └── gateway_router.go # 路由配置
│
├── configs/
│ ├── gateway.yaml # 网关配置
│ └── routes.yaml # 路由配置
│
└── deployments/
├── Dockerfile
└── k8s/
🎯 核心实现:跨域调用 Logic 在哪里
1. 网关层的协调逻辑 (Gateway Orchestrator)
// domains/gateway-domain/gateway-service/internal/application/service/gateway_orchestrator.go
type GatewayOrchestrator struct {
// gRPC客户端 - 调用各个域服务
userClient user.UserServiceClient
dataClient data.DataServiceClient
securityClient security.SecurityServiceClient
billingClient billing.BillingServiceClient
productClient product.ProductServiceClient
auditClient audit.AuditServiceClient
// 网关自身的服务
routerService *RouterService
discoveryService *DiscoveryService
}
// 🔥 这里实现跨域调用的核心逻辑
func (g *GatewayOrchestrator) ProcessAPIRequest(ctx context.Context, req *APIRequest) (*APIResponse, error) {
// 1. 解析路由 - 确定目标域
route, err := g.routerService.ResolveRoute(req.Path)
if err != nil {
return nil, err
}
// 2. 根据不同的业务场景,实现不同的协调逻辑
switch route.Domain {
case "data":
return g.handleDataDomainRequest(ctx, req)
case "user":
return g.handleUserDomainRequest(ctx, req)
case "billing":
return g.handleBillingDomainRequest(ctx, req)
default:
return nil, errors.New("unknown domain")
}
}
// 🔥 数据域请求的协调逻辑 (你之前问的API调用流程)
func (g *GatewayOrchestrator) handleDataDomainRequest(ctx context.Context, req *APIRequest) (*APIResponse, error) {
// 注意:这里只做最基础的协调,复杂的业务逻辑在Data Domain内部
// 1. 前置验证 (网关层职责)
if err := g.validateBasicRequest(req); err != nil {
return nil, err
}
// 2. 认证检查 (网关层职责)
userInfo, err := g.authenticateUser(ctx, req.Headers.Authorization)
if err != nil {
return nil, err
}
// 3. 调用数据域服务 (核心业务逻辑在数据域内部)
dataReq := &data.ProcessAPIRequestRequest{
UserId: userInfo.UserId,
EnterpriseId: userInfo.EnterpriseId,
ApiPath: req.Path,
Parameters: req.Parameters,
ClientIp: req.ClientIP,
}
// 🚨 重点:复杂的跨域协调逻辑在数据域的DataOrchestrator中实现
dataResp, err := g.dataClient.ProcessAPIRequest(ctx, dataReq)
if err != nil {
return nil, err
}
// 4. 响应转换 (网关层职责)
return g.convertToHTTPResponse(dataResp), nil
}
// 简单的认证逻辑 (复杂认证在User Domain)
func (g *GatewayOrchestrator) authenticateUser(ctx context.Context, authHeader string) (*UserInfo, error) {
// 调用用户域进行认证
authReq := &user.AuthenticateRequest{
Token: authHeader,
}
authResp, err := g.userClient.Authenticate(ctx, authReq)
if err != nil {
return nil, err
}
return &UserInfo{
UserId: authResp.UserId,
EnterpriseId: authResp.EnterpriseId,
}, nil
}
2. 数据域的协调逻辑 (Data Orchestrator)
// domains/data-domain/data-service/internal/application/service/data_orchestrator.go
type DataOrchestrator struct {
// 数据域内部的业务服务
riskService *RiskAssessmentService // 原FLXG
creditService *CreditCheckService // 原JRZQ
companyService *CompanyInfoService // 原QYGL
queryService *DataQueryService // 原IVYZ
// 其他域的gRPC客户端
securityClient SecurityServiceClient // 安全域
userClient UserServiceClient // 用户域
productClient ProductServiceClient // 产品域
billingClient BillingServiceClient // 计费域
auditClient AuditServiceClient // 审计域
}
// 🔥 这里实现你问的那个复杂API调用流程的核心协调逻辑
func (d *DataOrchestrator) ProcessAPIRequest(ctx context.Context, req *ProcessAPIRequestRequest) (*ProcessAPIResponseResponse, error) {
// === 第一阶段:安全验证 ===
// 1. IP白名单验证 (调用安全域)
whitelistReq := &security.CheckWhitelistRequest{
EnterpriseId: req.EnterpriseId,
ClientIp: req.ClientIp,
}
if _, err := d.securityClient.CheckWhitelist(ctx, whitelistReq); err != nil {
return nil, fmt.Errorf("IP白名单验证失败: %w", err)
}
// 2. 企业ID验证 (调用用户域)
enterpriseReq := &user.ValidateEnterpriseRequest{
UserId: req.UserId,
EnterpriseId: req.EnterpriseId,
}
enterpriseResp, err := d.userClient.ValidateEnterprise(ctx, enterpriseReq)
if err != nil {
return nil, fmt.Errorf("企业验证失败: %w", err)
}
// 3. 密钥解密 (调用安全域)
decryptReq := &security.DecryptSecretRequest{
EnterpriseId: req.EnterpriseId,
EncryptedKey: enterpriseResp.EncryptedSecretKey,
}
decryptResp, err := d.securityClient.DecryptSecret(ctx, decryptReq)
if err != nil {
return nil, fmt.Errorf("密钥解密失败: %w", err)
}
// === 第二阶段:权限与产品验证 ===
// 4. 产品权限检查 (调用产品域)
productReq := &product.CheckProductAccessRequest{
UserId: req.UserId,
ApiPath: req.ApiPath,
SecretKey: decryptResp.SecretKey,
}
productResp, err := d.productClient.CheckProductAccess(ctx, productReq)
if err != nil {
return nil, fmt.Errorf("产品权限检查失败: %w", err)
}
// 5. 余额检查 (调用计费域)
balanceReq := &billing.CheckBalanceRequest{
UserId: req.UserId,
ProductCode: productResp.ProductCode,
ApiPath: req.ApiPath,
}
balanceResp, err := d.billingClient.CheckBalance(ctx, balanceReq)
if err != nil {
return nil, fmt.Errorf("余额检查失败: %w", err)
}
// === 第三阶段:业务处理 ===
// 6. 根据API路径选择对应的业务服务 (数据域内部逻辑)
var businessResult *BusinessResult
switch {
case strings.Contains(req.ApiPath, "risk-assessment"):
businessResult, err = d.riskService.ProcessRequest(ctx, req.Parameters)
case strings.Contains(req.ApiPath, "credit-check"):
businessResult, err = d.creditService.ProcessRequest(ctx, req.Parameters)
case strings.Contains(req.ApiPath, "company-info"):
businessResult, err = d.companyService.ProcessRequest(ctx, req.Parameters)
case strings.Contains(req.ApiPath, "data-query"):
businessResult, err = d.queryService.ProcessRequest(ctx, req.Parameters)
default:
return nil, errors.New("不支持的API路径")
}
if err != nil {
return nil, fmt.Errorf("业务处理失败: %w", err)
}
// === 第四阶段:计费与审计 ===
// 7. 计费扣款 (调用计费域)
chargeReq := &billing.ChargeRequest{
UserId: req.UserId,
ProductCode: productResp.ProductCode,
ApiPath: req.ApiPath,
Amount: balanceResp.RequiredAmount,
RequestId: generateRequestId(),
}
chargeResp, err := d.billingClient.Charge(ctx, chargeReq)
if err != nil {
return nil, fmt.Errorf("计费失败: %w", err)
}
// 8. 记录审计日志 (调用审计域)
auditReq := &audit.RecordAPICallRequest{
UserId: req.UserId,
EnterpriseId: req.EnterpriseId,
ApiPath: req.ApiPath,
ClientIp: req.ClientIp,
RequestId: chargeResp.TransactionId,
Result: "success",
ResponseTime: time.Since(startTime).Milliseconds(),
}
go d.auditClient.RecordAPICall(context.Background(), auditReq) // 异步记录
// 9. 返回最终结果
return &ProcessAPIResponseResponse{
Success: true,
Data: businessResult.Data,
TransactionId: chargeResp.TransactionId,
RemainingBalance: chargeResp.RemainingBalance,
}, nil
}
3. HTTP 处理器 (接口适配器层)
// domains/gateway-domain/gateway-service/internal/interfaces/http/data_handler.go
type DataHandler struct {
orchestrator *GatewayOrchestrator
}
// HTTP入口点
func (h *DataHandler) HandleDataAPI(c *gin.Context) {
// 1. HTTP请求转换
req := &APIRequest{
Path: c.Request.URL.Path,
Method: c.Request.Method,
Parameters: extractParameters(c),
Headers: extractHeaders(c),
ClientIP: c.ClientIP(),
}
// 2. 调用网关协调器
resp, err := h.orchestrator.ProcessAPIRequest(c.Request.Context(), req)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// 3. HTTP响应
c.JSON(http.StatusOK, resp)
}
🌊 完整的调用流程
1. 客户端 HTTP请求
↓
2. 网关域 (Gateway Domain)
├── HTTP Handler (接口适配器层)
├── Gateway Orchestrator (应用层)
│ ├── 基础验证
│ ├── 用户认证 → User Domain
│ └── 路由到目标域
└── 调用 Data Domain
↓
3. 数据域 (Data Domain)
└── Data Orchestrator (应用层) 🔥 核心协调逻辑
├── 安全验证 → Security Domain
├── 企业验证 → User Domain
├── 权限检查 → Product Domain
├── 余额检查 → Billing Domain
├── 业务处理 (内部服务)
├── 计费扣款 → Billing Domain
└── 审计记录 → Audit Domain
🎯 总结:Logic 实现的分层
1. 网关域的职责 (简单协调)
- HTTP 协议处理
- 路由分发
- 基础认证
- 中间件处理 (限流、CORS 等)
2. 数据域的职责 (复杂协调) 🔥
- 这里是你问的那个复杂 API 调用流程的主要实现位置
- 跨域服务协调
- 业务流程编排
- 事务一致性保证
3. 其他域的职责 (专业服务)
- 各自领域的专业逻辑
- 对外提供 gRPC 接口
关键点:网关域负责"谁来处理",数据域负责"怎么处理"!