当前位置: 首页 > news >正文

Python 实现的风控系统(使用了kafka、Faust、模拟drools、redis、分布式数据库)

以下是一个使用 Python 实现的风控系统示例,涵盖以下技术组件:

  1. Kafka 消息中间件:用于实时接收支付业务系统传递的交易数据。
  2. Faust(Kafka Streams 的 Python 等价):用于流式处理 Kafka 中的消息。
  3. 规则引擎:使用 Python 实现简单的规则评估逻辑,模拟 Drools 的功能。
  4. Redis 内存数据库:用于存储风险标签,快速获取账户的风险级别。
  5. 分布式数据库:使用 SQLite 模拟,从中获取风险标签数据(当 Redis 中没有时)。

我们将构建一个简单的风控系统,流程如下:

  • 从 Kafka 中消费实时交易数据。
  • 从 Redis 获取对应的风险标签,如果没有则从分布式数据库获取并更新到 Redis。
  • 使用规则引擎对交易数据和风险标签进行评估。
  • 将评估结果返回给支付业务系统或记录下来。
  • 实时交易模块:接收交易数据 ——> 获取风险标签(Redis) ——> 调用规则引擎 ——> 评估结果返回↓                                           ↓                          ↑
    规则引擎模块:交易数据 + 风险标签 ---> 规则执行 ----> 输出评估结果(通过/拒绝)
    

     

项目结构和依赖

1. 项目结构

risk_control_demo/
├── app.py                      # 主应用程序
├── models.py                   # 数据模型定义
├── rules.py                    # 规则引擎逻辑
├── database.py                 # 数据库服务类
├── redis_service.py            # Redis 服务类
├── requirements.txt            # 项目依赖
└── producer.py                 # Kafka 生产者,发送测试数据

2. 项目依赖(requirements.txt)

faust==1.10.4
redis==4.5.5
aiokafka==0.7.2
sqlite3==0.0.1

安装依赖

pip install -r requirements.txt

详细代码

1. models.py(数据模型定义)
# models.py
from dataclasses import dataclass@dataclass
class Transaction:transaction_id: straccount_id: stramount: floattimestamp: float@dataclass
class RiskTag:account_id: strrisk_level: int  # 1-低风险, 2-中风险, 3-高风险
2. database.py(数据库服务类)
# database.py
import sqlite3
from models import RiskTagclass DatabaseService:def __init__(self):# 连接 SQLite 数据库,内存模式self.conn = sqlite3.connect(':memory:')self.initialize_database()def initialize_database(self):cursor = self.conn.cursor()# 创建风险标签表cursor.execute('''CREATE TABLE IF NOT EXISTS risk_tags (account_id TEXT PRIMARY KEY,risk_level INTEGER)''')# 插入示例数据cursor.execute('''INSERT INTO risk_tags (account_id, risk_level) VALUES ('account123', 2)''')self.conn.commit()def get_risk_tag(self, account_id):cursor = self.conn.cursor()cursor.execute('SELECT risk_level FROM risk_tags WHERE account_id = ?', (account_id,))result = cursor.fetchone()if result:return RiskTag(account_id, result[0])else:return Nonedef close(self):self.conn.close()

3. redis_service.py(Redis 服务类)

# redis_service.py
import redis
from models import RiskTagclass RedisService:def __init__(self, host='localhost', port=6379):self.redis_client = redis.Redis(host=host, port=port, decode_responses=True)def get_risk_tag(self, account_id):risk_level = self.redis_client.get(f'risk:{account_id}')if risk_level:return RiskTag(account_id, int(risk_level))return Nonedef set_risk_tag(self, risk_tag):self.redis_client.set(f'risk:{risk_tag.account_id}', risk_tag.risk_level)def close(self):self.redis_client.close()

 4. rules.py(规则引擎逻辑)

# rules.py
from models import Transaction, RiskTagclass RiskEvaluator:def evaluate(self, transaction: Transaction, risk_tag: RiskTag) -> bool:"""返回 True 表示交易存在风险,需要阻止。返回 False 表示交易安全,可以通过。"""# 高风险交易规则if transaction.amount > 10000 and risk_tag.risk_level == 3:print(f"检测到高风险交易:{transaction}")return True  # 阻止交易# 中风险交易规则if 5000 < transaction.amount <= 10000 and risk_tag.risk_level >= 2:print(f"检测到中风险交易:{transaction}")return True  # 阻止交易# 低风险交易规则print(f"交易通过:{transaction}")return False  # 允许交易

5. app.py(主应用程序)

