GitLab Forked 如何跟随 upstream 主库

:::info 通过 PR 的方式共同对主仓库进行贡献的方式,是开源项目协作的非常有效的方法;通常我们不会直接对主仓库直接提交代码。 :::

一般情况下,我们的操作是,在需要贡献时,Fork 一份项目,然后自己修改以 PR 的方式提交贡献请求。

image.png

Github 的实现方式

熟悉 Github 的同学会发现,在 Github 上最近更新了 Sync fork的功能,通过简单的点击操作,即可完成对源库 (upstream) 的更新同步。 CleanShot 2022-09-28 at 10.01.33.jpg 通过以上方式,我们可以方便在跟随主库的更新

Tips Github 的方式,仅在 Web 端 和 Github CLI 官方提供的 GH 才可以使用这样的功能

No Github, When Gitlab ?

Github 更多在开源项目时贡献,实际上,在我们日常的工作当中,更多会有自建的 Gitlab 或者其他的代码 Hub,这里以 Gitlab 为例

CleanShot 2022-09-28 at 10.19.20.jpg Gitlab 并未提供 Sync fork 的功能,所以我们需要自行解决同步的需求

为仓库添加 upstream 源仓库

:::success 以下方式会在终端或本地使用Sourcetree更加自由,仅使用 Git 的方式协作,自由度很大 ::: 基于这个方式我们可以实现,有关联的 主库到从库的同步;也可以完成跨 Hub 的同步,比如:

  • Github -> Gitlab
  • Github -> Github
  • Gitlab -> Gitlab
  • Gitlab -> Github
  • Gitee -> Gitlab
  • Gitee -> Github
samzonglu at samzongs-MacBook-Pro in ~/Git/daocloud/DaoCloud-docs(main✔)
± git remote add upstream https://github.com/DaoCloud/DaoCloud-docs.git
Alias tip: gra upstream https://github.com/DaoCloud/DaoCloud-docs.git

samzonglu at samzongs-MacBook-Pro in ~/Git/daocloud/DaoCloud-docs(main✔)
± git remote
Alias tip: gr
origin
upstream

samzonglu at samzongs-MacBook-Pro in ~/Git/daocloud/DaoCloud-docs(main✔)
± git fetch upstream
Alias tip: gf upstream
remote: Enumerating objects: 1268, done.
remote: Counting objects: 100% (182/182), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 1268 (delta 177), reused 182 (delta 177), pack-reused 1086
Receiving objects: 100% (1268/1268), 1.87 MiB | 2.74 MiB/s, done.
Resolving deltas: 100% (637/637), completed with 119 local objects.
From https://github.com/DaoCloud/DaoCloud-docs
 * [new branch]      feature/theme                            -> upstream/feature/theme
 * [new branch]      fix-typo                                 -> upstream/fix-typo
 * [new branch]      gh-pages                                 -> upstream/gh-pages
 * [new branch]      main                                     -> upstream/main
 * [new branch]      patch-new-gh-pages-01                    -> upstream/patch-new-gh-pages-01
 * [new branch]      stash/bug-codes                          -> upstream/stash/bug-codes

samzonglu at samzongs-MacBook-Pro in ~/Git/daocloud/DaoCloud-docs(main✔)
± git pull upstream main
Alias tip: gl upstream main
From https://github.com/DaoCloud/DaoCloud-docs
 * branch            main       -> FETCH_HEAD
Already up to date.

samzonglu at samzongs-MacBook-Pro in ~/Git/daocloud/DaoCloud-docs(main✔)
± git push origin main
Alias tip: gp origin main
Everything up-to-date

2022-09-28 GitLab

Kafka 调研及功能设计

调研对象

厂家 产品控制台主页 应用模式
阿里云 https://kafka.console.aliyun.com/ 中间件 PaaS 模块之一
腾讯云 https://console.cloud.tencent.com/ckafka/overview 中间件 PaaS 模块之一
华为云 https://console.huaweicloud.com/dms/?region=cn-east-3&engine=kafka 中间件 PaaS 模块之一
QingCloud https://console.qingcloud.com/pek3/app/app-n9ro0xcp/ 中间件 AppCenter 模块之一
UCloud https://console.ucloud.cn/ukafka/ukafka 中间件 PaaS 模块之一
时速云 https://console.tenxcloud.com/middleware_center/app 中间件 应用之一

operator 选型

功能横向对比

功能点 阿里云 腾讯云 华为云 QingCloud UCloud 时速云 strimzi-kafka-operator koperator
Kafka 实例的生命周期管理
Kafka 多版本支持 √ 默认固定,工单调整 √(仅 1 个)
Kafka 节点列表     跳转 Pod √ (能创建 pod)
Kafka 原生参数管理              
  √ 原生 √ 原生  
Kafka 常用参数抽象    
Kafka 模块自带 Zookeeper    
               
消息查询功能 √ 原生   √ 原生    
消息下载功能 √(高级版)            
               
Topic 管理列表 √ 原生 √ 原生  
               
Topic 增删改查 √ 原生 √ 原生  
             
               
Topic 高级参数支持 √ 原生 √ 原生  
             
               
Topic 详情          
√ 原生 √ 原生      
Consumer Group 列表   √ 原生   √ 原生    
Consumer Group 增删改查   √ 原生 √ 原生    
资源监控看板   √ grafana dashboard √ grafana dashboard
Kafka 业务数据监控 (消息量/积压/消费情况)   √Grafana √ exporter+grafana √ exporter+grafana
示例接入代码          
消息发送测试窗口          
Kafka 服务日志查看                
操作审计日志查看          
提供 Kafka Manager UI            
提供 kafka export 备份功能            
友好性帮助文档      
提供帮助用户迁入上云          

Kafka 创建过程及开放参数

