0%

知识体系

知识体系

hexo之next主题文档

hexo之next主题文档

Linux命令学习网站

Linux命令

Spring Boot Admin 2.1.0 全攻略

Spring Boot Admin 2.1.0 全攻略

Java 设计模式

Java 设计模式

git 保存用户密码

1
git config credential.helper store

Idea 生成类继承图(实用)

在你所在的类里面点击右键,会出现上下文菜单 Diagrams | Show Diagram

快捷键 Ctrl+Alt+Shift+U,便会进入一个类继承图面板

查看各类型tcp链接个数

1
2
ss -s 
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

冷熊简历,markdown写简历

冷熊简历

美团2018技术干货推荐

【前端系列】下载链接
【后台系列】下载链接
【系统系列】下载链接
【算法系列】下载链接
【运维系列】下载链接
【测试系列】下载链接
【工程师成长系列】下载链接
【2018年美团点评技术文章合辑】下载链接

添加swap分区

1
2
3
4
cd /data0/
dd if=/dev/zero of=swapfile bs=1024 count=8192000000
mkswap swapfile
swapon swapfile

快速安装 node

1
2
3
4
curl http://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | sh 
source ~/.bashrc
export NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node
nvm install stable

快速免密

1
2
3
4
curl  http://cdn.laohand.com/sh/install_no_password.sh | sh
add_host 192.168.100.3
add_host 192.168.100.10
cat source ~/.ssh/config

maven加速

1
curl http://cdn.laohand.com/sh/maven_fast.sh | sh

安装java

1
curl http://cdn.laohand.com/sh/install_java.sh | sh

mongodb中文文档

mongodb中文文档

idea插件

【推荐】GitToolBox: 在代码里面显示提交记录

java 设计模式

java设计模式

安装node

1
2
3
4
5
6
7
8
9
10
11
12
13
wget http://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh
sh install.sh
rm install.sh
source ~/.bashrc
export NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node
nvm install stable

npm install -g hexo-cli
tmp=/tmp/laohand_blog
hexo init ${tmp}
cd ${tmp}
git clone https://github.com/iissnan/hexo-theme-next themes/next
hexo g

idea破解

[中华人民共和国个人信息保护法]https://m.thepaper.cn/baijiahao_14154156
2021年开源安全和风险分析

ibmonitor

ibmonitor

yum切换阿里

1
2
3
4
5
6
cd /etc/yum.repos.d/
mkdir bak
mv * bak/
wget https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo -O /etc/yum.repos.d/Centos-vault-8.5.2111.repo
wget https://mirrors.aliyun.com/repo/epel-archive-8.repo -O /etc/yum.repos.d/epel-archive-8.repo
yum clean all && yum makecache

pcstat

https://github.com/tobert/pcstat

git clone https://github.com/tobert/pcstat.git
cd pcstat
go build
cp -a pcstat /usr/bin
pcstat /usr/bin/pcstat
cd ../
rm -rf pcstat


wget http://cdn.laohand.com/sh/pcstat/pcstat
chmod +x pcstat
mv pcstat /usr/bin

常用命令

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
# 开启防火墙
systemctl start firewalld.service
# 防火墙开机启动
systemctl enable firewalld.service
# 查看服务状态
systemctl enable firewalld.service

# 查看当前状态
firewall-cmd --list-all
firewall-cmd --list-services
firewall-cmd --list-ports
firewall-cmd --state

# 开放通过tcp访问3306
firewall-cmd --permanent --add-port=3306/tcp
# 阻止通过tcp访问
firewall-cmd --permanent --remove-port=3306/tcp
# 添加多个端口
firewall-cmd --permanent --zone=public --add-port=8080-8083/tcp

# 针对某个 IP开放端口
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.142.166" port protocol="tcp" port="6379" accept"
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.0.233" accept"
# 删除某个IP
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.1.51" accept"
# 针对一个ip段访问
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.0.0/16" accept"
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="9200" accept"


# 将80端口的流量转发至8080
firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080
# 将80端口的流量转发至192.168.0.1
firewall-cmd --permanent --add-forward-port=proto=80:proto=tcp:toaddr=192.168.1.0.1
# 将80端口的流量转发至192.168.0.1的8080端口123
firewall-cmd --permanent --add-forward-port=proto=80:proto=tcp:toaddr=192.168.0.1:toport=8080

# 重载
firewall-cmd --reload

远程访问端口转发命令

1
2
3
4
5
6
7
8
9
10
11
echo 1 >/proc/sys/net/ipv4/ip_forward
systemctl start firewalld
systemctl enable firewalld
firewall-cmd --zone=public --add-masquerade --permanent
firewall-cmd --zone=public --permanent --add-port=53389/tcp
firewall-cmd --zone=public --permanent --add-port=2222/tcp
firewall-cmd --zone=public --permanent --add-port=1194/tcp
firewall-cmd --zone=public --permanent --add-forward-port=port=53389:proto=tcp:toaddr=10.8.0.3:toport=3389
firewall-cmd --zone=public --permanent --add-forward-port=port=2222:proto=tcp:toaddr=10.8.0.4:toport=2222
firewall-cmd --zone=public --permanent --add-port=8080/tcp
firewall-cmd --reload

参考文档

https://www.niwoxuexi.com/blog/php/article/339.html

html Upgrade-Insecure-Requests:1 请求头
HTTP Upgrade-Insecure-Requests 请求头向服务器发送一个客户端对HTTPS加密和认证响应良好,并且可以成功处理的信号,可以请求所属网站所有的HTTPS资源。
在https页面中,如果调用了http资源,那么浏览器就会抛出一些错误。
为了改变成这一状况,chrome(谷歌浏览器)会在http请求中加入 ‘Upgrade-Insecure-Requests: 1’ ,服务器收到请求后会返回 “Content-Security-Policy: upgrade-insecure-requests” 头,告诉浏览器,可以把所属本站的所有 http 连接升级为 https 连接。
例:

JAVA的CA根证书库是在 JRE的$JAVA_HOME/jre/lib/security/cacerts,该文件会随着JRE版本的升级而升级

下载http://curl.haxx.se/ca/cacert.pem 替换/etc/pki/tls/certs/ca-bundle.crt

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

ECDHE_RSA:密钥协商交换算法
ECDHE:使用基于椭圆曲线签密方案(EC, Elliptic Curve)的 Diffie-Hellman(DH)密钥协商协议。尾部的 E 为 Ephemeral 首字母,表示协商的是临时会话密钥。相对每次会话协商的临时密钥,证书中的公钥则是永久的(long-term)。
RSA:证书公钥加密算法,用于对证书数据部分的散列值进行签密、对 ECDHE 交换参数(的 HASH 值)进行签密。可能替换值为 ECDSA(椭圆曲线数字签名算法)。

rfc4492 & rfc5289 定义了该 CipherSuite 的具体实现。
the long term authenticity is confirmed via the server cert’s RSA signature but the transient keys are derived via ephemeral EC keys (which then generate the symmetric key)
ECDHE-RSA uses Diffie-Hellman on an elliptic curve group while DHE-RSA uses Diffie-Hellman on a modulo-prime group.

AES_128_GCM:传输会话(对称)加解密使用 GCM 模式的 AES-128 算法。
AES_128:使用128位的会话对称加密算法,双方通过 ECDHE 交换参数协商出对称密钥。
GCM:Galois计数器模式(Galois/Counter Mode)。消息认证码(MAC,Message Authentication Code)用于保障消息的完整性,防止各种伪造。AES-CMAC 使用分组密码,取代 HMAC 的加密散列函数。Galois 消息认证码(GMAC)则采用了 AES 算法的一种特殊模式。

主流加密算法趋势是 AES(128/256),加密模式的趋势是 GCM。
GCM 是一种特殊的称为 AEAD 的加密模式,不需要配合 MAC。

SSL和TLS-SSL Change Cipher Spec Protocol
SSL change cipher spec协议是通信双方加密策略的转换信息。协议本身很简单。由一条消息(ChangeCipherSpec)组成,使用当前的cipher spec压缩和加密。
ChangeCipherSpec消息放在SSL握手消息内。当继续一个先前建立的SSL session时,在hello消息之后,立刻发送ChangeCipherSpec消息

ChangeCipherSpec消息以5字节的SSL记录头开始,长度属性值是1,因为ChangeCipherSpec消息只有一个字节(值是1)。
ChangeCipherSpec消息没加密,而Finished消息是加密的,两条消息的内容类型不同,所以不能在一条SSL记录中传输。
————————————————
版权声明:本文为CSDN博主「此心光明-超然」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43364172/article/details/83860247

SSL/TLS 握手过程详解:https://www.jianshu.com/p/7158568e4867

client Hello

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
40
41
42
43
44
45
46
47
48
49
50
Frame 4: 240 bytes on wire (1920 bits), 240 bytes captured (1920 bits)
Ethernet II, Src: ee:ff:ff:ff:ff:ff (ee:ff:ff:ff:ff:ff), Dst: fa:16:3e:3b:e4:33 (fa:16:3e:3b:e4:33)
Internet Protocol Version 4, Src: 182.148.14.88, Dst: 172.31.0.20
Transmission Control Protocol, Src Port: 55508, Dst Port: 443, Seq: 1, Ack: 1, Len: 186
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 181
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 177
Version: TLS 1.2 (0x0303)
Random: 5e99ad73bc8705a2f6c5f4951574d36c77f4cd2dfc2074a0…
GMT Unix Time: Apr 17, 2020 21:21:55.000000000 中国标准时间
Random Bytes: bc8705a2f6c5f4951574d36c77f4cd2dfc2074a09a852b9e…
Session ID Length: 0
Cipher Suites Length: 44
Cipher Suites (22 suites)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003c)
Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 (0xc025)
Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 (0xc029)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067)
Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 (0x0040)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA (0xc004)
Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA (0xc00e)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033)
Cipher Suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02d)
Cipher Suite: TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 (0xc031)
Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e)
Cipher Suite: TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 (0x00a2)
Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 92
Extension: supported_groups (len=22)
Extension: ec_point_formats (len=2)
Extension: signature_algorithms (len=22)
Extension: server_name (len=30)


server hello

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Frame 6: 2958 bytes on wire (23664 bits), 2958 bytes captured (23664 bits)
Ethernet II, Src: fa:16:3e:3b:e4:33 (fa:16:3e:3b:e4:33), Dst: ee:ff:ff:ff:ff:ff (ee:ff:ff:ff:ff:ff)
Internet Protocol Version 4, Src: 172.31.0.20, Dst: 182.148.14.88
Transmission Control Protocol, Src Port: 443, Dst Port: 55508, Seq: 1, Ack: 187, Len: 2904
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Server Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 93
Handshake Protocol: Server Hello
TLSv1.2 Record Layer: Handshake Protocol: Certificate
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 2565
Handshake Protocol: Certificate
Handshake Type: Certificate (11)
Length: 2561
Certificates Length: 2558
Certificates (2558 bytes)

