13 KiB
我现在有一个python爬虫项目启动是在项目目录内手动:python update_yt_week.py > output_week.log 2>&1 &,产生的进程日志就放在output_week.log文件内。 现在有问题就是这个进程会直接中断结束,我需要有方法自己检测这个进程,有什么方法思路或者工具,我初步的想法:有一个东西可以每10分钟检查改进程,假如没有进程就执行启动命令,执行完启动后每10秒重新检查进程是否启动,假如连续3次没有检查到重新启动的进程,就再次立即执行启动命令,连续3次执行启动命令且则进程都检查不到说明python项目有问题则整体停止这个检查工具。 你有什么方式方法实现吗?不用写具体的脚本代码给我,就说有什么方法思路方式工具可以实现,并且需要保留日志文件,pyhton脚本本身的日志文件,以及该工具执行检查启动相关动作的日志文件,并且最好这两个文件能够按天分割成不同文件。
is_running() { pgrep -f "python update_yt_week.py" > /dev/null 2>&1 return $? }
pgrep -f "python update_yt_week.py" | head -n 1
当前项目: 机器A:43.159.145.241: 安装了tengine,部署了前端文件、运行了python项目5001端口,本机的5001负责接收前端页面的请求,再由python项目的代码请求别的机器上的jar包服务, tengine配置文件主要为 server { listen 443 ssl; server_name jennie.deal www.jennie.deal; ssl ... ... location / { root /data/tengine/html/jennie_web/dist/; index index.html index.htm; try_files $uri $uri/ /index.html; } location /prod-api/ { proxy_pass http://127.0.0.1:5001; proxy_set_header Host $host; ... } }
python项目调用后端jar的配置: [api]
远程API基础URL
api_base_url = http://129.204.158.54:8070/prod-api/
目标服务器
target_server_8070 = http://129.204.158.54:8070
机器B和C在同个局域网:BC都运行了相同的jar包作为机器A的jar后端 机器B: 公网:129.204.158.54,内网为:172.24.16.10 机器C:公网:43.138.204.95,内网为:172.24.16.7
机器B安装了tengine,配置负载均衡: upstream agent_backend { server 127.0.0.1:8070 max_fails=3 fail_timeout=30s; server 172.24.16.7:8070 max_fails=3 fail_timeout=30s; keepalive 300; } server { listen 8070; location / { proxy_pass http://agent_backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; ... } }
现在查看机器BCjar的日志,只有机器B,有机器C没有,说明机器A的前端页面的接口都是访问的机器B,负载均衡没起作用,为什么怎么办?能给单独一个sever块的产生的日志单独产生到另外的日志文件吗?
python脚本查询es
TARGET_EVENT = "达人搜索"
query = {
"query": {
"bool": {
"filter": [
{"term": {"mylog.module": "business"}},
{"term": {"mylog.level": "warning"}},
{"wildcard": {"mylog.tail.keyword": f"*[event: {TARGET_EVENT}]*"}},
{"range": {
"@timestamp": {
"gte": start_time.isoformat(),
"lte": end_time.isoformat()
}
}}
]
}
},
"sort": [{"@timestamp": "desc"}],
"size": 1,
"track_total_hits": True
}
注释{"wildcard": {"mylog.tail.keyword": f"[event: {TARGET_EVENT}]"}}, 就得到,加上就查不到 日志原本的样子:2025-06-12 18:11:48 - business - WARNING - [user_email: 302866617a@gmail.com] [conversation_id: d998dc11-d7a9-4817-8e90-e208454c80a1] [event: 达人搜索 | msg: 处理完成,耗时: 1.43秒,未找到匹配达人 | context: duration:1.43s,results_count:0] mylog.tail字段是 [event: 达人搜索 | msg: 处理完成,耗时: 1.43秒,未找到匹配达人 | context: duration:1.43s,results_count:0]
echo "2025-06-12 19:16:48 - business - WARNING - [user_email: 123@gmail.com] [conversation_id: 123-d7a9-4817-8e90-e208454c80a1] [event: 达人搜索 | msg: 这是测试的,耗时: 9.13秒,匹配71个达人 | context: duration:9.13s,results_count:71]" >> influencer_search_20250612_184513.log
现在我的ai对话产品有4个套餐等级:Free、Basic、Pro、Max,格式是:“套餐(月付价格,年付平均月价,每月积分)” Free: ($0,$0,60) Basic:($99.00,$84.90,1000) Pro:($199,$169,2500) Max:($299,$259,6000) 以下是套餐按钮交互逻辑补充:
- 用户当前订阅了任意一个套餐
- 订阅月度套餐
- 允许用户切换不同套餐类型
- 订阅的是Basic套餐
- 月度套餐界面
- Free套餐按钮:Unavailable
- Basic套餐显示:Current Plan
- Pro以及Max显示:Upgrade to Pro & Max
- 年度套餐界面
- Free套餐按钮:Unavailable
- Basic套餐显示:Switch to Basic (Yearly)
- Pro以及Max显示:Upgrade to Pro & Max
- 月度套餐界面
- 订阅是Max(最高级别)套餐
- 月度套餐界面
- Free套餐按钮:Unavailable
- Basic以及Pro显示:Downgrade to Basic & Pro
- (下个月生效)
- Max套餐显示:Current Plan
- 年度套餐页面
- Free套餐按钮:Unavailable
- Basic显示:
- Pro套餐显示:
- Max套餐显示:Switch to Max (Yearly)
- 月度套餐界面
- 用户订阅的年度套餐
- 年度basic套餐
- 月度套餐页面
- Free套餐按钮:Unavailable
- 所有套餐按钮均为Unavailable
- 鼠标hover显示:Switching from annual to monthly isn’t supported directly. If you accidentally purchased an annual plan, contact us at support@lessie.ai and we’ll process your refund.
- 不允许用户自己从年度切换回月度
- 年度套餐页面
- Free套餐按钮:Unavailable
- Basic显示:Current Plan
- Pro和Max套餐显示: Upgrade to Pro & Max
- 点击之后直接进入check out页面,补足差价
- 月度套餐页面
- 年度Pro套餐
- 月度套餐页面
- Free套餐按钮:Unavailable
- 年度套餐页面
- Basic以及Max显示:Downgrade to Basic & Pro
- Pro:Current Plan
- 月度套餐页面
- 年度Max套餐
- Basic以及Pro显示:Downgrade to Basic & Pro
- Max:Current Plan
- 年度basic套餐
- 订阅月度套餐
当前套餐:按钮文案为 Current Plan(不可点击) 升级套餐:按钮文案格式为 Upgrade to Plus / Pro / Max 降级套餐: 1. 若用户当前套餐为 Plus 或 Pro,且页面中出现低版本套餐(如 Basic),按钮文案为: Switch to Basic 2. 若用户降级至免费套餐(假设 Basic 为免费版时),则按钮文案建议为: Downgrade to Basic / Plus / Pro
我补充一下套餐流转的规则: 1、升级套餐:更新订阅周期,立即生效,积分补足至新版套餐标准 示例:用户升级前积分剩余500,生成Pro后,积分补足到2500 2、套餐降级:下一个订阅周期生效,用户退款全部人工处理 订阅周期以当前用户的订阅情况来计算 示例: 用户当前购买套餐为 月付Pro版,订阅有效期为2025-08-01至2025-09-01,用户08-15修改套餐为 月付Basic版 则 月付Basic版 的生效日期为2025-09-01 下一个订阅周期生效 3、低套餐升级到高套餐 及时生效 更新下次扣款日期 从用户付款日开始 收新版本套餐的金额,减去上个月 差价金额 = 高级版金额 - 当月积分消耗比例 × 无折扣(用户付款时)的月付价格
现在整个系统是在腾讯云多台服务器上运行的: 前端放在nginx并反向代理请求go、python、java
1、前端有些接口直接请求pyhon or java,也有些是经过go后再到python or java
2、后端之间java和go会互相请求,python是一个ai项目,会调用很多mcp、llm等ai接口
3、java内部之间有多个jar,目前是注册在nacos, 做成配置中心以及形成ouble框架
4、go和python也会拿nacos做配置中心,比如python的ai项目会把很多ai提示词在nacos中配置
5、java的多个jar需要连接mysql(云服务),redis(jar运行所在机器自建)
6、go需要连接mysql(云服务)和MongoDB(云服务),redis(jar运行所在机器自建)
7、python需连接mysql(云服务)、调用很多外部的api
8、日志采集是服务器上安装了filebast采集机器上的日志文件
9、监控是用普罗米修斯的node采集器和进程采集器监控服务进程或机器资源的
10、cicd流程是开发把代码合到自建的gitlab,然后自建jenkins的机器用流水线脚本拉代码: java、go代码就在jenkins机器上构建成jar、二进制文件,然后scp到目标服务器,执行启动命令 python代码就是在jenkins机器上直接同步到目标服务器上,然后jenkins 机器ssh登录到目标服务执行pip安装依赖命令后执行启动命令,python的日志很大,安装完依赖有1G+
、
[default] aws_access_key_id=AKIATFBxxxxxQM aws_secret_access_key=LdZXdtSxHjxxxxxxxxVn6ExM1BnnZe
[bedrock-216989094777] aws_access_key_id=AKIATFBxxxxVQ5RA653 aws_secret_access_key=z7AOlHA+SxxxxxxxxH7vYxbyM2RVT
[bedrock-767398059253] aws_access_key_id=AKIAxxxxx2Z3NDDWNU aws_secret_access_key=qd7DJnxxxxxxnFSPrjiz/18F4
PS C:\备份文件\工作相关配置文件\test-k8s-server\configmap> kubectl apply -f aws-credentials-configmap.yaml E1015 14:46:20.079445 18448 request.go:1196] "Unexpected error when reading response body" err="net/http: request canceled (Client.Timeout or context cancellation while reading body)" PS C:\备份文件\工作相关配置文件\test-k8s-server\configmap> kubectl apply -f google-superlinear-configmap.yaml E1015 14:47:21.094340 18544 request.go:1196] "Unexpected error when reading response body" err="context deadline exceeded (Client.Timeout or context cancellation while reading body)" PS C:\备份文件\工作相关配置文件\test-k8s-server\configmap> ls
Directory: C:\备份文件\工作相关配置文件\test-k8s-server\configmap
Mode LastWriteTime Length Name
d---- 2025/10/15 14:23 ai-api-key密钥原文件 -a--- 2025/10/15 14:43 99 资源清单命令.sh -a--- 2025/10/15 14:45 533 aws-credentials-configmap.yaml -a--- 2025/10/15 14:42 2589 google-superlinear-configmap.yaml
PS C:\备份文件\工作相关配置文件\test-k8s-server\configmap> cat .\aws-credentials-configmap.yaml
apiVersion: v1 kind: ConfigMap metadata: name: aws-credentials namespace: test-lessie data: credentials: | [default] aws_access_key_id=xxxxxxxxxxxx44W2D26QM aws_secret_access_key=LdZXdtSxxxxxxxxxxxxxBH6JFDQXtSwVn6ExM1BnnZe
[bedrock-216989094777]
aws_access_key_id=AKIAxxxxxxxxxxVQ5RA653
aws_secret_access_key=z7AOlHA+SbtxxxxxxxxxxxxxcH7vYxbyM2RVT
[bedrock-767398059253]
aws_access_key_id=AKIAxxxxxxxxxxxZ3NDDWNU
aws_secret_access_key=qd7DJnlpl5fxxxxxxxxxxxxxrA4BsDHnFSPrjiz/18F4
PS C:\备份文件\工作相关配置文件\test-k8s-server\configmap> cat .\google-superlinear-configmap.yaml
apiVersion: v1 kind: ConfigMap metadata: name: google-credentials namespace: test-lessie data: credentials: { "type": "service_account", "project_id": "superxxxxxxar-47xxxxxxxxx09", "private_key_id": "dec3d35a18d6dxxxxxxxxxx2a61cebaf89e244fd936", "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCv3SQukw3xbiqP\njJVH2JhTRTmBcZcBDbsYrPvcmptwxW4HR7WM64OK9pMWP2N2F9I8HmJqJbnCKI0M\n/ClkJZdfWQZnmhG7/GaOxPf3tZlqeJBauizTJI5sdcGpxxxxxxxxxxxxxxxxxxxxxxm0leK\n4/YaJlifTgK9T2Rf63z1wVrYxTCJy6W0paBQZBJR9Y3gKviYL5XPBHNIJIMKDpPu\nhojHLlP66ID+9812tFA4TfPiGk2G+xxJqiQhIO2ftqdYKmuaJMuCYrpBN+0mXwe7\nW1mzb/Yhxh7/27ZHny30uc9WaiQ2rVgxQO/LgIv1JuMt2bQlNPPoFOAvEpK2RN4m\n4m/4t21lAgMBAAECggEADfOqFWzSsBrokvtY83p2OTL2eTO5AlsjwvUkRQ/Z8ZQk\nIr04ZL3xxxxxxxxxxxxtg11PxI9BgVIq6PabtOJeBm4XNbb+HejXQnM3Bo5vuPgEC+Q\n6jW3bSfLCcU80De3lgrJnNlG8/vBTm9lBQ6JPXFZ2gePFZQ5FxgAUaHdknFwZJoK\n0SySvMN7xxxxxxxxg2urq3I5PXizGSPzOrPfea/M4vumKYPuzzXhqweo6rNaxa72OgbJiX9u\nPByUMA3KcfJ17b6M0hvRg3hMTVD5e7P33H6hvWKgqJNgouTwoKZ9EGPxS3bzNZZ4\nFCRkJFvk27F8BIzJTF8ol5W6anZuiigq3+hcbRKcIQKBgQDpb2Vr2GfiX5oPmr2/\nV+ecoy7SEfMRClT+CG/S6X5RdAvK3WKxxxxxxxS4lBwdaJQNzgi2vPLtzo2mSEDlK3hWjhAoGAdkYyjkQvd9eNdoVDcJeH\nXwXlp7RyB+0urpf7EaBzcL0xT+jKev/8DmuYx3rK+zlbBw58Kt/56UzEusLNSTRl\nmVP55lyksLzq2+HUunSkz+0E1TOhrN5MHOrOI8HqYc1eXz8OkZE/7c6o05tJOyHV\n3SeNh5V4jNsKDdeDljMITkM=\n-----END PRIVATE KEY-----\n", "client_email": "superlinear-claude-service@superlinear-470909.iam.gserviceaccount.com", "client_id": "103396741707999098774", "auth_uri": "https://accountsxxxxxxxxxxxuth2/auth", "token_uri": "https://oauth2xxxxxxxxxxxom/token", "auth_provider_x509_cert_url": "https://www.googxxxxxxxxxxxcom/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapisxxxxxxxxxxxxxxxx09/superlinear-claude-service%xxxxxxxx-470909.iam.gserviceaccount.com", "universe_domain": "gooxxxxxxeapis.com" }