厂家 字段
阿里云 名称流量规格集群流量 = 业务流量 + 集群内副本复制流量,该规格实际业务读流量处理峰值为 50 MB/s,业务写流量处理峰值为 10 MB/s。磁盘容量数据默认 3 副本存储。实例规格为标准版时,如购买 300G 磁盘,实际存储业务的磁盘大小为 100G,其余 200G 为备份容量。实例规格为专业版时,如购买 300G 磁盘,实际存储业务的磁盘大小为 300G,额外赠送 600G 备份容量。消息保留最长时间是指在磁盘容量充足的情况下,消息的最长保留时间;在磁盘容量不足(即磁盘水位达到 85%)时,将提前删除旧的消息,以确保服务可用性;默认 72 小时,可选 24 小时 ~ 168 小时。最大消息大小,默认 1MB 边界值?标准版实例单条消息最大为 256KB,专业版实例单条消息最大为 10MB 且支持下载Topic 数量
腾讯云 名称 Kafka 版本实例规格配置存储容量消息保留时长
华为云 名称 Kafka 版本实例规格配置存储容量
QingCloud 名称 Kafka 版本 Kafka 节点配置:CPU / 内存 / 节点数(规格)客户端节点配置:CPU / 内存 / 节点数(规格)Kafka-Manager / CLI)Zookeeper 实例存储容量自定义参数配置内部 Topic offset replicasKafka manager 认证 zabbix.agentkafka scale version
UCloud 名称 Kafka 版本实例规格配置 + 存储容量实例数 3<设定值<100 消息保留时长

基础设计问题

部署方式?

DCE5 支持多集群,Kafka 采用 operator 的方式部署,则需要先安装 Operator 模板到集群内

什么时间安装 Kafka-operator?

在用户创建 kafka 实例时,检测是否目标集群是否存在 kafka-operator,如果不存在则同步安装

什么时间移除 kafka-operator,默认情况下安装后不移除;交由 Kpanda 对集群释放时处理

如果支持 Kafka 多版本?

通过多版本 对应 多 Kafka-opeator 的方式,让用户进行多版本选择

Operator 更新后,存量 Kafka 怎么办?

非必要需求,短期不支持

默认情况下更新了 operator 之后,不对存量做处理;后续可以做友好提示用户升级即可

调研对象主要功能截图

阿里云

实例生命周期管理

实例创建

CleanShot 2022-08-24 at 10.19.23.jpg

实例详情

CleanShot 2022-08-24 at 10.20.05.jpg

Kafka Topic 管理

CleanShot 2022-08-24 at 10.18.17.jpg

Kafka 消息查询

CleanShot 2022-08-24 at 10.16.43.jpg

监控告警页面

CleanShot 2022-08-24 at 10.20.49.jpg

Topic 详情

CleanShot 2022-08-24 at 12.27.10@2x.jpg CleanShot 2022-08-24 at 15.18.33@2x.jpg CleanShot 2022-08-24 at 15.18.54@2x.jpg CleanShot 2022-08-24 at 15.19.07@2x.jpg

Group 管理

CleanShot 2022-08-24 at 15.19.37.jpg CleanShot 2022-08-24 at 15.19.45@2x.jpg CleanShot 2022-08-24 at 15.19.54@2x.jpg

Prom 监控

CleanShot 2022-08-24 at 14.28.53.jpg

腾讯云

CleanShot 2022-08-24 at 15.23.24@2x.jpg

Kafka 实例生命周期管理

CleanShot 2022-08-24 at 15.22.56@2x.jpg

消息查询功能

CleanShot 2022-08-24 at 15.23.44@2x.jpg

数据同步任务

CleanShot 2022-08-24 at 15.24.04@2x.jpg

迁移上云功能

CleanShot 2022-08-24 at 15.24.21@2x.jpg

Topic 管理

CleanShot 2022-08-24 at 17.18.06@2x.jpg CleanShot 2022-08-24 at 17.18.35@2x.jpg https://cloud.tencent.com/document/product/597/73566

查看 Topic 详情

CleanShot 2022-08-24 at 17.19.00@2x.jpg

查看 Topic 生产端连接

CleanShot 2022-08-24 at 17.19.30@2x.jpg

发送测试消息

CleanShot 2022-08-24 at 17.20.13@2x.jpg

Group 管理

CleanShot 2022-08-24 at 17.21.06@2x.jpg CleanShot 2022-08-24 at 17.21.36@2x.jpg

华为云

实例的创建

CleanShot 2022-08-24 at 15.26.48@2x.jpg CleanShot 2022-08-24 at 15.27.28@2x.jpg

实例基本信息

CleanShot 2022-08-24 at 15.44.29@2x.jpg

实例配置修改

CleanShot 2022-08-24 at 15.42.03@2x.jpg

创建 Topic

CleanShot 2022-08-24 at 15.41.07@2x.jpg

监控

CleanShot 2022-08-24 at 15.41.43@2x.jpg CleanShot 2022-08-24 at 15.43.01@2x.jpg CleanShot 2022-08-24 at 15.43.16@2x.jpg CleanShot 2022-08-24 at 15.43.40@2x.jpg CleanShot 2022-08-24 at 15.43.56@2x.jpg

示例代码

CleanShot 2022-08-24 at 15.44.07@2x.jpg

QingCloud

Kafka 实例的创建

CleanShot 2022-08-24 at 15.59.07@2x.jpg CleanShot 2022-08-24 at 15.59.23@2x.jpg CleanShot 2022-08-24 at 15.59.33@2x.jpg CleanShot 2022-08-24 at 15.59.43@2x.jpg

创建时,需要关联依赖服务 zookeeper

CleanShot 2022-08-24 at 15.59.51@2x.jpg

实例详情

CleanShot 2022-08-24 at 16.10.36@2x.jpg

Topic 管理

提供了原生的 Kafka-manager 管理 UI https://docsv3.qingcloud.com/middware/kafka/manual/kafka_manager/kafka_manager_topic/

访问方式,以 openvpn 的方式接入到 VPC(需绑定入口公网 IP) 后,通过 client 内网地址访问 CleanShot 2022-08-24 at 17.57.01@2x.jpg

UCloud

创建实例

CleanShot 2022-08-24 at 16.32.07@2x.jpg

Kafka 实例详情