客户端发送服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Frame 13: 105 bytes on wire (840 bits), 105 bytes captured (840 bits)
Ethernet II, Src: ee:ff:ff:ff:ff:ff (ee:ff:ff:ff:ff:ff), Dst: fa:16:3e:3b:e4:33 (fa:16:3e:3b:e4:33)
Internet Protocol Version 4, Src: 182.148.14.88, Dst: 172.31.0.20
Transmission Control Protocol, Src Port: 60501, Dst Port: 443, Seq: 531, Ack: 153, Len: 51
Transport Layer Security
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
Content Type: Change Cipher Spec (20)
Version: TLS 1.2 (0x0303)
Length: 1
Change Cipher Spec Message
TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 40
Handshake Protocol: Encrypted Handshake Message

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
Frame 7: 165 bytes on wire (1320 bits), 165 bytes captured (1320 bits)
Ethernet II, Src: fa:16:3e:3b:e4:33 (fa:16:3e:3b:e4:33), Dst: ee:ff:ff:ff:ff:ff (ee:ff:ff:ff:ff:ff)
Internet Protocol Version 4, Src: 172.31.0.20, Dst: 182.148.14.88
Transmission Control Protocol, Src Port: 443, Dst Port: 55508, Seq: 2905, Ack: 187, Len: 111
[2 Reassembled TCP Segments (338 bytes): #6(236), #7(102)]
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 333
Handshake Protocol: Server Key Exchange
Handshake Type: Server Key Exchange (12)
Length: 329
EC Diffie-Hellman Server Params
Curve Type: named_curve (0x03)
Named Curve: secp256r1 (0x0017)
Pubkey Length: 65
Pubkey: 048eed293223d97dc5df9c80ec01507b5e7e374b0e938bc6…
Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
Signature Hash Algorithm Hash: SHA512 (6)
Signature Hash Algorithm Signature: RSA (1)
Signature Length: 256
Signature: 3717c02646ffeed321cbbf9750c009078f178b83959ab519…
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 4
Handshake Protocol: Server Hello Done
Handshake Type: Server Hello Done (14)
Length: 0

Client Key Exchange

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Frame 9: 129 bytes on wire (1032 bits), 129 bytes captured (1032 bits)
Ethernet II, Src: ee:ff:ff:ff:ff:ff (ee:ff:ff:ff:ff:ff), Dst: fa:16:3e:3b:e4:33 (fa:16:3e:3b:e4:33)
Internet Protocol Version 4, Src: 182.148.14.88, Dst: 172.31.0.20
Transmission Control Protocol, Src Port: 55508, Dst Port: 443, Seq: 187, Ack: 3016, Len: 75
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Key Exchange
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 70
Handshake Protocol: Client Key Exchange
Handshake Type: Client Key Exchange (16)
Length: 66
EC Diffie-Hellman Client Params
Pubkey Length: 65
Pubkey: 04fc34dce73bcea0400a79ed68ae8acbee4a874ac7b8dbf2…

Change Cipher Spec

1
2
3
4
5
6
7
8
9
10
11
Frame 10: 60 bytes on wire (480 bits), 60 bytes captured (480 bits)
Ethernet II, Src: ee:ff:ff:ff:ff:ff (ee:ff:ff:ff:ff:ff), Dst: fa:16:3e:3b:e4:33 (fa:16:3e:3b:e4:33)
Internet Protocol Version 4, Src: 182.148.14.88, Dst: 172.31.0.20
Transmission Control Protocol, Src Port: 55508, Dst Port: 443, Seq: 262, Ack: 3016, Len: 6
Transport Layer Security
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
Content Type: Change Cipher Spec (20)
Version: TLS 1.2 (0x0303)
Length: 1
Change Cipher Spec Message

Encrypted Handshake Message

1
2
3
4
5
6
7
8
9
10
11
Frame 12: 99 bytes on wire (792 bits), 99 bytes captured (792 bits)
Ethernet II, Src: ee:ff:ff:ff:ff:ff (ee:ff:ff:ff:ff:ff), Dst: fa:16:3e:3b:e4:33 (fa:16:3e:3b:e4:33)
Internet Protocol Version 4, Src: 182.148.14.88, Dst: 172.31.0.20
Transmission Control Protocol, Src Port: 55508, Dst Port: 443, Seq: 268, Ack: 3016, Len: 45
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 40
Handshake Protocol: Encrypted Handshake Message

发送数据

1
2
3
4
5
6
7
8
9
10
11
12
Frame 17: 856 bytes on wire (6848 bits), 856 bytes captured (6848 bits)
Ethernet II, Src: fa:16:3e:3b:e4:33 (fa:16:3e:3b:e4:33), Dst: ee:ff:ff:ff:ff:ff (ee:ff:ff:ff:ff:ff)
Internet Protocol Version 4, Src: 172.31.0.20, Dst: 182.148.14.88
Transmission Control Protocol, Src Port: 443, Dst Port: 60501, Seq: 153, Ack: 1612, Len: 802
Transport Layer Security
TLSv1.2 Record Layer: Application Data Protocol: http-over-tls
Content Type: Application Data (23)
Version: TLS 1.2 (0x0303)
Length: 797
Encrypted Application Data: 412f12c643ebe0c701291c8c21a18e36feb778d965214e8b…


Encrypted handshake message

https://blog.csdn.net/mrpre/article/details/77868570
无论是客户端还是服务端,都会在握手完成之后,发送 Encrypted handshake message,且各自收到对端的Encrypted handshake message后会去验证这个数据。 主要是为了验证对称密钥的准确性

SSL 握手第一次握手

client:Client Hello

第一步是客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1、客户端支持的加密套件(Support Ciphers)和 SSL Version 等信息。通过 Wireshark 抓包,我们可以看到如下信息

server:Server Hello

第二步是服务端向客户端发送 Server Hello 消息,这个消息会从 Client Hello 传过来的 Support Ciphers 里确定一份加密套件,这个套件决定了后续加密和生成摘要时具体使用哪些算法,另外还会生成一份随机数 Random2。注意,至此客户端和服务端都拥有了两个随机数(Random1+ Random2),这两个随机数会在后续生成对称秘钥时用到

server:Server Key Exchange

如果是DH算法,这里发送服务器使用的DH参数。RSA算法不需要这一步

验证服务端证书(第二次握手)

server:Certificate(有可能会和Server Hello一起发送数据包)

这一步是服务端将自己的证书下发给客户端,让客户端验证自己的身份,客户端验证通过后取出证书中的公钥

client:Certificate Verify

客户端收到服务端传来的证书后,先从 CA 验证该证书的合法性,验证通过后取出证书中的服务端公钥,再生成一个随机数 Random3,再用服务端公钥非对称加密 Random3 生成 PreMaster Key。

client:Client Key Exchange

上面客户端根据服务器传来的公钥生成了 PreMaster Key,Client Key Exchange 就是将这个 key 传给服务端,服务端再用自己的私钥解出这个 PreMaster Key 得到客户端生成的 Random3。
至此,客户端和服务端都拥有 Random1 + Random2 + Random3,两边再根据同样的算法就可以生成一份秘钥,握手结束后的应用层数据都是使用这个秘钥进行对称加密。
为什么要使用三个随机数呢?这是因为 SSL/TLS 握手过程的数据都是明文传输的,并且多个随机数种子来生成秘钥不容易被暴力破解出来

验证客户端证书(三次握手 可选)

Certificate Request

Certificate Request 是服务端要求客户端上报证书,这一步是可选的,对于安全性要求高的场景会用到。

四次握手

client:Change Cipher Spec(Client)

这一步是客户端通知服务端后面再发送的消息都会使用前面协商出来的秘钥加密了,是一条事件消息。

client:Encrypted Handshake Message(Client)

这一步对应的是 Client Finish 消息,客户端将前面的握手消息生成摘要再用协商好的秘钥加密,这是客户端发出的第一条加密消息。服务端接收后会用秘钥解密,能解出来说明前面协商出来的秘钥是一致的。

server:Change Cipher Spec(Server)

这一步是服务端通知客户端后面再发送的消息都会使用加密,也是一条事件消息。

server:Encrypted Handshake Message(Server)

这一步对应的是 Server Finish 消息,服务端也会将握手过程的消息生成摘要再用秘钥加密,这是服务端发出的第一条加密消息。客户端接收后会用秘钥解密,能解出来说明协商的秘钥是一致的。

Application Data
到这里,双方已安全地协商出了同一份秘钥,所有的应用层数据都会用这个秘钥加密后再通过 TCP 进行可靠传输。

TLS 协议主要有五种类型 Content Type:
Content types

Hex Dec Type
0x14 20 加密消息确认协议 ChangeCipherSpec
0x15 21 报警协议 Alert
0x16 22 握手协议 Handshake
0x17 23 应用数据层协议 Application
0x18 24 心跳协议 Heartbeat

对称加密

客户端与服务器使用相同的密钥对消息进行加密
优点:
加密强度高,很难被破解
计算量小,仅为非对称加密计算量的 0.1%
缺点:
无法安全的生成和管理密钥
服务器管理大量客户端密钥复杂

非对称加密

非对称指加密与解密的密钥为两种密钥。服务器提供公钥,客户端通过公钥对消息进行加密,并由服务器端的私钥对密文进行解密。
优点:安全
缺点
性能低下,CPU 计算资源消耗巨大,一次完全的 TLS 握手,密钥交换时的非对称加密解密占了整个握手过程的 90% 以上。而对称加密的计算量只相当于非对称加密的 0.1%,因此如果对应用层使用非对称加密,性能开销过大,无法承受。
非对称加密对加密内容长度有限制,不能超过公钥的长度。比如现在常用的公钥长度是 2048 位,意味着被加密消息内容不能超过 256 字节

HTTPS一般使用的加密与HASH算法如下:

非对称加密算法:RSA,DSA/DSS
对称加密算法:AES,RC4,3DES
HASH算法:MD5,SHA1,SHA256

关于证书(确保公钥的完整性、可靠性)
证书需要申请,并由专门的数字证书认证机构 CA 通过非常严格的审核之后颁发的电子证书,证书是对服务器端的一种认证。
颁发的证书同时会产生一个私钥和公钥。私钥有服务器自己保存,不可泄露,公钥则附带在证书的信息中,可以公开。
证书本身也附带一个证书的电子签名,这个签名用来验证证书的完整性和真实性,防止证书被篡改。此外证书还有个有效期。
证书包含以下信息:

使用者的公钥值
使用者标识信息(如名称和电子邮件地址)
有效期(证书的有效时间)
颁发者标识信息
颁发者的数字签名,用来证明使用者的公钥和使用者的标识符信息之间的绑定的有效性

https://www.jianshu.com/p/33feb2fadb15

HTTPS为了追求性能,又要保证安全,采用了共享密钥加密和公开密钥加密混合的方式进行报文传输

TCP 关闭连接:http://hi.csdn.net/attachment/201112/26/0_132491065957O6.gif

你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文

6.最大报文长度
在建立连接的时候,通信的双方要互相确认对方的最大报文长度(MSS),以便通信。一般这个SYN长度是MTU减去固定IP首部和TCP首部长度。对于一个以太网,一般可以达到1460字节。当然如果对于非本地的IP,这个MSS可能就只有536字节,而且,如果中间的传输网络的MSS更佳的小的话,这个值还会变得更小。
————————————————
版权声明:本文为CSDN博主「jayxu无捷之径」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ls5718/article/details/51583514

https://blog.csdn.net/ls5718/article/details/51583514

所以如果服务器端主动断开连接时,就需要注意,或者做一些处理:不让它等待2MSL后才可以使用,具体做法:使能SO_REUSEPORT(允许重用本地地址),可以通过调用setsockopt函数来使能。

MSL : Max segment lifetime ,报文最大生存时间,是指任何报文在网络上存在的最长时间,超过这个时间报文将会被丢弃。在 Linux 系统中,MSL 被定义成 30 秒, 2MSL 就是 60 秒。

TCP_PAWS_MSL 60秒

https://www.cnblogs.com/charlieroro/p/11593410.html

https://github.com/torvalds/linux/blob/c839682c719f0e3dc851951c9e2eeb8a41cd9609/include/net/tcp.h#L120

https://www.zhuxiaodong.net/2018/tcp-time-wait-instruction/

TCP 报文

https://img-blog.csdn.net/20180913164138814?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZseWluZ3NiaXJk/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70

1.端口号

  标记同一台计算机上的不同进程
  源端口:占2个字节,源端口和IP的作用是标记报文的返回地址。
  目的端口:占2个字节,指明接收方计算机上的应用程序接口。
  TCP报头中的源端口号和目的端口号同IP报头中的源IP和目的IP唯一确定一条TCP连接。

2.序号

  占4个字节,是TCP可靠传输的关键部分。是本报文段发送的数据组的第一个字节的序号。
  在TCP传输流中,每一个字节一个序号。(例如:一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为400.)所以序号确保了TCP传输的有序性。

3.确认序号

  即ack,占4个字节,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK=1时才有效。比如建立连接时,SYN报文的ACK标志位为0。

4.数据偏移

  占4位,它指出TCP报文的数据距离TCP报文段的起始处有多远。
  由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任选子段时长度为20字节;4位首部长度字段所能表示的最大值为1111,转化为10进制为15,故报头最大长度为15*32/8=60个字节。首部长度也叫数据偏移。

5.保留

  为将来定义新的用途保留,一般置为0。

6.控制位

  URG:紧急指针标志。1:紧急指针有效;0:忽略紧急指针。
  ACK:确认序号标志。1:确认号有效;0:忽略确认号段。
  PSH:push标志。1:带有push标志的数据,表示接收方在接收到该报文后应尽快将这个报文段交给应用程序,而不是缓冲区排队。
  RST:重置连接标志。用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。
  SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。
  FIN:结束标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。

7.窗口

  滑动窗口大小,用来告知发送端接收端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小是2个字节,因而窗口大小最大为65536。

8.校验和

  奇偶校验,此校验和是针对整个TCP报文段的,包括TCP报头和TCP报文数据段,以2个字节进行计算所得。由发送端计算和存储,并由接收端进行验证。

9.紧急指针

  只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。

10.选项和填充

  最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN=1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的0,以保证TCP头部是32的整数倍。

11.数据部分

  TCP报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有TCP首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

原文链接:https://blog.csdn.net/flyingsbird/article/details/82693368

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
Frame 1: 74 bytes on wire (592 bits), 74 bytes captured (592 bits)
Ethernet II, Src: ee:ff:ff:ff:ff:ff (ee:ff:ff:ff:ff:ff), Dst: fa:16:3e:3b:e4:33 (fa:16:3e:3b:e4:33)
Internet Protocol Version 4, Src: 182.148.14.88, Dst: 172.31.0.20
Transmission Control Protocol, Src Port: 60502, Dst Port: 443, Seq: 0, Len: 0
Source Port: 60502
Destination Port: 443
[Stream index: 0]
[TCP Segment Len: 0]
Sequence number: 0 (relative sequence number)
[Next sequence number: 0 (relative sequence number)]
Acknowledgment number: 0
1010 .... = Header Length: 40 bytes (10)
Flags: 0x002 (SYN)
Window size value: 64240
[Calculated window size: 64240]
Checksum: 0x7e2a [unverified]
[Checksum Status: Unverified]
Urgent pointer: 0
Options: (20 bytes), Maximum segment size, No-Operation (NOP), Window scale, SACK permitted, Timestamps
TCP Option - Maximum segment size: 1452 bytes
TCP Option - No-Operation (NOP)
TCP Option - Window scale: 8 (multiply by 256)
TCP Option - SACK permitted
TCP Option - Timestamps: TSval 337554530, TSecr 0
[Timestamps]
[Time since first frame in this TCP stream: 0.000000000 seconds]
[Time since previous frame in this TCP stream: 0.000000000 seconds]

查询支持的 TCP 拥塞控制算法
sysctl net.ipv4.tcp_available_congestion_control

net.ipv4.tcp_available_congestion_control = reno cubic bbr

查询应用的 TCP 拥塞控制算法
sysctl net.ipv4.tcp_congestion_control

sysctl net.ipv4.tcp_congestion_control
启用 BBR TCP 拥塞控制算法
sysctl net.core.default_qdisc=fq
sysctl net.ipv4.tcp_congestion_control=bbr

linux 内核4.9以上 默认使用bbr拥塞控制方法(GOOGLE),其他一般使用 cubic(内核2.6以后)

Nginx下关于缓存控制字段cache-control的配置说明 - 运维小结
https://www.cnblogs.com/kevingrace/p/10459429.html

https://juejin.im/post/5bf3c28ee51d4514df5b7625

(3) 强缓存
[1] 强缓存概念
强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。
实际就是我们整体流程内的,查看是否存在缓存以及,查看缓存是否有效。
[2] 如何实现强缓存
实现强缓存,主要是根据客户端保留的一个服务器端的response header中的两个字段:expires、cache-control。
cache-control优先级比expires高。

协商缓存

协商缓存的标识也是在响应报文的HTTP头中和请求结果一起返回给浏览器的,控制协商缓存的字段分别有:Last-Modified / If-Modified-Since 和 Etag / If-None-Match。
Etag / If-None-Match 优先级比 Last-Modified / If-Modified-Since 高

两者异同
两者的共同点是:如果命中,都是从客户端缓存中加载资源,而不是从服务器加载资源数据;
两者的区别是:强缓存不发请求到服务器,协商缓存会发请求到服务器。

刷新的时候 不会使用强缓存, Cache-Control:max-age=0
强制刷新的时候 2中缓存都不会使用 Cache-Control:no-cache

在无法确定客户端的时间是否与服务端的时间同步的情况下,Cache-Control相比于expires是更好的选择,所以同时存在时,只有Cache-Control生效。

http 1.1 Cache-Control http1.0 expires

public:所有内容都将被缓存(客户端和代理服务器都可缓存)
private:所有内容只有客户端可以缓存,Cache-Control的默认取值
no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效

(1) 分布式系统相关
这部分没有实际实践过,只是摘选了部分文章的观点:
分布式系统里多台服务器间的文件的Last-Modified必须保持一致,以免负载均衡到不同服务器导致对比结果不一致。
分布式系统尽量关闭掉ETag(每台机器生成的ETag都会不一样,淘宝页面中的静态资源response headers中都没有ETag)。

egag默认生成方式:文件的修改时间(时间戳)转成16进制+文件大小 转成16进制
sprintf( str_buffer, (char *) loc_conf->etag_format.data, r->uri.data, (unsigned int) stat_result.st_size, (unsigned int) stat_result.st_mtime );
Nginx官方ETag算法
Nginx官方的ETag计算出的值为 文件最后修改时间16进制-文件长度16进制。例:ETag: “59e72c84-2404”
文件长度为:

10进制为->9220
转为16进制->2404

文件最后修改时间:

标准日期格式->Sat, 21 Oct 2017 09:14:34 GMT
转为秒->1508322436
转为16进制->59e72c84

location / {

etag on;

}

W/ 可选
‘W/‘(大小写敏感) 表示使用弱验证器。 弱验证器很容易生成,但不利于比较。 强验证器是比较的理想选择,但很难有效地生成。 相同资源的两个弱Etag值可能语义等同,但不是每个字节都相同。

问题1:周期性更改,内容不改变
问题2:修改频繁,秒以下的时间内进行修改
问题3:某些服务器不能精确得到文件最后修改时间

调查了一下 腾信视频 天猫 、爱奇艺都是通过 last modify 来缓存的

more_clear_headers “Etag”

Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html
Accept-Charset 浏览器可以接受的字符编码集。 Accept-Charset: iso-8859-5
Accept-Encoding 指定浏览器可以支持的web服务器返回内容压缩编码类型。 Accept-Encoding: compress, gzip
Accept-Language 浏览器可接受的语言 Accept-Language: en,zh
Accept-Ranges 可以请求网页实体的一个或者多个子范围字段 Accept-Ranges: bytes
Authorization HTTP授权的授权证书 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control 指定请求和响应遵循的缓存机制 Cache-Control: no-cache
Connection 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) Connection: close
Cookie HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 Cookie: $Version=1; Skin=new;
Content-Length 请求的内容长度 Content-Length: 348
Content-Type 请求的与实体对应的MIME信息 Content-Type: application/x-www-form-urlencoded
Date 请求发送的日期和时间 Date: Tue, 15 Nov 2010 08:12:31 GMT
Expect 请求的特定的服务器行为 Expect: 100-continue
From 发出请求的用户的Email From: user@email.com
Host 指定请求的服务器的域名和端口号 Host: www.zcmhi.com
If-Match 只有请求内容与实体相匹配才有效 If-Match: “737060cd8c284d8af7ad3082f209582d”
If-Modified-Since 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT
If-None-Match 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 If-None-Match: “737060cd8c284d8af7ad3082f209582d”
If-Range 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag If-Range: “737060cd8c284d8af7ad3082f209582d”
If-Unmodified-Since 只在实体在指定时间之后未被修改才请求成功 If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT
Max-Forwards 限制信息通过代理和网关传送的时间 Max-Forwards: 10
Pragma 用来包含实现特定的指令 Pragma: no-cache
Proxy-Authorization 连接到代理的授权证书 Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range 只请求实体的一部分,指定范围 Range: bytes=500-999
Referer 先前网页的地址,当前请求网页紧随其后,即来路 Referer: http://www.zcmhi.com/archives/71.html
TE 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 TE: trailers,deflate;q=0.5
Upgrade 向服务器指定某种传输协议以便服务器进行转换(如果支持) Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
User-Agent User-Agent的内容包含发出请求的用户信息 User-Agent: Mozilla/5.0 (Linux; X11)
Via 通知中间网关或代理服务器地址,通信协议 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning 关于消息实体的警告信息 Warn: 199 Miscellaneous warning

