Skip to content

Commit 4519156

Browse files
committed
定时任务改成redis
1 parent eb4f029 commit 4519156

6 files changed

Lines changed: 83 additions & 13 deletions

File tree

README.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,43 @@ gateway等网关插件的高扩展性
99
### 通过docker运行
1010

1111
```bash
12-
docker run anjia0532/discovery-syncer-python:v2.6.13
12+
docker run anjia0532/discovery-syncer-python:v2.7.0
1313
```
1414

1515
特别的,`-c ` 支持配置远端http[s]的地址,比如读取静态资源的,比如读取nacos的
1616
`-c http://xxxxx/nacos/v1/cs/configs?tenant=public&group=DEFAULT_GROUP&dataId=discovery-syncer.yaml` ,便于管理
1717

18+
**破坏性更新**
19+
20+
v2.7.0 版本增加了redis的依赖,原方案会导致内存缓慢增长,部分情况下甚至出现任务阻塞卡死的情况,如果不想引入redis,可以退回v2.6.13版本
21+
22+
或者修改 `app.tasks.task_syncer.py``app.scheduler.scheduler.py``funboost_background_scheduler_redis_store` 改为 `funboost_aps_scheduler`
23+
<https://github.com/anjia0532/discovery-syncer-python/blob/master/app/tasks/common.py> 改为
24+
```python
25+
class FunboostCommonConfig(BoosterParams):
26+
# 中间件选型见3.1章节 https://funboost.readthedocs.io/zh/latest/articles/c3.html
27+
broker_kind: BrokerEnum = BrokerEnum.SQLITE_QUEUE
28+
# 是否使用分布式控频
29+
is_using_distributed_frequency_control: bool = True
30+
# 是否将发布者的心跳发送到redis,有些功能的实现需要统计活跃消费者。因为有的中间件不是真mq。这个功能,需要安装redis.
31+
is_send_consumer_hearbeat_to_redis: bool = True
32+
```
33+
1834
### 配置文件
1935

