当前位置: 首页 > 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的一…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

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 &…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...