渲染页面:浏览器的工作原理

大部分情况下,浏览器是单线程执行的.为了有流畅的交互,需要尽可能快的发送请求,减少网络等待时间.Web性能优化则需要尽可能快的

页面资源的访问

DNS 查找

  • 缓存
  • 递归
  • 权威
  • DNS 查找的问题
    • 移动端距离
    • TCP 协议
    • TLS 加密传输协议

TCP

8次往返后浏览器才发出请求

服务端响应

与 web 服务器建立连接后, 浏览器才发送初始的 HTTP GET 请求获取页面资源

响应

  • 一旦服务器收到请求,使用相关的 响应头 和 HTML 回复
  • 初始请求的响应包含所接收数据的第一个字节
  • “Time to First Byte” (TTFB) 是进行请求到收到第一个包之间的时间
  • 第一块 内容通常是14kb

TCP 慢开始 / 14kb 规则

  • 第一个响应包是 14kb 大小
  • 慢开始是一种均衡网络连接的速度的算法,逐渐增减发送数据的大小,直到最大网络带宽
  • 在收到 ACK 后 会加倍 包的大小 (直到阈值 或 遇到拥塞)

TCP slow start

这就是为什么web性能优化需要将此初始14Kb响应作为优化重点的原因

  • 比如 webpack 打包文件的大小限制
阅读全文

Python3.7 编译安装-SSL Module

https://bugs.python.org/issue34028

openssl1.1.1 编译安装

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
----- install_python3.7.sh ---- 
#!/bin/bash
set -euo pipefail

mkdir /tmp/openssl
cd /tmp/openssl
wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz
tar -xvf openssl-1.1.1a.tar.gz
cd openssl-1.1.1a
./config --prefix=/usr/local/openssl1.1.1 --openssldir=/usr/local/openssl1.1.1
make
make install
rm -rf /tmp/opensll

echo /usr/local/openssl1.1.1/lib > /etc/ld.so.conf.d/openssl1.1.1.conf
ldconfig

mkdir /tmp/python37
wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz
tar xfz Python-3.7.3.tgz
cd Python-3.7.3
./configure --with-ensurepip=yes --with-openssl=/usr/local/openssl1.1.1 CFLAGS="-I/usr/local/openssl1.1.1/include" LDFLAGS="-L/usr/local/openssl1.1.1/lib" CXX=/usr/bin/g++
make
make install
rm -rf /tmp/python37

ldconfig
--------------------

This important pieces are:

echo /usr/local/openssl1.1.1/lib > /etc/ld.so.conf.d/openssl1.1.1.conf
ldconfig

to make it find the .so to load it at runtime and

./configure --with-ensurepip=yes --with-openssl=/usr/local/openssl1.1.1 CFLAGS="-I/usr/local/openssl1.1.1/include" LDFLAGS="-L/usr/local/openssl1.1.1/lib" CXX=/usr/bin/g++

specifying the non-standard openssl-version specifically.

golang-heap-prority-queue-max-min-heap

golang 容器包中 heap 的使用

原文: https://golang.org/pkg/container/heap/

golang 中提供了可以使用 container/heap 操作所有实现了 heap.Interface 类型的 堆数据结构.
操作函数:

1
2
3
4
5
func Fix(h Interface, i int)
func Init(h Interface)
func Pop(h Interface) interface{}
func Push(h Interface, x interface{})
func Remove(h Interface, i int) interface{}

需要实现的接口:

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
type Interface interface {
sort.Interface
Push(x interface{}) // add x as element Len()
Pop() interface{} // remove and return element Len() - 1.
}

type sort.Interface interface {
// Len is the number of elements in the collection.
Len() int

// Less reports whether the element with index i
// must sort before the element with index j.
//
// If both Less(i, j) and Less(j, i) are false,
// then the elements at index i and j are considered equal.
// Sort may place equal elements in any order in the final result,
// while Stable preserves the original input order of equal elements.
//
// Less must describe a transitive ordering:
// - if both Less(i, j) and Less(j, k) are true, then Less(i, k) must be true as well.
// - if both Less(i, j) and Less(j, k) are false, then Less(i, k) must be false as well.
//
// Note that floating-point comparison (the < operator on float32 or float64 values)
// is not a transitive ordering when not-a-number (NaN) values are involved.
// See Float64Slice.Less for a correct implementation for floating-point values.
Less(i, j int) bool

// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}

阅读全文

k8s-cronjob-自动删除

使用 K8s CronJob 记录

在公司私有集群中部署了一个定时服务,结果一段时间之后产生了 大量的 UnavailablePods.
总结下操作的步骤

  1. 直接在 rancher 服务上创建 CronJob:

    • 配置了 镜像地址 , 服务名字,最大失败/成功数量…

    但结果就是 Pod 无限增长,所以开始另辟蹊径. 通过 yaml 创建 CronJob

  2. 初始 application/job/cronjob.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    apiVersion: batch/v1
    kind: CronJob
    metadata:
    name: hello
    spec:
    schedule: "*/1 * * * *"
    jobTemplate:
    spec:
    template:
    spec:
    containers:
    - name: hello
    image: busybox
    imagePullPolicy: IfNotPresent
    command:
    - /bin/sh
    - -c
    - date; echo Hello from the Kubernetes cluster
    restartPolicy: OnFailure

    执行结果:

    - `batch/v1` 不存在 , 当前k8s环境只有 `batch/v1beta1` 🤦‍♂️

    修改后结果一样,不会自动删除

阅读全文

wkhtmltox-docker-golang

使用 wkhtmltopdf 生成用户定时报表.pdf

方案选择

Golnag 渲染 HTML

template/template 包使用

图表渲染

wkhtmltopdf 使用上存在 JS 语法兼容的问题,目前只支持 ES5.所以在使用图表组件的时候需要确认开发支持的JS语法版本

  • Antv.G2.js
  • Echart.js

wkhtmltopdf-alpine 镜像,容器化部署

  • 使用 docker 多段构建 压缩镜像到最小
阅读全文