Header 解释 示例
Accept-Ranges 表明服务器是否支持指定范围请求及哪种类型的分段请求 Accept-Ranges: bytes
Age 从原始服务器到代理缓存形成的估算时间(以秒计,非负) Age: 12
Allow 对某网络资源的有效的请求行为,不允许则返回405 Allow: GET, HEAD
Cache-Control 告诉所有的缓存机制是否可以缓存及哪种类型 Cache-Control: no-cache
Content-Encoding web服务器支持的返回内容压缩编码类型。 Content-Encoding: gzip
Content-Language 响应体的语言 Content-Language: en,zh
Content-Length 响应体的长度 Content-Length: 348
Content-Location 请求资源可替代的备用的另一地址 Content-Location: /index.htm
Content-MD5 返回资源的MD5校验值 Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Range 在整个返回体中本部分的字节位置 Content-Range: bytes 21010-47021/47022
Content-Type 返回内容的MIME类型 Content-Type: text/html; charset=utf-8
Date 原始服务器消息发出的时间 Date: Tue, 15 Nov 2010 08:12:31 GMT
ETag 请求变量的实体标签的当前值 ETag: “737060cd8c284d8af7ad3082f209582d”
Expires 响应过期的日期和时间 Expires: Thu, 01 Dec 2010 16:00:00 GMT
Last-Modified 请求资源的最后修改时间 Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT
Location 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 Location: http://www.zcmhi.com/archives/94.html
Pragma 包括实现特定的指令,它可应用到响应链上的任何接收方 Pragma: no-cache
Proxy-Authenticate 它指出认证方案和可应用到代理的该URL上的参数 Proxy-Authenticate: Basic
refresh 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持) Refresh: 5; url=http://www.zcmhi.com/archives/94.html
Retry-After 如果实体暂时不可取,通知客户端在指定时间之后再次尝试 Retry-After: 120
Server web服务器软件名称 Server: Apache/1.3.27 (Unix) (Red-Hat/Linux)
Set-Cookie 设置Http Cookie Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
Trailer 指出头域在分块传输编码的尾部存在 Trailer: Max-Forwards
Transfer-Encoding 文件传输编码 Transfer-Encoding:chunked
Vary 告诉下游代理是使用缓存响应还是从原始服务器请求 Vary: *
Via 告知代理客户端响应是通过哪里发送的 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning 警告实体可能存在的问题 Warning: 199 Miscellaneous warning
WWW-Authenticate 表明客户端请求实体应该使用的授权方案 WWW-Authenticate: Basic