# app.py
import faust
import asyncio
import json
from models import Transaction, RiskTag
from database.py import DatabaseService
from redis_service import RedisService
from rules import RiskEvaluator# 定义 Faust 应用
app = faust.App('risk_control_app',broker='kafka://localhost:9092',value_serializer='raw',
)# 定义 Kafka 主题
transaction_topic = app.topic('transaction_topic')# 初始化服务
redis_service = RedisService()
database_service = DatabaseService()
risk_evaluator = RiskEvaluator()@app.agent(transaction_topic)
async def process_transaction(stream):async for event in stream:try:# 解析交易数据data = json.loads(event)transaction = Transaction(transaction_id=data['transaction_id'],account_id=data['account_id'],amount=data['amount'],timestamp=data['timestamp'])# 从 Redis 获取风险标签risk_tag = redis_service.get_risk_tag(transaction.account_id)if not risk_tag:# 如果 Redis 中没有,从数据库获取并更新到 Redisrisk_tag = database_service.get_risk_tag(transaction.account_id)if risk_tag:redis_service.set_risk_tag(risk_tag)else:# 如果数据库中也没有,设定默认风险标签risk_tag = RiskTag(transaction.account_id, 1)# 使用规则引擎进行风险评估is_risky = risk_evaluator.evaluate(transaction, risk_tag)# 根据评估结果进行处理if is_risky:print(f"交易 {transaction.transaction_id} 存在风险,执行阻止操作")# TODO: 将结果返回给支付业务系统,阻止交易else:print(f"交易 {transaction.transaction_id} 安全,允许通过")# TODO: 将结果返回给支付业务系统,允许交易except Exception as e:print(f"处理交易时发生错误:{e}")if __name__ == '__main__':app.main()

注释:

  • 使用 Faust 定义 Kafka Streams 应用程序,处理 transaction_topic 中的消息。
  • process_transaction 函数中,逐条处理交易数据。
  • 从 Redis 获取风险标签,如果没有则从数据库获取并更新到 Redis。
  • 使用自定义的 RiskEvaluator 进行风险评估,根据评估结果执行相应的操作

6. producer.py(Kafka 生产者,发送测试数据)

# producer.py
from kafka import KafkaProducer
import json
import timeproducer = KafkaProducer(bootstrap_servers='localhost:9092',value_serializer=lambda v: json.dumps(v).encode('utf-8')
)# 创建示例交易数据
transaction_data = {'transaction_id': 'tx1001','account_id': 'account123','amount': 12000.0,'timestamp': time.time()
}# 发送交易数据到 Kafka
producer.send('transaction_topic', transaction_data)
producer.flush()
print(f"已发送交易数据:{transaction_data}")
producer.close()

运行示例

1. 启动必要的服务

注意事项


总结

上述示例提供了一个基本的 Python 程序框架,演示了如何将 Kafka、Faust、Redis、规则引擎和分布式数据库集成在一起,完成实时风控的基本功能。您可以根据具体的业务需求和技术环境,对程序进行扩展和优化。

扩展建议:

  • Redis:确保 Redis 服务在本地的 6379 端口运行

  • redis-server
    

    Kafka:确保 Kafka 服务在本地的 9092 端口运行,并创建主题 transaction_topic

  • # 启动 Zookeeper
    zookeeper-server-start.sh config/zookeeper.properties
    # 启动 Kafka
    kafka-server-start.sh config/server.properties
    # 创建主题
    kafka-topics.sh --create --topic transaction_topic --bootstrap-server localhost:9092
    

    2. 运行应用程序

  • 启动风控系统(app.py):

  • python app.py worker -l info
    

    运行 Kafka 生产者,发送交易数据(producer.py):

  • python producer.py
    

    3. 预期输出

    风控系统将处理交易数据,使用规则引擎进行评估,并根据规则打印评估结果。例如:

  • 检测到高风险交易:Transaction(transaction_id='tx1001', account_id='account123', amount=12000.0, timestamp=...)
    交易 tx1001 存在风险,执行阻止操作
    

    说明

  • Faust:Python 的流式处理库,类似于 Kafka Streams,用于处理 Kafka 中的消息流。
  • 规则引擎:使用 Python 自定义规则评估逻辑,模拟 Drools 的功能。
  • Redis:作为缓存,存储风险标签,快速获取账户的风险级别。
  • 分布式数据库(SQLite 模拟):当 Redis 中没有风险标签时,从数据库获取,并更新到 Redis。
  • 风险标签:简单地使用风险级别(1-低风险,2-中风险,3-高风险)来表示。
  • 异常处理:在实际应用中,需要更完善的异常处理机制,防止因异常导致程序崩溃。
  • 引入异步 Redis 客户端:使用 aioredis 提升 Redis 操作的性能。
  • 使用真正的分布式数据库:替换 SQLite,使用例如 PostgreSQL、MySQL 等数据库,并配置集群模式。
  • 完善规则引擎:使用现有的 Python 规则引擎库(如 durable_rulesexperta)实现更复杂的规则逻辑。
  • 添加日志和监控:集成日志系统和监控工具,便于维护和故障排查。
    • 性能优化:对于高并发场景,需要考虑异步 I/O、连接池等技术优化性能。
    • 配置管理:将硬编码的配置(如主机地址、端口、主题名)提取到配置文件或环境变量中,便于管理和修改。
    • 安全性:在生产环境中,注意保护敏感信息,确保数据传输和存储的安全。

