python 代码性能分析工具
环境信息
- python 3.10
pyinstrument 使用
pyinstrument 可以快速找到代码运行最慢的部分,帮助提高代码的性能。支持 Python 3.7+ 且能够分析异步代码,仅需一条命令即可显示具体代码的耗时 [1]
安装
pip install pyinstrument |
命令行使用
在无需更改代码的情况下,直接通过命令行使用 pyinstrument 分析目标代码
pyinstrument main.py |
pyinstrument 可以快速找到代码运行最慢的部分,帮助提高代码的性能。支持 Python 3.7+ 且能够分析异步代码,仅需一条命令即可显示具体代码的耗时 [1]
pip install pyinstrument |
在无需更改代码的情况下,直接通过命令行使用 pyinstrument 分析目标代码
$ pyinstrument main.py |
Python 中操作 json 相关格式,主要使用模块 json
python 数据类型转换为 json ,主要使用方法 dumps()
>>> adict = {'a': 1, 'b': 'st'} |
>>> ajson = '[1, 2, 3, 4]' |
docker pull mysql:5.7.31 |
启动容器前先在本地创建 Mysql 数据目录以用来持久化 Mysql 数据,如果需要配置文件,可以在本地创建好配置文件挂载到容器的 /etc/mysql/my.cnf,无需配置文件的话,则只需要将持久化的本地数据目录挂载到容器默认的数据目录 /var/lib/mysql,本示例中 Mysql 本地持久化数据目录为 /opt/docker_mysql_home/data/。使用以下命令启动容器
docker run -d --name mysql -v /opt/docker_mysql_home/data/:/var/lib/mysql/ -p 3306:3306 \ |
-e MYSQL_ROOT_PASSWORD=123456 通过环境变量配置 Mysql 初始化后的密码
容器启动后,通过以下命令连接数据库
mysql -h 127.0.0.1 -uroot -p |
通过配置 Live Template 实现快速插入时间
打开 File > Setting > Editor: Live Templates
选中常用的语言,比如 Python,点击右上角的 +,添加 Live Template
Abbreviation 输入快捷输入的名称,比如 currentTime
Description 输入描述信息
Template Text 输入 $time$

点击 Edit Variables 配置命令及格式

Define 选择 Everywhere,Apply让配置生效
编辑时输入 currentTime,可以直接插入当前时间

打开 File -> Settings -> Version Control -> Git,在 Path to Git executable 处选择 git 的安装位置。配置完成之后,点击【Test】按钮,如果成功,则会显示 Git 版本信息
点击 VCS -> Get from Version Control,输入 Git 仓库的地址和本地目录。
本文档中涉及服务器的操作,都是在 Kubernetes 集群的 Master 节点上进行。如果在其他服务器启动 Halyard 容器,需要确保容器中可以访问到 Kubernetes 集群的 API Server
宿主机创建 local Halyard config directory [1]
mkdir /root/spinnaker_data |
Spinnaker 的部署配置会写入容器目录 /home/spinnaker/.hal,将此配置映射到宿主机,可保证配置持久化。
拷贝 Kubernetes 集群管理配置文件到 /root/spinnaker_data/.kube/config [2]
cp /etc/kubernetes/admin.conf /root/spinnaker_data/.kube/config |
随着 HTTPS 不断普及,越来越多的网站都在从 HTTP 升级到 HTTPS,使用 HTTPS 就需要向权威机构申请证书,需要付出一定的成本,如果需求数量多,也是一笔不小的开支。cert-manager 是 Kubernetes 上的全能证书管理工具,如果对安全级别和证书功能要求不高,可以利用 cert-manager 基于 ACME 协议与 Let’s Encrypt 来签发免费证书并自动续期,实现永久免费使用证书。
cert-manager 部署到 Kubernetes 集群后,它会 watch 它所支持的 CRD 资源,我们通过创建 CRD 资源来指示 cert-manager 为我们签发证书并自动续期: [1]
解释下几个关键的资源:
Issuer/ClusterIssuer: 用于指示 cert-manager 用什么方式签发证书,本文主要讲解签发免费证书的 ACME 方式。ClusterIssuer 与 Issuer 的唯一区别就是 Issuer 只能用来签发自己所在 namespace 下的证书,ClusterIssuer 可以签发任意 namespace 下的证书。Certificate: 用于告诉 cert-manager 我们想要什么域名的证书以及签发证书所需要的一些配置,包括对 Issuer/ClusterIssuer 的引用。ConfigMap 是 Kubernetes 用来向应用 Pod 中注入配置数据的方法。[1]
ConfigMap 中将环境变量定义为键值对: kubectl create configmap special-config --from-literal=special.how=very |
apiVersion: v1 |
SPECIAL_LEVEL_KEY=very。| 文件/目录 | 说明 | 示例 |
|---|---|---|
/etc/kubernetes/{admin.conf, controller-manager.conf, kubelet.conf, scheduler.conf } |
master 管理节点上的管理节点(admin,controller-manager,kubelet,scheduler)配置文件 admin 配置文件具有全局管理员权限,可以跳过 RBAC 权限控制系统,应该禁止其共享。 |
|
/etc/kubernetes/kubelet.conf |
worker 节点上,kubelet 配置文件 |
|
/etc/kubernetes/manifests/ |
管理节点上,管理节点的启动参数配置文件,主要包括 etcd.yaml, kube-apiserver.yaml, kube-controller-manager.yaml, kube-scheduler.yaml。是静态 Pod 的主要配置路径 |
|
/etc/kubernetes/pki/ |
- 管理节点上,存放所有节点之间的通信证书文件, - worker 节点上,存放集群 CA 证书文件。 只有 ca.crt |
|
/etc/cni/net.d/10-flannel.conflist |
管理节点上,flannel 配置文件 |

