kk Blog —— 通用基础


date [-d @int|str] [+%s|"+%F %T"]
netstat -ltunp
sar -n DEV 1

Base64编码知识详解

https://www.cnblogs.com/jimojianghu/p/15993027.html

在我们进行前端开发时,针对项目优化,常会提到一条:针对较小图片,合理使用Base64字符串替换内嵌,可以减少页面http请求。 并且还会特别强调下,必须是小图片,大小不要超过多少KB,等等。

那么,Base64又到底是什么呢?

初步认识

下面的这段字符串,应该是大家都很常见的。通过这种固定的格式,来表示一张图片,并被浏览器识别,可以完整的展示出图片:

1
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......

这里展示的是一个svg格式的图片,当然我们还可以加载任何浏览器支持的格式的图片。

这段字符串就是基于Base64编码得来的,其中base64,后面那一长串的字符串,就是Base64编码字符串。

Base64是怎么诞生的

互联网发展早起,电子邮件是最有效的应用。

而电子邮件的SMTP传输协议在早期,只能用于传送7位的ASCII码,而ASCII码就是基于英语设计的,对于非英语国家的文字等资源就无法发送。

为了解决这个问题,后来有了通用互联网邮件扩充MIME,增加了邮件的主体结构,定义了非ASCII码的编码传输规则,这就是Base64。

关于字符编码的知识,请查看前端开发中需要搞懂的字符编码知识

基础定义

Base64是基于64个可打印字符来表示二进制数据的编解码方式。

正因为可编解码,所以它主要的作用不在于安全性,而在于让内容能在各个网关间无错的传输。

这64个可打印字符包括大写字母A-Z、小写字母a-z、数字0-9共62个字符,再加上另外2个 + 和 /。

Base64是一种索引编码,每个字符都对应一个索引,具体的关系图,如下:

这也是名称中64的由来。

编码方式

由于64等于2的6次方,所以一个Base64字符实际上代表着6个二进制位(bit)。

然而,二进制数据1个字节(byte)对应的是8比特(bit),因此,3字节(3 x 8 = 24比特)的字符串/二进制数据正好可以转换成4个Base64字符(4 x 6 = 24比特)。

为什么是3个字节一组呢? 因为6和8的最小公倍数是24,24比特正好是3个字节。

具体的编码方式:

1
2
3
4
5
将每3个字节作为一组,3个字节一共24个二进制位
将这24个二进制位分为4组,每个组有6个二进制位
在每组的6个二进制位前面补两个00,扩展成32个二进制位,即四个字节
每个字节对应的将是一个小于64的数字,即为字符编号
再根据字符索引关系表,每个字符编号对应一个字符,就得到了Base64编码字符

上图中的字符串 ‘you',经过转换后,得到的编码为: 'eW91'。

体积增大

我们可以看到,当3个字符进行Base64转换编码后,最后变成了4个字符。因为每个6比特位,都补了2个0,变成8比特位,对应1字节。

这里正好多了三分之一,所以正常情况下,Base64编码的数据体积通常比原数据的体积大三分之一。

这也是为什么我们在前面讲使用Base64编码优化图片时,需要强调是小图标,如果图片都使用该方式,则静态文件会增大很多,并不合适。

= 等号

3个英文字符,正好能转成4个Base64字符。那如果字符长度不是3的倍数,那应该使用什么样的规则呢?

其实也简单,我们在实际使用Base编码时,常会发现有第65个字符的存在,那就是 ‘=’ 符号,这个等于号就是针对这种特殊情况的一种处理方式。

对于不足3个字节的地方,实际都会在后面补0,直到有24个二进制位为止。

但要注意的是,在计算字节数时,会直接使用总长度除以3,如果余数为1则会直接在最后补一个=,如果余数为2则补两个=。

因此,转码后的字符串需要补的后缀等号,要么是1个,要么是2个,具体的可以见下图:

图中第二个,使用的是单独的字符 ’d',是为了区分索引字符表里的索引0,这个时候,得到编码中,会存在一个索引0对应的A字符,而'=‘是直接补上2个。

非ASCII码字符

由于 Base64 仅可对 ASCII 字符进行编码,如果是中文字符等非ASCII码,就需要先将中文字符转换为ASCII字符后,再进行编码才行。

编解码方法

btoa 和 atob

JavaScript提供了两个原生方法,用来处理Base64编码:btoa() 和 atob()。

btoa(): 将字符串或二进制值转换成Base64编码字符串。

注意:btoa方法只能直接处理ASCII码的字符,对于非ASCII码的字符,则会报错。

atob(): 对base64 编码的字符串进行解码。

