跳到主要内容

OpenVPN 的 server.conf 配置

· 阅读需 1 分钟
push "route 192.168.11.0 255.255.255.0"

表示将路由下发给客户端. 当客户端连上 VPN 之后,服务器会通知客户端,到 192.168.11.0/24 这个网段流量,走 VPN 隧道。

route 192.168.11.0 255.255.255.0

CCD 文件 + iroute

route 192.168.11.0 255.255.255.0
client-config-dir ccd
iroute 192.168.11.0 255.255.255.0

让 OpenVPN 进程内部知道这个网段在某个特定客户端后面。

分片与副本机制研究

· 阅读需 2 分钟

Gemini: https://gemini.google.com/share/f5c5f79c9d34

导读

副本

  • 主从复制
  • 多主复制

分片

  • 数据在哪里分片?
    1. 在应用程序管理一个巨大的数据库连接池集合,对 JDBC 进行连接.(Apache-ShardingSphere-JDBC)
    2. 在应用程序与数据库之间搭建一个代理(Vitess)
  • 分片策略
    • 散列算法
    • 范围分片
    • 目录分片
    • 地理位置分片
    • 列表分片
    • 复合/混合分片
  • 读写分离
    • 读请求:负载均衡至所有分片
    • 写请求:请求主库
  • 数据聚合
    • 聚合函数
      • max,min
      • count
      • sum
      • avg -> sun/count
    • 关联查询
      • 从分片上下功夫,将关联条件作为分片的 key
      • 广播表(每个分片中都存在)
      • 数据冗余,避免关联查询
      • 在应用程序层面关联
  • 全局唯一 ID
    • UUID 的升级版(包含时间戳)
    • 号段模式(美团 Leaf)
    • 雪花算法(单机递增,全局趋势递增,时间回拨问题)
    • Redis 自增
    • Zookeeper 自增
  • 分布式事务

短链系统

  1. 号段模式(Segment) + 混淆加密(Feistel Cipher) + Base62 编码
  2. 独立预发号服务(Key Generation Service,KGS)
    • 独立的后台服务,在空闲时不断生成 6-7 位的 Base62 字符串
    • 查询数据库是否已存在
    • 从未使用密钥表中快速拿走一个可用的短字符串。
  3. uuid , 不推荐,长度太长
  4. 雪花算法,长度不符合,递增
  5. 哈希值,取前 6-7 位,有重复危险

Feistel Cipher 算法

  1. 将连续,自增的 ID 转换为完全随机,跳跃的密文整数
  2. 不会出现碰撞
  3. 生成的整数通过 base62 编码等到的字符串长度为 5-7
  4. 可以逆向解码

EditorConfig, ESLint, Prettier 之间的关系

· 阅读需 1 分钟

Gemini Deep research: https://gemini.google.com/share/2881e5f26082

EditorConfig

EditorConfig 是为了解决不同的操作系统,编辑器之间差异的。如 换行符,tab 字符的长度。对任何文本格式的文件生效。如 .md,Makefile,.yaml,.sh

从 JSLint 到 ESLint

在不运行代码的前提下,解析代码(AST 静态分析), 发现语法逻辑问题(未定义变量,类型错误等)

JSLint,不可配置 JSHint, 可配置,不支持第三方插件 ESLint, 一切皆可插拔

ESLint 要求每一个规则都是原子性的。

Prettier

Prettier 是为了解决代码格式化问题的。

  • 最大行宽
  • 括号对齐
  • 标签闭合
  • ...

eslint-config-prettier

解决 eslint 与 prettier 职责交叉的问题。

Oxlint

Rust 开发,性能更好。比 ESLint 快 50~100 倍

git log 命令过滤提交记录