Http 1.0 和Http 1.1 的区别
https://blog.csdn.net/hudashi/article/details/50789164?utm_source=blogxgwz9

chunked_transfer_encoding off;

HTTP头
\r\n
\r\n –连续的两个\r\n之后就是HTTP体了
16进制值代表的数据长度
\r\n
上面所指的数据长度
\r\n –每段数据结束后,以\r\n标识

16进制代表的第二段数据
\r\n
XX长度的数据
\r\n

………… (反复通过这样的方式表示每次传输的数据长度)

0 –数据结束部分用0表示,然后是连续的两个\r\n
\r\n
\r\n

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
GET /pdf/test4 HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7

HTTP/1.1 200
Transfer-Encoding: chunked
Date: Sun, 19 Apr 2020 07:09:12 GMT

7
hello

6
word

0

GET /favicon.ico HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1/pdf/test4
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7

HTTP/1.1 200
Last-Modified: Tue, 20 Aug 2019 03:31:05 GMT
Accept-Ranges: bytes
Content-Type: image/x-icon
Content-Length: 946
Date: Sun, 19 Apr 2020 07:09:12 GMT

HTTP2.0,HTTP1.1,HTTP1.0 的区别
https://blog.csdn.net/qq_30322803/article/details/83142300

一丶HTTP1.0与HTTP1.1通信性能上的区别

持久化连接
管线化技术
二丶HTTP2.0与HTTP1.1通信性能上的区别

多路复用
HTTP协议头部压缩

HTTP/2让服务器可以将响应主动“推送”到客户端缓存中

http2多路复用解决的问题,由于浏览器的限制访问网站资源的时候浏览器在同一个域名下最多开启6个线程,这样如果前几个线程执行比较慢的任务或者需要等待服务器端响应,后面的资源就被阻塞住了 .以往的做法是把静态资源如图片 css等文件放在不同的域名下以提高页面加载速度.

另外一点就是明显减少了tcp连接的3次握手4次挥手,和ssl(tsl)协议中反复的client hello servier hello与证书传输的浪费.
http2采用二进制分帧,把header与data分成二进制帧
https://img-blog.csdn.net/20180703134821445?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3RpYW5kYW8zMjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70

length字段分配在前三个字节标示整个流的长度

type字段标示流的类型 分别为 HEADERS ,DATA ,MAGIC,SETTINGS 如果比较小的话headers与data可以放在一个包里.

magic 第一次传输之前client端都会发送magic让服务器端确认使用http2协议

HTTP/2 就是超文本传输协议的第二个主要版本,是自1999年 HTTP 1.1 之后发布的首个更新,主要基于 SPDY 协议(是Google开发的基于TCP的应用层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验)

Accept-Encoding: gzip, deflate
Content-Encoding: gzip

mod_deflate压缩速度略快而mod_gzip 的压缩比略高。一般默认情况下,mod_gzip 会比mod_deflate 多出4%~6%的压缩量。

一般来说mod_gzip 对服务器CPU的占用要高一些。mod_deflate 是专门为确保服务器的性能而使用的一个压缩模块,mod_deflate 需要较少的资源来压缩文件。这意味着在高流量的服务器,使用mod_deflate 可能会比mod_gzip 加载速度更快。

compress是一个相当古老的 unix 档案压缩指令,压缩后的档案会加上一个 .Z 延伸档名以区别未压缩的档案,压缩后的档案可以以 uncompress 解压。若要将数个档案压成一个压缩档,必须先将档案 tar 起来再压缩。由于 gzip 可以产生更理想的压缩比例,一般人多已改用 gzip 为档案压缩工具。

如果服务器在响应所有对应的 请求之前关闭了连接,客户端必须准备去重新发送请求。所以要求管线请求需要满足幂等性 GET

POST方法的响应是不可缓存的。除非响应里有合适的Cache-Control或者Expires头域。然而, 303(见其他)响应能被用户代理利用去获得可缓存的响应

curl ‘https://1eapem1yuzto.leanapp.cn/smallTools_h5/timeMemo/privacyPolicy.html' -H ‘if-modified-since: Fri, 21 Feb 2020 03:16:03 GMT’ -H ‘Range:bytes=0-90’ -i
curl ‘https://1eapem1yuzto.leanapp.cn/smallTools_h5/timeMemo/privacyPolicy.html' -H ‘Range:bytes=0-99’ -i
HTTP/1.1 206 Partial Content
Server: openresty
Date: Sun, 19 Apr 2020 13:38:23 GMT
Content-Type: text/html;charset=utf-8
Content-Length: 100
Connection: keep-alive
ETag: “5e4f4b73-1c29”
Last-Modified: Fri, 21 Feb 2020 03:16:03 GMT
Expires: Sun, 19 Apr 2020 13:39:22 GMT
Cache-Control: max-age=30
Content-Range: bytes 0-99/7209
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
X-Cache-Status: HIT from KS-CLOUD-TY-UN-11-32
X-Cdn-Request-ID: c43ff212e892ae05905b49bdf1084443

。302响应是只有在Cache-Control或Expires 头域指明的情况下才能被缓存。
。303响应不能被缓存,但是再次重定向请求的响应应该被缓存。

303和307的存在,归根结底是由于POST方法的非幂等属性引起的。
在HTTP1.1中,302理论上是要被放弃掉的,它被细化为303和307,但为了兼容,它目前还在业界中大量使用,而303和307状态码我还没遇到过(没有使用场景,也没抓到过这样的响应报文)。为什么业界少使用303和307呢?
对于GET和HEAD方法来说,307是没必要存在的,用302或者303就可以满足需求了,307仅在POST方法的重定向上有用处。所以我猜测它们少见的原因有两方面:1、POST方法重定向的使用场景太少,使得307状态码没有用武之地;2、GET方法虽然常需要使用的重定向,但使用302状态码也能正确运转,再考虑到微乎其微的兼容问题(现在的浏览器怎么可能不支持HTTP1.1呢!),也就没有使用303的必要了。

age:表示缓存在代理服务器上缓存的时间(CDN等)
Date: Sun, 19 Apr 2020 14:15:54 GMT 服务器发送报文的时间(源站) age=当前时间-date

Age头域出现在响应里说明响应不是第一手的(first-hand)(译注:第一手的说明,响应是直 接来自于源服务器到达接收端的,而不是来自于缓存里保存的副本)。
然而相反的情况并不成 立,因为响应里缺少Age头域并不能说明响应是第一手的(fisrt-hand),除非所有请求路径上的 缓存都遵循HTTP/1.1协议(也就是说,以前HTTP版本缓存没有定义Age头域

那么客户端应该无条件的重试请求,并且包含 Cache-Control: max-age=0

去强制任何中间缓存通过源服务器来验证(validate)它们的缓存副本,或者 Cache-Control: no-cache

所以通常希望实体发 生任何变化时验证器也相应变化,这样的验证器为强验证器。.
在资源变化时验证器未必变化的验证器 称为弱验证器. W\

下面的HTTP/1.1头域是hop-by-hop头域:

  • Connection - Keep-Alive - Proxy-Authenticate - Proxy-Authorization - TE - Trailers - Transfer-Encoding - Upgrade
    所有其它被HTTP/1.1定义的头域均为end-to-end头

一个透明代理不能改变请求或响应里的下面头域,而且它不能添加这些头域到没有这些头域的 请求或响应里:

  • Contents-location - Content-MD5 - ETag - Last-Modified

Content-location:数据的备用地址,如创建了一个资源 返回资源的访问地址 在 Content-location

https://cloud.tencent.com/developer/section/1189923

$.ajax({
url : ‘http://remote.domain.com/corsrequest',
data : data,
dataType: ‘json’,
type : ‘POST’,
xhrFields: {
withCredentials: true
},
crossDomain: true,
contentType: “application/json”,})
对应客户端的 xhrFields.withCredentials: true 参数,服务器端通过在响应 header 中设置 Access-Control-Allow-Credentials = true 来运行客户端携带证书式访问。
通过对 Credentials 参数的设置,就可以保持跨域 Ajax 时的 Cookie。这里需要注意的是:
服务器端 Access-Control-Allow-Credentials = true时,参数Access-Control-Allow-Origin 的值不能为 ‘*’

凭证是 Cookie ,授权标头或 TLS 客户端证

Access-Control-Allow-Credentials 是否允许携带cookie

可缓存
public指示响应可能被任何缓存缓存。
private指示该响应是针对单个用户的,并且不能由共享缓存存储。私有缓存可以存储该响应。
no-cache在释放缓存副本之前,强制高速缓存将请求提交给原始服务器进行验证。
only-if-cached表示不检索新数据。客户端只希望获得缓存的响应,并且不应该联系原始服务器以查看是否存在新的副本。
Expiration
max-age=指定资源被视为新鲜的最长时间。相反Expires,这个指令是相对于请求的时间而言的。
s-maxage=覆盖max-age或Expires标题,但它只适用于共享缓存(例如,代理)并被私有缓存忽略。
max-stale[=]表示客户愿意接受超过其到期时间的响应。或者,您可以以秒为单位指定一个值,指示响应不能过期的时间。
min-fresh=表示客户想要的响应至少在指定的秒数内仍然是新鲜的。
stale-while-revalidate=指示客户端愿意接受陈旧的响应,同时在后台异步检查新的响应。秒值指示客户愿意接受陈旧响应的时间。
stale-if-error=
重新验证和重新加载
must-revalidate缓存必须在使用前验证陈旧资源的状态,不应使用过期资源。与之proxy-revalidate相同must-revalidate,但它仅适用于共享缓存(例如,代理)并被私有缓存忽略。
immutable表示响应主体不会随着时间而改变。资源如果未到期,则在服务器上保持不变,因此,即使用户明确刷新页面,客户端也不应为其发送条件重新验证(以检查更新。根据 HTTP 规范,不知道这个扩展的客户端必须忽略它们。在 Firefox 中,immutable只有在交易中才有荣誉。
其他
no-store缓存不应该存储有关客户端请求或服务器响应的任何内容。
no-transform不应该对资源进行转换或转换。Content-Encoding ,Content-Range ,Content-Type 标头不得被代理修改。例如,一个不透明的代理可能会在图像格式之间进行转换,以节省缓存空间或减少慢速链接上的流量。该no-transform指令不允许这样做。

Content-Disposition:表示下载文件 或者 Content-Type:application/stream ,application/force-download

Cookie: name=value; name2=value2; name3=value3

Trailer
所述 trailers 允许在发送数据后再发送响应头,只有部分header支持

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
Trailer: Expires

7\r\n
Mozilla\r\n
9\r\n
Developer\r\n
7\r\n
Network\r\n
0\r\n
Expires: Wed, 21 Oct 2015 07:28:00 GMT\r\n
\r\n

Strict-Transport-Security响应报头(通常缩写为 HSTS)是一种安全功能,可以让一个网站告诉大家,它应该只使用
HTTPS,而不是使用 HTTP 进行通信的浏览器。

所有现在和将来的子域名都是 HTTPS,最大年龄为1年。这会阻止访问只能通过 HTTP 提供服务的页面或子域。
Strict-Transport-Security: max-age=31536000; includeSubDomains

Set-Cookie: qwerty=219ffwef9w0f; Domain=somecompany.co.uk; Path=/; Expires=Wed, 30 Aug 2019 00:00:00 GMT

Retry-After响应的 HTTP 报头指示所述用户代理应该多长时间使一个后续请求之前等待。有两种主要的情况使用这个头文件:
When sent with a 503 (Service Unavailable) response, it indicates how long the service is expected to be unavailable.
纠错
当使用重定向响应(如301永久移动)发送时,它表示用户

Connection和Keep-Alive在 HTTP / 2 忽略; 连接管理由其他机制处理

Keep-Alive: timeout=5, max=1000

net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 15

keepalive
https://www.cnblogs.com/havenshen/p/3850167.html

刷新也会断开长连接,如果在服务端有一些判断,要注意发生重复的可能
Connection:keep-alive
Keep-Alive:timeout=20 服务器有时候会告诉客户端超时时间

对于客户端来说,如果服务器没有告诉客户端超时时间也没关系,服务端可能主动发起四次握手断开TCP连接,客户端能够知道该TCP连接已经无效;另外TCP还有心跳包来检测当前连接是否还活着,方法很多,避免浪费资源。

upstream test_keepalive{
server 127.0.0.1:5002;
keepalive 4;
}

keepalive: 4, 每个nginx worker可以保留的idle连接,也就是说最多可保留的长连接,如果超过这个数量,会根据LRU算法,least recently used 用的最少的连接会被close,需要注意的是,这个参数不会限制worker的跟upstream的连接数。
keepalive_timeout :60, nginx跟upstreamd的 idle 空闲长连接,最大超时时间,超过时间没有数据往来则超时关闭
keepalive_requests : 100,设置每个长连接最多能处理的请求次数,超过了以后连接就会被close,定期关闭对于清理每个连接的占用的内存是非常必要的,否则连接占用的内存会越来越大,这是不推荐的

高并发场景下的httpClient优化使用

https://www.cnblogs.com/davidwang456/articles/8526964.html

更少的tcp连接意味着更少的系统内核调用,socket的accept()和close()调用)

keepalive_timout时间值意味着:一个http产生的tcp连接在传送完最后一个响应后,还需要hold住keepalive_timeout秒后,才开始关闭这个连接

Nginx 负载均衡演示之 upstream 参数 & location 参数

https://blog.csdn.net/caijunsen/article/details/83002219

= 开头表示精确匹配
^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。
~ 开头表示区分大小写的正则匹配
*  开头表示不区分大小写的正则匹配
!
和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则
/ 通用匹配,任何请求都会匹配到。
多个location配置的情况下匹配顺序为(参考资料而来,还未实际验证,试试就知道了,不必拘泥,仅供参考):

首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

dubbo分为同步和异步调用 但是在底层都是异步IO

为什么要用Dubbo?

因为是阿里开源项目,国内很多互联网公司都在用,已经经过很多线上考验。内部使用了 Netty、Zookeeper,保证了高性能高可用性。

使用 Dubbo 可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用灵活扩展,使前端应用能更快速的响应多变的市场需求

12、在 Provider 上可以配置的 Consumer 端的属性有哪些?

1)timeout:方法调用超时
2)retries:失败重试次数,默认重试 2 次
3)loadbalance:负载均衡算法,默认随机
4)actives 消费者端,最大并发调用限制