CleanShot 2022-08-24 at 16.36.01@2x.jpg CleanShot 2022-08-24 at 16.36.29@2x.jpg CleanShot 2022-08-24 at 16.36.41@2x.jpg CleanShot 2022-08-24 at 16.36.55@2x.jpg

Kafka 节点的详情页面

CleanShot 2022-08-24 at 16.50.34@2x.jpg CleanShot 2022-08-24 at 16.39.28@2x.jpg

kafka 自定义配置

CleanShot 2022-08-24 at 16.50.13@2x.jpg

Kafka 连接器

将上游 Kafka 数据传输到 HDFS 或者 es CleanShot 2022-08-24 at 16.53.11@2x.jpg CleanShot 2022-08-24 at 16.52.58@2x.jpg CleanShot 2022-08-24 at 16.52.43@2x.jpg

监控看板

CleanShot 2022-08-24 at 16.38.11@2x.jpg

创建 Topic

CleanShot 2022-08-24 at 16.50.50@2x.jpg CleanShot 2022-08-24 at 16.38.45@2x.jpg CleanShot 2022-08-24 at 16.51.29@2x.jpg CleanShot 2022-08-24 at 16.51.05@2x.jpg

时速云

实例生命周期管理

CleanShot 2022-08-24 at 16.59.24@2x.jpg

  • 需要提前安装 zookeeper
  • 需要联系时速云管理员安装 kafka-cluster-operator
    • 到交付中心,找到 Operator Hub,选择 Kafka-cluster-operator 安装
    • 安装完成后,可通过 Yaml + 表单形式 创建 Kafka
  • 提供 Kafka manger 原生 UI 控制台

Kafka 实例详情

提供原生的实例管理界面,进行配置更新等 CleanShot 2022-08-24 at 17.56.16@2x.jpg CleanShot 2022-08-24 at 17.47.02@2x.jpg

Kafka 实例下节点信息

直接跳转到 K8s 容器组界面查看 CleanShot 2022-08-24 at 17.53.57@2x.jpg

Topic 管理

在 Kafka manger 原生 UI 控制台内管理,默认启用了控制台公网访问能力 CleanShot 2022-08-24 at 17.57.01@2x.jpg

实例资源监控

基础 CPU、内存、网络、存储监控 CleanShot 2022-08-24 at 17.55.38@2x.jpg

Kafka 性能监控

接入 Grafana 提供一个 Dashboard 的,可以查看 Topics 的消息数,消费量,积压数 CleanShot 2022-08-24 at 17.55.57@2x.jpg

调研对象操作视频录制

操作视频已上传到 OneDrive 共享空间

CleanShot 2022-08-24 at 18.45.08@2x.jpg

https://yongyu2000hotmailcom.sharepoint.cn/:f:/s/ndx/EuCYqMaXhdlPh411YVnihRQBmCbGLQ4BvU1QW_2DX7_uUQ?e=18NyTR

腾讯云只可以按月份订购,所以没有录制视频。

选型确认

方案一:

  • 中间件实例 LCM + 三方 UI 管理工具

实现:

  • Kafka 实例 LCM
  • Kafka Manage UI (三方)
  • 监控三件套 (Insight) [只需要做实例级别]

方案比对:

  • 现有 Opeator 不带 Kafka Manger,需要自行处理
  • 不需要关心 Topic LCM
  • 不需要做业务监控
  • 沿用现有的 DCE 中间件的设计思路

方案二:

  • 不增加三方 Kafka Manage UI

实现:

  • Kafka 实例 LCM
  • Topic LCM
  • 监控三件套 (Insight) [需要做实例 + 业务监控]

方案对比:

  • 现有 Operator 带有 Topic CR,可以用
  • 需要做业务监控
  • 需要做 Topic LCM
  • 与其他中间件模块定义不一致(当前阶段)

2022-09-27 Kafka

Poetry 使用笔记

poetry 是目前比较流行的 Python 环境管理工具 和 包管理工具,对多项目开发时的环境隔离有非常大的帮助,同时集成了包管理能力。

官方网站 https://python-poetry.org/ 集成了所有 Poetry 最新的使用文档,以下仅在我的环境上经过验证

安装方式

# In Pip
- 安装 pip install poetry # pip3
- 更新 poetry self update

# In my Mac
- 安装 brew install poetry
- 更新 brew upgrade poetry

# In my CentOS
- 安装 curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
- 更新 poetry self update

配置技巧相关

在开始使用前,建议先对 poetry 的配置有些了解,并调整为适合你的方式,主要是调整一下虚拟环境的安装位置 :::info poetry config poetry 相关的查看和编辑的命令 :::

~ poetry config --list  # 获取当前 poetry 的配置情况

cache-dir = "/Users/$username/Library/Caches/pypoetry"
experimental.new-installer = true
installer.parallel = true
virtualenvs.create = true
virtualenvs.in-project = true
virtualenvs.path = "{cache-dir}/virtualenvs"  # /Users/$username/Library/Caches/pypoetry/virtualenvs

| 配置项目 | 配置内容 | 配置项说明 | 建议配置 | | — | — | — | — | | cache-dir | String | 缓存目录配置,使用 poetry 安装的包源文件都会缓存到这个目录。 | 不建议更改 | | installer.parallel | boolean | 此配置会被忽略 | | | virtualenvs.create | boolean | 默认为 true,如果当前工程的虚拟环境不存在,就创建一个 | 不建议更改 | | virtualenvs.in-project | boolean | None:poetry 会在系统特定目录创建一个.venv 目录,由下面的 path 参数指定 true:poetry 会在项目根目录创建一个.venv 目录 false:poetry 将会忽略已存在的.venv 目录 | 《建议修改》

推荐这种方式,在项目根目录创建虚拟环境,这样就算移动目录位置也不影响虚拟环境的使用        
  virtualenvs.path string 默认是{cache-dir}/virtualenvs,虚拟环境创建的目录,如果上面的 in-project 为 true,此配置就无效 不建议更改

:::danger 建议 在使用前 启用 virtualenvs.in-project,这样会在每个项目下有一个.venv 方便隔离管理 :::

# poetry 配置说明
poetry config virtualenvs.in-project true

poetry 常用指令说明