TCP 连接通信过程中,client 和 server 端各自维护自己的 seq。后面一个数据包的 seq 是前面一个数据包的 seq 加上前面一个数据包的大小。表示发送的字节位置。
假如当前连接中,之前一个包 seq = 100,其发送数据包大小为 0,则当前要发送的数据包的 seq = 0
假如当前连接中,之前一个包 seq = 100,其发送数据包大小为 20,则当前要发送的数据包的 seq = 120
TCP 连接通信过程中,client 和 server 端要发送给对方的包的 ACK 的值为:收到的包的 seq + 收到的包的 Len,此值告知发送方,接收方希望接收到的下一个包的序列号。
假如接收方接收到了 seq = 100 ,Len = 0 的包,接收方需要发送的 ACK = 100 + 1
假如接收方接收到了 seq = 100 ,Len = 20 的包,接收方需要发送的 ACK = 100 + 20
Wireshark 提供了两种过滤器
这两种过滤器所使用的语法是完全不同的,捕捉网卡数据的其实并不是 Wireshark,而是 WinPcap,要按 WinPcap 的规则来,显示过滤器就是 Wireshark 对已捕捉的数据进行筛选。
| 符号 | 说明 | 示例 |
|---|---|---|
eq== |
等于 | ip.src==10.10.10.10 ip.src eq 10.10.10.10 |
ne!= |
不等于 | ip.src!=10.10.10.10 ip.src ne 10.10.10.10 |
gt> |
大于 | |
lt< |
小于 | |
ge>= |
大于等于 | |
le<= |
小于等于 | |
contains |
包含 | http.host contains com |
| 符号 | 说明 | 示例 |
|---|---|---|
and&& |
与 | http.host contains com && ip.src == 44.199.163.86http.host contains com and ip.src == 44.199.163.86 |
or|| |
或 | |
not! |
非 |
ip.src == 192.168.0.1ip.dst == 192.168.0.1ip.addr == 192.168.0.1! 即可!(ip.addr == 192.168.0.1)针对某种协议的数据包,表达式很简单仅仅需要把协议的名字(必须小写)输入即可
常见协议:tcpudparpicmphttpsmtpftpdnsmsnmsipssloicqbootp
tcp.port == 80and 来连接,下面是捕获高于某端口的表达式(以 udp 协议为例)udp.port >= 2048user 的请求,不包括域名http.request.uri contains "User"http.host==baidu.comhttp.host contains "baidu"http.content_type =="text/html"http.request.method=="POST"tcp.port==80http && tcp.port==80 or tcp.port==5566http.response.code==302http.cookie contains "userid"Kubernetes 中的 Namespace,对应 Spinnaker 中的 Application,当 在 Kubernetes 中创建 Namespace ,并在此 Namespace 创建资源后,Spinnaker 会自动读取到此 Namespace,并显示在 Applications 中。
在 Pipelines 中配置 Docker Registry 类型的触发器,并在后面的 Stage 中自动引用。
在要配置的 Pipeline 的 Configuration 部分,配置 Automated Triggers,选择 type 为 Docker Registry