3、Dubbo启动时如果依赖的服务不可用会怎样?
Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,默认 check=”true”,可以通过 check=”false” 关闭检查。
14、Dubbo推荐使用什么序列化框架,你知道的还有哪些?
推荐使用Hessian序列化,还有Duddo、FastJson、Java自带序列化。
15、Dubbo默认使用的是什么通信框架,还有别的选择吗?
Dubbo 默认使用 Netty 框架,也是推荐的选择,另外内容还集成有Mina、Grizzly

32、Dubbo的管理控制台能做什么?
管理控制台主要包含:路由规则,动态配置,服务降级,访问控制,权重调整,负载均衡,等管理功能。
33、说说 Dubbo 服务暴露的过程。
Dubbo 会在 Spring 实例化完 bean 之后,在刷新容器最后一步发布 ContextRefreshEvent 事件的时候,通知实现了 ApplicationListener 的 ServiceBean 类进行回调 onApplicationEvent 事件方法,Dubbo 会在这个方法中调用 ServiceBean 父类 ServiceConfig 的 export 方法,而该方法真正实现了服务的(异步或者非异步)发布。

、服务读写推荐的容错策略是怎样的?

读操作建议使用 Failover 失败自动切换,默认重试两次其他服务器。
写操作建议使用 Failfast 快速失败,发一次调用失败就立即报错。
Dubbo Refence 原理
https://blog.csdn.net/lkforce/article/details/90479966

用于直接调用的服务目标URL,如果指定了此URL,则注册中心不生效。 - 【直连提供者】
如果是线上需求需要点对点,可在 dubbo:reference 中配置 url 指向提供者,将绕过注册中心,多个地址用分号隔开
<dubbo:reference id=”xxxService” interface=”com.alibaba.xxx.XxxService” url=”dubbo://localhost:20890” />

常见容错机制:failover ,failsafe,failfase ,failback,forking,来源于阿里的定义。

Failover 失败自动切换
当出现失败,重试其它服务器,通常用于读操作(推荐使用)。 重试会带来更长延迟。
Failfast  快速失败
只发起一次调用,失败立即报错,通常用于非幂等性的写操作。 如果有机器正在重启,可能会出现调用失败 。
Failsafe 失败安全
出现异常时,直接忽略,通常用于写入审计日志等操作。 调用信息丢失 可用于生产环境 Monitor。
Failback  失败自动恢复
后台记录失败请求,定时重发。通常用于消息通知操作 不可靠,重启丢失。 可用于生产环境 Registry。
Forking  并行调用多个服务器
只要一个成功即返回,通常用于实时性要求较高的读操作。 需要浪费更多服务资源。
Broadcast
广播调用,所有提供逐个调用,任意一台报错则报错。通常用于更新提供方本地状态 速度慢,任意一台报错则报错

事件通知允许 Consumer 端在调用之前、调用正常返回之后或调用出现异常时,触发 oninvoke、onreturn、onthrow 三个事件。
oninvoke 方法参数与调用方法的参数相同;
onreturn方法第一个参数为调用方法的返回值,其余为调用方法的参数;
onthrow方法第一个参数为调用异常,其余为调用方法的参数

https://www.jianshu.com/p/142b35998947
sayHello方法为同步调用,因此事件通知方法的执行也是同步执行。可以配置 async=true让方法调用为异步,这时事件通知的方法也是异步执行的。特别强调一下,oninvoke方法不管是否异步调用,都是同步执行的
keepalive: 4, 每个nginx worker可以保留的idle连接,也就是说最多可保留的长连接,如果超过这个数量,会根据LRU算法,least recently used 用的最少的连接会被close,需要注意的是,这个参数不会限制worker的跟upstream的连接数。
keepalive_timeout :60, nginx跟upstreamd的 idle 空闲长连接,最大超时时间,超过时间没有数据往来则超时关闭
keepalive_requests : 100,设置每个长连接最多能处理的请求次数,超过了以后连接就会被close,定期关闭对于清理每个连接的占用的内存是非常必要的,否则连接占用的内存会越来越大,这是不推荐的。
proxy_http_version 1.1;
proxy_set_header Connection “”;

keepalive-timout, 设置成0就是不开启keepalive

redolog

redo log又称重做日志文件,用于记录事务操作的变化,记录的是数据修改之后的值,不管事务是否提交都会记录下来。在实例和介质失败(media failure)时,redo log文件就能派上用场,如数据库掉电,InnoDB存储引擎会使用redo log恢复到掉电前的时刻,以此来保证数据的完整性。

redo日志文件名