Poetry Command 解释
$ poetry –version 显示您的 Poetry 安装版本。
$ poetry new 创建一个新的 Poetry 项目。
$ poetry init 将 Poetry 添加到现有项目中。
$ poetry run 使用 Poetry 执行给定的命令。
$ poetry add 添加一个包 pyproject.toml 并安装它。
$ poetry update 更新项目的依赖项。
$ poetry install 安装依赖项。
$ poetry show 列出已安装的软件包。
$ poetry lock 将最新版本的依赖项固定到 poetry.lock.
$ poetry lock –no-update 刷新 poetry.lock 文件而不更新任何依赖版本。
$ poetry check 验证 pyproject.toml。
$ poetry config –list 显示 Poetry 配置。
$ poetry env list 列出项目的虚拟环境。
$ poetry export 导出 poetry.lock 为其他格式。

新项目初始化流程

这里以 初始化一个 FastAPI 项目作为 实例

➜  fastapi poetry new fastapi-demo
Created package fastapi_demo in fastapi-demo
➜  fastapi ls -lh fastapi-demo
total 8
-rw-r--r--  1 samzonglu  staff     0B  2 15 14:28 README.rst
drwxr-xr-x  3 samzonglu  staff    96B  2 15 14:28 fastapi_demo
-rw-r--r--  1 samzonglu  staff   304B  2 15 14:28 pyproject.toml
drwxr-xr-x  4 samzonglu  staff   128B  2 15 14:28 tests

➜  fastapi cd fastapi-demo
➜  fastapi-demo poetry env use 3.10.2  # 配置项目的虚拟环境

requirements.txt 已存在项目使用 poetry

这里会遇到一个问题,已存在的项目基本都已经有了 requirements.txt,所以 poetry 最好可以直接读取它

poetry add `cat requirements.txt`

将项目依赖导出为 requirements.txt

poetry export --output requirements.txt

更新内容

如何把项目移交给一个 not use Poetry 的人运行,对于 Python 的 环境包 依赖,上述的 ouput/input 的方式,会存在一些问题,这里进行纠正。

问题 pip freeze 不能用了

:::warning pip freeze > requirements.txt :::

anyio @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/cd/3f/ae/baff749ce6cb4d7985e4142650605d2d30cb92eb418e2d121868e4413d/anyio-3.6.1-py3-none-any.whl
certifi @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/b1/9b/6f/cd63ce97294ee9a1fb57e5cebf02f251fbb8f9ac48353a27ceeddc410b/certifi-2022.6.15-py3-none-any.whl
charset-normalizer @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/86/c8/3e/d878881698fbd2b72f484e4fca340588d633102920a002b66a293f9480/charset_normalizer-2.1.0-py3-none-any.whl
click @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/63/f3/4c/2270b95f4d37b9ea73cd401abe68b6e9ede30380533cd4e7118a8e3aa3/click-8.1.3-py3-none-any.whl
fastapi @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/f9/37/53/c998e9ffd7ace66218174711f5c3ef1026a0bd3cd72f5fe2908e9b949b/fastapi-0.78.0-py3-none-any.whl
h11 @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/ef/5c/a2/a6d556bc5e3493616e52726df9c880b2da2fbf9c3be5e8351c84fbfafd/h11-0.13.0-py3-none-any.whl
idna @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/90/36/8c/81eabf6ac88608721ab27f439c9a6b9a8e6a21cc58c59ebb1a42720199/idna-3.3-py3-none-any.whl
pydantic @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/c2/13/d4/b9f7dbf75702d85504b4a5f36545ff903c7e2264d4889e94ce02637276/pydantic-1.9.1-cp310-cp310-macosx_11_0_arm64.whl
requests @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/14/1f/4d/1b93db6513b8ab38db841e4ce62691288ba549a5c1b6f3ca7274a1c9fd/requests-2.28.1-py3-none-any.whl
sniffio @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/2b/1b/93/9c34d727e29f7bb11ce5b2ca7f43e77cb4e96a81ee5e07a92763951416/sniffio-1.2.0-py3-none-any.whl
starlette @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/3d/fc/74/569a1206737284325f5bb2e4f34689632c159dafbe8b7ff30bf2893c2d/starlette-0.19.1-py3-none-any.whl
typing_extensions @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/4a/aa/fe/e4680f3423fbdb5ac89a6fb2f83d9e7ff7fb48173b0fa1604786182558/typing_extensions-4.3.0-py3-none-any.whl
urllib3 @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/8a/87/ce/4a44bf6bb59a745f4af7082c6977ab23a478fca039ad4d631dfdc0185b/urllib3-1.26.10-py2.py3-none-any.whl
uvicorn @ file:///Users/samzonglu/Library/Caches/pypoetry/artifacts/62/76/ec/dcafe6bae872839618dbf982c87eb314eee97784f7df74895e07bd198a/uvicorn-0.18.2-py3-none-any.whl

可以看到,默认情况下pip freeze在输出时,携带里对应的安装路径;如果这个时候,我们把项目移交给其他人运行时,会遇到以下问题

ERROR: Could not install packages due to an EnvironmentError: [Errno 2] No such

这是 pip 安装软件包的一种特殊语法(自 19.1 开始受支持)PEP404, 但是该此种路径取决于环境,file:///URL 仅在本地文件系统上可用,你不能将生成的 requirements.txt 文件提供给其他人使用

先说解决方法 01 [poetry style]

poetry export --without-hashes --format=requirements.txt > requirements.txt

通过 poetry 自带的导出能力,会携带更多的一些信息:对于环境中 python 版本的依赖,虽然更加友好一些。

anyio==3.6.1; python_full_version >= "3.6.2"
certifi==2022.6.15; python_version >= "3.6"
charset-normalizer==2.1.0; python_full_version >= "3.6.0"
click==8.1.3; python_version >= "3.7"
colorama==0.4.5; python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" or platform_system == "Windows" and python_version >= "3.7" and python_full_version >= "3.5.0"
fastapi==0.78.0; python_full_version >= "3.6.1"
h11==0.13.0; python_version >= "3.6"
idna==3.3; python_version >= "3.5"
pydantic==1.9.1; python_full_version >= "3.6.1"
requests==2.28.1; python_version >= "3.7" and python_version < "4"
sniffio==1.2.0; python_version >= "3.5"
starlette==0.19.1; python_version >= "3.6"
typing-extensions==4.3.0; python_version >= "3.7"
urllib3==1.26.10; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0" and python_version < "4")
uvicorn==0.18.2; python_version >= "3.7"

