晨曦's Blog

This is a window to the soul

https://github.com/ccakes/nomad-pgsql-patroni

Highly available elephant herd: HA PostgreSQL cluster using Docker

https://github.com/zalando/spilo

HA 解决方案

https://github.com/bitnami/containers/tree/main/bitnami/postgresql-repmgr

patroni 方案

https://github.com/zalando/patroni/blob/master/docker-compose.yml

Cluster 解决方案 (不支持 Docker)

Patroni + HAProxy + Etcd + PgBouncer

https://github.com/vitabaks/postgresql_cluster

其他方案

https://www.jianshu.com/p/2fd3f4096493

https://blog.csdn.net/fly910905/article/details/125291186

https://zhuanlan.zhihu.com/p/640147253

1
peewee.OperationalError: (2013, 'Lost connection to MySQL server during query ([Errno 104] Connection reset by peer)')

原因是 peewee 不会主动去重连数据库

https://github.com/coleifer/peewee/issues/1992

如果在事务中也不会主动链接可以用如下方式

https://github.com/coleifer/peewee/issues/2628

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try:
MysqlClient.connect()
with MysqlClient.atomic():
for batch in chunked(lists, 100):
ProjectResourceUtilization.insert_many(
batch,
[
"cluster_name"
],
).execute()
MysqlClient.close()
return True, None
except Exception as error:
logging.info("项目资源使用率:" + str(error))
return False, str(error)

函数 TIMESTAMPDIFF

1
2
3
4
5
6
from peewee import SQL, fn

Task.select().where(
(Task.recent_sync_time.is_null(True))
| (fn.TIMESTAMPDIFF(SQL("MINUTE"), Task.recent_sync_time, fn.NOW()) > Task.interval)
)

注意这里的 MINUTE 必须使用 SQL 函数格式化,如:SQL("MINUTE")

参考

JSONField

Peewee 中本来是没有 JSONField 这个数据类型的,我们可以利用官方的扩展包

1
from playhouse.mysql_ext import JSONField

也可以通过自定义类型或者 jsonfield 这个三方包完成

参考

Model To Dict

1
2
3
4
5
6
7
from playhouse.shortcuts import model_to_dict

def get_data_list(info_id):
datas = Data.select().where(Data.info_id == info_id)
datas = [model_to_dict(data) for data in datas]
return datas

json_extract

1
2
3
4
Data.delete().where(
Data.info_id == info_id,
fn.json_extract(Data.data, "$." + field) == value,
).execute()

参考

https://fugary.com/?p=238

https://liyuyu.cn/post/synology-calibre-web-jour/

https://github.com/janeczku/calibre-web/blob/master/library/metadata.db

安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
docker create \
--name calibre-web \
-p 8080:8080 \
-p 8083:8083 \
-e UID=0 \
-e GID=0 \
-e ENABLE_CALIBRE_SERVER=true \
-e ENABLE_CALIBRE_SERVER_OPDS=true \
-e CALIBRE_SERVER_USER=admin \
-e CALIBRE_SERVER_PASSWORD=england_Spending_untagged4 \
-e CALIBRE_SERVER_WEB_LANGUAGE=zh_CN \
-e CALIBRE_WEB_LANGUAGE=zh_Hans_CN \
-v /volume1/docker/calibre-web:/config \
-v /volume1/books/calibre:/library \
-v /volume1/books/plug-in:/usr/local/calibre-web/app/cps/metadata_provider \
-v /volume1/books/autoaddbooks:/autoaddbooks \
johngong/calibre-web:0.6.23-7.9.0

需要手动启动容器

FAQ

1、web 或者 opds 下载图书 404

参考:https://github.com/gshang2017/docker/issues/233

前记

想在 Mac 中优雅的开启和关闭 http_proxy

实现

~/.zshrc 中加入以下函数

1
2
3
4
5
6
7
8
9
10
11
12
13
# on proxy
func onproxy () {
export http_proxy="http://127.0.0.1:1080"
export https_proxy="http://127.0.0.1:1080"
echo "Proxy ON"
}

# off proxy
func offproxy () {
unset http_proxy
unset https_proxy
echo "Proxy OFF"
}

使用

1
2
> onproxy
Proxy ON

前记

最近在升级 hexo 各种包的版本,对于升级推荐使用 npm-check-updates,这个包可以做所有 npm oudatednpm upgrade 能做的事情

安装

1
npm install -g npm-check-updates

检查

