demo
This commit is contained in:
commit
cb6fa04ca7
|
@ -0,0 +1,52 @@
|
|||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
|
||||
# Intellij
|
||||
*.ipr
|
||||
*.iml
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# Maven
|
||||
target/
|
||||
|
||||
# Gradle
|
||||
build
|
||||
.gradle
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# out
|
||||
**/out/
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar
|
||||
*.tar.gz
|
||||
*.rar
|
||||
*.pid
|
||||
*.orig
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
# Mac
|
||||
.DS_Store
|
||||
|
||||
*.tmp
|
|
@ -0,0 +1,40 @@
|
|||
from recommendation_service.kafka.book_event_consumer import BookEventConsumer
|
||||
import signal
|
||||
import sys
|
||||
import logging
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
logger.info('接收到终止信号,正在关闭消费者...')
|
||||
consumer.close()
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("启动图书推荐服务...")
|
||||
|
||||
# 注册信号处理器
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
|
||||
# 创建并启动消费者
|
||||
logger.info("初始化Kafka消费者...")
|
||||
consumer = BookEventConsumer(
|
||||
bootstrap_servers=['localhost:9092']
|
||||
)
|
||||
|
||||
try:
|
||||
logger.info("开始监听图书事件...")
|
||||
consumer.start_consuming()
|
||||
except KeyboardInterrupt:
|
||||
logger.info('接收到中断信号,正在关闭...')
|
||||
consumer.close()
|
||||
except Exception as e:
|
||||
logger.error(f"服务运行出错: {str(e)}")
|
||||
consumer.close()
|
||||
sys.exit(1)
|
|
@ -0,0 +1,229 @@
|
|||
import pandas as pd
|
||||
import numpy as np
|
||||
from sklearn.feature_extraction.text import TfidfVectorizer
|
||||
from sklearn.metrics.pairwise import cosine_similarity
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class PreferenceAnalyzer:
|
||||
def __init__(self):
|
||||
self.vectorizer = TfidfVectorizer()
|
||||
# 定义类别之间的相关性矩阵
|
||||
self.category_similarity = {
|
||||
'科幻': {'科技': 0.6, '文学': 0.3},
|
||||
'科技': {'科幻': 0.6, '教育': 0.4},
|
||||
'文学': {'历史': 0.4, '哲学': 0.5},
|
||||
'历史': {'哲学': 0.4, '文学': 0.4},
|
||||
'哲学': {'文学': 0.5, '历史': 0.4},
|
||||
'经济': {'教育': 0.3, '科技': 0.3},
|
||||
'教育': {'科技': 0.4, '经济': 0.3}
|
||||
}
|
||||
|
||||
def analyze_reading_pattern(self, user_history):
|
||||
"""分析用户阅读模式"""
|
||||
if not user_history:
|
||||
return {}
|
||||
|
||||
df = pd.DataFrame(user_history)
|
||||
|
||||
patterns = {
|
||||
'偏好时段': self._analyze_reading_time(df),
|
||||
'分类权重': self._calculate_category_weights(df),
|
||||
'阅读完成度': self._analyze_completion_rate(df),
|
||||
'阅读趋势': self._analyze_reading_trends(df),
|
||||
'推荐类别': self._get_recommended_categories(df)
|
||||
}
|
||||
return patterns
|
||||
|
||||
def _analyze_reading_time(self, df):
|
||||
"""分析用户的阅读时间模式"""
|
||||
try:
|
||||
# 将时间戳转换为datetime对象
|
||||
df['timestamp'] = pd.to_datetime(df['timestamp'])
|
||||
|
||||
# 提取小时
|
||||
df['hour'] = df['timestamp'].dt.hour
|
||||
|
||||
# 统计每个小时段的阅读次数
|
||||
hourly_counts = df['hour'].value_counts().to_dict()
|
||||
|
||||
# 将小时分成时段
|
||||
time_periods = {
|
||||
'早晨 (6-9)': [6, 7, 8, 9],
|
||||
'上午 (9-12)': [9, 10, 11, 12],
|
||||
'下午 (12-18)': [12, 13, 14, 15, 16, 17, 18],
|
||||
'晚上 (18-23)': [18, 19, 20, 21, 22, 23],
|
||||
'深夜 (23-6)': [23, 0, 1, 2, 3, 4, 5]
|
||||
}
|
||||
|
||||
period_counts = defaultdict(int)
|
||||
for hour, count in hourly_counts.items():
|
||||
for period, hours in time_periods.items():
|
||||
if hour in hours:
|
||||
period_counts[period] += count
|
||||
|
||||
# 找出最常阅读的时段
|
||||
if period_counts:
|
||||
preferred_period = max(period_counts.items(), key=lambda x: x[1])[0]
|
||||
else:
|
||||
preferred_period = "未知"
|
||||
|
||||
return {
|
||||
'最佳阅读时段': preferred_period,
|
||||
'时段分布': dict(period_counts)
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
return {'错误': f'分析阅读时间时出错: {str(e)}'}
|
||||
|
||||
def _calculate_category_weights(self, df):
|
||||
"""计算各类别权重"""
|
||||
try:
|
||||
category_counts = df['category'].value_counts()
|
||||
total_reads = len(df)
|
||||
return {cat: count / total_reads for cat, count in category_counts.items()}
|
||||
except Exception as e:
|
||||
return {'错误': f'计算类别权重时出错: {str(e)}'}
|
||||
|
||||
def _analyze_completion_rate(self, df):
|
||||
"""分析完成率"""
|
||||
try:
|
||||
if 'progress' in df.columns:
|
||||
avg_progress = df['progress'].mean()
|
||||
completion_stats = {
|
||||
'平均进度': round(avg_progress, 2),
|
||||
'已完成书籍': len(df[df['progress'] >= 95]),
|
||||
'总书籍数': len(df),
|
||||
'完成率': round(len(df[df['progress'] >= 95]) / len(df) * 100, 2)
|
||||
}
|
||||
return completion_stats
|
||||
return {'错误': '没有进度数据'}
|
||||
except Exception as e:
|
||||
return {'错误': f'分析完成率时出错: {str(e)}'}
|
||||
|
||||
def get_reading_speed(self, df):
|
||||
"""计算阅读速度"""
|
||||
try:
|
||||
if 'duration' in df.columns:
|
||||
avg_duration = df['duration'].mean()
|
||||
return {
|
||||
'平均阅读时长': round(avg_duration, 2),
|
||||
'总阅读时间': df['duration'].sum()
|
||||
}
|
||||
return {'错误': '没有时长数据'}
|
||||
except Exception as e:
|
||||
return {'错误': f'计算阅读速度时出错: {str(e)}'}
|
||||
|
||||
def _analyze_reading_trends(self, df):
|
||||
"""分析阅读趋势"""
|
||||
try:
|
||||
df['timestamp'] = pd.to_datetime(df['timestamp'])
|
||||
df = df.sort_values('timestamp')
|
||||
|
||||
# 计算每天的阅读时长
|
||||
daily_reading = df.groupby(df['timestamp'].dt.date)['duration'].sum()
|
||||
|
||||
# 计算趋势
|
||||
if len(daily_reading) > 1:
|
||||
trend = np.polyfit(range(len(daily_reading)), daily_reading.values, 1)[0]
|
||||
trend_direction = '上升' if trend > 0 else '下降' if trend < 0 else '稳定'
|
||||
else:
|
||||
trend_direction = '数据不足'
|
||||
|
||||
return {
|
||||
'阅读趋势': trend_direction,
|
||||
'日均阅读时长': round(daily_reading.mean(), 2),
|
||||
'最长阅读时长': round(daily_reading.max(), 2)
|
||||
}
|
||||
except Exception as e:
|
||||
return {'错误': f'分析阅读趋势时出错: {str(e)}'}
|
||||
|
||||
def _get_recommended_categories(self, df):
|
||||
"""基于当前阅读偏好推荐类别"""
|
||||
try:
|
||||
# 获取当前阅读类别的权重
|
||||
current_weights = df['category'].value_counts(normalize=True).to_dict()
|
||||
|
||||
# 计算推荐权重
|
||||
recommended_weights = defaultdict(float)
|
||||
for category, weight in current_weights.items():
|
||||
# 考虑当前类别的相关类别
|
||||
if category in self.category_similarity:
|
||||
for related_cat, similarity in self.category_similarity[category].items():
|
||||
recommended_weights[related_cat] += weight * similarity
|
||||
|
||||
# 排除已经经常阅读的类别
|
||||
for category in current_weights:
|
||||
if category in recommended_weights:
|
||||
recommended_weights[category] *= 0.5
|
||||
|
||||
# 获取top3推荐类别
|
||||
top_recommendations = sorted(
|
||||
recommended_weights.items(),
|
||||
key=lambda x: x[1],
|
||||
reverse=True
|
||||
)[:3]
|
||||
|
||||
return {
|
||||
'推荐类别': [cat for cat, _ in top_recommendations],
|
||||
'推荐理由': self._generate_recommendation_reasons(top_recommendations, current_weights)
|
||||
}
|
||||
except Exception as e:
|
||||
return {'错误': f'生成类别推荐时出错: {str(e)}'}
|
||||
|
||||
def _generate_recommendation_reasons(self, recommendations, current_weights):
|
||||
"""生成推荐理由"""
|
||||
reasons = {}
|
||||
for category, score in recommendations:
|
||||
if score > 0:
|
||||
# 找出与该类别最相关的当前阅读类别
|
||||
related_categories = []
|
||||
for curr_cat in current_weights:
|
||||
if curr_cat in self.category_similarity and \
|
||||
category in self.category_similarity[curr_cat]:
|
||||
related_categories.append(curr_cat)
|
||||
|
||||
if related_categories:
|
||||
reasons[category] = f"基于您对{','.join(related_categories)}的兴趣推荐"
|
||||
else:
|
||||
reasons[category] = "扩展阅读领域"
|
||||
|
||||
return reasons
|
||||
|
||||
def calculate_user_similarity(self, user1_history, user2_history):
|
||||
"""计算用户相似度"""
|
||||
try:
|
||||
if not user1_history or not user2_history:
|
||||
return {
|
||||
'相似度': 0.0,
|
||||
'共同兴趣': []
|
||||
}
|
||||
|
||||
df1 = pd.DataFrame(user1_history)
|
||||
df2 = pd.DataFrame(user2_history)
|
||||
|
||||
# 计算类别偏好相似度
|
||||
cat_weights1 = df1['category'].value_counts(normalize=True)
|
||||
cat_weights2 = df2['category'].value_counts(normalize=True)
|
||||
|
||||
# 使用余弦相似度计算
|
||||
categories = set(cat_weights1.index) | set(cat_weights2.index)
|
||||
vec1 = [cat_weights1.get(cat, 0) for cat in categories]
|
||||
vec2 = [cat_weights2.get(cat, 0) for cat in categories]
|
||||
|
||||
similarity = cosine_similarity([vec1], [vec2])[0][0]
|
||||
|
||||
# 计算共同兴趣
|
||||
common_interests = list(set(cat_weights1.index) & set(cat_weights2.index))
|
||||
|
||||
return {
|
||||
'相似度': round(similarity, 2),
|
||||
'共同兴趣': common_interests
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'错误': f'计算用户相似度时出错: {str(e)}',
|
||||
'相似度': 0.0,
|
||||
'共同兴趣': []
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
from kafka import KafkaConsumer
|
||||
import json
|
||||
import logging
|
||||
from ..models.user_profile import UserProfile
|
||||
from ..analyzer.preference_analyzer import PreferenceAnalyzer
|
||||
|
||||
# 配置日志
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class BookEventConsumer:
|
||||
def __init__(self, bootstrap_servers=['localhost:9092']):
|
||||
"""初始化Kafka消费者"""
|
||||
self.consumer = KafkaConsumer(
|
||||
'book-events', # topic名称
|
||||
bootstrap_servers=bootstrap_servers,
|
||||
group_id='python-recommendation-group',
|
||||
auto_offset_reset='earliest',
|
||||
enable_auto_commit=True,
|
||||
value_deserializer=lambda x: json.loads(x.decode('utf-8'))
|
||||
)
|
||||
self.user_profiles = {}
|
||||
self.analyzer = PreferenceAnalyzer()
|
||||
|
||||
def _handle_read_event(self, user_id, event):
|
||||
"""处理阅读事件"""
|
||||
reading_record = {
|
||||
'book_id': event['bookId'],
|
||||
'duration': event['readDuration'],
|
||||
'progress': event['progress'],
|
||||
'category': event['bookInfo']['category'],
|
||||
'author': event['bookInfo']['author'],
|
||||
'timestamp': event['timestamp']
|
||||
}
|
||||
self.user_profiles[user_id].update_reading_history(reading_record)
|
||||
self.user_profiles[user_id].update_preferences(reading_record)
|
||||
logger.info(f"用户 {user_id} 的阅读记录已更新")
|
||||
|
||||
# 分析用户阅读模式
|
||||
self._analyze_user_patterns(user_id)
|
||||
|
||||
def _analyze_user_patterns(self, user_id):
|
||||
"""分析用户模式并输出结果"""
|
||||
try:
|
||||
# 获取用户的阅读模式分析
|
||||
patterns = self.analyzer.analyze_reading_pattern(
|
||||
self.user_profiles[user_id].reading_history
|
||||
)
|
||||
logger.info(f"\n用户 {user_id} 的阅读分析报告:")
|
||||
logger.info("=" * 50)
|
||||
|
||||
# 输出时间偏好
|
||||
if '偏好时段' in patterns:
|
||||
logger.info(f"时间偏好: {patterns['偏好时段']['最佳阅读时段']}")
|
||||
logger.info(f"时段分布: {patterns['偏好时段']['时段分布']}")
|
||||
|
||||
# 输出分类偏好
|
||||
if '分类权重' in patterns:
|
||||
logger.info("\n分类偏好:")
|
||||
for category, weight in patterns['分类权重'].items():
|
||||
logger.info(f"- {category}: {weight:.2%}")
|
||||
|
||||
# 输出阅读完成度
|
||||
if '阅读完成度' in patterns:
|
||||
logger.info("\n阅读完成情况:")
|
||||
for key, value in patterns['阅读完成度'].items():
|
||||
logger.info(f"- {key}: {value}")
|
||||
|
||||
# 输出阅读趋势
|
||||
if '阅读趋势' in patterns:
|
||||
logger.info("\n阅读趋势分析:")
|
||||
for key, value in patterns['阅读趋势'].items():
|
||||
logger.info(f"- {key}: {value}")
|
||||
|
||||
# 输出推荐类别
|
||||
if '推荐类别' in patterns:
|
||||
logger.info("\n推荐类别:")
|
||||
logger.info(f"推荐类别: {patterns['推荐类别']['推荐类别']}")
|
||||
logger.info("推荐理由:")
|
||||
for category, reason in patterns['推荐类别']['推荐理由'].items():
|
||||
logger.info(f"- {category}: {reason}")
|
||||
|
||||
# 分析用户相似度
|
||||
self._analyze_user_similarities(user_id)
|
||||
|
||||
logger.info("=" * 50)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"分析用户模式时出错: {str(e)}")
|
||||
|
||||
def _analyze_user_similarities(self, current_user_id):
|
||||
"""分析用户间的相似度"""
|
||||
try:
|
||||
if len(self.user_profiles) > 1:
|
||||
logger.info("\n用户相似度分析:")
|
||||
for other_user_id, other_profile in self.user_profiles.items():
|
||||
if other_user_id != current_user_id:
|
||||
similarity = self.analyzer.calculate_user_similarity(
|
||||
self.user_profiles[current_user_id].reading_history,
|
||||
other_profile.reading_history
|
||||
)
|
||||
logger.info(f"\n与用户 {other_user_id} 的相似度:")
|
||||
logger.info(f"- 相似度指数: {similarity['相似度']:.2%}")
|
||||
logger.info(f"- 共同兴趣: {', '.join(similarity['共同兴趣']) if similarity['共同兴趣'] else '暂无'}")
|
||||
except Exception as e:
|
||||
logger.error(f"分析用户相似度时出错: {str(e)}")
|
||||
|
||||
def _handle_rate_event(self, user_id, event):
|
||||
"""处理评分事件"""
|
||||
self.user_profiles[user_id].update_book_rating(
|
||||
event['bookId'],
|
||||
event['rating']
|
||||
)
|
||||
logger.info(f"用户 {user_id} 的评分记录已更新")
|
||||
|
||||
def _handle_bookmark_event(self, user_id, event):
|
||||
"""处理收藏事件"""
|
||||
self.user_profiles[user_id].add_bookmark(event['bookId'])
|
||||
logger.info(f"用户 {user_id} 的收藏记录已更新")
|
||||
|
||||
def process_message(self, message):
|
||||
"""处理接收到的消息"""
|
||||
try:
|
||||
event = message.value
|
||||
logger.info(f"收到事件: {event}")
|
||||
|
||||
# 获取用户画像,如果不存在则创建
|
||||
user_id = event['userId']
|
||||
if user_id not in self.user_profiles:
|
||||
self.user_profiles[user_id] = UserProfile()
|
||||
|
||||
# 根据事件类型处理
|
||||
event_type = event['eventType']
|
||||
if event_type == 'READ':
|
||||
self._handle_read_event(user_id, event)
|
||||
elif event_type == 'RATE':
|
||||
self._handle_rate_event(user_id, event)
|
||||
elif event_type == 'BOOKMARK':
|
||||
self._handle_bookmark_event(user_id, event)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"处理消息时发生错误: {str(e)}")
|
||||
|
||||
def start_consuming(self):
|
||||
"""开始消费消息"""
|
||||
logger.info("开始消费Kafka消息...")
|
||||
try:
|
||||
for message in self.consumer:
|
||||
self.process_message(message)
|
||||
except Exception as e:
|
||||
logger.error(f"消费消息时发生错误: {str(e)}")
|
||||
|
||||
def close(self):
|
||||
"""关闭消费者"""
|
||||
self.consumer.close()
|
||||
logger.info("消费者已关闭")
|
|
@ -0,0 +1,28 @@
|
|||
class UserProfile:
|
||||
def __init__(self):
|
||||
self.reading_history = []
|
||||
self.category_preferences = {}
|
||||
self.reading_time_pattern = {}
|
||||
self.favorite_authors = set()
|
||||
self.book_ratings = {}
|
||||
self.bookmarks = set()
|
||||
|
||||
def update_book_rating(self, book_id, rating):
|
||||
"""更新书籍评分"""
|
||||
self.book_ratings[book_id] = rating
|
||||
|
||||
def add_bookmark(self, book_id):
|
||||
"""添加书签"""
|
||||
self.bookmarks.add(book_id)
|
||||
|
||||
def update_reading_history(self, reading_record):
|
||||
"""更新阅读历史"""
|
||||
self.reading_history.append(reading_record)
|
||||
|
||||
def update_preferences(self, reading_record):
|
||||
"""更新用户阅读偏好"""
|
||||
category = reading_record['category']
|
||||
self.category_preferences[category] = \
|
||||
self.category_preferences.get(category, 0) + 1
|
||||
|
||||
self.favorite_authors.add(reading_record['author'])
|
|
@ -0,0 +1,79 @@
|
|||
import random
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
class TestDataGenerator:
|
||||
def __init__(self):
|
||||
self.categories = ['科幻', '文学', '历史', '科技', '哲学', '经济', '教育']
|
||||
self.authors = ['刘慈欣', '余华', '东野圭吾', '村上春树', '张三', '李四', '王五']
|
||||
self.event_types = ['READ', 'RATE', 'BOOKMARK']
|
||||
|
||||
def generate_book(self):
|
||||
"""生成一本书的基本信息"""
|
||||
return {
|
||||
'bookId': str(random.randint(1000, 9999)),
|
||||
'title': f'测试书籍_{random.randint(1, 100)}',
|
||||
'author': random.choice(self.authors),
|
||||
'category': random.choice(self.categories),
|
||||
'pageCount': random.randint(100, 500)
|
||||
}
|
||||
|
||||
def generate_random_time(self):
|
||||
"""生成随机时间"""
|
||||
# 随机生成过去30天内的某一天
|
||||
days_ago = random.randint(0, 30)
|
||||
base_date = datetime.now() - timedelta(days=days_ago)
|
||||
|
||||
# 随机生成一天中的时间
|
||||
hour = random.randint(0, 23)
|
||||
minute = random.randint(0, 59)
|
||||
second = random.randint(0, 59)
|
||||
|
||||
# 组合日期和时间
|
||||
random_time = base_date.replace(
|
||||
hour=hour,
|
||||
minute=minute,
|
||||
second=second
|
||||
)
|
||||
|
||||
return random_time
|
||||
|
||||
def generate_event(self, user_id=None):
|
||||
"""生成一个随机事件"""
|
||||
if user_id is None:
|
||||
user_id = str(random.randint(1, 3))
|
||||
|
||||
event_type = random.choice(self.event_types)
|
||||
book = self.generate_book()
|
||||
timestamp = self.generate_random_time()
|
||||
|
||||
event = {
|
||||
'eventId': str(random.randint(10000, 99999)),
|
||||
'eventType': event_type,
|
||||
'userId': user_id,
|
||||
'timestamp': timestamp.isoformat(),
|
||||
'bookId': book['bookId'],
|
||||
'bookInfo': book
|
||||
}
|
||||
|
||||
# 根据事件类型添加特定字段
|
||||
if event_type == 'READ':
|
||||
event['readDuration'] = random.randint(10, 180) # 阅读时长(分钟)
|
||||
event['progress'] = random.randint(1, 100) # 阅读进度
|
||||
elif event_type == 'RATE':
|
||||
event['rating'] = random.randint(1, 5) # 评分 1-5
|
||||
|
||||
return event
|
||||
|
||||
def generate_events(self, num_events=10):
|
||||
"""生成多个事件"""
|
||||
events = []
|
||||
# 为每个用户生成一些事件
|
||||
for user_id in range(1, 4): # 假设有3个用户
|
||||
user_events = [self.generate_event(str(user_id))
|
||||
for _ in range(num_events // 3)]
|
||||
events.extend(user_events)
|
||||
|
||||
# 随机打乱事件顺序
|
||||
random.shuffle(events)
|
||||
return events
|
|
@ -0,0 +1,34 @@
|
|||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from recommendation_service.utils.data_generator import TestDataGenerator
|
||||
from recommendation_service.kafka.book_event_consumer import BookEventConsumer
|
||||
from kafka import KafkaProducer
|
||||
import json
|
||||
import time
|
||||
|
||||
def test_recommendation_system():
|
||||
# 创建Kafka生产者
|
||||
producer = KafkaProducer(
|
||||
bootstrap_servers=['localhost:9092'],
|
||||
value_serializer=lambda x: json.dumps(x).encode('utf-8')
|
||||
)
|
||||
|
||||
# 创建测试数据生成器
|
||||
data_generator = TestDataGenerator()
|
||||
|
||||
# 生成测试事件
|
||||
test_events = data_generator.generate_events(num_events=20)
|
||||
|
||||
# 发送测试事件到Kafka
|
||||
for event in test_events:
|
||||
producer.send('book-events', event)
|
||||
print(f"发送事件: {event}")
|
||||
time.sleep(1) # 每秒发送一个事件
|
||||
|
||||
producer.flush()
|
||||
producer.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_recommendation_system()
|
Loading…
Reference in New Issue