2036
[点击查看 config.yaml](https://github.com/anjia0532/discovery-syncer-python/blob/master/config-example.yaml)
2137

38+
运行的时候,需要配置环境变量
39+
```ini
40+
REDIS_HOST=127.0.0.1
41+
REDIS_USERNAME=
42+
REDIS_PASSWORD=
43+
REDIS_PORT=6379
44+
REDIS_DB=7
45+
REDIS_DB_FILTER_AND_RPC_RESULT=8
46+
REDIS_URL=f'redis://{REDIS_USERNAME}:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}'
47+
```
48+
2249
### Api接口
2350

2451
**注意:**
@@ -33,12 +60,17 @@ docker run anjia0532/discovery-syncer-python:v2.6.13
3360
| `GET /redoc/` | redocly ui | Redocly 接口文档 |
3461
| `GET /docs/` | swagger ui | Swagger 接口文档 |
3562
| `GET /-/reload` | `OK` | 重新加载配置文件,加载成功返回OK,主要是cicd场景或者k8s的configmap reload 场景使用 |
63+
| `GET /show-memory` | text/plain | 显示当前内存使用情况,主要是排查内存泄露等问题用 |
3664
| `GET /health` | JSON | 判断服务是否健康,可以配合k8s等容器服务的健康检查使用 |
3765
| `PUT /discovery/{discovery-name}?alive_num=1` | `OK` | 主动下线上线注册中心的服务,配合CI/CD发版业务用 |
3866
| `GET /gateway-api-to-file/{gateway-name}` | text/plain | 读取网关admin api转换成文件用于备份或者db-less模式(目前仅支持apisix,kong建议用deck) |
3967
| `POST /migrate/{gateway-name}/to/{gateway-name}` | `OK` | 将网关数据迁移(目前仅支持apisix,kong建议用deck) |
4068
| `PUT /restore/{gateway-name}` | `OK` | 将 db-less 文件还原到网关(目前仅支持apisix,kong建议用deck) |
4169

70+
#### `GET /show-memory?num=20` 查看内存使用情况
71+
72+
num 是显示的条数,默认20条
73+
4274
#### `GET /-/reload` 重新加载配置文件
4375

4476
加载成功返回OK
@@ -74,7 +106,8 @@ docker run anjia0532/discovery-syncer-python:v2.6.13
74106

75107
`discovery-name` 是注册中心的名字,如果不存在,则返回 `Not Found` http status code 是404
76108

77-
`alive_num` 是执行上下线操作后,断言存活实例数量,小于等于0则不判断,不传默认1,不满足则报错,http status code 是500, content 类似 `('最少存活实例数1不满足,总实例数(含之前已下线数量)2,要下线实例数2,剩余在线实例数0',)`
109+
`alive_num` 是执行上下线操作后,断言存活实例数量,小于等于0则不判断,不传默认1,不满足则报错,http status code 是500, content
110+
类似 `('最少存活实例数1不满足,总实例数(含之前已下线数量)2,要下线实例数2,剩余在线实例数0',)`
78111

79112
body入参
80113

@@ -347,6 +380,7 @@ targets:
347380
3. 同步机制目前是基于定时轮询,效率比较低,有待优化,比如增加缓存开关,上游注册中心与缓存比对没有差异的情况下,不去拉取/变更下游网关的upstream信息,或者看看注册中心支不支持变动主动通知机制等。
348381

349382
## 鸣谢
383+
350384
- [funboost -- python万能分布式函数调度框架](https://github.com/ydf0509/funboost)
351385
- [apisix -- 云原生Api网关](https://github.com/apache/apisix)
352386
- [kong -- 云原生Api网关](https://github.com/Kong/kong)

app/handler/index.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
import gc
2+
import sys
13
from datetime import datetime, timedelta
4+
from typing import Annotated
25

36
from fastapi import APIRouter
47
from fastapi import Response
8+
from fastapi.params import Query
59
from starlette.responses import JSONResponse
610

7-
from . import RESP_OK
811
from app.model.syncer_model import Jobs
912
from core.database import db
1013
from core.lib.logger import for_handler
14+
from . import RESP_OK
1115

1216
router = APIRouter()
1317

@@ -41,6 +45,24 @@ def reload():
4145
return Response(content=RESP_OK)
4246

4347

48+
@router.get('/show-memory', summary="显示内存占用最大的前N个对象", description="显示内存占用最大的前N个对象")
49+
def show_memory(num: Annotated[int, Query(title="num", description="前几,默认20")] = 20):
50+
"""
51+
显示内存占用最大的前N个对象
52+
@rtype: str
53+
@return: 成功返回 OK
54+
"""
55+
objects_list = []
56+
contents = []
57+
for obj in gc.get_objects():
58+
size = sys.getsizeof(obj)
59+
objects_list.append((obj, size))
60+
sorted_values = sorted(objects_list, key=lambda x: x[1], reverse=True)
61+
for obj, size in sorted_values[:num]:
62+
contents.append(f"OBJ: {id(obj)}, TYPE:{type(obj)}, SIZE: {size / 1024 / 1024:.2f}MB, REPR: {str(obj)[:100]}")
63+
return Response(content="\n".join(contents))
64+
65+
4466
@router.get("/health", summary="健康检查", description="健康检查")
4567
def health():
4668
"""

app/tasks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from functools import wraps
33
from threading import Thread
44

5-
from funboost import boost, BrokerEnum, BoostersManager
5+
from funboost import BoostersManager
66

77
task_list = list()
88

funboost_config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22
import logging
3+
import os
34

45
from funboost.utils.simple_data_class import DataClassBase
56

@@ -26,6 +27,16 @@ class BrokerConnConfig(DataClassBase):
2627
如果@boost装饰器设置is_using_rpc_mode为True或者 is_using_distributed_frequency_control为True或do_task_filtering=True则需要把redis连接配置好,默认是False不强迫用户安装redis。
2728
"""
2829

30+
# redis 相关配置
31+
REDIS_HOST = os.environ.get('REDIS_HOST', '127.0.0.1')
32+
REDIS_USERNAME = os.environ.get('REDIS_USERNAME', '')
33+
REDIS_PASSWORD = os.environ.get('REDIS_PASSWORD', '')
34+
REDIS_PORT = os.environ.get('REDIS_PORT', 6379)
35+
REDIS_DB = os.environ.get('REDIS_DB', 7) # redis消息队列所在db,请不要在这个db放太多其他键值对,框架里面有的功能会scan扫描unacked的键名,使用单独的db。
36+
REDIS_DB_FILTER_AND_RPC_RESULT = os.environ.get('REDIS_DB', 8) # 如果函数做任务参数过滤 或者使用rpc获取结果,使用这个db,因为这个db的键值对多,和redis消息队列db分开
37+
REDIS_URL = f'redis://{REDIS_USERNAME}:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}'
38+
# MongoDB 相关配置
39+
MONGO_CONNECT_URL = os.environ.get('MONGO_CONNECT_URL', None)
2940

3041
class FunboostCommonConfig(DataClassBase):
3142
# nb_log包的第几个日志模板,内置了7个模板,可以在你当前项目根目录下的nb_log_config.py文件扩展模板。

misc/docker/Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ ENV PROJECT_ENV=prod
1111
WORKDIR /opt/discovery-syncer/
1212
COPY requirements.txt /opt/discovery-syncer/
1313

14-
RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --no-cache-dir --upgrade -r /opt/discovery-syncer/requirements.txt
14+
RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list && \
15+
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --no-cache-dir --upgrade -r /opt/discovery-syncer/requirements.txt
16+
1517

1618
ADD . /opt/discovery-syncer/
1719

requirements.txt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
fastapi==0.110.1
1+
fastapi==0.115.0
22
python-dotenv==1.0.1
33
typing-extensions==4.11.0
4-
uvicorn[standard]==0.29.0
5-
pytest==8.1.1
4+
uvicorn[standard]==0.31.0
5+
pytest==8.3.3
66
# pytest-cov==5.0.0
77
# pytest-html==4.1.1
88
# pytest-asyncio==0.23.6
99
# pytest-trio==0.8.0
10-
httpx==0.27.0
10+
httpx==0.27.2
1111
BeautifulReport==0.1.3
1212
# aiocache~=0.12.2
1313
# databases==0.9.0
1414
# asyncpg==0.29.0
15-
funboost==43.2
16-
pydantic-settings==2.2.1
15+
funboost==46.2
16+
pydantic-settings==2.5.2
1717
db-libs==1.0
18-
nb-time==1.3
18+
nb-time==1.8
1919
pydantic-yaml==1.3.0
20-
cachetools==5.3.3
20+
cachetools==5.5.0
21+
async-timeout==4.0.3

0 commit comments

Comments
 (0)