再说解决方法 02

在新版的 python 中,推荐采用另外一个命令方式,pip list --format=freeze 这样会输出一份干净的依赖清单,我们可以通过这个方式,快速导出一份 原汁原味 的 requirements.txt

poetry run pip list --format=freeze
anyio==3.6.1
certifi==2022.6.15
charset-normalizer==2.1.0
click==8.1.3
fastapi==0.78.0
h11==0.13.0
idna==3.3
pip==22.2
pydantic==1.9.1
requests==2.28.1
setuptools==62.6.0
sniffio==1.2.0
starlette==0.19.1
typing_extensions==4.3.0
urllib3==1.26.10
uvicorn==0.18.2
wheel==0.37.1

补充安装来自于 requirements.txt 的方式

with poetry

cat requirements.txt | xargs poetry add

without poetry

pip install -r requirements.txt

2022-09-22 Python

Skoala 部署教程

使用之前的话

Skoala 的微服务治理和微服务是强依赖的 Ghippo、Insight 和 Kpanda 作为基石;同时 Skoala 也支持了 Mesh 服务治理能力,所以也需要 Mspider。 为了保证良好的使用体验,以及减少不可预知的部署问题,请确认以上组件均可正常工作。

检测方式一

访问 UI 界面环境,可以在左侧导航栏能够正确看到所有模块,并且可以正常使用。 CleanShot 2022-09-07 at 18.07.42@2x.jpg

检测方式二

通过终端查看集群内的 apiserver 是否正常,检查服务 Pod 是否正常运行

# 检测 ghippo
~ kubectl -n ghippo-system get pods | egrep "apiserver|ui"
ghippo-apiserver-589c4ddcf6-cmct7              3/3     Running     0          17h
ghippo-apiserver-589c4ddcf6-sts8t              3/3     Running     0          17h
ghippo-ui-7ddddc548c-nsbkj                     2/2     Running     0          94m


# 检查 kpanda
~ kubectl -n kpanda-system get pods | egrep "apiserver|ui"
kpanda-apiserver-695b76f476-kdb8l                                 2/2     Running     0          5m56s
kpanda-apiserver-695b76f476-mvllg                                 2/2     Running     0          7m51s
kpanda-clusterpedia-apiserver-574d49c4c-hptm7                     2/2     Running     0          74m
kpanda-clusterpedia-apiserver-574d49c4c-mjm84                     2/2     Running     0          74m
kpanda-ui-5f9586d49b-f4mn2                                        2/2     Running     0          66m
kpanda-ui-5f9586d49b-qpgwd                                        2/2     Running     0          66m


# 检查 Insight
~ kubectl -n insight-system get pods | egrep "server|ui"
insight-server-5bbc96bb94-n2wc7                                1/1     Running   0          174m
insight-ui-66b6795c44-zm6qj                                    1/1     Running   0          3h38m


# 检查 mspider
~ kubectl -n mspider-system get pods | egrep "api|ui"
mspider-api-service-7d96c6798-mljst       2/2     Running   0          3h20m
mspider-ui-6f5d58cdc6-59hbn               2/2     Running   0          170m
mspider-work-api-684b75dccb-4659g         2/2     Running   0          3h20m

配置 skoala helm repo

配置好 skoala 仓库,即可查看和获取到 skoala 的应用 chart

helm repo add skoala-release https://release.daocloud.io/chartrepo/skoala
helm repo update

需要实现安装 Helm

安装依赖 mysql

在安装 skoala 的组件时,hive 和 sesame 需要用到 mysql 组件,所以这里需要预先安装一下 mysql,执行下方 yaml。

# 使用如下命令
kubectl -n skoala-system apply -f skoala-mysql.yml
# 保存到 skoala-mysql.yml 文件

~ cat skoala-mysql.yml
apiVersion: v1
kind: Service
metadata:
  name: skoala-mysql
  namespace: skoala-system
spec:
  ports:
  - port: 3306
  selector:
    app: mysql
  clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: skoala-mysql
  namespace: skoala-system
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: release.daocloud.io/skoala/mysql:5.7.32
        name: mysql
        env:
          # Use secret in real usage
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim
  • 注意修改以上,mysql 的密码。

初始化 mysql

登录到 pod 内,并成功登录到 mysql 内

kubectl -n skoala-system exec pods/`kubectl -n skoala-system get pods | grep skoala-mysql | awk '{print $1}'` -it bash

CleanShot 2022-09-07 at 18.54.47@2x.jpg

初始化数据库表

注意把对应的版本,建议使用最新的版本,这里建议 v0.6.1

helm upgrade --install skoala --create-namespace -n skoala-system --cleanup-on-fail \
--set image.tag=v0.6.1 \
skoala/skoala-agent \
--version 0.6.1

这里会将资源部署到 skoala-system 命名空间内,可以通过查看该命名空间内的资源来查看是否部署成功。

~ kubectl -n skoala-system get pods
NAME                           READY   STATUS    RESTARTS         AGE
hive-96b58785c-shhnh           0/1     Running   0                23h
sesame-cdd894f74-l55hw         0/1     Running   0                23h
ui-7df9754f85-v2gg5            1/1     Running   0                23h

安装 Skoala

查看 skaola 当前最新版本

helm search repo skoala-release/skoala --versions
NAME                CHART VERSION APP VERSION DESCRIPTION
skoala-release/skoala       0.6.1         0.6.1       The helm chart for Skoala
skoala-release/skoala       0.6.0         0.6.0       The helm chart for Skoala
skoala-release/skoala       0.5.1         0.5.1       The helm chart for Skoala

执行部署