每个InnoDB存储引擎至少有1个重做日志文件组(group),每个文件组至少有2个重做日志文件,如默认的ib_logfile0和ib_logfile1。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kHz7zVve-1584783729916)(https://i.imgur.com/wbDzJFm.png)]

尽量保持Redo Log存储在一段连续的空间上。因此在系统第一次启动时就会将日志文件的空间完全分配。 以顺序追加的方式记录Redo Log,通过顺序IO来改善性能

未提交的事务和回滚了的事务也会记录Redo Log

影响redo log参数

  • innodb_log_file_size:指定每个redo日志大小,默认值48MB
  • innodb_log_files_in_group:指定日志文件组中redo日志文件数量,默认为2
  • innodb_log_group_home_dir:指定日志文件组所在路劲,默认值./,指mysql的数据目录datadir
  • innodb_mirrored_log_groups:指定日志镜像文件组的数量,默认为1,此功能属于未实现的功能,在5.6版本中废弃,在5.7版本中删除了

binlog

binlog记录了对MySQL数据库执行更改的所有操作,但是不包括SELECT和SHOW这类操作,因为这类操作对数据本身并没有修改。然后,若操作本身并没有导致数据库发生变化,那么该操作也会写入二进制日志

影响binlog的参数

  • max_binlog_size:指定单个binlog文件最大值。默认值为1g,最大值1g,如果超过该值,则产生新的binlog文件,后缀名+1,并记录到.index文件。
  • binlog_cache_size:使用事务表存储引擎(如innodb存储引擎)时,所有未提交的binlog日志会被记录到一个缓存中去,等事务提交时再将缓存中的binlog写入到binlog文件中。缓存的大小由binlog_cache_size决定,默认大小为32K
  • max_binlog_cache_size:如果事务需要的内存超过很多字节,则服务器会生成多于“max_binlog_cache_size”字节的存储错误所需的并发事务。 最小值为4096字节,最大可能值为16EB(exabytes)。 建议的最大值为4GB; 这是因为MySQL目前无法使用大于4GB的二进制日志位置。
  • expire_logs_days:表示binlog文件自动删除N天前的文件。默认值为0,表示不自动删除,最大值99.要手动删除binlog文件,可以使用purge binary logs语句
  • sync_binlog:sync_binlog=[N]表示没写缓冲N次就同步到磁盘,如果将N设为1,即sync_binlog表示采用同步写磁盘的方式来写二进制日志,在MySQL5.7.7后,默认为1。会对数据库的IO系统带来一定影响,但可以得到最大的高可用行。
  • binlog_checksum:该参数目的就是写入binlog进行校验,有两个值[crc32|none],默认为crc32
  • binlog-do-db:表示需要写入日志的数据库,默认为空,表示同步所有库
  • binlog-ignore-db:表示忽略写入日志的数据库,默认为空,表示同步所有库
  • log-slave-update:表示从master端取得并执行的binlog,写入自己的binlog文件中,一般应用在master=>slave=>slave架构
  • binlog_format:记录binlog的格式。[statement,row,mixed],在MySQL5.7.7之后,默认为row

redo log与binlog的区别

  • redo log是在InnoDB存储引擎层产生,而binlog是MySQL数据库的上层产生的,并且二进制日志不仅仅针对INNODB存储引擎,MySQL数据库中的任何存储引擎对于数据库的更改都会产生二进制日志。
  • 内容形式不同。MySQL的binlog是逻辑日志,其记录是对应的SQL语句。而innodb存储引擎层面的重做日志是物理日志。
  • 写入磁盘的时间点不同,二进制日志只在事务提交完成后进行一次写入。而innodb存储引擎的重做日志在事务进行中不断地被写入,并日志不是随事务提交的顺序进行写入的。
  • 二进制日志仅在事务提交时记录,并且对于每一个事务,仅在事务提交时记录,并且对于每一个事务,仅包含对应事务的一个日志。而对于innodb存储引擎的重做日志,由于其记录是物理操作日志,因此每个事务对应多个日志条目,并且事务的重做日志写入是并发的,并非在事务提交时写入,其在文件中记录的顺序并非是事务开始的顺序。
  • binlog不是循环使用,在写满或者重启之后,会生成新的binlog文件,redo log是循环使用。
  • binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用

undo

事务开始之前,将当前事务的版本生成undo-log,当事务提交之后,undo log并不能立马被删除,而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间

异步复制(Asynchronous replication)
半同步复制(Semisynchronous replication)
全同步复制(Fully synchronous replication)

sysbench

参考文档

安装

1
yum install sysbench -y

使用帮助

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
General options:
--threads=N number of threads to use [1]
--events=N limit for total number of events [0]
--time=N limit for total execution time in seconds [10]
--forced-shutdown=STRING number of seconds to wait after the --time limit before forcing shutdown, or 'off' to disable [off]
--thread-stack-size=SIZE size of stack per thread [64K]
--rate=N average transactions rate. 0 for unlimited rate [0]
--report-interval=N periodically report intermediate statistics with a specified interval in seconds. 0 disables intermediate reports [0]
--report-checkpoints=[LIST,...] dump full statistics and reset all counters at specified points in time. The argument is a list of comma-separated values representing the amount of time in seconds elapsed from start of test when report checkpoint(s) must be performed. Report checkpoints are off by default. []
--debug[=on|off] print more debugging info [off]
--validate[=on|off] perform validation checks where possible [off]
--help[=on|off] print help and exit [off]
--version[=on|off] print version and exit [off]
--config-file=FILENAME File containing command line options
--tx-rate=N deprecated alias for --rate [0]
--max-requests=N deprecated alias for --events [0]
--max-time=N deprecated alias for --time [0]
--num-threads=N deprecated alias for --threads [1]

Pseudo-Random Numbers Generator options:
--rand-type=STRING random numbers distribution {uniform,gaussian,special,pareto} [special]
--rand-spec-iter=N number of iterations used for numbers generation [12]
--rand-spec-pct=N percentage of values to be treated as 'special' (for special distribution) [1]
--rand-spec-res=N percentage of 'special' values to use (for special distribution) [75]
--rand-seed=N seed for random number generator. When 0, the current time is used as a RNG seed. [0]
--rand-pareto-h=N parameter h for pareto distribution [0.2]

Log options:
--verbosity=N verbosity level {5 - debug, 0 - only critical messages} [3]

--percentile=N percentile to calculate in latency statistics (1-100). Use the special value of 0 to disable percentile calculations [95]
--histogram[=on|off] print latency histogram in report [off]

General database options:

--db-driver=STRING specifies database driver to use ('help' to get list of available drivers) [mysql]
--db-ps-mode=STRING prepared statements usage mode {auto, disable} [auto]
--db-debug[=on|off] print database-specific debug information [off]


Compiled-in database drivers:
mysql - MySQL driver
pgsql - PostgreSQL driver

mysql options:
--mysql-host=[LIST,...] MySQL server host [localhost]
--mysql-port=[LIST,...] MySQL server port [3306]
--mysql-socket=[LIST,...] MySQL socket
--mysql-user=STRING MySQL user [sbtest]
--mysql-password=STRING MySQL password []
--mysql-db=STRING MySQL database name [sbtest]
--mysql-ssl[=on|off] use SSL connections, if available in the client library [off]
--mysql-ssl-cipher=STRING use specific cipher for SSL connections []
--mysql-compression[=on|off] use compression, if available in the client library [off]
--mysql-debug[=on|off] trace all client library calls [off]
--mysql-ignore-errors=[LIST,...] list of errors to ignore, or "all" [1213,1020,1205]
--mysql-dry-run[=on|off] Dry run, pretend that all MySQL client API calls are successful without executing them [off]

pgsql options:
--pgsql-host=STRING PostgreSQL server host [localhost]
--pgsql-port=N PostgreSQL server port [5432]
--pgsql-user=STRING PostgreSQL user [sbtest]
--pgsql-password=STRING PostgreSQL password []
--pgsql-db=STRING PostgreSQL database name [sbtest]

Compiled-in tests:
fileio - File I/O test
cpu - CPU performance test
memory - Memory functions speed test
threads - Threads subsystem performance test
mutex - Mutex performance test

io测试

1
2
3
sysbench fileio --file-num=1 --file-io-mode=async --file-total-size=5G --file-test-mode=rndrw --time=30 prepare
sysbench fileio --file-num=1 --file-io-mode=async --file-total-size=5G --file-test-mode=rndrw --time=30 run
sysbench fileio --file-num=1 --file-io-mode=async --file-total-size=5G --file-test-mode=rndrw --time=30 cleanup

cpu压测

1
2
sysbench cpu --cpu-max-prime=3 run
sysbench --threads=2 cpu run

memory

1
sysbench memory --memory-total-size=2G run

threads

1
sysbench threads --thread-yields=2 --thread-locks=4 run

haparam 测试磁盘性能

1
2
3
yum install hdparm -y
hdparm -t /dev/vda L
hdparm -T /dev/vda L

vmstat

  • in:每秒的中断数,包括时钟中断。
  • cs:每秒上下文切换的次数
  • r:等待运行的进程数
  • b:阻塞中的进程

iostat

top、htpop

通过top -Hp 23344可以查看该进程下各个线程的cpu

iotop

iftop、ifstat

ss

1
2
3
4
5
# ss -tnap
# ss -tnap6
# ss -tnap
# ss -s
# ss -tn -o state established -p

lsof

sar

sar命令

iperf

1
2
3
4
yum install iperf -y
iperf -s
iperf -s -u
iperf -c 198.51.100.5

参考文档

mtr

slabtop

sync && echo 2 > /proc/sys/vm/drop_caches

slabinfo

linux-fincore

1
2
3
4
5
6
7
8
yum install automake autoconf -y
git clone https://github.com/waleedmazhar/linux-ftools
cd linux-ftools/

aclocal && autoconf && automake && automake --add-missing
./configure && make && make install

linux-fincore --pages=false --summarize --only-cached *

Linux Page Cache调优在Kafka中的应用

基本概念

关系(Relation)

TABLE

元组(Tuple)

RECORD、ROW

字段 Field

Column

表空间(Tablespace)

是一个存储位置,可以在其中保存底层数据库对象的实际数据,定义一个文件系统位置,代表数据库对象(表、索引等)的文件可以存储在该文件目录下

数据段(Segment)和数据页(Page)

每个表和索引都保存在一个单独的文件中,每个文件就是一个数据段(Segment)。在默认情况下,当一个表或索引的大小超过1GB时,它会被拆分出另一个数据段。第1个数据段以PostgreSQL内部定义的filenode命名,第2个数据段则命名为filenode.1,以此类推。一个数据段内部是以数据页的形式来组织的,数据页表示硬盘中的数据块,默认大小为8KB,最大为32KB,数据页的大小是在编译时确定的。行就存储在数据页中,由于每个数据页是等价的,因此一个特定的行可以存储在任意一个数据页中

存储结构

数据库族 -> 数据库 -> schema -> 表 -> 行 -> 字段

安装

安装脚本

管理

1
2
3
4
5
pg_ctl start -D /opt/postgresql/data 
pg_ctl stop -D /opt/postgresql/data -m smart/fast/immediate
pg_ctl restart -D /opt/postgresql/data
pg_ctl reload -D /opt/postgresql/data
pg_ctl status -D /opt/postgresql/data

sql

sql分类

DQL、DML、DDL

控制台客户端

psql –help

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
40
41
42
43
44
45
46
47
48
49
50
51
General options:
-c, --command=COMMAND run only single command (SQL or internal) and exit
-d, --dbname=DBNAME database name to connect to (default: "postgres")
-f, --file=FILENAME execute commands from file, then exit
-l, --list list available databases, then exit
-v, --set=, --variable=NAME=VALUE
set psql variable NAME to VALUE
(e.g., -v ON_ERROR_STOP=1)
-V, --version output version information, then exit
-X, --no-psqlrc do not read startup file (~/.psqlrc)
-1 ("one"), --single-transaction
execute as a single transaction (if non-interactive)
-?, --help[=options] show this help, then exit
--help=commands list backslash commands, then exit
--help=variables list special variables, then exit

Input and output options:
-a, --echo-all echo all input from script
-b, --echo-errors echo failed commands
-e, --echo-queries echo commands sent to server
-E, --echo-hidden display queries that internal commands generate
-L, --log-file=FILENAME send session log to file
-n, --no-readline disable enhanced command line editing (readline)
-o, --output=FILENAME send query results to file (or |pipe)
-q, --quiet run quietly (no messages, only query output)
-s, --single-step single-step mode (confirm each query)
-S, --single-line single-line mode (end of line terminates SQL command)

Output format options:
-A, --no-align unaligned table output mode
--csv CSV (Comma-Separated Values) table output mode
-F, --field-separator=STRING
field separator for unaligned output (default: "|")
-H, --html HTML table output mode
-P, --pset=VAR[=ARG] set printing option VAR to ARG (see \pset command)
-R, --record-separator=STRING
record separator for unaligned output (default: newline)
-t, --tuples-only print rows only
-T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)
-x, --expanded turn on expanded table output
-z, --field-separator-zero
set field separator for unaligned output to zero byte
-0, --record-separator-zero
set record separator for unaligned output to zero byte

Connection options:
-h, --host=HOSTNAME database server host or socket directory (default: "local socket")
-p, --port=PORT database server port (default: "5432")
-U, --username=USERNAME database user name (default: "postgres")
-w, --no-password never prompt for password
-W, --password force password prompt (should happen automatically)

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 列举数据库
\l
# 选择数据库
\c databasename
# 查看该某个库中的所有表
\d
# 查看某个库中的某个表结构
\d tablename
# 显示字符集
\encoding
# 退出psgl
\q
# 显示帮助
\?

表空间

1
2
3
4
5
6
7
mkdir -p /opt/postgresql/tablespace/testspace && chown -R postgres:postgres  /opt/postgresql
CREATE TABLESPACE testspace OWNER postgres LOCATION '/opt/postgresql/tablespace/testspace';
\db;
create TABLE test(a int) tablespace testspace;
select oid,datname from pg_database where datname = 'postgres';
select relname,relfilenode from pg_class where relname='test';
drop TABLESPACE testspace;

创建数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 获取帮助
\h create database
# 用法
CREATE DATABASE name
[ [ WITH ] [ OWNER [=] user_name ]
[ TEMPLATE [=] template ]
[ ENCODING [=] encoding ]
[ LC_COLLATE [=] lc_collate ]
[ LC_CTYPE [=] lc_ctype ]
[ TABLESPACE [=] tablespace_name ]
[ ALLOW_CONNECTIONS [=] allowconn ]
[ CONNECTION LIMIT [=] connlimit ]
[ IS_TEMPLATE [=] istemplate ] ]