利用 ncu 检查包的版本,输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> ncu
Checking /hexo/package.json
[====================] 16/16 100%

hexo ^5.4.2 → ^6.3.0
hexo-deployer-git ^2.1.0 → ^4.0.0
hexo-generator-archive ^1.0.0 → ^2.0.0
hexo-generator-category ^1.0.0 → ^2.0.0
hexo-generator-index ^2.0.0 → ^3.0.0
hexo-generator-sitemap ^2.2.0 → ^3.0.1
hexo-generator-tag ^1.0.0 → ^2.0.0
hexo-pangu ^0.2.1 → ^0.2.2
hexo-renderer-ejs ^1.0.0 → ^2.0.0
hexo-renderer-marked ^3.3.0 → ^6.0.0
hexo-server ^2.0.0 → ^3.0.0
hexo-theme-next ^8.12.1 → ^8.15.0
hexo-word-counter 0.0.3 → 0.1.0

Run ncu -u to upgrade package.json

升级

upgrade package.json

1
ncu -u

install new versions

1
npm install

添加的 synocommunity 本来是没有问题的,最近发现没法显示相关组件,从新添加提示无效的位置

解决

1
sudo mv /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt.bak && sudo curl -Lko /etc/ssl/certs/ca-certificates.crt https://curl.se/ca/cacert.pem

参考:can’t add community repo - “invalid location” error - problem solved

前记

最近在使用 Caddy 的时候出现如下错误

1
2
3
4
5
6
7
8
9
10
Jan 05 02:16:47 C20230104172971 caddy[3271]: HOME=/root
Jan 05 02:16:47 C20230104172971 caddy[3271]: LOGNAME=root
Jan 05 02:16:47 C20230104172971 caddy[3271]: USER=root
Jan 05 02:16:47 C20230104172971 caddy[3271]: SHELL=/bin/sh
Jan 05 02:16:47 C20230104172971 caddy[3271]: INVOCATION_ID=91c06f7e038e4ed2a5e12d9d975650b1
Jan 05 02:16:47 C20230104172971 caddy[3271]: JOURNAL_STREAM=8:26524
Jan 05 02:16:47 C20230104172971 caddy[3271]: {"level":"info","ts":1672885007.9022179,"msg":"using provided configuration","config_file":"/etc/caddy/Caddyfile","config_adapter":""}
Jan 05 02:16:47 C20230104172971 caddy[3271]: run: loading initial config: loading new config: starting caddy administration endpoint: listen tcp 127.0.0.1:2019: bind: cannot assign>
Jan 05 02:16:47 C20230104172971 systemd[1]: caddy.service: Main process exited, code=exited, status=1/FAILURE
Jan 05 02:16:47 C20230104172971 systemd[1]: caddy.service: Failed with result 'exit-code'.

解决

Caddyfile 开头增加下面配置即可

1
2
3
{
admin 0.0.0.0:2019
}

IP

首先找到 google.cn 在大陆可用的 IP,可以利用下面 chinaz

https://ping.chinaz.com/google.cn

尽量找延迟低一点的 IP

Host

修改 HostWindows 如:C:\Windows\System32\drivers\etc\hosts

将下面记录加入到 hosts 文件

1
180.163.151.162 translate.googleapis.com

参考


题外话:Chrome 翻译插件可以用火山翻译,字节出品还比较好用

Go 语言中生成特定长度和特定组合的密码

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
31
32
33
34
35
36
37
38
39
package utils

import (
"fmt"
"math/rand"
"time"
)

const (
NUmStr = "0123456789"
CharStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
SpecStr = "!@#$%&"
)

func GeneratePasswd(length int, charset string) string {
var passwd []byte = make([]byte, length, length)
var sourceStr string

if charset == "num" { // 数字
sourceStr = NUmStr
} else if charset == "char" { // 字母
sourceStr = charset
} else if charset == "mix" { // 数字、字母混合模式
sourceStr = fmt.Sprintf("%s%s", NUmStr, CharStr)
} else if charset == "advance" { // 数字、字母、字符混合模式
sourceStr = fmt.Sprintf("%s%s%s", NUmStr, CharStr, SpecStr)
} else {
sourceStr = NUmStr
}
// fmt.Println("source:", sourceStr)

// 生成密码
rand.Seed(time.Now().UnixNano())
for i := 0; i < length; i++ {
index := rand.Intn(len(sourceStr))
passwd[i] = sourceStr[index]
}
return string(passwd)
}
0%