· 阅读需 1 分钟
git log --grep="feat" --grep="接口" -i --oneline --all-match
  1. 单独使用 --grep="feat" --grep="接口" 表示过滤出 git commit message 包含 feat接口 的提交记录(OR 的逻辑). 如果加上 --all-match 表示要包含 feat接口。(AND 的逻辑
  2. -i 忽略大小写
  3. `--oneline

Markdown 中的 mermaid 语法

· 阅读需 3 分钟

注释: %%

Flowchart 流程图

  • TD 表示 "top-down"

  • LR 表示 "left-right"

节点形状

  • [矩形]
  • (圆角矩形)
  • {菱形} 用于判断条件
  • ((圆))

连接线

  • --> 带箭头的实线
  • --- 实线
  • ==> 加粗
  • -.-> 带箭头的虚线
  • |文字|,在线上添加文字, 或 --text-->
  • <--> 双向箭头

Sequence Diagram 时序图

参与者

  • participant 名字 参与者
  • actor 名字 将参与者显示为小人图标

消息交互

  • A->>B: 文字 实现箭头 请求
  • B-->>A: 文字 虚线剪头 响应

生命周期

  • activate A 激活 deactivate A 取消激活 表示一个参与者处于“处理中”的状态
  • ->>+ 激活 -->>- 取消激活

注释

  • Note right of A: 文字 在 A 的右侧添加注释

扫码登录

flowchart TD
Start((开始)) --> GetQR[PC端请求登录]
GetQR --> ShowQR[展示二维码]

subgraph Mobile [手机端操作]
Scan[用户打开App扫码] --> Auth{是否授权?}
Auth -->|是| AppConfirm[点击确认登录]
Auth -->|否| AppCancel[点击取消]
end

ShowQR -- 轮询/Scoket --> CheckState{检查二维码状态}

Scan -.-> CheckState
AppConfirm -.-> CheckState

CheckState -->|wait| ShowQR
CheckState -->|scan| Prompt[请在手机端确认]
Prompt --> CheckState

CheckState -->|过期| Expired[二维码失效]
Expired --> Refresh[点击刷新] --> GetQR

CheckState -->|登录成功| Success[获取 token/跳转首页]
Success --> End((结束))

subgraph ... end 表示把这一块逻辑框在一起,在视觉上把他们看成一个整体。

sequenceDiagram
autonumber
participant PC as 浏览器
participant Server as 服务器
participant Phone as 手机APP

Note over PC,Server: 阶段一:初始化二维码
PC->>Server: 1. 请求生成二维码(GET /qrcode)
Server-->>PC: 2. 返回二维码ID(UUID)

Note over PC,Server: 阶段二:轮询检测状态
loop 每隔2秒查询一次
PC->>Server: 3. 询问 UUID状态(GET /check?uuid=xyz)
alt 状态: 已扫码(WAITING)
Server-->>PC: keep waiting
else 状态: 已扫码(SACNNED)
Phone->>Server: 4. 扫码请求(POST /scan)
Server-->>PC: scanned(PC显示用户头像)
else 状态:已确认(CONFIRMED)
Phone->>Server: 5. 登录确认(POST /confirm)
Server-->>PC: token(登录凭证)
end
end

Note over PC: 阶段三: 登录完成
PC->>PC: 写入token并跳转首页
  1. autonumber 表示自动给箭头添加序号
  2. loop...end 表示循环块
  3. alt...else...end 表示 if -else if - else
  4. Note over ... 跨越多个参与者的注释,用于划分流程/阶段。

yaml 的数组语法

· 阅读需 1 分钟

块格式

fruits:
- Apple
- Orange
numbers:
- 1
- 2

流格式

fruits: ["Apple", "Orange"]
numbers: [1, 2]

对象数组

users:
- name: Alice
job: Engineer
active: true
- name: Bob
job: Designer
active: false

- 表示一个新的数组元素的开始。 name,hob,active 属于同一个对象。

多维数组

matrix_flow:
- [1, 2, 3]
- [11, 22, 33]
- [111, 222, 333]

yaml 的长文本语法

· 阅读需 1 分钟

保留换行 |

script: |
echo "hello wrold"
date

| 会保留每次换行。 (末尾有多个换行符时,只会保留一个)

{"script": "echo \"Hello World\"\ndate\n"}

折叠换行 >

description: >
aaa1
bbb2
ccc3

ddd4

> 会将换行符替换为空格。 如果包含空行,会保留一个换行符

{"description":"aaa1 bbb2 ccc3\ndddd4\n"}

剪裁控制

|- 删除末尾的 \n

|+ 保留末尾的 \n