URL: https://www.postgresql.org/docs/12/sql-createdatabase.html
# 创建数据库
CREATE database dennis WITH ENCODING='utf8' TABLESPACE=testspace OWNER=postgres;

字段说明

  • name:要创建的数据库的名称
  • user_name:要创建的数据库所属的用户如果没有指定,则默认属于执行该命令的用户
  • template:要创建的数据库所用的模板库,默认的模板库是template1
  • encoding:要创建的数据库所使用的字符集。如果没有指定,则默认使用其模板库的字符集
  • lc_collate:要创建的数据库所使用的collation顺序。这会影响在ORDER BY语法中字符串类型列的顺序,也会影响text类型列的索引顺序。如果没有指定,则默认使用其模板库的collation顺序
  • lc_ctype:要创建的数据库所使用的字符分类。这会影响字符的分类,如大小写和数字。如果没有指定,则默认使用其模板库的字符分类
  • tablespace_name:要创建的数据库所关联的表空间。默认使用模板库对应的表空间
  • allowconn:是否可以连接该数据库,默认设置为true。如果设置为false,则任何用户都不能连接该数据库
  • connlimit:允许并发连接该数据库的个数。默认设置为-1,即没有限制
  • istemplate:是否是模板库,默认设置为false。如果设置为true,则任何具有创建数据库权限的用户均可以用其复制新的数据库;如果设置为false,则只有超级用户和该数据库的用户可以用其复制新的数据库

创建数据表

官方文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
drop TABLE IF EXISTS company;
CREATE TABLE IF NOT EXISTS company (
id serial PRIMARY KEY,
title CHAR(50) UNIQUE NOT NULL,
subtitle varchar(500) UNIQUE NOT NULL,
age INT NOT NULL DEFAULT 0,
address TEXT,
salary REAL,
money decimal,
status double precision,
guid uuid
);
-- \d+ company
insert into company(name,address,age,salary) values('dennis','成都','28',3.14);
insert into company(name,address,age,salary) values('dennis1','成都','28',3.14);
insert into company(name,address,age,salary) values('dennis2','成都','28',3.14);
insert into company(name,address,age,salary) values('dennis3','成都','28',3.14);
insert into company(name,address,age,salary) values('dennis4','成都','28',3.14);
insert into company(name,address,age,salary) values('dennis5','成都','28',3.14);
delete from company where age=28;

postgresql、mysql数据类型比较

postgresql mysql
TINYINT
smallint(2字节) SMALLINT(2字节)
MEDIUMINT(3字节)
integer(4字节) INT或INTEGER(4字节)
bigint(8字节) BIGINT(8字节)
decimal(可变长) DECIMAL
numeric(可变长)
real(4字节) FLOAT(4字节)
double(8字节) DOUBLE(8字节)
character varying(n), varchar(n) CHAR(0-255 bytes)
character(n), char(n) VARCHAR(0-65535 byte)
TINYTEXT
text(无长度限制) TEXT(0-65 535 bytes)
MEDIUMTEXT(0-16 777 215 bytes)
LONGTEXT(0-4 294 967 295 bytes)
timestamp(8字节) TIMESTAMP(4字节)
date(4字节) DATE(3字节)
time(8字节) TIME(0-4 294 967 295 bytes)
interval(12字节)
smallserial(2字节)
serial(4字节)
bigserial(8字节)

json、jsonb数据类型

二者的区别在于json写入快,读取慢,jsonb写入慢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
drop table if exists json_test;
CREATE TABLE json_test (
id serial,
board_id float NOT NULL,
data jsonb
);
INSERT INTO json_test VALUES (1, 1, '{"name": "Paint house", "tags": ["Improvements", "Office"], "finished": true}');
INSERT INTO json_test VALUES (2, 1, '{"name": "Wash dishes", "tags": ["Clean", "Kitchen"], "finished": false}');
INSERT INTO json_test VALUES (3, 1, '{"name": "Cook lunch", "tags": ["Cook", "Kitchen", "Tacos"], "ingredients": ["Tortillas", "Guacamole"], "finished": false}');
INSERT INTO json_test VALUES (4, 1, '{"name": "Vacuum", "tags": ["Clean", "Bedroom", "Office"], "finished": false}');
INSERT INTO json_test VALUES (5, 1, '{"name": "Hang paintings", "tags": ["Improvements", "Office"], "finished": false}');
SELECT data->>'name' AS name FROM json_test;
SELECT * FROM json_test WHERE data->>'finished' = 'true';

insert into json_test select * from json_test;

vacuum full json_test

->将以JSON对象的形式返回该属性,而->>将以整数或文本

数组类型

在存储一些数据时能更节省空间

1
2
3
4
5
6
7
8
9
10
11
drop table if exists array_test;
CREATE TABLE array_test (
id serial primary key,
data int[]
);
INSERT INTO array_test VALUES (1,'{3,5}');
select * from array_test;
update array_test set data[0]=3434 where id=1;
select * from array_test;
update array_test set data[7]=3434 where id=1;
select * from array_test;

postgresql还支持几何类型、uuid类型、xml类型、数组类型、复合类型、范围类型、布尔类型等

uuid采用16位存储,更节省空间

1
2
3
4
5
6
7
8
select * from pg_database;
select * from pg_class;
COPY json_test TO '/opt/postgresql/test.copy';
select * from json_test;
delete from json_test;
COPY json_test FROM '/opt/postgresql/test.copy';
COPY json_test(id, name) TO '/opt/postgresql/test.copy' DELIMITER ' ';

查询正在执行的sql

1
SELECT procpid,START,now() - START AS lap,current_query FROM(SELECT backendid,pg_stat_get_backend_pid(S.backendid) AS procpid,pg_stat_get_backend_activity_start (S.backendid) AS START,pg_stat_get_backend_activity (S.backendid) AS current_query FROM(SELECT pg_stat_get_backend_idset () AS backendid) AS S) AS S WHERE current_query <> '<IDLE>' ORDER BY lap DESC;

配置相关接口

1
2
3
4
5
select name,setting from pg_settings where category='File Locations';
select name,setting from pg_settings;
alter system set log_statement='none';
SELECT pg_reload_conf();
show log_statement;

upsert

1
insert into test values (1,'test',now()) on conflict(id) do update set info=excluded.info,crt_time=excluded.crt_time;

其他

  • postgre 事务号32位,约49亿
  • vacuum 不会锁表,只是单纯的回收空间以被重用,被回收的空间一般情况不会被返还给操作系统,仅仅被保留在同一个表中以备重用
  • vacuum full会锁表,会将表的整个内容重写到一个新的磁盘文件中,并且不包含额外的空间,这使得没有被 使用的空间被还给操作系统

索引组织表和堆表

  • 堆表:存储存储,插入速度块,查询速度慢(postgresql),索引的二级索引为堆表上面的绝对位置(页号,页内偏移),所以不一定要有主键,索引一般用B树
  • 索引组织表:有序存储,插入速度慢,查询速度快,写入时需要在特定的位置写入(mysql innodb),索引的二级索引为主键,所以是需要有主键的,索引一般用B+树

cpu 选取方法

最好的方法是通过类似top工具对当前数据库所在服务器进行监测。如果每个CPU运行的进程很少,则速度更快的CPU方案会更加适合这种类型的工作负载,单个查询一般只能使用一个核心(9.6引入了并行查询机制)

内存选取方式

  • 数据量相对于系统RAM来说非常小,那么加大内存也不会提升性能。此时,用户需要使用速度更快的处理器
  • 表的数据量远远大于可以为数据库分配的内存时,如数据仓库系统,这时用户需要选取更快的硬盘,而不是增加内存
  • 用户频繁访问的数据量相对于内存较大时,加大内存往往能起到显著效果,一般尽可能把热数据放在内存中

pg_buffercache

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- 搜索contrib
yum search contrib
-- 安装 contrib
yum install postgresql12-contrib.x86_64
-- 查看已安装扩展 \dx
-- 查看pg_buffercache插件是否存在
select * from pg_available_extensions where name='pg_buffercache';
-- 安装插件
create extension pg_buffercache;
-- 查询
select * from pg_buffercache;
-- 查看buffer配置
SELECT name,setting,unit,current_setting(name) FROM pg_settings WHERE name='shared_buffers';
-- 查看当前buffer使用情况
select d.datname, c.relname, c.relkind, count(*) as buffers from pg_class c inner join pg_buffercache b on b.relfilenode=c.relfilenode inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database()) where 1=1 group by d.datname, c.relname, c.relkind order by d.datname,4 desc ;
-- 删除buffer
drop extension pg_buffercache;

wal和lsm

PostgreSQL实现MVCC方式

PostgreSQL如何实现MVCC (基于xmin、xmax、cmin、cmax)

常用运维sql

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
-- 查看数据库
select * from pg_database;
-- 查看表空间
select * from pg_tablespace;
-- 查看用户
select * from pg_user;
select * from pg_shadow;
select * from pg_roles;
-- 查看表
select * from pg_tables;
-- 查看索引
select * from pg_index;
-- 查看锁
select * from pg_locks;
-- 查看表页数,表存储空间大小为 8k*relpages
select relname,relpages,reltuples,relallvisible,reltuples/relpages as avg_record_per_page from pg_class where relpages>0 order by relpages desc;
-- 查看会话进程
select usename,application_name,client_addr,query_start,query,backend_type from pg_stat_activity;
-- 查看表大小
select pg_relation_size('json_test')/1024 as table_size;
-- 查看数据库统计信息
select * from pg_stat_database;
-- 查看表io信息
select * from pg_statio_user_tables;
-- 查看报表统计 vacuum
select * from pg_stat_all_tables;
-- 查看索引使用情况
select * from pg_stat_all_indexes;
select * from pg_statio_user_indexes;

pg_statio_user_indexes、pg_statio_all_indexes

返回字段含义

  • idx_blks_read:从磁盘中读取索引的次数
  • idx_blks_hit:从内存中读取索引次数
1
2
3
select * from pg_statio_user_indexes;
-- 查询索引内存命中率
select relname,relname,idx_blks_read,idx_blks_hit,idx_blks_hit*100/(idx_blks_read+idx_blks_hit) as idx_hit_rate from pg_statio_user_indexes;

pg_statio_user_tables、pg_statio_all_tables

heap_blks_read:读取的磁盘块数
heap_blks_hit:缓冲区命中数
idx_blks_read:所有索引读取的磁盘块数
idx_blks_hit:所有索引缓冲区命中数
toast_blks_read:TOAST表读取的磁盘块数(如果存在)
toast_blks_hit:TOAST表命中缓冲区数(如果存在)
tidx_blks_read:TOAST表索引读取的磁盘块数(如果存在)
tidx_blks_hit:TOAST表索引命中缓冲区数(如果存在)

1
2
3
select * from pg_statio_user_tables;
-- 查询索引内存命中率
select heap_blks_read,heap_blks_hit,idx_blks_read,idx_blks_hit,heap_blks_hit*100/(heap_blks_hit+heap_blks_read) as heap_hit_rate,idx_blks_hit*100/(idx_blks_read+idx_blks_hit) as idx_hit_rate from pg_statio_user_tables;

pg_stat_user_tables、pg_stat_all_tables