这里注意各个组件的版本,建议安装如下版本,直接执行命令即可,【在 demo 部署时】

helm upgrade --install skoala --create-namespace -n skoala-system --cleanup-on-fail \
--set ui.image.tag=v0.5.3 \
--set hive.image.tag=v0.6.1 \
--set sesame.image.tag=v0.6.1 \
daocloud-registry/skoala \
--version 0.6.1

查看部署的 pod 是否启动成功

~ kubectl -n skoala-system get pods
NAME                           READY   STATUS             RESTARTS          AGE
hive-96b58785c-shhnh           1/1     Running            0                 25h
sesame-cdd894f74-l55hw         1/1     Running            0                 25h
skoala-mysql-75dc5cfc7-99tbs   1/1     Running            0                 25h
ui-7df9754f85-v2gg5            1/1     Running            0                 23h

卸载

helm uninstall skoala -n skoala-system

更多参数的配置

Key Type Default Description
global.image.pullPolicy string "IfNotPresent"  
global.image.repository string "release.daocloud.io"  
global.imageCredentials.email string ""  
global.imageCredentials.password string ""  
global.imageCredentials.username string ""  
global.imagePullSecrets list []  
global.istioInjection.enable bool true  
global.namespace string "skoala-system"  
hive.configMap.chart-repos.skoala.name string "skoala"  
hive.configMap.chart-repos.skoala.password string ""  
hive.configMap.chart-repos.skoala.url string "https://release.daocloud.io/chartrepo/skoala"  
hive.configMap.chart-repos.skoala.user string ""  
hive.configMap.client.ghippo.kubeconfig string ""  
hive.configMap.client.ghippo.timeout int 30  
hive.configMap.client.insight string "insight-server.insight-system:80"  
hive.configMap.client.kpanda string "kpanda-apiserver.kpanda-system:80"  
hive.configMap.client.mspider string "mspider-api-service.mspider-system:8081"  
hive.configMap.client.mspider_mcpc string "mspider-work-api.mspider-system:8081"  
hive.configMap.data.database.database string "hive"  
hive.configMap.data.database.driver string "mysql"  
hive.configMap.data.database.host string "skoala-mysql"  
hive.configMap.data.database.max-connection-lifetime int 20  
hive.configMap.data.database.max-idle-connections int 150  
hive.configMap.data.database.max-open-connections int 150  
hive.configMap.data.database.password string "dangerous"  
hive.configMap.data.database.port int 3306  
hive.configMap.data.database.user string "root"  
hive.configMap.data.server.grpc.addr string "0.0.0.0:9091"  
hive.configMap.data.server.grpc.timeout string "1s"  
hive.configMap.data.server.http.addr string "0.0.0.0:8081"  
hive.configMap.data.server.http.timeout string "1s"  
hive.enable bool true  
hive.image.name string "skoala/hive"  
hive.image.pullPolicy string "IfNotPresent"  
hive.image.tag string "v0.6.0"  
hive.nameOverride string "hive"  
hive.replicaCount int 1  
hive.resources object {}  
hive.service.grpc.nodePort int 30091  
hive.service.grpc.port int 9091  
hive.service.http.nodePort int 30081  
hive.service.http.port int 8081  
hive.service.type string "NodePort"  
sesame.configMap.chart-repos.skoala.name string "skoala"  
sesame.configMap.chart-repos.skoala.password string ""  
sesame.configMap.chart-repos.skoala.url string "https://release.daocloud.io/chartrepo/skoala"  
sesame.configMap.chart-repos.skoala.user string ""  
sesame.configMap.client.ghippo.kubeconfig string ""  
sesame.configMap.client.ghippo.timeout int 30  
sesame.configMap.client.insight string "insight-server.insight-system:80"  
sesame.configMap.client.kpanda string "kpanda-apiserver.kpanda-system:80"  
sesame.configMap.data.server.grpc.addr string "0.0.0.0:9092"  
sesame.configMap.data.server.grpc.timeout string "1s"  
sesame.configMap.data.server.http.addr string "0.0.0.0:8082"  
sesame.configMap.data.server.http.timeout string "1s"  
sesame.configMap.log.development bool true  
sesame.configMap.log.disable-color bool false  
sesame.configMap.log.disable-stacktrace bool false  
sesame.configMap.log.enable-caller bool true  
sesame.configMap.log.error-output-paths string "dist/log/skoala-sesame.error.log"  
sesame.configMap.log.format string "console"  
sesame.configMap.log.level string "debug"  
sesame.configMap.log.name string "skoala-sesame"  
sesame.configMap.log.output-paths string "dist/log/skoala-sesame.log,stdout"  
sesame.enable bool true  
sesame.image.name string "skoala/sesame"  
sesame.image.pullPolicy string "IfNotPresent"  
sesame.image.tag string "v0.6.0"  
sesame.nameOverride string "sesame"  
sesame.replicaCount int 1  
sesame.resources object {}  
sesame.service.grpc.nodePort int 30092  
sesame.service.grpc.port int 9092  
sesame.service.http.nodePort int 30082  
sesame.service.http.port int 8082  
sesame.service.type string "NodePort"  
ui.enable bool true  
ui.image.name string "skoala/skoala-ui"  
ui.image.pullPolicy string "IfNotPresent"  
ui.image.tag string "v0.4.0"  
ui.nameOverride string "ui"  
ui.replicaCount int 1  
ui.resources object {}  
ui.service.nodePort int 30090  
ui.service.port int 80  
ui.service.type string "NodePort"  
create bool true  
ui.serviceAccount.name string ""  
ui.tolerations list []  

安装 skoala-agent

安装步骤说明

查看当前最新版本

~ helm search repo skoala-release/skoala-agent --versions
NAME                CHART VERSION APP VERSION DESCRIPTION
skoala/skoala-agent 0.6.1         0.6.1       A Helm chart for Skoala Agent
skoala/skoala-agent 0.6.0         0.6.0       A Helm chart for Kubernetes
skoala/skoala-agent 0.5.1         0.5.1       A Helm chart for Kubernetes
skoala/skoala-agent 0.5.0         0.5.0       A Helm chart for Kubernetes

