0%

有4个关键点:

  1. 对于导出数据中任意一行,尽量做到只做一次数据库查询,如果 Django 原生不支持,那就写 SQL 语句
  2. 只查询导出的字段,不要查询不需要的字段
  3. 分批获取数据,建议每次获取 10000 行(并非绝对,可以先用 SQL 语句在数据库查询,取一个较优的数值)
  4. 使用 StreamingHttpResponse 做流式响应(文本文件可以边查边响应,二进制文件就在临时文件生成之后再响应)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from django.db.models import Q
from django.http import StreamingHttpResponse

from sample.models import Bicycle


def export_csv(request):
heads = ('bicycle_num', 'bicycle_type', 'body_num',
'platform_qrcode', 'put_status', 'bicycle_qrcode', 'created_time',)

def query_data():
q = Q()
limit, offset = 10000, 0
while True:
bicycles = Bicycle.objects.filter(q).values(*heads)[offset: offset + limit]
if len(bicycles) == 0:
break
yield bicycles
offset += limit

def _to_csv():
yield ','.join(heads) + '\n'
for data in query_data():
for row in data:
yield ','.join([f'"{row[head]}"' for head in heads]) + '\n'

return StreamingHttpResponse(_to_csv(), headers={
'content_type': 'application/csv',
'content-disposition': 'attachment; filename=export.csv',
})
Read more »

requirements

1
2
3
4
5
6
7
8
django
gunicorn
gevent # use this if you use gevent workers
# eventlet # use this if you use eventlet workers
psycopg2-binary
psycogreen
django-db-geventpool
celery
Read more »

Kaniko 是一种在容器或 Kubernetes 集群内从 Dockerfile 构建容器镜像的工具。

Kaniko 不依赖于 Docker 守护进程,而是完全在用户空间中执行 Dockerfile 中的每个命令。 这使得在无法轻松或安全地运行 Docker 守护程序的环境中构建容器镜像成为可能,例如标准的 Kubernetes 集群。

下面是一个使用 Docker 构建并将镜像上传到 gcr.io 服务器的示例:

1
2
3
4
5
6
7
docker run \
-v "$HOME"/.config/gcloud:/root/.config/gcloud \
-v /path/to/context:/workspace \
gcr.io/kaniko-project/executor:latest \
--dockerfile /workspace/Dockerfile \
--destination "gcr.io/$PROJECT_ID/$IMAGE_NAME:$TAG" \
--context dir:///workspace/

Cryptography 是 Python 中的一个加密库,它只能在 Python3.6+PyPi3 7.2+ 上使用。

可以直接使用下面命令安装:

1
pip install cryptography

生成密钥对

1
2
3
4
from cryptography.hazmat.primitives.asymmetric import rsa

private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()

导出密钥对

可以生成多个格式的文件。

导出私钥

1
2
3
4
5
6
7
8
9
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption

for encoding in Encoding:
for fmt in PrivateFormat:
try:
# 无密码私钥
print(encoding, fmt, private_key.private_bytes(encoding, fmt, NoEncryption()))
except ValueError:
pass
Read more »

GoPathGolang 的工作空间,所有的 go 文件都必须放在 GoPath 目录下,才能编译运行。 这样做有以下明显的缺点:

  1. 第三方依赖的包和我们自己的 Golang 包混在一起,会给我们的项目文件管理带来一定的麻烦。
  2. 不同的 GoPath 都需要下载依赖,那么磁盘中重复的依赖就会非常多,会占用我们大量的磁盘空间。

GoModulego1.11 初步引入,go1.12 正式引入的概念,它用来管理项目文件。 但是在 go1.11go1.12 中默认是关闭的,可以设置 GO111MODULE=on 来开启 GoModule。 从 go1.13 开始,Golang 默认开启 GoModule,它会根据项目结构中是否包含 go.mod 文件来自动判断。

由此,引出一个疑问:有了 GoModule 之后,GoPath 是否无用了?

其实不然,在有了 GoModule 之后,GoPathGoModule 可以分别负责不同的职责:

  • 使用 GoPath 管理 Golang 依赖
  • 使用 GoModule 管理项目文件

在使用 GoModule 时,需要先执行命令 go mod init 模块名 进行初始化,例如: go mod init github.com/user/example

AssertionError [ERR_ASSERTION]: Task function must be specified

gulpfile.js 代码如下:

1
gulp.task('default', ['build'], () => {});

执行抛出异常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
AssertionError [ERR_ASSERTION]: Task function must be specified
at Gulp.set [as _setTask] (/path/to/project/node_modules/undertaker/lib/set-task.js:10:3)
at Gulp.task (/path/to/project/node_modules/undertaker/lib/task.js:13:8)
at Object.<anonymous> (/path/to/project/gulpfile.js:19:6)
at Module._compile (internal/modules/cjs/loader.js:1072:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
at Module.load (internal/modules/cjs/loader.js:937:32)
at Function.Module._load (internal/modules/cjs/loader.js:778:12)
at Module.require (internal/modules/cjs/loader.js:961:19)
at require (internal/modules/cjs/helpers.js:92:18)
at requireOrImport (/path/to/project/node_modules/gulp-cli/lib/shared/require-or-import.js:19:11) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '=='
}

经过查找,上述写法只能用于 gulp4 之前的版本,gulp4 之后改用以下写法:

1
2
3
gulp.task('default', gulp.parallel('build'), () => {})  // 并行
// or
gulp.task('default', gulp.series('build'), () => {}) // 串行

x509: cannot validate certificate for <ipaddress> because it doesn’t contain any IP SANs

一般情况下,证书会包含一些信息,如国家机构ip域名等等。 这个问题发生的时机在客户端访问服务器,如果证书中没有包含当前访问的ip域名等信息时,就会产生这个问题。

SkyWalking 是一款分布式链路追踪系统。

OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台, 其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。 用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

Read more »

pod内容器之间相互访问

由于 pod 内容器共享一个网络命名空间(network namespace), 故 pod 内容器之间可以直接使用 localhost 互相访问。

pod之间容器相互访问

address description
{service_name}.{namespace}.svc.cluster.local cluster.local 指的是集群域名
{service_name}.{namespace}.svc 集群内访问 svc
{service_name}.{namespace} 集群内访问 svc
{service_name} 集群内同一 namespace 内访问 svc