seq_scan:顺序扫描次数(全表扫描)
seq_tup_read:顺序扫描抓取的有live数据行的数目
idx_scan:索引扫描的次数
idx_tup_fetch:索引扫描抓取的有live数据行的数目
n_tup_ins:插入的行数
n_tup_upd:更新的行数
n_tup_del:删除的行数
n_tup_hot_upd:HOT更新的行数(即不需要单独的索引更新
n_live_tup:live行估计数
n_dead_tup:dead行估计数
last_vacuum:最后一次手动vacuum时间(不计算VACUUM FULL)
last_autovacuum:最后一次autovacuum时间
last_analyze:最后一次analyze时间
last_autoanalyze:最后一次autoanalyze时间
vacuum_count:vacuum的次数(不计算VACUUM FULL)
autovacuum_count:autovacuum的次数
analyze_count:analyze的次数
autoanalyze_count:autoanalyze的次数

1
2
3
4
5
6
7
select * from pg_stat_user_tables;
-- 查看全表扫描与索引扫描,seq_scan最好能为0
select relname,seq_scan,seq_tup_read,idx_scan,idx_tup_fetch from pg_stat_user_tables;
-- 查看操作行数
select relname,n_tup_ins,n_tup_upd,n_tup_del,n_tup_hot_upd,n_live_tup,n_dead_tup from pg_stat_user_tables;
-- 查看vacuum和analyze
select relname,last_vacuum,last_autovacuum,vacuum_count,autovacuum_count,last_analyze,last_autoanalyze,analyze_count,autoanalyze_count from pg_stat_user_tables;

PG_STAT_REPLICATION

PG_THREAD_WAIT_STATUS

https://support.huaweicloud.com/devg-dws/dws_04_0517.html

数据写入流程

  • change发生时:先将变更后内容写入 wal buffer,再将数据写入 data buffer
  • commit发生时:wal buffer中数据内容刷新到磁盘
  • checkpoint发生时:将所有data buffer刷新到磁盘

触发checkpoint时机

  • 手动执行checkpoint命令
  • 执行需要检查点的命令(pg_stat_backup、pg_ctl stop restart 等)
  • 达到检查点配置的时间(checkpoint_timeout)
  • max_wal_size 满了
1
2
show checkpoint_timeout
show max_wal_size

复制

日志复制

对wal日志进行拷贝,因此从库始终落后主库一个日志文件,并且使用rsync工具同步data目录

流复制

PostgreSQL通过wal日志来传送的方式有两种:基于文件的日志传送和流复制

流复制过程
$PGDATA/pg_wal(pg10之前叫pg_xlog)

procs ———–memory———- —swap– —–io—- -system– ——cpu—–
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 26416 25936 281156 0 0 0 0 521 1258 0 0 100 0 0
0 0 0 26528 25936 281156 0 0 0 0 508 1223 1 1 98 0 0
0 0 0 26540 25936 281156 0 0 0 0 513 1220 1 0 99 0 0
0 0 0 26544 25944 281152 0 0 0 20 517 1226 0 1 99 0 0

in:每秒的中断数,包括时钟中断。
cs:每秒上下文切换的次数
r:等待运行的进程数
b:阻塞中的进程

默认监控: sar 1 1 // CPU和IOWAIT统计状态
(1) sar -b 1 1 // IO传送速率
(2) sar -B 1 1 // 页交换速率
(3) sar -c 1 1 // 进程创建的速率
(4) sar -d 1 1 // 块设备的活跃信息
(5) sar -n DEV 1 1 // 网路设备的状态信息
(6) sar -n SOCK 1 1 // SOCK的使用情况
(7) sar -n ALL 1 1 // 所有的网络状态信息
(8) sar -P ALL 1 1 // 每颗CPU的使用状态信息和IOWAIT统计状态
(9) sar -q 1 1 // 队列的长度(等待运行的进程数)和负载的状态
(10) sar -r 1 1 // 内存和swap空间使用情况
(11) sar -R 1 1 // 内存的统计信息(内存页的分配和释放、系统每秒作为BUFFER使用内存页、每秒被cache到的内存页)
(12) sar -u 1 1 // CPU的使用情况和IOWAIT信息(同默认监控)
(13) sar -v 1 1 // inode, file and other kernel tablesd的状态信息
(14) sar -w 1 1 // 每秒上下文交换的数目
(15) sar -W 1 1 // SWAP交换的统计信息(监控状态同iostat 的si so)
(16) sar -x 2906 1 1 // 显示指定进程(2906)的统计信息,信息包括:进程造成的错误、用户级和系统级用户CPU的占用情况、运行在哪颗CPU上
(17) sar -y 1 1 // TTY设备的活动状态

————————————————
版权声明:本文为CSDN博主「liyongbing1122」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liyongbing1122/article/details/89517282

非对称加密

公钥加密的文件可以用私钥解密,私钥加密的文件可以用公钥解密

1
2
3
4
5
6
7
8
//生成私钥
openssl genpkey -algorithm rsa -out rsa_private.key
//从私钥中提取公钥
openssl rsa -pubout -in rsa_private.key
//用私钥对文件进行加密(签名)
openssl rsautl -sign -in text -inkey rsa_private.key -out text.en
//用公钥对文件进行解密(校验)
openssl rsautl -verify -in text.en -inkey rsa_pub.key -pubin

证书

公钥信息 + 额外的其他信息(所属的实体,加密解密算法等)= 证书,证书文件的扩展名一般为crt

证书格式

  • .DER或者.CER:二进制,只包含证书信息,不包含私钥
  • .CRT:二进制或者文本
  • .PEM:文本格式,可以存放证书或者私钥,或者都包含,如只是包含私钥,一般用.KEY文件替代
  • .P12或者.PFX:二进制格式,同时包含证书和私钥,一般有密码保护
  • .JKS:二进制格式,java使用证书
1
2
3
4
5
6
7
8
9
10
11
12
//查看证书信息
openssl x509 -in apiserver.crt -noout -text
//查看客户端证书
openssl s_client -connect www.baidu.com:443
//查看证书信息
openssl x509 -in tt.key -noout -text
//导出网站的公钥
export WEB_HOST=www.taobao.com && openssl s_client -showcerts -connect ${WEB_HOST}:443 < /dev/null | openssl x509 -outform pem > ${WEB_HOST}.pem && cat ${WEB_HOST}.pem
//同上
ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect www.baidu.com:443) -scq
//同上
openssl s_client -connect www.baidu.com:443 2 > /dev/null < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

ssh生成密钥

1
2
//使用工具生成密钥
ssh-keygen -t rsa

生成自签名证书过程

1
2
3
4
5
6
7
8
9
10
11
12
13
// 生成根证书私钥
openssl genrsa -out ca.key 2048
// 生成根证书请求文件
openssl req -new -key ca.key -out ca.csr
// 生成根证书
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt

// 生成证书私钥
openssl genrsa -out server.key 2048
// 生成证书请求文件
openssl req -new -key server.key -out server.csr
// 创建证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out server.crt

java使用证书

1
2
3
4
//keytool生成密钥文件keystore
keytool -importcert -noprompt -trustcacerts -alias test -file server.cer -keystore server.jks
//导入证书到java运行环境
keytool -importkeystore -srckeystore server.jks -destkeystore ${JAVA_HOME}/jre/lib/security/cacerts

概念

软件工程的目的是探索软件问题的解决办法

软件开发中存在的问题

30%完成,50% 延期、成本增加、由缺陷,20%失败

  • 开发成本高
  • 不能按时交付产品
  • 交付产品存在缺陷
  • 交付产品不符合客户需求

软件质量

软件开发过程中要平衡质量、成本、效率之间的关系,不能过度最求某一方面,质量不是测试出来的,而是在开发中构建出来的,强调质量的过程控制

  • 用户角度:满足需求,功能正常、性能正常、使用便捷
  • 开发角度:可测试、可读性好、可维护
  • 管理者:按时交付、满足预算、交付质量好

好的软件质量

  • 开发成本低
  • 按时交付软件产品
  • 实现客户需求
  • 具有良好的性能、可靠性、可扩展性、可以执行
  • 维护成本低

软件开发生命周期(开发过程)

问题定义

做可行性研究、产出可行性报告

需求设计

分析需求 -> 规格说明文档 -> 客户确认 -> 软件需求说明书

软件设计

结构设计、接口设计、组件设计、数据库设计 -> 软件设计说明书

软件开发

编写代码 -> 单元测试 -> 代码审查 -> 继承测试 -> 源代码 -> 构建

软件测试

单元测试 -> 子系统测试 -> 集成测试

部署维护

软件项目管理

计划:明确目标、制定计划、确定所需资源
组织:软件小组、明确成员的分工与职责、配置各种资源
领导:指导项目实施,检查、评价项目总体情况
控制:控制项目范围变更、监控项目进展、发现并纠正问题

软件配置管理

通过执行版本控制、变更控制的规程,使用核试的配置管理软件,来确保所有产品配置行的完整性和可追溯性

  • 版本管理
  • 变更管理

软件开发模型

迭代模型(增量模型、迭代模型)

迭代模型以价值驱动,强调在资源一定(人力等)的情况下完成价值最高的开发需求,一般也称敏捷开发

scrum 开发

scrum中由多个sprint(冲刺、里程碑)组成,在迭代中不允许变更需求、交付内容、交付日期,如果要进行需求调整,可以安排到下一个迭代中

  • 产品高经理根据产品的价值和市场需求排列出优先级列表(产品订单)
  • 开迭代规划会议,挑选出优先级最高的条目作为开发任务,一般任务的周期是1-4周
  • 每日会议,进展同步、困难提出、下次会议前需要做什么
  • 产生一个版本,确定产品质量,发布版本

参与角色

  • 产品负责人:确定产品的需求、发布计划、优先级,验收迭代结果
  • scrum主管:管理项目,帮助团队制定计划、组织会议、排除团队中的困难、保证团队不受打扰
  • 团队:4-10个人比较合适,人员过少可能技能不够,人员过多沟通复杂

xp极限编程

瀑布模型

原型模型

为应对需求难以确定的困难,将需求转化成可视化原型

软对开发管理

  • 人力资源管理 -> 团队组建 -> 团队建设(增强气氛、提高效率) -> 项目管理
  • 系统分析人员 -> 架构师 -> 程序员 -> 测试

团队沟通管理

  • 严格控制会议时间。一般不超过1小时,最多1.5小时
  • 明确会议的目的
  • 事先分发会议资料
  • 记录会议纪要及相关结论

用例图(Use-Case View)

4+1视图中的场景图,系统需要提供哪些功能、识别出系统与用户或其它系统的交互

元素

  • 参与者(Actor)
  • 系统边界(Boundary)
  • 用例(Use Case)

用例图之间的关系

  • 关联:参与者与用例之间的关系
  • 泛化:参与者之间、用例之间的关系,存在继承关系
  • 包含:用例之间的关系,一个大的测试用例包含多个子用例
  • 扩展:用例之间的关系,增加用例能力

逻辑视图(Logical View)

功能性需求,即在为用户提供服务方面系统所应该提供的功能

类图

类图之间的关系

  • 继承/泛化(generalization)
  • 实现(realization)
  • 依赖:A依赖B,B作为A方法的参数
  • 关联:A关联B,B作为A的属性
  • 聚合:关联的特例,根据语意区分,如:员工组成部门
  • 组合:关联的特例,根据语言区分,如:人由手脚构成

交互图

顺序图、时序图

强调相互顺序关系

通信图、协作图

强调相互之间的关系

对象图

状态图

实现视图或开发视图(Implementation View)

组件图

部署视图、物理视图(Deployment View)

非功能性需求,如可用性、可靠性、性能吞吐量和可伸缩性等

部署图

网络拓扑图

过程视图、运行视图或处理视图(Process View)

非功能性需求,如并发性、分布性、系统完整性、容错性

活动图