注意:atob方法如果传入字符串参数不是有效的Base64编码(如非ASCII码字符),或者其长度不是4的倍数,会报错。

1
2
3
4
5
btoa('you')  // 'eW91'
atob('eW91') // 'you'

btoa('中') // Uncaught DOMException: The string to be encoded contains characters outside of the Latin1 range.
atob('y')  // Uncaught DOMException: The string to be decoded is not correctly encoded.

处理中文字符

由于btoa、atob 仅支持对ASCII字符编码,也就是单字节字符,而我们平时的中文都是 2-4 字节的字符。

因此,可以先将中文字符转为 utf-8 的编码,将utf-8编码当做字符,这样就可以对多个单字节字符进行编码。

对于中文可以使用这两个方法: encodeURIComponent() 和 decodeURIComponent()。

1
2
3
encodeURIComponent():将非ACSII码的字符进行utf-8编码

decodeURIComponent():解码使用

如下,编解码中文的方式:

1
2
3
4
5
window.btoa(encodeURIComponent('中国'))
// 'JUU0JUI4JUFEJUU1JTlCJUJE'

decodeURIComponent(window.atob('JUU0JUI4JUFEJUU1JTlCJUJE'))
// '中国'

第三方库

js-base64

前端常见应用

接下来,我们了解下前端开发中常见的对Base64编码的一些使用场景。

Base64在前端方面的应用,多数都是针对图片的处理,一般都是基于DataURL的方式来使用。

Data URL 由 data:前缀、MIME类型(表明数据类型)、base64标志位(如果是文本,则可选)以及 数据本身 四部分组成。

具体的格式:data:[<mime type>][;base64],<data>

这里的第四部分 <data> 数据本身,就是一个Base64字符串。

小图片转码

即开篇说的针对图片优化,使用Base64能减少请求数的,可以在img标签下,或者css中:

1
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......Ii8+PC9nPjwvc3ZnPg==">
1
2
3
.icon {
	background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0c......Ii8+PC9nPjwvc3ZnPg==);
}

当我们使用vue或react框架时,也可以通过url-loader来配置,图标转Base64的大小:

1
2
3
4
5
.loader('url-loader')
.tap(options => {
	options.limit = 10240 // 10kb
	return options
})

文件读取

Web环境下,有提供 FileReader 的API,用来读取文件的数据,可以通过它的 readAsDataURL() 方法,将文件数据读取为Base64编码的字符串数据:

1
2
3
4
5
let reader = new FileReader()
reader.onload = () => {
	let base64Img = reader.result
};
reader.readAsDataURL(file)

该方法常用在图片上传中。

Canvas生成图片

Canvas本质上是一个位图图像,它有提供 toDataURL() 方法,将画布导出生成为一张图片,该图片将以Base64编码的格式进行保存。

1
2
const dataUrl = canvasEl.toDataURL()
// data:image/png;base64,PHN2ZyB4bWxucz0iaHR0c......

其他

处理图片展示外,还会在特殊数据传输、简单编码和加密、代码混淆、部分证书中,见到Base64编码字符串。

总结

最后再来总结一下Base64的特点:

将二进制数据转为字符串(ASCII码),方便数据传输。

浏览器能直接展示Base64编码图片,减少请求。

编码后数据会大至少三分之一,需要额外的方法处理编解码。

CentOS 多IP配置

https://www.cnblogs.com/dachenyi/p/15980164.html

https://www.cnblogs.com/jiftle/p/16692400.html

关闭 rp_filter 校验

在 /etc/sysctl.conf 或 /usr/lib/sysctl.d/50-default.conf 中关闭反向过滤

反向过滤指系统在接收到一个 IP 包后检查该 IP 是否符合要求,不合要求则被丢弃。

例如:用户在 A 网卡上收到一个 IP 包,发送 IP 为 B。而给 B 的 IP 发送时用的网卡不是 A,则会丢弃。由于默认路由走的是主网卡,所以开启反向过滤后,辅助网卡上的 IP 会 ping 不通。

net.ipv4.conf.default.rp_filter = 0 net.ipv4.conf.all.rp_filter = 0

cfg

cd /etc/sysconfig/network-scripts/

vim ifcfg-eth0

1
2
3
4
5
6
7
8
IPADDR0=172.27.0.10
IPADDR1=172.27.0.11
PREFIX=24
GATEWAY0=172.27.0.1
GATEWAY1=172.27.0.1

DEFROUTE=yes      # 双网卡都配网关
IPV4_ROUTE_METRIC=10  # 0-100 数字越小优先级越高,但是默认网关只能有一个,相当于主备网关, 只有当主网关断掉了,备用网关才会生效