相关文章:

Python 实现的风控系统(使用了kafka、Faust、模拟drools、redis、分布式数据库)

以下是一个使用 Python 实现的风控系统示例&#xff0c;涵盖以下技术组件&#xff1a; Kafka 消息中间件&#xff1a;用于实时接收支付业务系统传递的交易数据。Faust&#xff08;Kafka Streams 的 Python 等价&#xff09;&#xff1a;用于流式处理 Kafka 中的消息。规则引擎…...

Linux运维_Rocky8 安装配置Zabbix

Zabbix 是一个开源的监控解决方案&#xff0c;用于监控网络、服务器、应用程序和服务的性能。它提供实时监控、数据收集、告警通知以及图形化界面&#xff0c;方便用户查看和分析监控数据。Zabbix 支持多种数据收集方式&#xff0c;包括 SNMP、IPMI、JMX 和自定义脚本&#xff…...

jQuery Mobile 滚屏事件

jQuery Mobile 滚屏事件 在移动开发中,滚屏事件是一个非常重要的交互方式,它可以让用户通过滚动屏幕来浏览内容。jQuery Mobile 是一个流行的移动框架,它提供了一套丰富的组件和事件,使得在移动设备上实现滚屏效果变得简单。本文将详细介绍 jQuery Mobile 中的滚屏事件,包…...

3.1.1ReactOS系统中搜索给定长度的空间地址区间函数的实现

系列文章目录 //搜索给定长度的空间地址区间 MmFindGap&#xff08;&#xff09;&#xff1b; PMADDRESS_SPACE AddressSpace,//该进程用户空间 ULONG_PTR Length,//寻找的空间间隔大小 ULONG_PTR Granularity,//粒度位&#xff0c;表明空间起点的对齐要求&#xff0c;注意是起…...

arm64系统不支持32位的解决armel armhf

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

【毕业设计】工具大礼包之『Maven3.6.3安装与配置』

系统版本 电脑系统&#xff1a;Windows 10 一.Maven下载 &#x1f3af; 统一版本 apache-maven-3.6.3&#xff0c;下面两种下载方式2选1即可 1.官网直下 官网下载地址 https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/ 找到apache-maven-3.6.3-bin.zip 云盘…...

gin入门教程(9):路由分组与路由版本控制

在使用 Gin 框架构建 RESTful API 时,路由分组与版本控制是一种常见的实践,可以帮助你更好地管理不同版本的 API。下面是如何在 Gin 中实现路由分组和版本控制的示例。 目录结构 /hello-gin │ ├── cmd/ │ └── main.go ├── api/ │ ├── v1/ │ │ └─…...

rt-thread移植SystemView中遇到的问题

源代码地址dujunqiu/SystemView 我使用的rt-thread版本是5.2.0&#xff0c;应该是rt-thread适配的还有点问题 报错处理 1&#xff1a;warning: #223-D: function “typeof” declared implicitly 如下 typedef 的warning是C99规范没有typedef的定义&#xff0c;需要在keii中…...

【C++STL】list的模拟实现