Stage 中使用以下方式引用镜像
image: '${trigger.artifacts[0].reference}'
${trigger} 为镜像名称,当一个镜像名下有多个不同标签的镜像时,${trigger.artifacts[0] 表示第一个镜像,依此类推。${trigger.artifacts[0].reference} 值为第一个镜像的完整镜像名加标签。

常用选项
| 选项 | 说明 | 示例 |
|---|---|---|
-R, -r, --recursive |
递归拷贝 | |
-p, --preserve |
拷贝时保留文件信息(default: mode,ownership,timestamps) |
cp -rf dir1/* dir2/
使用此格式拷贝时,假如 dir1 下面包含隐藏文件,拷贝时隐藏文件不会被拷贝过去
$ tree -a |
如上所示的目录结构,执行命令 cp -rf dir1/* dir2/,观察目录结构:
$ tree -a |
看见,dir/.test 未被拷贝,如果拷贝时希望同时保护隐藏文件,可以使用 . 代替 *
$ tree -a |
官方镜像仓库 中搜索 jenkinsci/blueocean,下载最新镜像
docker pull jenkinsci/blueocean |
创建数据目录
mkdir /data/JenkinsData_blueocean |
启动 jenkins 容器
docker run -d -p 8080:8080 --name jenkins \ |
-v /var/run/docker.sock:/var/run/docker.sock - 在需要使用 Jenkins 构建 Docker 镜像时,Jenkins 容器中的 docker 客户端需要连接到宿主机的 Docker server-v /data/JenkinsData_blueocean/:/var/jenkins_home/ - 数据持久化到宿主机目录-u root - 容器中使用 root 用户运行,要使用 Jenkins 构建 Docker 镜像时,默认的 jenkins 用户无权限访问 /var/run/docker.sock| 环境 | 服务器 | 服务 | 端口 |
|---|---|---|---|
pro |
172.31.88.1 | apollo-portal | 8070 |
pro |
172.31.88.1 | 数据库 ApolloPortalDB | 3306 |
pro |
172.31.88.1 | apollo-configservice | 8080 |
pro |
172.31.88.1 | apollo-adminservice | 8090 |
pro |
172.31.88.1 | 数据库ApolloConfigDB | 3306 |
pro |
172.31.82.2 | apollo-configservice | 8080 |
pro |
172.31.82.2 | apollo-adminservice | 8090 |
uat |
172.31.83.3 | apollo-configservice | 8080 |
uat |
172.31.83.3 | apollo-adminservice | 8090 |
uat |
172.31.83.3 | 数据库ApolloConfigDB | 3306 |
其中 172.31.88.1、172.31.82.2 为 pro 环境的高可用节点。172.31.83.3 为 uat 环境的单节点。
apollo-portal 和 ApolloPortalDB 部署在 pro 环境,uat 环境共用 apollo-portal 和 ApolloPortalDB。
yum localinstall -y http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm |
如果因为源冲突,类似如下错误
Processing Conflict: mysql80-community-release-el7-2.noarch conflicts mysql57-community-release |
可以卸载旧的 yum 源安装包,重新安装
$ rpm -qa | grep mysql |
检查 yum 源中的 mysql-community-server 信息
$ yum info mysql-community-server |
wget https://github.com/goharbor/harbor/releases/download/v2.6.1/harbor-offline-installer-v2.6.1.tgz |
将申请好的证书上传到服务器,将 harbor.crt 转换为 harbor.cert
openssl x509 -inform PEM -in harbor.crt -out harbor.cert |
将转换好的证书和私钥拷贝到 Docker 的证书目录 /etc/docker/certs.d/yourdomain.com/
cp yourdomain.com.cert /etc/docker/certs.d/yourdomain.com/ |
重启 Docker
systemctl restart docker |
执行 install.sh 命令安装 Harbor 时,会使用配置文件 harbor.yml(需要拷贝安装包中的 harbor.yml.tmpl 为 harbor.yml)。
修改配置中的 hostname 选项,配置访问 Harbor 的域名。此为必须修改的参数。
修改配置中的 https.certificate 和 https.private_key,配置证书(harbor.crt)和私钥的路径,使用 HTTPS 时必须配置。
修改配置中的 data_volume,指定持久化数据卷的路径。默认为 data_volume: /data
本文档记录 GitLab 上面的代码更新时,使用 Jenkins 自动构建 Docker 镜像的过程。
docker run -d -p 8080:8080 --name jenkins \ |
以下分别记录使用 freestyle 和 Pipeline 类型的构建镜像的配置过程
freestyle 类型的 Item 构建镜像在 源码管理(Source Code Management) 中配置 git 地址,并配置认证
默认情况下,在构建时,Jenkins 会先从配置的 Git 地址拉取代码到 Jenkins 目录:
/var/jenkins_home/workspace/${PROJECT_NAME}
在 构建(Build) 中 Add build step ,选择构建类型为 Execute shell,此处构建的示例项目代码结构如下,其中 Dockerfile 路径为 k8s/server/Dockerfile
.: |
使用如下 shell 脚本
#!/bin/sh |

其中的
${Branch}来自 参数化的构建
为观察 Kubernetes 集群中跨主机 POD 之间的网络通信数据流,本文通过 tcpdump 抓包,对数据流向进行记录观察。
本示例中的 Kubernetes 集群由以下节点组成:
| 节点主机名 | 节点角色 | 节点 IP | 节点上测试 POD IP |
|---|---|---|---|
| master | master | eth0: 10.150.0.21 | 10.244.0.2 |
| worker1 | worker | eth0: 10.150.0.19 | 10.244.1.38 |
| worker2 | worker | eth0: 10.150.0.20 | 10.244.2.27 |
Kubernetes 系统上 POD 网络的实现依赖于第三方插件,Kubernetes 只负责提供了 CNI(容器网络接口),只要符合 CNI 规则的第三方插件都可以用于为 POD 提供网络实现。而 Flannel 是由 CoreOS 主推的目前比较主流的容器网络解决方案。
Flannel 支持三种不同后端实现,分别是:
UDP 是 Flannel 项目最早支持的一种方式,是性能最差的方式,目前已被废弃。
用的最多的是 VXLAN 和 host-gw 模式的部署。