nginx中的timeout超时设置

https://blog.csdn.net/HD243608836/article/details/111564684

nginx比较强大,可以针对单个域名请求做出单个连接超时的配置. 

比如些动态解释和静态解释可以根据业务的需求配置

1
2
3
4
5
proxy_connect_timeout :后端服务器连接的超时时间_发起握手等候响应超时时间

proxy_read_timeout:连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)

proxy_send_timeout :后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据

nginx使用proxy模块时,默认的读取超时时间是60s。

1、请求超时

1
2
3
4
5
6
7
8
9
10
11
12
13
http {
    include       mime.types;
    server_names_hash_bucket_size  512;     
    default_type  application/octet-stream;
    sendfile        on;

    keepalive_timeout  65;  #保持
    tcp_nodelay on;
    client_header_timeout 15;
    client_body_timeout 15;
    send_timeout 25;
    include vhosts/*.conf;
}

2、后端服务器处理请求的时间设置(页面等待服务器响应时间)

1
2
3
4
5
location / {
	...
	proxy_read_timeout 150;  # 秒
	...
}

nginx常用的超时配置说明

client_header_timeout

语法 client_header_timeout time

默认值 60s

上下文 http server

说明 指定等待client发送一个请求头的超时时间(例如:GET / HTTP/1.1).仅当在一次read中,没有收到请求头,才会算成超时。如果在超时时间内,client没发送任何东西,nginx返回HTTP状态码408(“Request timed out”)

client_body_timeout 

语法 client_body_timeout time

默认值 60s

上下文 http server location

说明 该指令设置请求体(request body)的读超时时间。仅当在一次readstep中,没有得到请求体,就会设为超时。超时后,nginx返回HTTP状态码408(“Request timed out”)

keepalive_timeout 

语法 keepalive_timeout timeout [ header_timeout ]

默认值 75s

上下文 http server location

说明 第一个参数指定了与client的keep-alive连接超时时间。服务器将会在这个时间后关闭连接。可选的第二个参数指定了在响应头Keep-Alive: timeout=time中的time值。这个头能够让一些浏览器主动关闭连接,这样服务器就不必要去关闭连接了。没有这个参数,nginx不会发送Keep-Alive响应头(尽管并不是由这个头来决定连接是否“keep-alive”)

两个参数的值可并不相同

1
2
3
4
5
6
    注意不同浏览器怎么处理“keep-alive”头
    MSIE和Opera忽略掉"Keep-Alive: timeout=<N>" header.
    MSIE保持连接大约60-65秒,然后发送TCP RST
    Opera永久保持长连接
    Mozilla keeps the connection alive for N plus about 1-10 seconds.
    Konqueror保持长连接N秒

lingering_timeout

语法 lingering_timeout time

默认值 5s

上下文 http server location

说明 lingering_close生效后,在关闭连接前,会检测是否有用户发送的数据到达服务器,如果超过lingering_timeout时间后还没有数据可读,就直接关闭连接;否则,必须在读取完连接缓冲区上的数据并丢弃掉后才会关闭连接。

resolver_timeout

语法 resolver_timeout time 

默认值 30s

上下文 http server location

说明 该指令设置DNS解析超时时间

proxy_connect_timeout

语法 proxy_connect_timeout time 

默认值 60s

上下文 http server location

说明 该指令设置与upstream server的连接超时时间,有必要记住,这个超时不能超过75秒。

这个不是等待后端返回页面的时间,那是由proxy_read_timeout声明的。如果你的upstream服务器起来了,但是hanging住了(例如,没有足够的线程处理请求,所以把你的请求放到请求池里稍后处理),那么这个声明是没有用的,由于与upstream服务器的连接已经建立了。

proxy_read_timeout

语法 proxy_read_timeout time 

默认值 60s

上下文 http server location

说明 该指令设置与代理服务器的读超时时间。它决定了nginx会等待多长时间来获得请求的响应。这个时间不是获得整个response的时间,而是两次reading操作的时间。

proxy_send_timeout

语法 proxy_send_timeout time 

默认值 60s

上下文 http server location

说明 这个指定设置了发送请求给upstream服务器的超时时间。超时设置不是为了整个发送期间,而是在两次write操作期间。如果超时后,upstream没有收到新的数据,nginx会关闭连接

proxy_upstream_fail_timeout(fail_timeout)

语法 server address [fail_timeout=30s]

默认值 10s

上下文 upstream

说明 Upstream模块下 server指令的参数,设置了某一个upstream后端失败了指定次数(max_fails)后,该后端不可操作的时间,默认为10秒