部署

helm upgrade --install skoala-agent --create-namespace -n skoala-agent --cleanup-on-fail \
--set image.tag=v0.6.1 \
skoala/skoala-agent \
--version 0.6.1

查看部署的 pod 是否启动成功

~ kubectl -n skoala-agent get pods
NAME                            READY   STATUS    RESTARTS   AGE
skoala-agent-679c6d64b4-tb7k4   1/1     Running   0          26h

卸载命令

helm uninstall skoala-agent -n skoala-agent

更多参数设置

Key Type Default Description
affinity object {}  
autoscaling.enabled bool false  
autoscaling.maxReplicas int 100  
autoscaling.minReplicas int 1  
autoscaling.targetCPUUtilizationPercentage int 80  
fullnameOverride string ""  
image.pullPolicy string "IfNotPresent"  
image.repository string "release-ci.daocloud.io/skoala/skoala-agent"  
image.tag string "v0.6.0"  
imagePullSecrets list []  
ingress.annotations object {}  
ingress.className string ""  
ingress.enabled bool false  
ingress.hosts[0].host string "chart-example.local"  
ingress.hosts[0].paths[0].path string "/"  
ingress.hosts[0].paths[0].pathType string "ImplementationSpecific"  
ingress.tls list []  
istioInjection.enable bool true  
nameOverride string ""  
nodeSelector object {}  
podAnnotations object {}  
podSecurityContext object {}  
replicaCount int 1  
resources object {}  
securityContext object {}  
service.port int 443  
service.type string "NodePort"  
serviceAccount.annotations object {}  
serviceAccount.create bool false  
serviceAccount.name string ""  
tolerations list []  

2022-09-20 Skoala

使用 canal 进行数据库增量同步

image.png

简介

image

