You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Django实现FinTS客户端多步骤交互的架构设计咨询

生产级FinTS Django客户端架构设计与问题解决方案

一、现有问题的针对性修复

1. 视图向BackgroundWorker发消息触发Redis类型错误

问题核心是Channels BackgroundWorker传递的消息必须是Redis可序列化的基础类型(字符串、数字、字典、列表),不能直接传递FinTS3PinTanClient这类复杂对象。

解决办法:

  • 视图层仅传递状态标识信息(如用户ID、会话ID、唯一任务ID),而非对象实例。
  • BackgroundWorker通过标识从存储介质(Redis/数据库)中读取序列化后的客户端状态,再反序列化为FinTS3PinTanClient实例。
  • 示例代码思路:
    # 视图中发送消息
    channel_layer.send("background_worker", {
        "type": "process.fints",
        "user_id": request.user.id,
        "session_key": request.session.session_key
    })
    # Worker中处理
    def process_fints(self, event):
        session_key = event["session_key"]
        serialized_state = redis_client.get(f"fints_client:{session_key}")
        client = FinTS3PinTanClient.deserialize(serialized_state)
        # 后续操作
    

2. FinTS3PinTanClient对象状态丢失

利用库的序列化能力,将状态持久化到Redis或Django数据库:

  • Redis选型:适合临时状态存储,用库自带的序列化方法把状态转成字符串,以用户会话ID/任务ID为键存储,设置30分钟左右的过期时间(覆盖TAN输入的常见超时窗口)。
  • 数据库选型:若需长期留存操作记录,新建FintsClientSession模型:
    from django.db import models
    from django.contrib.auth.models import User
    
    class FintsClientSession(models.Model):
        user = models.ForeignKey(User, on_delete=models.CASCADE)
        session_id = models.CharField(max_length=255, unique=True)
        serialized_state = models.TextField()
        created_at = models.DateTimeField(auto_now_add=True)
        expires_at = models.DateTimeField()
    
  • 操作流程:初始化客户端后立即序列化存储,Worker每次处理前读取反序列化,操作完成后重新序列化更新存储。

二、架构方案选型:混合方案优于纯WebSocket

纯WebSocket的局限性

FinTS的4步流程中,连接、请求TAN是耗时IO操作,纯WebSocket会长期占用连接资源;生产环境中WebSocket连接数有限,高并发场景下易出现资源瓶颈。

推荐生产级架构:Django表单 + Celery(替代BackgroundWorker) + WebSocket

BackgroundWorker适合轻量异步任务,生产级更推荐Celery做任务调度,整体流程如下:

  1. 凭证输入:用Django表单处理银行账号、PIN等敏感信息(HTTP POST提交,利用Django的CSRF防护、表单验证,比WebSocket更安全)。
  2. 异步初始化与TAN请求:
    • 表单提交后,生成唯一task_id,将用户凭证、task_id存入Redis,启动Celery任务。
    • Celery任务初始化FinTS3PinTanClient,完成连接并请求TAN,序列化状态到Redis,通过WebSocket向前端推送“等待TAN输入”消息(附带task_id)。
  3. TAN提交与交易获取:
    • 前端展示TAN输入框,用户输入后通过WebSocket发送task_id和TAN到后端。
    • WebSocket消费者读取Redis中的序列化状态,反序列化为客户端实例,提交TAN并获取交易数据,完成后清理或更新状态。
    • 通过WebSocket将交易结果推送给前端。

三、生产级优化要点

  • 安全防护:
    • 敏感信息传输强制HTTPS/WSS,Redis存储序列化状态时用cryptography加密,防止数据泄露。
    • task_id与用户身份绑定,校验请求合法性,避免越权。
  • 错误处理:
    • Celery任务添加重试机制(autoretry_for=(ConnectionError,)),重试次数设为2-3次。
    • 前端处理超时场景(如TAN请求超时),提供重试入口。
  • 资源清理:
    • Redis状态设置过期时间,用Celery Beat定时清理过期的FintsClientSession记录。
    • WebSocket断开后标记任务过期,终止无效处理。
  • 监控日志:
    • 对FinTS每一步操作打日志,包含task_id、用户ID、操作结果,便于排查问题。
    • 监控Celery任务成功率、Redis内存、WebSocket连接数,设置告警。

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 10:36:59