✨ Blog’s 主页: 白乐天_ξ( ✿&#xff1e;◡❛) &#x1f308; 个人Motto&#xff1a;他强任他强&#xff0c;清风拂山冈&#xff01; &#x1f525; 所属专栏&#xff1a;C深入学习笔记 &#x1f4ab; 欢迎来到我的学习笔记&#xff01; 一、三个类与成员函数接口 在list.…...

以30个面试问题和案例为导向:全面解析 Java Servlet是什么?基本概念、实现原理、生命周期、类结构、请求与响应的处理机制,以及性能优化和安全性管理

Servlet 是 Java Web 开发的核心组件之一&#xff0c;负责处理客户端请求并生成动态响应。本文将深入探讨 Servlet 的基本概念、实现原理、生命周期、类结构、请求与响应的处理机制&#xff0c;以及性能优化和安全性管理&#xff0c;帮助开发者从多方面掌握 Servlet。 文章目录…...

MFC小游戏设计

框架&#xff1a; 各个界面&#xff1a; 用户&#xff1a; 登录注册&#xff1a;账号和密码&#xff08;昵称&#xff09; 主菜单&#xff1a;各种游戏&#xff0c;查看自己信息&#xff08;积分&#xff0c;装备【游戏数据】&#xff09;&#xff0c;退出 游戏界面&#…...

[漏洞挖掘与防护] 04.Windows系统安全缺陷之5次Shift漏洞启动计算机机理分析

这是作者新开的一个专栏——“漏洞挖掘与防护”,前期会复现各种经典和最新漏洞,并总结防护技巧;后期尝试从零学习漏洞挖掘技术,包括Web漏洞和二进制及IOT相关漏洞,以及Fuzzing技术。新的征程,新的开启,漫漫长征路,偏向虎山行。享受过程,感谢您的陪伴,一起加油~ 欢迎关…...

​手机极简待办app哪款好用?

在快节奏的现代生活中&#xff0c;我们常常需要处理大量的任务和信息&#xff0c;这时候一款好用的极简待办软件就显得尤为重要。它们不仅能帮助我们记录和管理待办事项&#xff0c;还能提高我们的工作效率和生活质量。 在众多的待办软件中&#xff0c;敬业签是一款非常受欢迎…...

SpringBoot高级-底层原理

目录 1 SpringBoot自动化配置原理 01-SpringBoot2高级-starter依赖管理机制 02-SpringBoot2高级-自动化配置初体验 03-SpringBoot2高级-底层原理-Configuration配置注解 04-SpringBoot2高级-底层原理-Import注解使用1 05-SpringBoot2高级-底层原理-Import注解使用2 06-S…...

LabVIEW提高开发效率技巧----插入式架构

随着LabVIEW项目规模的扩大和系统复杂性的增加&#xff0c;传统的单一代码架构难以应对后期维护和功能扩展的需求。插入式架构&#xff08;Plug-In Architecture&#xff09;作为一种模块化设计方式&#xff0c;通过动态加载和运行子VI&#xff0c;使系统功能更加灵活、模块化&…...

MySQL COUNT(*)、COUNT(1)、COUNT(id)、COUNT(字段)效果及性能

文章目录 前言COUNT(exper)COUNT(*)优化COUNT(*) 与COUNT(1) COUNT(1)COUNT(id)COUNT(字段)总结参考 前言 业务开发中&#xff0c;我们经常要使用count做一些数据统计。今天根据MySQL5.7官方文档及丁奇老师的MySQL45讲&#xff0c;介绍一下COUNT(*)、COUNT(1)、COUNT(id)、COU…...

webpack4 - 动态导入文件 dynamic-import 报错的解决方法

介绍 webpack4动态导入文件报错&#xff0c;按照错误提示安装了插件&#xff0c;但未果。。 最后查到一个可行方案&#xff0c;记录如下。 1.通过懒加载的方式动态引入文件 const router new Router({routes: [{path: /home,name: Home,component: () >import(./views/h…...

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (四):状态码的使用

本项目旨在学习如何快速使用 nodejs 开发后端api&#xff0c;并为以后开展其他项目的开启提供简易的后端模版。&#xff08;非后端工程师&#xff09; 由于文档是代码写完之后&#xff0c;为了记录项目中需要注意的技术点&#xff0c;因此文档的叙述方式并非开发顺序&#xff0…...

springboot061基于B2B平台的医疗病历交互系统(论文+源码)_kaic

摘 要 进入21世纪&#xff0c;计算机技术迅速向着网络化的、集成化方向发展。传统的单机版应用软件正在逐渐退出舞台&#xff0c;取而代之的是支持网络、支持多种数据信息的新一代网络版应用软件&#xff0c;形成了信息化的社会。信息化社会的形成和微电子技术日新月异的发展&…...

基于FFT + CNN -Transformer时域、频域特征融合的电能质量扰动识别模型

往期精彩内容&#xff1a; Python-电能质量扰动信号数据介绍与分类-CSDN博客 Python电能质量扰动信号分类(一)基于LSTM模型的一维信号分类-CSDN博客 Python电能质量扰动信号分类(二)基于CNN模型的一维信号分类-CSDN博客 Python电能质量扰动信号分类(三)基于Transformer的一…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...