canal [kə’næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费

早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务 trigger 获取增量变更。从 2010 年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。

基于日志增量订阅和消费的业务包括

  • 数据库镜像
  • 数据库实时备份
  • 索引构建和实时维护 (拆分异构索引、倒排索引等)
  • 业务 cache 刷新
  • 带业务逻辑的增量数据处理

当前的 canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x

工作原理

MySQL 主备复制原理

image

  • MySQL master 将数据变更写入二进制日志 ( binary log, 其中记录叫做二进制日志事件 binary log events,可以通过 show binlog events 进行查看)
  • MySQL slave 将 master 的 binary log events 拷贝到它的中继日志 (relay log)
  • MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据

canal 工作原理

  • canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave,向 MySQL master 发送 dump 协议
  • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
  • canal 解析 binary log 对象 (原始为 byte 流)

文档支持

多语言

canal 特别设计了 client-server 模式,交互协议使用 protobuf 3.0 , client 端可采用不同语言实现不同的消费逻辑,欢迎大家提交 pull request

canal 作为 MySQL binlog 增量获取和解析工具,可将变更记录投递到 MQ 系统中,比如 Kafka/RocketMQ,可以借助于 MQ 的多语言能力

资料整理

canal 的策略是模拟了 MySQL Slave 的行为,因此需要有 SELECT, REPLICATION SLAVE, REPLICATION CLIENT 的权限


2022-09-18 Canal , MySQL

K8s 系列 南北流量和东西流量

南北流量和东西流量 是什么意思?

在 Service Mesh 微服务架构中,我们常常会听到东西流量和南北流量两个术语。

南北流量(NORTH-SOUTH traffic)和东西流量(EAST-WEST traffic)是数据中心环境中的网络流量模式。下面我们通过一个例子来理解这两个术语。

假设我们尝试通过浏览器访问某些 Web 应用。Web 应用部署在位于某个数据中心的应用服务器中。在多层体系结构中,典型的数据中心不仅包含应用服务器,还包含其他服务器,如负载均衡器、数据库等,以及路由器和交换机等网络组件。假设应用服务器是负载均衡器的前端。

当我们访问 web 应用时,会发生以下类型的网络流量:

img

数据中心树型拓扑图是一个典型的包含接入层、汇聚层、核心层三层的网络结构。这种结构诞生之初就是为了将外部流量引流到内部应用。

流量从外部穿过防火墙或者数据中心其它外围网络设备进来,对应到上⾯这张图里,流动方向为从上到下,称为南向流量(和地图一样,上北下南),而与之对应的,数据中心内部产生的,离开数据中心的流量,从下到上故称为北向流量。合起来称为南北流量。

在微服务化流行之前,以巨石系统(monolithic)这种单体应用为单位部署的方式,产生的是典型的南北流量。一个单体应用配有一个专门的服务器(或虚拟机),一个外部请求通常在单体应用内独立完成,除了访问数据库等必须依赖服务之外,很少会发生横向的流量。

但云计算机、大数据、微服务、云原生等技术的发展催生了大量的从左到右以及从右到左的流量,也被称为东西流量。

数据中心内部南北流量的削弱,而东西流量的井喷在硬件上要求数据中心要横向扩展以提供更宽的大二层以及容纳更多的服务器,而在软件上则要求一种新的服务编排方式以便能充分挖掘、利用现有的计算能力,从这个角度看 K8s 的出现是一种必然。

举两个例子:

  • 客户端(位于数据中心一侧的浏览器)与负载均衡器(位于数据中心)之间的网络流量

  • 负载均衡器、应用服务器、数据库等之间的网络流量,它们都位于数据中心。

在这个例子中,前者即即客户端和服务器之间的流量被称为南北流量。简而言之,南北流量是 server-client 流量。

第二种流量即不同服务器之间的流量与数据中心或不同数据中心之间的网络流被称为东西流量。简而言之,东西流量是 service-service 流量。

当下,东西流量远超南北流量,尤其是在当今的大数据生态系统中,比如 Hadoop 生态系统(大量 server 驻留在数据中心中,用 map reduce 处理),server-server 流量远大于 server-client 流量。

大家可能会好奇,东西南北,为什么这么命名?

该命名来自于绘制典型 network diagrams 的习惯。在图表中,通常核心网络组件绘制在顶部(NORTH),客户端绘制在底部(SOUTH),而数据中心内的不同服务器水平(EAST-WEST)


2022-09-12 K8s

Docker for Mac 网络技巧

在 Windows 和 Linux 中使用 Docker,可以通过 docker0 这个网络 IP,在容器内访问宿主机的端口及服务

➜  ~ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:65:e2:82:de  txqueuelen 0  (Ethernet)
        RX packets 19240  bytes 9107695 (8.6 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 16989  bytes 9952021 (9.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

但以上在 macOS 中无 docker0 端口,那我们如何在 Docker for Mac 中访问宿主机的服务呢?

docker.for.mac.host.internal

可以采用以上本地域名内实现在容器内访问 宿主机的服务


2022-08-17 Docker , Mac

瓦尔登湖

亨利••大卫••梭罗 7 highlights, 1 note

  • 在这段时间里把车钱挣出来了,会在明天的什么时候到达那里,如果你幸运地及时找到了工作,也可能今晚到达。你大半天的时间不是去了菲奇堡,却是在这里干活。因此,如果铁路通到全世界,我想我还是会在你前头;至于说长见识,如果净是那方面的见识,我就得和你完全断绝来往了。
  • 如果你决定明天开始做一件事情,那为什么不现在就开始呢?实用主义,不应该追求虚无的东西。
  • 最好在坏事一开始的时候就防止它。

  • 在任何一个社会中,书籍的作者都是天生的极富魅力的精英分子,对人类发挥着比帝王们更大的影响。当目不识丁的、也许还是鄙视一切的商人,通过魄力和勤奋挣得了垂涎已久的闲暇和衣食无忧的生活,进入了财富和时尚的圈子以后,最终不可避免地会转向那更高的然而却难以企及的知识和才赋的圈子,这时他才会意识到自己文化的残缺,以及他一切财富的空虚无用;于是他不遗余力地要使子女获得知识文化,他深刻地感到自己这方面的不足,从而证明了他的明智;就这样,他成了一个家族的缔造者。

  • 我们应该和古代的圣贤一样优秀,但是首先要知道他们有多么优秀。我们是一群矮子,我们智力翱翔所达之处只不过稍高于报纸的专栏而已。

  • 德不孤,必有邻。

  • 孤独不能以一个人和别人之间有多少英里的空间来衡量。

  • 在他身上肉体的人得到了充分发展。

2022-08-15 读书笔记

Contour 学习笔记

Contour 官方的资料

参考文档一:使用 Contour 接管 K8s 南北流量

image.png 容器公司 Heptio 开源的项目 Contour 使用 Envoy 作为 Kubernetes 的 Ingress Controller 实现。

Contour 的组成

Contour Ingress controller 由两个组件组成:

  • Envoy : 提供高性能反向代理。
  • Contour : 充当 Envoy 的控制平面,为 Envoy 的路由配置提供统一的来源。

Contour 的部署方式

官方文档提供了三种部署方法:

  1. 通过 DaemonSet 来部署,每个节点上跑一个 Contour 实例(Contour 与 Envoy 在同一个 Pod 中)。
  2. 通过 Deployment 来部署,总共跑两个 Contour 实例(Contour 与 Envoy 在同一个 Pod 中)。
  3. 通过 Deployment 来部署 Contour,总共跑两个 Contour 实例;通过 DaemonSet 来部署 Envoy,每个节点上跑一个 Envoy 实例。

第三种方案比较巧妙,这样可以让 Contour 和 Envoy 这两个组件解耦,可以分别按需对不同的组件进行扩展,具体的优势如下:

  • Envoy 以 Daemonset 的形式运行,具有很强的扩展性,后续可通过 ipvs 和 keepalived 等工具来实现其负载均衡和高可用。
  • Envoy 运行的网络模式是 hostNetwork,减少了额外的网络性能损耗。
  • Contour 与 Envoy 之间通过双向认证的自签名证书进行通信,大大增强了安全性。
  • 升级 Contour 不需要重启 Envoy。

image.png

启动分析

在 Envoy 的 Pod 初始化期间,Contour 作为 Init 容器运行,并将 bootstrap(初始化)配置写入一个 temporary volume。该 Volume 被传递给 Envoy 容器并告诉 Envoy 将另一个 Deployment 中的 Contour 容器视为控制平面。

image

Contour 会根据启动参数和 K8S API Server 中的配置信息生成 Envoy 的初始配置文件

  1. Envoy initContainer 根据启动参数和 K8S API Server 中的配置信息生成 Envoy 的初始配置文件 envoy.json,该文件告诉 Envoy 从 xDS server 中获取动态配置信息,并配置了 xDS server 的地址信息,即控制平面的 Contour。
  2. Envoy 使用配置文件 envoy.json 启动。
  3. Envoy 根据获取到的动态配置启动 Listener,并根据 Listener 的配置,结合 Route 和 Cluster 对进入的流量进行处理。

Contour 作为 Envoy 的 initContainer

参考文档 二:Contour 中 Envoy 优雅停服的实现与源码分析


2022-08-10 Contour

通过 pipreqs 获取当前项目的依赖库

如果在开始开发一个项目时,未注意项目的依赖库隔离;可能会导致后续给项目打包时:

  • 导致缺少依赖库,导致项目初始化麻烦
  • 读取了全局依赖库,导致项目安装了大量的实际无用的库

这里推荐一个专门解决这个问题的 Python 库, pipreqs

使用注意事项

# linux & mac
pipreqs $python_project_dir

# Windows 需要增加 --encoding=utf-8 字母编码,否则会有出错,懂得都懂
pipreqs ./ --encoding=utf-8

# 会自动在当前目录生成一个 requirements.txt, 如果已存在会提示失败
# 也可以使用 --force 强制覆盖
pipreqs . --force

支持的其他功能

更多的功能,可以在安装后研究下,通过 -h 可以获取更多有价值的信息

\--diff <file>         将 requirements.txt 中的模块与项目导入进行比较。  >> 仅追加
\--clean <file>     通过删除项目中没有导入的模块来清理 requirements.txt   >> 瘦身

2022-07-24 Python