云计算SRE工程师快捷查询资料
云计算SRE工程师快捷查询资料

云计算SRE工程师快捷查询资料

文本三剑客

取出网站访问量最大的前3个IP

[root@VM_0_10_centos logs]# awk '{print $1}' nginx.access.log-20200428|sort |
uniq -c |sort -nr|head -3
5498 122.51.38.20
2161 117.157.173.214
953 211.159.177.120
[root@centos8 ~]#awk '{print $1}' access_log |sort |uniq -c|sort -nr|head
4870 172.20.116.228
3429 172.20.116.208
2834 172.20.0.222
2613 172.20.112.14
2267 172.20.0.227
2262 172.20.116.179
2259 172.20.65.65
1565 172.20.0.76
1482 172.20.0.200
1110 172.20.28.145

取出分区利用率

[root@wing ~]# df|awk -F' +|%' '/^\/dev\/sd/{print $1,$5}'
/dev/sda2 8
/dev/sda5 2
/dev/sda1 25

取 ifconfig 输出结果中的IP地址

[root@wing ~]# ifconfig eth0|sed -n '2p' |awk '{print $2}'
10.0.0.156
[root@wing ~]# ifconfig eth0 | awk '/netmask/{print $2}'
10.0.0.156
[root@wing ~]# ifconfig eth0|awk '/\<inet\>/{print $2}'
10.0.0.156
[root@wing ~]# ifconfig eth0|sed -nr "2s/^[^0-9]+([0-9.]+) .*$/\1/p"
10.0.0.156
[root@wing ~]# ifconfig eth0 |head -n2|egrep -o "inet ([0-9]+.){3}[0-9]+"|cut -d " " -f2
10.0.0.156

文件host_list.log 如下格式,请提取”.magedu.com”前面的主机名部分并写入到回到该文件中

[root@wing ~]# awk -F"[ .]+" '{print $2}' host_list.log >> host_list.log 
[root@wing ~]# cat host_list.log 
1 www.magedu.com
2 blog.magedu.com
3 study.magedu.com
4 linux.magedu.com
5 python.magedu.com
www
blog
study
linux
python

连接数最多的前3个IP

[root@RS ~]# ss -nt|awk -F"[ :]+"   'NR!=1 {print $6}'|sort|uniq -c|sort -nr
      2 115.171.63.98
      1 100.100.30.25
[root@RS ~]# ss -nt|awk -F"[ :]+"   'NR!=1 {ip[$6]++}END{for(i in ip){print ip[i],$6} } '
2 100.100.30.25
1 100.100.30.25

文件abc,txt只有一行数字,计算其总和

[root@wing ~]# cat abc.txt
1 2 3 4 5 
[root@wing ~]# awk '{for(i=1;i<=NF;i++){sum+=i}print sum}' abc.txt 
15

磁盘和存储

swap

Swap 空间的作用可简单描述为:当系统的物理内存不够用的时候,就需要将物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap空间中,等到那些程序要运行时,再从Swap中恢复保存的数据到内存中。这样,系统总是在物理内存不够时,才进行Swap交换。  

虚拟内存

是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存,而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换

使用parted命令将4T硬盘分区,然后制作成LVM,硬盘并挂载到/data目录,请写出操作步骤?(系统:Centos7)

df和du的区别

#df 查看是文件系统的空间使用,包括元数据和数据,删除文件后,如果此文件正在使用,不会立即释放空间
#du 查看是文件数据空间使用,不包括元数据,删除文件后空间立即释放

查看一下那几个文件的占用磁盘空间大,需要做一个使用空间大小的排序?

[root@RS ~]# du -a  | sort -n -r

说说Raid0,1,5,6,10的区别

什么时候df >du,什么时候df < du

#df >du:空分区
#df <du:目录内挂载有其它分区时的情况

当删除文件但不释放空间时,有什么不同?

#du查看文件空间释放,df不释放;因为df包含的元数据不会立刻释放.

网络部分

ip段报文长度

因为IP数据报报文总长度字段为16位,因此数据报的最大长度为2^16-1=65535字节。

这个和IP数据报的格式有关,IP数据报中有一个16位的字段表示IP数据报的长度,这个16位是二进制表示的,每一位中可以为0或者1,那最大可表示的数据报的长度就是16个1,也就是1111 1111 1111 1111表示IP数据报的长度,这16位二进制数转换成十进制就是65535。

IP数据报的构成:

1、固定部分

版本占4位、首部长度占4位、区分服务占8位、总长度、标识(identification)占16位、标志(flag)占3位、片偏移占13位、生存时间占8位、协议占8位、首部检验和占16位、源地址占32位和目的地址占32位。

2、可变部分

可变部分

IP首部的可变部分就是一个可选字段。选项字段用来支持排错、测量以及安全等措施,内容很丰富。此字段的长度可变,从1个字节到40个字节不等,取决于所选择的项目。某些选项项目只需要1个字节,它只包括1个字节的选项代码。

vlan和vxlan区别

vxlan和vlan主要区别在于:1、传统的VLAN技术因为最多只能支持4096个VLAN,已经不能满足云提供商的严格要求,但是VXLAN技术可以通过将第2层扩展到第3层网络来构建大型多租户数据中心而备受青睐,这种技术可以有效克服VLAN带来的扩展局限性。2、VLAN是虚拟局域网,是由802.1Q标准所定义。VXLAN是虚拟扩展局域网,是由IETF定义的NVO3标准技术之一。
相比VLAN技术,VXLAN技术具有以下的优势:
1、24位长度的VNI字段值可以支持更多数量的虚拟网络,解决了VLAN数目上限为4094的局限性的问题。
2、VXLAN技术通过隧道技术在物理的三层网络中虚拟二层网络,处于VXLAN网络的终端无法察觉到VXLAN的通信过程,这样也就使得逻辑网络拓扑和物理网络拓扑实现了一定程度的解耦,网络拓扑的配置对于物理设备的配置的依赖程度有所降低,配置更灵活更方便。
3、VLAN技术仅仅解决了二层网络广播域分割的问题,而VXLAN技术还具有多租户支持的特性,通过VXLAN分割,各个租户可以独立组网、通信,地址分配方面和多个租户之间地址冲突的问题也得到了解决。

判断网线是否断了

[root@RS ~]# ethtool eth0 
Settings for eth0:
	Supported ports: [  ]
	Supported link modes:   Not reported
	Supported pause frame use: No
	Supports auto-negotiation: No
	Supported FEC modes: Not reported
	Advertised link modes:  Not reported
	Advertised pause frame use: No
	Advertised auto-negotiation: No
	Advertised FEC modes: Not reported
	Speed: Unknown!
	Duplex: Unknown! (255)
	Auto-negotiation: off
	Port: Other
	PHYAD: 0
	Transceiver: internal
	Link detected: yes
[root@wing ~]# mii-tool eth0
eth0: negotiated 1000baseT-FD flow-control, link ok

三次握手是什么,为什么是三次握手

A为客户机     B为服务机
   A    --------->  B
   A    <---------  B
   A    --------->  B
   三次握手是确保A和B两者间网络连接正常
   前两次要保证A的数据有去有回但只有两次无法保证B的数据是否能回来,所以需要第三次B传给A

怎么探测网络冲突

#arping 地址 查看是否有不同的mac地址

Linux启动和内核管理

启动流程

CentOS 6启动流程
POST
boot loader
vmlinux(initramfs.img)
roofs
/sbin/init
/etc/inittab 设置默认运行级别
/etc/rc.d/rc.sysinit 运行系统初始脚本完成系统初始化
/etc/rc#.d/Sxxxx 启动需要启动服务关闭对应下需要关闭的服务
/etc/rc.d/rc.local
设置登录终

centos7之后版本引导顺序
1. UEFi或BIOS初始化,运行POST开机自检
2. 选择启动设备
3. 引导装载程序, centos7是grub2,加载装载程序的配置文件:
/etc/grub.d/
/etc/default/grub
/boot/grub2/grub.cfg
4. 加载initramfs驱动模块
5. 加载内核选项
6. 内核初始化,centos7使用systemd代替init
7. 执行initrd.target所有单元,包括挂载/etc/fstab
8. 从initramfs根文件系统切换到磁盘根目录
9. systemd执行默认target配置,配置文件/etc/systemd/system/default.target
10. systemd执行sysinit.target初始化系统及basic.target准备操作系统
11. systemd启动multi-user.target下的本机与服务器服务
12. systemd执行multi-user.target下的/etc/rc.d/rc.local
13. Systemd执行multi-user.target下的getty.target及登录服务
14. systemd执行graphical需要的服务

启动等级

0:关机
1:单用户模式(root自动登录), single, 维护模式
2:多用户模式,启动网络功能,但不会启动NFS;维护模式
3:多用户模式,正常模式;文本界面
4:预留级别;可同3级别
5:多用户模式,正常模式;图形界面
6:重启

0 ==> runlevel0.target, poweroff.target
1 ==> runlevel1.target, rescue.target
2 ==> runlevel2.target, multi-user.target
3 ==> runlevel3.target, multi-user.target
4 ==> runlevel4.target, multi-user.target
5 ==> runlevel5.target, graphical.target
6 ==> runlevel6.target, reboot.target

DNS

我的网站域名需要更改,如何使其更快的生效?

[root@wing ~]# rndc reload

更改TTL值为多少比较合适呢?是如何生效的?

DNS 记录的典型 TTL 时间是多少?
TTL 时间始终以秒表示;例如,300 秒等于 5 分钟的生命。以下 TTL 时间将为您粗略估计 DNS 配置中通常设置的内容:
300 秒 = 5 分钟 = “非常短” - 在此时间范围内的网站使用低 TTL 焦点进行快速更改,但仍可以利用某种程度的缓存来帮助减少资源消耗。
3600 秒 = 1 小时 = “短” - 在此时间范围内的网站使用低 TTL 焦点进行快速更改,但仍可以利用某种程度的缓存来帮助减少资源消耗。
86400 秒 = 24 小时 = “长” ——相反的情况适用于使用 24 小时 TTL 的网站,因为焦点更多地转向每日缓存利用率。
604800 秒 = 7 天 = “非常长” - 每周 TTL 不常见,但可用于包含不经常更改的已发布或信誉良好信息的网站(例如图书馆资源、参考网站等)

DNS工作原理

第一步:客户机提出域名解析请求,并将该请求发送给本地的域名服务器。
第二步:当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器就直接把查询的结果返回。
第三步:如果本地的缓存中没有该纪录,则本地域名服务器就直接把请求发给根域名服务器,然后根域名服务器再返回给本地域名服务器一个所查询域(根的子域) 的主域名服务器的地址。
第四步:本地服务器再向上一步返回的域名服务器发送请求,然后接受请求的服务器查询自己的缓存,如果没有该纪录,则返回相关的下级的域名服务器的地址。
第五步:重复第四步,直到找到正确的纪录。
第六步:本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时还将结果返回给客户机。

递归和迭代查询的区别

递归查询:递归查询是一种DNS 服务器的查询模式,在该模式下DNS 服务器接收到客户机请求,必须使用一个准确的查询结果回复客户机。如果DNS 服务器本地没有存储查询DNS 信息,那么该服务器会询问其他服务器,并将返回的查询结果提交给客户机。

迭代查询:DNS 服务器另外一种查询方式为迭代查询,DNS 服务器会向客户机提供其他能够解析查询请求的DNS 服务器地址,当客户机发送查询请求时,DNS 服务器并不直接回复查询结果,而是告诉客户机另一台DNS 服务器地址,客户机再向这台DNS 服务器提交请求,依次循环直到返回查询的结果.

DNS 什么时候使用端口号 53/tcp 和 53/udp

当DNS进行区域传输的时候使用TCP/53的端口,其他时候使用UDP/53端口
区域传输:例如DNS主从服务器传送区域数据就使用TCP/53

CDN工作原理

CDN的全称是Content Delivery Network,即内容分发网络;
CDN的基本原理是在用户访问相对集中的地区和网络设置一些缓存服务器。
当用户访问网站时,利用全局的负载均衡技术将用户的访问指向距离最近的缓存服务器,由缓存服务器代替源站响应用户的访问请求。
这样一方面减轻了源站服务器的工作压力,另一方面使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。

上家公司域名解析是怎么解析的,哪个平台解析的


进程和计划任务面试题目

列出监测各类性能的工具

CPU:
mpstat
top
htop
iostat

内存:
free
top
htop
pmap 52346
vmstat

磁盘IO:
iotop

网络:
iftop
nload
nethogs
iptraf-ng

进程:
pstree
ps
pstate
pgrep
pidof
lsof

负载情况:
uptime

系统资源统计:
dstat

综合监控:
glances

找到未知进程的执行程序文件路径

[root@centos8 ~]#ls -l /proc/1272/exe
lrwxrwxrwx 1 root root 0 Jan 4 15:47 /proc/1272/exe -> /usr/bin/bash

11月每天的6-12点之间每隔2小时执行/app/bin/test.sh

#在6,8,10,12点整共4次分别执行test.sh
[root@centos8 ~]#crontab -l
0 6-12/2 * 11 * /app/bin/test.sh
#以下配置只会在5,7,9,11点整执行
0 5-12/2 * 11 * /app/bin/test.sh

解释 top 命令的内容

top - 20:53:39 up 3 days, 23:49,  1 user,  load average: 0.09, 0.03, 0.01    
Tasks: 138 total,   2 running, 136 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.3 sy,  0.0 ni, 99.0 id,  0.0 wa,  0.3 hi,  0.0 si,  0.0 st
MiB Mem :   1969.0 total,    194.3 free,    878.6 used,    896.1 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.    877.8 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                  
    793 redis     20   0  261488   7196   3176 S   0.7   0.4   5:02.02 redis-server                                                             
   1016 root      10 -10  258848  47832  16768 S   0.7   2.4  39:25.88 AliYunDun                                                                
      1 root      20   0  112716  12120   9068 S   0.0   0.6   0:06.29 systemd                                                                  
      2 root      20   0       0      0      0 S   0.0   0.0   0:00.02 kthreadd                                                                 
      3 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp                                                                   
      4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_par_gp                                                               
      6 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/0:0H-events_highpri                                              
      8 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 mm_percpu_wq                                                             
      9 root      20   0       0      0      0 S   0.0   0.0   0:00.00 rcu_tasks_rude_                                                          
     10 root      20   0       0      0      0 S   0.0   0.0   0:00.00 rcu_tasks_trace                                                          
     11 root      20   0       0      0      0 S   0.0   0.0   0:01.27 ksoftirqd/0                                                              
     12 root      20   0       0      0      0 R   0.0   0.0   0:12.69 rcu_sched                                                                
     13 root      rt   0       0      0      0 S   0.0   0.0   0:00.03 migration/0                                                              
     14 root      20   0       0      0      0 S   0.0   0.0   0:00.00 cpuhp/0                                                                  
     16 root      20   0       0      0      0 S   0.0   0.0   0:00.00 kdevtmpfs                                                                
     17 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 netns                                                                    
     18 root      20   0       0      0      0 S   0.0   0.0   0:00.00 kauditd                                                                  
     19 root      20   0       0      0      0 S   0.0   0.0   0:00.06 khungtaskd                                                               
     20 root      20   0       0      0      0 S   0.0   0.0   0:00.00 oom_reaper                                                               
     21 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 writeback                                                                
     22 root      20   0       0      0      0 S   0.0   0.0   0:02.56 kcompactd0                                                               
     23 root      25   5       0      0      0 S   0.0   0.0   0:00.00 ksmd                                                                     
     24 root      39  19       0      0      0 S   0.0   0.0   0:01.60 khugepaged                                                               
     25 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 memcg_wmark                                                              
     39 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 cryptd                                                                   
     74 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kintegrityd     

如何查看一个进程的是否是多线程

#使用命令ps aux 其中STAT一列中带有l的就是有多线程的进程
[root@RS ~]# ps aux
mysql       2062  0.0  4.9 391420 99060 ?        Sl   Aug11   1:43 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --
....

#使用pstree,带有下面相同括号的就表示为线程,上一级不带括号的为进程,由此可看出同一进程下是否有多线程
[root@RS ~]# pstree
systemd─┬─AliSecGuard───6*[{AliSecGuard}]
....

#查看文件信息,Threads一行
[root@RS ~]# cat /proc/2062/status 
Threads:	30

如何查到使用指定文件的进程

[root@RS ~]# lsof /etc/hosts
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
tail    48844 root    3r   REG  253,1      258 655624 /etc/hosts

如何实现秒级的计划任务

运用sleep和for循环实现

说明cron计划任务的格式

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
分时日月周

如何查看服务名为“mysqld”的进程信息

[root@RS ~]# ps aux |grep mysql
[root@RS ~]# pgrep mysql -a

查看CPU占用前十的进程

[root@RS ~]# ps aux  k -%cpu|head
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root        1016  0.6  2.3 258848 46832 ?        S<sl Aug11  34:56 /usr/local/aegis/aegis_client/aegis_11_33/AliYunDun
root           1  0.0  0.5 104340 11908 ?        Ss   Aug11   0:05 /usr/lib/systemd/systemd --switched-root --system --deserialize 17
root           2  0.0  0.0      0     0 ?        S    Aug11   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   Aug11   0:00 [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   Aug11   0:00 [rcu_par_gp]
root           6  0.0  0.0      0     0 ?        I<   Aug11   0:00 [kworker/0:0H-events_highpri]
root           8  0.0  0.0      0     0 ?        I<   Aug11   0:00 [mm_percpu_wq]
root           9  0.0  0.0      0     0 ?        S    Aug11   0:00 [rcu_tasks_rude_]
root          10  0.0  0.0      0     0 ?        S    Aug11   0:00 [rcu_tasks_trace]

如何寻找进程

ps aux|grep
pgrep -t pts/1 -a
pidof ping 

uptime应用

[root@RS ~]# uptime
 10:18:04 up 3 days, 13:13,  1 user,  load average: 0.00, 0.00, 0.00
#load average负载值:1,5,15分钟的均值取下面两个状态
#R状态
#D状态
#(不要超过5,或者CPU数的三倍)

mpstats描述里面的信息


[root@RS ~]# mpstat 1 3
Linux 5.10.84-10.4.al8.x86_64 (RS) 	08/15/2022 	_x86_64_	(1 CPU)

10:31:47 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
10:31:48 AM  all    0.00    0.00    0.99    0.99    0.99    0.00    0.00    0.00    0.00   97.03
10:31:49 AM  all    1.01    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   98.99
10:31:50 AM  all    0.00    0.00    1.00    0.00    1.00    0.00    0.00    0.00    0.00   98.00
Average:     all    0.33    0.00    0.67    0.33    0.67    0.00    0.00    0.00    0.00   98.00

缓冲和缓存的区别

[root@RS ~]# free -h
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       857Mi       105Mi        43Mi       1.0Gi       906Mi
Swap:            0B          0B          0B
#buffer 缓冲  write 缓冲   减少IO
#cache  缓存  read  缓存   减少IO

iotop查看每个进程IO读写的情况

Total DISK READ :	0.00 B/s | Total DISK WRITE :       0.00 B/s
Actual DISK READ:	0.00 B/s | Actual DISK WRITE:       0.00 B/s
    TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                                         
      1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % systemd --switched-root --system --deserialize 17
      2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
  ....

iftop查看网络带宽使用情况

[root@RS ~]# iftop -n

nload查看网络实时吞吐量

lsof用法

#查看端口占用
lsof -i :22

#查看文件占用
[root@RS ~]# lsof /etc/hosts
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
tail    48844 root    3r   REG  253,1      258 655624 /etc/hosts

#查看命令占用
[root@RS ~]# lsof -c tail
COMMAND   PID USER   FD      TYPE DEVICE  SIZE/OFF    NODE NAME
tail    48844 root  cwd       DIR  253,1      4096  917505 /root
tail    48844 root  rtd       DIR  253,1      4096       2 /
tail    48844 root  txt       REG  253,1     79920 1184600 /usr/bin/tail
tail    48844 root  mem       REG  253,1 223542144 1182564 /usr/lib/locale/locale-archive
tail    48844 root  mem       REG  253,1   3225984 1182071 /usr/lib64/libc-2.32.so
tail    48844 root  mem       REG  253,1    264400 1182554 /usr/lib64/ld-2.32.so
tail    48844 root    0u      CHR  136,1       0t0       4 /dev/pts/1
tail    48844 root    1u      CHR  136,1       0t0       4 /dev/pts/1
tail    48844 root    2u      CHR  136,1       0t0       4 /dev/pts/1
tail    48844 root    3r      REG  253,1       258  655624 /etc/hosts
tail    48844 root    4r  a_inode   0,13         0   10526 inotify

#根据进程号查占用
[root@RS ~]# lsof -p pidof tail
COMMAND   PID USER   FD      TYPE DEVICE  SIZE/OFF    NODE NAME
tail    48844 root  cwd       DIR  253,1      4096  917505 /root
tail    48844 root  rtd       DIR  253,1      4096       2 /
tail    48844 root  txt       REG  253,1     79920 1184600 /usr/bin/tail
tail    48844 root  mem       REG  253,1 223542144 1182564 /usr/lib/locale/locale-archive
tail    48844 root  mem       REG  253,1   3225984 1182071 /usr/lib64/libc-2.32.so
tail    48844 root  mem       REG  253,1    264400 1182554 /usr/lib64/ld-2.32.so
tail    48844 root    0u      CHR  136,1       0t0       4 /dev/pts/1
tail    48844 root    1u      CHR  136,1       0t0       4 /dev/pts/1
tail    48844 root    2u      CHR  136,1       0t0       4 /dev/pts/1
tail    48844 root    3r      REG  253,1       258  655624 /etc/hosts
tail    48844 root    4r  a_inode   0,13         0   10526 inotify

杀死进程的方式

pkill 
kill
killall

11月每天的6点到12点之间每隔2小时执行/app/bin/test.sh

* 6-12/2 * 11 * /app/bin/test.sh

防火墙

链接数过大使日志撑满,导致无法访问,如何解决

#连接跟踪,需要加载模块: modprobe nf_conntrack_ipv4
#当服务器连接多于最大连接数时dmesg 可以观察到 :kernel: ip_conntrack: table full, dropping packet错误,并且导致建立TCP连接很慢。
#各种状态的超时后,链接会从表中删除
[root@Net1 sbin]#echo 1 > /proc/sys/net/netfilter/nf_conntrack_max
[root@Net1 sbin]#cat /var/log/syslog
Aug 18 10:17:53 Net1 kernel: [51552.588096] nf_conntrack: nf_conntrack: table full, dropping packet

#连接过多的解决方法两个:
#(1) 加大nf_conntrack_max 值
[root@Net1 sbin]#vi /etc/sysctl.conf
net.nf_conntrack_max = 393216
net.netfilter.nf_conntrack_max = 393216
[root@Net1 sbin]#sysctl -p
net.nf_conntrack_max = 393216
net.netfilter.nf_conntrack_max = 393216

#(2) 降低 nf_conntrack timeout时间
[root@Net1 sbin]#vi /etc/sysctl.conf
net.netfilter.nf_conntrack_tcp_timeout_established = 300
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
[root@Net1 sbin]#sysctl -p
net.netfilter.nf_conntrack_tcp_timeout_established = 300
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120

MYSQL

VARCHAR(50) 能存放几个 UTF8 编码的汉字?

放的汉字个数与版本相关。
mysql 4.0以下版本,varchar(50) 指的是 50 字节,如果存放 UTF8 格式编码的汉字时(每个汉字3字
节),只能存放16 个。
mysql 5.0以上版本,varchar(50) 指的是 50 字符,无论存放的是数字、字母还是 UTF8 编码的汉字,
都可以存放 50 个。

MSQL操作语句

DDL语句:
create 
show
alter
drop

DML语句:
inster
update
delete

DQl语句:
select
left join 
right join
inner jion
union
cross

#DCL
grant

MYSQL数据引擎的区别

InnodbMyIsam
支持事务不支持事务
支持外键不支持外键
默认是锁表,索引时是锁行锁表
innodb索引基于b+树,叶子节点是存放数据的MyIsam索引基于b+树,叶子节点是存放指针的
聚簇索引,必须要有主键,一定会基于主键查询非聚簇索引,索引和数据是分离的,索引里保存的是数据地址的指针,主键索引和辅助索引是分开的
不存储表的行数存储表的行数
读写阻塞与事务隔离级别相关读写相互阻塞,写入不能读,读时不能写
从MySQL5.5后支持全文索引只缓存索引
读取数据较快,占用资源较少
支持MVCC高并发不支持MVCC(多版本并发控制机制)高并发
崩溃恢复性更好崩溃恢复性较差
从MySQL5.5.5开始为默认的数据库引擎MySQL5.5.5 前默认的数据库引擎
Innodb 存储引擎适用场景MyISAM 存储引擎适用场景
生产环境只读(或者写较少)
需要用到事务和外键的情况表较小(可以接受长时间进行修复操作)
Innodb 引擎文件MyISAM 引擎文件
数据文件:ibdata1, ibdata2,存放在datadir定义的目录下bl_name.frm 表格式定义
表格式定义:tb_name.frmtbl_name.MYD 数据文件
数据文件(存储数据和索引):tb_name.ibdtbl_name.MYI 索引文件

InnoDB中一颗的B+树可以存放多少行数据?

假设定义一颗B+树高度为2,即一个根节点和若干叶子节点。那么这棵B+树的存放总行记录数=根节点指针数*
单个叶子记录的行数。这里先计算叶子节点,B+树中的单个叶子节点的大小为16K,假设每一条目为1K,那么
记录数即为16(16k/1K=16),然后计算非叶子节点能够存放多少个指针,假设主键ID为bigint类型,那么长
度为8字节,而指针大小在InnoDB中是设置为6个字节,这样加起来一共是14个字节。那么通过页大小/(主键
ID大小+指针大小),即16384/14=1170个指针,所以一颗高度为2的B+树能存放16*1170=18720条这样的
记录。根据这个原理就可以算出一颗高度为3的B+树可以存放16*1170*1170=21902400条记录。所以在
InnoDB中B+树高度一般为2-3层,它就能满足千万级的数据存储

事务特性

A:atomicity 原子性;整个事务中的所有操作要么全部成功执行,要么全部失败后回滚
C:consistency一致性;数据库总是从一个一致性状态转换为另一个一致性状态,类似于能量守恒定律(N50周启皓语录)
I:Isolation隔离性;一个事务所做出的操作在提交之前,是不能为其它事务所见;隔离有多种隔离级别,实现并发
D:durability持久性;一旦事务提交,其所做的修改会永久保存于数据库中

事务的隔离级别

READ UNCOMMITTED;读未提交
READ COMMITTED;读提交
REPEATABLE READ;可重复读
SERIALIZABLE;序列化
隔离级别脏读不可重复读幻读加读锁
读未提交可以出现可以出现可以出现
读提交不允许出现可以出现可以出现
可重复读不允许出现不允许出现可以出现
序列化不允许出现不允许出现不允许出现

MYSQL日志

#事务日志调优,变量2,的安全性和性能最优.先存入系统内核的缓存空间,再统一存入磁盘
mysql> set global innodb_flush_log_at_trx_commit=2;
Query OK, 0 rows affected (0.00 sec)

mysql> select  @@innodb_flush_log_at_trx_commit;
+----------------------------------+
| @@innodb_flush_log_at_trx_commit |
+----------------------------------+
|                                2 |
+----------------------------------+
1 row in set (0.00 sec)

#错误日志
mysql> SHOW GLOBAL VARIABLES LIKE 'log_error' ;
+---------------+--------------------------+
| Variable_name | Value                    |
+---------------+--------------------------+
| log_error     | /var/log/mysql/error.log |
+---------------+--------------------------+
1 row in set (0.01 sec)

#mysql8.0
mysql> SHOW GLOBAL VARIABLES LIKE 'log_error_verbosity';
+---------------------+-------+
| Variable_name       | Value |
+---------------------+-------+
| log_error_verbosity | 2     |
+---------------------+-------+
1 row in set (0.00 sec)
#mariadb和mysql5.7以前
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'log_warnings';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_warnings  | 2     |
+---------------+-------+
1 row in set (0.001 sec)

#通用日志
mysql> select @@general_log;
+---------------+
| @@general_log |
+---------------+
|             1 |
+---------------+
1 row in set (0.00 sec)

mysql> SHOW GLOBAL VARIABLES LIKE 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output    | FILE  |
+---------------+-------+
1 row in set (0.00 sec)

mysql> select @@general_log_file;
+-------------------------------+
| @@general_log_file            |
+-------------------------------+
| /var/lib/mysql/Ubuntu2004.log |
+-------------------------------+
1 row in set (0.00 sec)

#慢查询日志
MariaDB [(none)]> select @@slow_query_log;
+------------------+
| @@slow_query_log |
+------------------+
|                1 |
+------------------+
1 row in set (0.000 sec)

MariaDB [(none)]> select @@long_query_time;
+-------------------+
| @@long_query_time |
+-------------------+
|          3.000000 |
+-------------------+
1 row in set (0.000 sec)

#二进制日志(备份)
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.01 sec)

MYSQL主从复制原理

条件
1.多实例
2.二进制日志开启
3.三个线程(dump,IO,SQL)

注意集群升级先升级从服务的版本,后升级主服务的版本;
监控主从状态:show slave status;

主从复制的延迟

升级到MySQL5.7以上版本(5.7之前的版本,没有开GTID之前,主库可以并发事务,但是dump传
输时是串行)利用GTID(MySQL5.6需要手动开启,MySQL5.7以上默认开启)支持并发传输binlog及并
行多个SQL线程
减少大事务,将大事务拆分成小事务
减少锁
sync_binlog=1 加快binlog更新时间,从而加快日志复制
需要额外的监控工具的辅助
多线程复制:对多个数据库复制
一从多主:Mariadb10 版后支持

主从复制数据不一致的原因,及解决方案

#原因
主库binlog格式为Statement,同步到从库执行后可能造成主从不一致。
主库执行更改前有执行set sql_log_bin=0,会使主库不记录binlog,从库也无法变更这部分数据。
从节点未设置只读,误操作写入数据
主库或从库意外宕机,宕机可能会造成binlog或者relaylog文件出现损坏,导致主从不一致
主从实例版本不一致,特别是高版本是主,低版本为从的情况下,主数据库上面支持的功能,从数据库上面可能不支持该功能
主从sql_mode 不一致
MySQL自身bug导致

#解决方案
将从库重新实现
将从库重新实现
手动重建不一致的表

#如何避免主从不一致
主库binlog采用ROW格式
主从实例数据库版本保持一致
主库做好账号权限把控,不可以执行set sql_log_bin=0
从库开启只读,不允许人为写入
定期进行主从一致性检验

mysql监控指标

1.系统mysql的进程数

ps -ef | grep "mysql" | grep -v "grep" | wc –l

2.Slave_running

mysql > show status like 'Slave_running';

如果系统有一个从复制服务器,这个值指明了从服务器的健康度

3.Threads_connected

mysql > show status like 'Threads_connected';

当前客户端已连接的数量。这个值会少于预设的值,但你也能监视到这个值较大,这可保证客户端是处在活跃状态。

4.Threads_running

mysql > show status like 'Threads_running';

如果数据库超负荷了,你将会得到一个正在(查询的语句持续)增长的数值。这个值也可以少于预先设定的值。这个值在很短的时间内超过限定值是没问题的。当Threads_running值超过预设值时并且该值在5秒内没有回落时, 要同时监视其他的一些值。

5.Aborted_clients

mysql > show status like 'Aborted_clients';

客户端被异常中断的数值,即连接到mysql服务器的客户端没有正常地断开或关闭。对于一些应用程序是没有影响的,但对于另一些应用程序可能你要跟踪该值,因为异常中断连接可能表明了一些应用程序有问题。

6.Questions

mysql> show status like 'Questions';

每秒钟获得的查询数量,也可以是全部查询的数量,根据你输入不同的命令会得到你想要的不同的值。

7.Handler_*

mysql> show status like 'Handler_%';

如果你想监视底层(low-level)数据库负载,这些值是值得去跟踪的。

如果Handler_read_rnd_next值相对于你认为是正常值相差悬殊,可能会告诉你需要优化或索引出问题了。Handler_rollback表明事务被回滚的查询数量。你可能想调查一下原因。

8.Opened_tables

mysql> show status like 'Opened_tables';

表缓存没有命中的数量。如果该值很大,你可能需要增加table_cache的数值。典型地,你可能想要这个值每秒打开的表数量少于1或2。

9.Select_full_join

mysql> show status like 'Select_full_join';

没有主键(key)联合(Join)的执行。该值可能是零。这是捕获开发错误的好方法,因为一些这样的查询可能降低系统的性能。

10.Select_scan

mysql> show status like 'Select_scan';

执行全表搜索查询的数量。在某些情况下是没问题的,但占总查询数量该比值应该是常量(即Select_scan/总查询数量商应该是常数)。如果你发现该值持续增长,说明需要优化,缺乏必要的索引或其他问题。

11.Slow_queries

mysql> show status like 'Slow_queries';

超过该值(--long-query-time)的查询数量,或没有使用索引查询数量。对于全部查询会有小的冲突。如果该值增长,表明系统有性能问题。

12.Threads_created

mysql> show status like 'Threads_created';

该值应该是低的。较高的值可能意味着你需要增加thread_cache的数值,或你遇到了持续增加的连接,表明了潜在的问题。

13.客户端连接进程数

shell> mysqladmin processlist

mysql> show processlist;

你可以通过使用其他的统计信息得到已连接线程数量和正在运行线程的数量,检查正在运行的查询花了多长时间是一个好主意。如果有一些长时间的查询,管理员可以被通知。你可能也想了解多少个查询是在"Locked"的状态—---该值作为正在运行的查询不被计算在内而是作为非活跃的。一个用户正在等待一个数据库响应。

14.innodb状态

mysql> show innodb status;

该语句产生很多信息,从中你可以得到你感兴趣的。首先你要检查的就是“从最近的XX秒计算出来的每秒的平均负载”。

(1)Pending normal aio reads: 该值是innodb io请求查询的大小(size)。如果该值大到超过了10—20,你可能有一些瓶颈。

(2)reads/s, avg bytes/read, writes/s, fsyncs/s:这些值是io统计。对于reads/writes大值意味着io子系统正在被装载。适当的值取决于你系统的配置。

(3)Buffer pool hit rate:这个命中率非常依赖于你的应用程序。当你觉得有问题时请检查你的命中率

(4)inserts/s, updates/s, deletes/s, reads/s:有一些Innodb的底层操作。你可以用这些值检查你的负载情况查看是否是期待的数值范围。

15.主机性能状态

shell> uptime

16.CPU使用率

shell> top

shell> vmstat

17.磁盘IO

shell> vmstat

shell> iostat

18.swap进出量(内存)

shell> free

19.MySQL错误日志

在服务器正常完成初始化后,什么都不会写到错误日志中,因此任何在该日志中的信息都要引起管理员的注意。
20.InnoDB表空间信息

InnoDB仅有的危险情况就是表空间填满----日志不会填满。检查的最好方式就是:show table status;你可以用任何InnoDB表来监视InnoDB表的剩余空间。

21.QPS每秒Query量

QPS = Questions(or Queries) / seconds

mysql > show /* global */ status like 'Question';

22.TPS(每秒事务量)

TPS = (Com_commit + Com_rollback) / seconds

mysql > show status like 'Com_commit';

mysql > show status like 'Com_rollback';

23.key Buffer 命中率

key_buffer_read_hits = (1-key_reads / key_read_requests) * 100%

key_buffer_write_hits = (1-key_writes / key_write_requests) * 100%

mysql> show status like 'Key%';

24.InnoDB Buffer命中率

Innodb_buffer_read_hits = (1 - innodb_buffer_pool_reads / innodb_buffer_pool_read_requests) * 100%

mysql> show status like 'innodb_buffer_pool_read%';

25.Query Cache命中率

Query_cache_hits = (Qcahce_hits / (Qcache_hits + Qcache_inserts )) * 100%;

mysql> show status like 'Qcache%';

26.Table Cache状态量

mysql> show status like 'open%';

27.Thread Cache 命中率

Thread_cache_hits = (1 - Threads_created / connections ) * 100%

mysql> show status like 'Thread%';

mysql> show status like 'Connections';

28.锁定状态

mysql> show status like '%lock%';

29.复制延时量

mysql > show slave status

30.Tmp Table状况(临时表状况)

mysql > show status like 'Create_tmp%';

31.Binlog Cache使用状况

mysql > show status like 'Binlog_cache%';

32.Innodb_log_waits量

mysql > show status like 'innodb_log_waits';

日志管理

last的用法

#显示系统关机项和运行级别更改
last -x, --system
#显示登陆失败的记录
[root@localhost ~]#lastb

日志管理工具 journalctl

#查看所有日志(默认情况下 ,只保存本次启动的日志)
journalctl
#查看内核日志(不显示应用日志)
journalctl -k
#查看系统本次启动的日志
journalctl -b
journalctl -b -0
#查看上一次启动的日志(需更改设置)
journalctl -b -1
#查看指定时间的日志
journalctl --since="2017-10-30 18:10:30"
journalctl --since "20 min ago"
journalctl --since yesterday
journalctl --since "2017-01-10" --until "2017-01-11 03:00"
journalctl --since 09:00 --until "1 hour ago"
#显示尾部的最新10行日志
journalctl -n
#显示尾部指定行数的日志
journalctl -n 20
#实时滚动显示最新日志
journalctl -f
#查看指定服务的日志
journalctl /usr/lib/systemd/systemd
#查看指定进程的日志
journalctl _PID=1
#查看某个路径的脚本的日志
journalctl /usr/bin/bash
#查看指定用户的日志
journalctl _UID=33 --since today
#查看某个 Unit 的日志
journalctl -u nginx.service
journalctl -u nginx.service --since today
#实时滚动显示某个 Unit 的最新日志
journalctl -u nginx.service -f
#合并显示多个 Unit 的日志
journalctl -u nginx.service -u php-fpm.service --since today
#查看指定优先级(及其以上级别)的日志,共有8级
0: emerg
1: alert
2: crit
3: err
4: warning
5: notice
6: info
7: debug
journalctl -p err -b
#日志默认分页输出,--no-pager 改为正常的标准输出
journalctl --no-pager
#日志管理journalctl
#以 JSON 格式(单行)输出
journalctl -b -u nginx.service -o json
#以 JSON 格式(多行)输出,可读性更好
journalctl -b -u nginx.service -o json-pretty
#显示日志占据的硬盘空间
journalctl --disk-usage
#指定日志文件占据的最大空间
journalctl --vacuum-size=1G
#指定日志文件保存多久
journalctl --vacuum-time=1years

查看硬件使用信息

/var/log/dmesg:CentOS7 之前版本系统引导过程中的日志信息,文本格式,开机后的硬件变化将不再记录,也可以通过专用命令dmesg查看,可持续记录硬件变化的情况

lvs面试题

负载均衡的会话保持

LVS四层模型和十种算法

四种模式:
LVS-NAT
类似于DNAT工作原理,本质是多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和
可以实现端口转发

LVS-DR(默认)
工作在数据链路层,不支持端口映射
应用服务器vip和rip要用不同的网卡,vip网卡需要关闭广播相应的内核参数(vip一般配置域回环网卡lo)
lvs服务器和应用服务器不能跨网段,中间不能加路由器

LVS-TUNNEL
解决了lvs-dr不能跨网段的问题
依旧不支持端口映射
必须支持隧道功能
使用特殊网卡tun

LVS-FULLNAT
SNAT和DNAT的结合,目标地址和源地址都做转换
相对NAT模式,可以更好的实现LVS-RealServer间跨VLAN通讯

调度算法: (目前有始终调度算法,常用的有十种)
静态调度算法:
RR:轮询调度,roundrobin
WRR:权重调度,Weighted RR
SH:用源IP通过hash运算绑定session,Source Hashing
DH:用目标IP做hash调度,Destination Hashing

动态调度算法:
LC:least connections 适用于长连接应用,Overhead=activeconns*256+inactiveconn
WLC:(默认)Weighted LC,默认调度方法,较常用,Overhead=(activeconns*256+inactiveconns)/weight
SED:Shortest Expection Delay,初始连接高权重优先,只检查活动连接,而不考虑非活动连接,Overhead=(activeconns+1)*256/weight
NQ:Never Queue,第一轮均匀分配,后续SED
LBLC:Locality-Based LC,动态的DH算法,使用场景:根据负载状态实现正向代理,实现WebCache等
LBLCR:LBLC with Replication,带复制功能的LBLC,解决LBLC负载不均衡问题,从负载重的复制到负载轻的RS,,3实现Web Cache等

Linux 集群有哪些分类

高可用性集群(High Availability Cluster)HA
负载均衡集群(Load Balance Cluster)LB
高性能集群(High Performance Computing Cluster)HPC

正向代理和反向代理区别

1、正向代理其实是客户端的代理,帮助客户端访问其无法访问的服务器资源。反向代理则是服务器的代理,帮助服务器做负载均衡,安全防护等。
2、正向代理一般是客户端架设的,比如在自己的机器上安装一个代理软件。而反向代理一般是服务器架设的,比如在自己的机器集群中部署一个反向代理服务器。
3、正向代理中,服务器不知道真正的客户端到底是谁,以为访问自己的就是真实的客户端。而在反向代理中,客户端不知道真正的服务器是谁,以为自己访问的就是真实的服务器。
4、正向代理和反向代理的作用和目的不同。正向代理主要是用来解决访问限制问题。而反向代理则是提供负载均衡、安全防护等作用。二者均能提高访问速度。

四层代理和七层代现的区别

七层:会将请求报文拆开至应用层,分析用户请求的资源,然后haproxy会代替用户请求后端服务器的资源;后端服务器把资源返还给haproxy,haproxy会对资源再次进行封装,然后返还给客户端;七层代理是由haproxy进行处理的,并且需要建立两次TCP连接,一次是客户端,一次是后端的服务器。
四层:会把请求报文拆开至传输层,根据请求的服务器的IP加端口号进行转发;四层代理是由后端服务器进行处理,包括报文的封装都是后端服务器进行封装;四层代理相当于是一个路由器。

LVS的工作模式有哪些,有什么特点

LVS根据请求报文的目标IP和目标协议及端口将其调度转发至某RS,根据调度算法来挑选RS。LVS是内核级功能,工作在INPUT链的位置,将发往INPUT的流量进行“处理”
LVS只支持四层代理

LVS和nginx,haproxy的区别

LVS: 是基于四层的转发
HAproxy: 是基于四层和七层的转发,是专业的代理服务器
Nginx: 是WEB服务器,缓存服务器,又是反向代理服务器,可以做七层的转发

区别: LVS由于是基于四层的转发所以只能做端口的转发而基于URL的、基于目录的这种转发LVS就做不了

HAproxy和Nginx由于可以做七层的转发,所以URL和目录的转发都可以做
在很大并发量的时候我们就要选择LVS,像中小型公司的话并发量没那么大
选择HAproxy或者Nginx足已,由于HAproxy由是专业的代理服务器
配置简单,所以中小型企业推荐使用HAproxy

nginx服务

浏览器访问网站的过程

1.用户从电脑发起访问请求
2.电脑去DNS查询本机hosts文件,寻找域名解析,如果没有就去DNS缓存服务器寻找,在没有就去递归查询或者迭代查询,获得目标域名的ip地址
3.向目标ip发送访问请求,进行三次握手(SYN,ACK,SEQ)
4.服务器处理请求,服务器对请求报文进行解析,并获取请求的资源及请求方法等相关信息,根据方法,资源,首部和可选的主体部分对请求进行处理
5.构建相应报文
6.返回响应报文,浏览器读取文件进行渲染构建网页,进行四次挥手

http1.0和http1.1和http2.0的区别

http/1.0http/1.1http2.0
1996年1997年2015年
每个TCP连接只能发送一个请求持久连接,TCP连接默认不关闭,可以被多个请求复用,但只能顺序处理,会出现堵塞的情况持久连接,TCP连接默认不关闭,可以被多个请求复用,不用按顺序执行
支持cache, MIME, method支持cache, MIME, method支持cache, MIME, method
GET,POST新增方法:PUT、PATCH、OPTIONS、DELETE包含前面所有的方法
头信息和数据体都是二进制,称为头信息帧和数据帧
引入头信息压缩机制(header compression)
HTTP/2 允许服务器未经请求,主动向客户端发送资源,即服务器推送(server push)

为什么nginx比apache的性能高

nginx可以使用epoll事件驱动,提高并发访问量
apache只能使用select时间驱动效率低

apahce工作模式

Apache prefork 模型
Apache worker 模型
Apache event 模型

Nginx健康性检查方式

Nginx健康性检查时懒惰的,访问后端时才查看后端的健康状态
haproxy 定时的健康检查,定时向后端发送请求
keepalive 定时的健康检查,定时向后端发送请求
MHA 定时的健康检查,定时向后端发送请求

nginx调度算法

默认轮询  
权重 whight=number
ip_hash 取ip前24为作为负载均衡的调度条件
least_conn 最少连接数算法,看后端连接数多少进行调度
hash $remote_addr  根据客户端地址调度,32位匹配 ;不推荐单独使用,需要配合一致性算法使用
hash KEY [consistent] 一致性的hash算法
hash $requset_uri 根据uri连接调度(应用层的算法调度)
hash cookei  根据cookie进行调度
hash KEY [consistent] 一致性的hash算法

响应码200,但是仍无法访问,原因是什么?

有可能是有,302或301跳转,并出现了跨域问题
return 指定返回200

说明各种响应码分类,499的原因,502和504的区别

1xx:100-101 信息提示
2xx:200-206 成功
3xx:300-307 重定向
4xx:400-415 错误类信息,客户端错误
5xx:500-505 错误类信息,服务器端错误

499:客户端主动断开连接。然而在实际业务开发中,当出现 HTTP 499 状态码时,大部分都是由于服务端请求时间过长,导致客户端等的“不耐烦”了,因此断开了连接。比如:慢SQL问题,499是客户端读超时关闭连接造成的,推荐从超时时间或者优化响应速度入手,web服务器发现客户端主动关闭连接后,记录到access日志中的。可能是客户端接收响应超时了,可以先在客户端统计下是不是这个原因,再调查为什么会导致超时
502:Bad Gateway,代理服务器从后端服务器收到了一条错误响应,如无法连接到网关;Bad Gateway,比如:后端服务端口没有打开,或后端服务不可用,iptable -j REJECT
504:Gateway Timeout,网关超时,或者后端服务器无回应报文,比如:服务端口虽然打开,但服务返回结果时间过长,iptable -j DROP

nginx 的功能

搭建web应用服务器
七层负载均衡
伪四层负载均衡
反向代理

常见的nginx 性能优化方法

一、性能优化考虑点

一、当前系统结构瓶颈

二、了解业务模式

三、系统与Nginx性能优化

1、文件句柄

(1)设置方式

(2)系统全局性修改和用户局部性修改

(3)进程局部性修改

2、cpu的亲和配置

 (1)具体设置

3、事件处理模型优化

4、设置work_connections连接数

5、keepalive timeout会话保持时间

6、GZIP压缩性能优化

7、连接超时时间

8、proxy超时设置

buffer工作原理

9、proxy_set_header

10、高效传输模式

11、fastcgi调优

12、expires缓存调优

13、访问限流 

四、内核参数优化
一、性能优化考虑点
        当我需要进行性能优化时,说明我们服务器无法满足日益增长的业务。性能优化是一个比较大的课题,需要从以下几个方面进行探讨。

        当前系统结构瓶颈

        了解业务模式

        性能和安全

一、当前系统结构瓶颈
        首先需要了解的是当前系统瓶颈,用的是什么,跑的什么业务。里面的服务是什么样子,每个服务最大支持多少并发。比如针对Nginx而言,我们处理静态资源最高的瓶颈是多大。

        可以通过查看当前cpu负荷,内存使用率,进程使用率来做简单判断。还可以通过操作系统的一些工具来判断当前系统性能瓶颈,如分析对应日志,查看请求数量。

        也可以通过nginx vts模块来查看对应的来凝结数,总握手次数,总请求数。以对上线进行压力测试,来了解当前的系统的性能,并发数,做好性能评估。

二、了解业务模式
        虽然我们是在做性能优化,但还是要熟悉业务,最终目的都是为了业务服务的。我们要了解每一个接口业务类型是什么样的业务,比如电子商务抢购模式,这种情况配是流量会很小,但是到了抢购时间,流量一下子就会猛涨。也要了解系统层级结构,每一层中间层做的是代理还是动静分离,还是后台进行直接服务。需要我们对业务接入层和系统层次要有一个梳理。

三、系统与Nginx性能优化
        大家对相关的系统瓶颈及现状有了一定的了解之后,就可以根据邮箱性能方面做一个全体的优化。

        网络(网络流量、是否有丢包、网络的稳定性都会邮箱用户请求)

        系统(系统负载、饱和、内存使用率、系统的稳定性、硬盘磁盘是否损坏)

        服务(连接优化、内核性能优化、http服务请求优化都可以在nginx中根据业务来进行设置)

        程序(接口性能、处理请求速度、每个程序的执行效率)

        数据库、底层服务

上面列举出来每一级都会有关联,也会影响整体性能,这里主要关注的是Nginx服务这一层。
1、文件句柄
        linux/unix,一切皆文件,每一次用户发起请求就会生成一个文件句柄,文件句柄可以理解为就是一个索引,所有文件句柄就会随着请求量的增多,而进程调用的频率增加,文件句柄的产生就会越多,系统对文件句柄默认的限制是1024个,对于nginx来说非常小了,需要改大一点

ulimit -n #可以查看系统设置的最大文件句柄
(1)设置方式
        系统全局性修改

        用户局部性修改

        进程局部性修改

(2)系统全局性修改和用户局部性修改
vim /etc/security/limits.conf
soft:软控制,到达设定值后,操作系统不会采取措施,只是发提醒
hard:硬控制,到达设定值后,操作系统会采取机制对当前进行进行限制,这个时候请求就会受到影响
root:这里代表root用户(系统全局性修改)
*:代表全局,即所有用户都受此限制(用户局部性修改)
尤其在企业新装的系统,这个地方应该根据实际情况进行设置,可以设置全局的,也可以设置用户级别的。
su  #刷新以下环境
ulimit -n   #再次查看系统最大文件句柄
这里就改为了,我们对root用户设置的最大文件句柄65535
(3)进程局部性修改
vim /usr/local/nginx/conf/nginx.conf
每个进程的最大文件打开数,所以最好与ulimit -n的值保持一致。
worker_rlimit_nofile 

2、cpu的亲和配置
cpu的亲和能偶使nginx对于不同的work工作进程绑定到不同的cpu上面去。就能够减少在work间不断切换cpu,把进程通常不会在处理器之间频繁迁移,进程迁移的频率小,来减少性能损耗。
(1)具体设置
Nginx允许工作进程个数一般设置CPU的核心或者核心数*2.如果不了解cpu核数,可以使用top后按1看出来,也可以查看/proc/cpuinfo文件

cat /proc/cpuinfo | grep ^processor | wc -l  #查看cpu核数
lscpu | grep "CPU(s)"  #另一种查看cpu核数的方式

vim /usr/local/nginx/conf/nginx.conf
user nginx;
worker_processes  4;
worker_cpu_affinity auto;
当然也可以改为 worker_cpu_affinity 0001 0010 0100 1000;
worker_rlimit_nofile 65535;

worker_rlimit_nofile更改worker进程的最大打开文件数限制。如果没设置的话,这个值为操作系统的限制。设置后你的操作系统和Nginx可以处理比“ulimit -a”更多的文件,使用把这个值设高,这样nginx就不会由 “too many open files”问题了。
重启一下nginx,查看一下nginx worker进程绑定对应的cpu
ps -eo pid,args,psr | grep -v grep | grep nginx
3、事件处理模型优化
nginx的连接处理机制在于不同的操作系统会采用不同的I/O模型,Linux下,nginx使用epoll的I/O多路复用模型,在freebsd(类unix操作系统)使用kqueue的I/O多路复用模型,在Solaris(unix系统的一个重要分支操作系统)使用/dev/pool方式的I/O多路复用模型,在windows使用的icop等等。要根据系统类型不同选择不同的事物处理模型,我们使用的是centos,因此讲nginx的事件处理模型调整为epoll。

进入配置文件再进行修改
events {
    worker_connections  10240;
    multi_accept on;  
    use epoll;
}

multi_accept 告诉nginx收到一个新连接通知后接受尽可能多的连接,默认是on,设置为on后,多个worker按串行 方式来处理连接,也就是一个连接只有一个worker被唤醒,其他的处于休眠状态,设置为off后,多个worker按并行 方式来处理连接,也就是一个连接会唤醒所有的worker,直到连接分配完毕,没有取得连接的继续休眠。当你的服 务器连接数不多时,开启这个参数会让负载有一定的降低,但是当服务器的吞吐量很大时,为了效率,可以关闭这个参数。
4、设置work_connections连接数
 work_connections表示每个worker(子进程)可以创建多少个连接,默认1024,最大是65535.

这里我自己改为10240(这个参数与服务器性能相关)

worker_connections  10240;
5、keepalive timeout会话保持时间
keepalive_timeout  65;
keepalive其他的一些配置
keepalive:像上游服务器的保留连接数
keepalive_disable:是指把某些浏览器禁用掉
keepalive_requests:这个表示当我们建立一个可复用长连接,在当前这一个连接里可以并发接收多少个请求,默认1000个
send_timeout:在向客户端发送数据时,建立好连接后,超过两次活动时间(服务器很长时间没有返回数据)那么就会将这个连接关掉
keepalive_time:一个tcp连接的总时长,超过这个时间要再请求连接一下
 
这里先解释一下什么是keepalive,keepalive就是建立一下长连接,这个timeout就是,当浏览器建立一个连接之后,这个连接最长能存在多少事件不给他关闭,这个65也不是说建立65s连接后就直接关闭,而是一个活跃事件,就是第一次请求和下一次请求都会刷新这个65s,再65s内没有再请求数据才会真的关闭这个连接,所以这个事件也不应该太长,60左右也差不多了。
6、GZIP压缩性能优化
gzip  on;   #表示开启压缩功能
gzip_min_length 1k;  #表示允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值为0,表示不管页面多大都进行压缩,设置建议设大于1k。如果小于1k可能会越压越大。
gzip_buffers 4 32k; #压缩缓存区大小
gzip_http_version 1.1; #压缩版本
gzip_comp_level 6; #压缩比率,一般选择4-6,为了性能gzip_typs text/css text/xml application/javascript; #指>定压缩的类型 gzip_vary on; #vary header支持;
gzip_types text/plain text/css text/javascript application/json application/javascript
gzip_vary on :varyheader支持,改选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过nginx压缩的数据。
 

1.gzip_min_length 1k :设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值是0,不管页面多大都进行压缩,建议设置成大于1K,如果小与1K可能会越压越大。

2.gzip_buffers 4 32k :压缩缓冲区大小,表示申请4个单位为32K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。

3.gzip_http_version 1.1 :压缩版本,用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可。

4.gzip_comp_level 6 :压缩比例,用来指定GZIP压缩比,1压缩比最小,处理速度最快,9压缩比最大,传输速度快,但是处理慢,也比较消耗CPU资源。

5.gzip_types text/css text/xml application/javascript :用来指定压缩的类型,‘text/html’类型总是会被压缩。默认值: gzip_types text/html (默认不对js/css文件进行压缩)

    压缩类型,匹配MIME型进行压缩;
7、连接超时时间
其目的是保护服务器资源,cpu,内存没控制连接数,因为建立连接也是需要消耗资源的。

keepalive_timeout 60;
tcp_nodelay on;
client_header_buffer_size 4k;
open_file_cache max=102400 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 1;
client_header_timeout 15;
client_body_timeout 15;
reset_timedout_connection on;
send_timeout 15;
server_tokens off;
client_max_body_size 10m;
keepalived_timeout :客户端连接保持会话超时时间,超过这个时间,服务器断开这个链接。
tcp_nodelay:也是防止网络阻塞,不过要包涵在keepalived参数才有效。
client_header_buffer_size 4k:客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过 1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。
open_file_cache max=102400 inactive=20s :这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。
open_file_cache_valid 30s:这个是指多长时间检查一次缓存的有效信息。
open_file_cache_min_uses 1 :open_file_cache指令中的inactive 参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除。
client_header_timeout : 设置请求头的超时时间。我们也可以把这个设置低些,如果超过这个时间没有发送任何数据,nginx将返回request time out的错误。
client_body_timeout设置请求体的超时时间。我们也可以把这个设置低些,超过这个时间没有发送任何数据,和上面一样的错误提示。
reset_timeout_connection :告诉nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。
send_timeout :响应客户端超时时间,这个超时时间仅限于两个活动之间的时间,如果超过这个时间,客户端没有任何活动,nginx关闭连接。
server_tokens :并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。
client_max_body_size:上传文件大小限制。
8、proxy超时设置
proxy_connect_timeout 90; #后端服务器连接的超时时间,发起握手等候响应超时时间
proxy_send_timeout 90;  #后端服务器数据回传时间,就是在规定时间内后端服务器必须传完所有的数据
proxy_read_timeout 90;  #连接成功后,等候后端服务器响应时间,其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间,页面等待服务器响应时间)
proxy_buffers 4 32k;  #4是数量 32k是大小 该指令设置缓存区的大小和数量,从被代理的后端服务器取得的第一部分响应内容,会放置到这里,默认情况下,一个缓存区的大小等于内存页面大小,可能是4k也可能是8k取决于平台
proxy_busy_buffers_size 64k; #nginx在收到服务器数据后,会分配一部分缓冲区来用于向客户端发送数据,这个缓存区大小由proxy_busy_buffers_size决定的。大小通常是proxy_buffers单位大小的两倍,官网默认是8k/16k。
buffer工作原理
1.所有的proxy buffer参数都是作用到每一个请求的。每一个全球有会按照参数的配置获得自己的buffer。proxy buffer不是global(全局配置),而是per request(在请求前执行的操作(如时间戳、签名))的

2、proxy_buffering是为了开启response buffering of the proxied server(反向代理服务器响应数据的缓存),开启后proxy_buffers和proxy_busy_buffers_size参数才会起作用

3、无论peoxy_buffer是否开启,proxy_buffer_size都是工作的,proxy_buffer_size所设置的buffer_size的作用是用来存储upstream端response的header。

4、在proxy_buffering 开启的情况下,Nginx将会尽可能的读取所有的upstream端传输的数据到buffer,直到proxy_buffers设置的所有buffer们被写满或者数据被读取完(EOF)。此时nginx开始向客户端传输数据,会同时传输这一整串buffer们。同时如果response的内容很大的话,Nginx会接收并把他们写入到temp_file里去。大小由proxy_max_temp_file_size控制。如果busy的buffer传输完了会从temp_file里面接着读数据,直到传输完毕。

5、一旦proxy_buffers设置的buffer被写入,直到buffer里面的数据被完整的传输完(传输到客户端),这个buffer将会一直处在busy状态,我们不能对这个buffer进行任何别的操作。所有处在busy状态的buffer size加起来不能超过proxy_busy_buffers_size,所以proxy_busy_buffers_size是用来控制同时传输到客户端的buffer数量的。
9、proxy_set_header
proxy_set_header用来设定被代理服务器接收到的header信息。

语法:proxy_set_header field value;
field :为要更改的项目,也可以理解为变量的名字,比如host
value :为变量的值
如果不设置proxy_set_header,则默认host的值为proxy_pass后面跟的那个域名或者IP(一般写IP)

proxy_set_header X-Real-IP $remote_addr;和proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
用来设置被代理端接收到的远程客户端IP,如果不设置,则header信息中并不会透传远程真实客户端的IP地址。
实战配置
server {
        ...
        location /http/ {
                proxy_pass http://http_backend;
                proxy_http_version 1.1;                 # 对于http协议应该指定为1.1
                proxy_set_header Connection "";         # 清除"connection"头字段 , Connection: keep-alive
                proxy_set_header Host $http_host;		# 代理服务器匹配请求web01服务器的时候,默认加上Host头信息(域名)	
				proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;		# 追加客户端ip地址以及全链路ip地址到web服务器记录日志	
				proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
				# 当Nginx虚拟服务池其中任意一台服务器返回错误码500,502,503,504等错误时,可以分配到下一台服务器程序继续处理,提高平台访问的成功率
				proxy_connect_timeout 60s;				# nginx代理与后端服务器连接超时时间(代理连接超时)
				proxy_read_timeout 60s;					# nginx代理等待后端服务器的响应时间(代理响应超时)
				proxy_send_timeout 60s;					# 后端服务器数据回传给nginx代理超时时间(回传数据给代理超时)
				
				proxy_buffering on;						# nginx会把后端返回的内容先放到缓冲区中,然后再返回给客户端,边收边传,不是全部接收再传给客户端
				proxy_buffers_size 4k;					# 设置nginx代理保存用户头信息的缓存区大小
				proxy_buffers 8 8k;						# 设置nginx代理缓冲区大小(8*8 = 64k)
        ...
        }
}
       $proxy_host 自然是 proxy_pass后面跟着的host 比如一个请求 https://zhidao.baidu.com/question/22908463.html
       Request.ServerVariables("HTTP_HOST") 可以获得HTTP_HOST请求标题:zhidao.baidu.com

      $http_host始终等于HTTP_HOST请求标题

      $host等于$http_host,小写并且没有端口号(如果存在),除非HTTP_HOST不存在或是空值。在这种情况下,$host等于server_name
      $proxy_add_x_forwarded_for  。从客户访问到到最后的后台服务所经理的所有节点的ip汇总221.221.1.100,10.30.30.109,...  

        nginx的自带变量 $remote_addr 代表客户端的IP

        $remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP。

        $remote_addr 只能获取到与服务器本身直连的上层请求ip,所以设置$remote_addr一般都是设置第一个代理上面;但是问题是,有时候是通过cdn访问过来的,那么后面web服务器获取到的,永远都是cdn 的ip 而非真是用户ip,那么这个时候就要用到X-Forwarded-For 了,这个变量的意思,其实就像是链路反追踪,从客户的真实ip为起点,穿过多层级的proxy ,最终到达web 服务器,都会记录下来,所以在获取用户真实ip的时候,一般就可以设置成,proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 这样就能获取所有的代理ip 客户ip。 $proxy_add_x_forwarded_for变量包含客户端请求头中的X-Forwarded-For与$remote_addr两部分,他们之间用逗号分开。
10、高效传输模式
sendfile on; #开启高效文件传输模式。
tcp_nopush on;#需要在sendfile开启模式才有效,防止网络阻塞,级级的减少网络报文段的数量。将响应头和正文的开始部分一起发送,而不是一个接一个的发送(也就是说数据包不会马上传出等到数据包最大时一次性传)
tcp_nodelay on; #只要有数据包产生,不管大小多少,就尽快传输
11、fastcgi调优
fastcgi_connect_timeout 600;
fastcgi_send_timeout 600;
fastcgi_read_timeout 600;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_temp_path/usr/local/nginx1.22/nginx_tmp;
fastcgi_intercept_errors on;
fastcgi_cache_path/usr/local/nginx1.22/fastcgi_cache levels=1:2
keys_zone=cache_fastcgi:128minactive=1d max_size=10g;
fastcgi_connect_timeout 600 :指定连接到后端FastCGI的超时时间。
fastcgi_send_timeout 600 :向FastCGI传送请求的超时时间。
fastcgi_read_timeout 600 :指定接收FastCGI应答的超时时间。
fastcgi_buffer_size 64k :指定读取FastCGI应答第一部分需要用多大的缓冲区,默认的缓冲区大小为。fastcgi_buffers指令中的每块大小,可以将这个值设置更小。
fastcgi_buffers 4 64k :指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求,如果一个php脚本所产生的页面大小为256KB,那么会分配4个64KB的缓冲区来缓存,如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp_path指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于磁盘。一般这个值应该为站点中php脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“8 32K”、“4 64k”等。
fastcgi_busy_buffers_size 128k :建议设置为fastcgi_buffers的两倍,繁忙时候的buffer。
fastcgi_temp_file_write_size 128k :在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍,该数值设置小时若负载上来时可能报502BadGateway。
fastcgi_temp_path :缓存临时目录。
fastcgi_intercept_errors on :这个指令指定是否传递4xx和5xx错误信息到客户端,或者允许nginx使用error_page处理错误信息。注:静态文件不存在会返回404页面,但是php页面则返回空白页!
fastcgi_cache_path /usr/local/nginx1.10/fastcgi_cachelevels=1:2
keys_zone=cache_fastcgi:128minactive=1d max_size=10g :fastcgi_cache缓存目录,可以设置目录层级,比如1:2会生成16*256个子目录,cache_fastcgi是这个缓存空间的名字,cache是用多少内存(这样热门的内容nginx直接放内存,提高访问速度),inactive表示默认失效时间,如果缓存数据在失效时间内没有被访问,将被删除,max_size表示最多用多少硬盘空间。
fastcgi_cache cache_fastcgi :#表示开启FastCGI缓存并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502的错误放生。cache_fastcgi为proxy_cache_path指令创建的缓存区名称。
fastcgi_cache_valid 200 302 1h :#用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存一小时,要和fastcgi_cache配合使用。
fastcgi_cache_valid 301 1d :将301应答缓存一天。
fastcgi_cache_valid any 1m :将其他应答缓存为1分钟。
fastcgi_cache_min_uses 1 :该指令用于设置经过多少次请求的相同URL将被缓存。
fastcgi_cache_key http://h o s t hosthostrequest_uri :该指令用来设置web缓存的Key值,nginx根据Key值md5哈希存储.一般根据h o s t ( 域 名 ) 、 host(域名)、host(域名)、request_uri(请求的路径)等变量组合成proxy_cache_key 。
fastcgi_pass :指定FastCGI服务器监听端口与地址,可以是本机或者其它。
总结:
nginx的缓存功能有:proxy_cache / fastcgi_cache

proxy_cache的作用是缓存后端服务器的内容,可能是任何内容,包括静态的和动态。
fastcgi_cache的作用是缓存fastcgi生成的内容,很多情况是php生成的动态的内容。
proxy_cache缓存减少了nginx与后端通信的次数,节省了传输时间和后端宽带。
fastcgi_cache缓存减少了nginx与php的通信的次数,更减轻了php和数据库(mysql)的压力。
12、expires缓存调优
        缓存,主要针对于图片,css,js等元素更改机会比较少的情况下使用,特别是图片,占用带宽大,我们完全可以设置图片在浏览器本地缓存365d,css,js,html可以缓存个10来天,这样用户第一次打开加载慢一点,第二次,就非常快了!缓存的时候,我们需要将需要缓存的拓展名列出来, Expires缓存配置在server字段里面。

location ~* \.(ico|jpe?g|gif|png|bmp|swf|flv)$ {
	expires 30d;  #过期时间为30天
	#log_not_found off;
	access_log off;
}
location ~* \.(js|css)$ {
	expires 7d;
	log_not_found off;
	access_log off;
}
注:log_not_found off;是否在error_log中记录不存在的错误。默认是。

Expires:是缓存到期的时间
13、访问限流 
        我们构建网站是为了让用户访问它们,我们希望用于合法访问。所以不得不采取一些措施限制滥用访问的用户。这种滥用指的是从同一IP每秒到服务器请求的连接数。因为这可能是在同一时间内,世界各地的多台机器上的爬虫机器人多次尝试爬取网站的内容。

#限制用户连接数来预防DOS攻击
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
#限制同一客户端ip最大并发连接数
limit_conn perip 2;
#限制同一server最大并发连接数
limit_conn perserver 20;
#限制下载速度,根据自身服务器带宽配置
limit_rate 300k; 
四、内核参数优化
vim /etc/sysctl.conf  #进入这个文件修改
sysctl -p   #让修改的内核信息生效
 
#################################################
 
fs.file-max = 999999
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 10240 87380 12582912
net.ipv4.tcp_wmem = 10240 87380 12582912
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 40960
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000
fs.file-max = 999999:这个参数表示进程(比如一个worker进程)可以同时打开的最大句柄数,这个参数直线限制最大并发连接数,需根据实际情况配置。
net.ipv4.tcp_max_tw_buckets = 6000 :这个参数表示操作系统允许TIME_WAIT套接字数量的最大值,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。该参数默认为180000,过多的TIME_WAIT套接字会使Web服务器变慢。注:主动关闭连接的服务端会产生TIME_WAIT状态的连接
net.ipv4.ip_local_port_range = 1024 65000 :允许系统打开的端口范围。
net.ipv4.tcp_tw_recycle = 1 :启用timewait快速回收。
net.ipv4.tcp_tw_reuse = 1 :开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接。这对于服务器来说很有意义,因为服务器上总会有大量TIME-WAIT状态的连接。
net.ipv4.tcp_keepalive_time = 30:这个参数表示当keepalive启用时,TCP发送keepalive消息的频度。默认是2小时,若将其设置的小一些,可以更快地清理无效的连接。
net.ipv4.tcp_syncookies = 1 :开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理。
net.core.somaxconn = 40960 :web 应用中 listen 函数的 backlog 默认会给我们内核参数的。
net.core.somaxconn :限制到128,而nginx定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。注:对于一个TCP连接,Server与Client需要通过三次握手来建立网络连接.当三次握手成功后,我们可以看到端口的状态由LISTEN转变为ESTABLISHED,接着这条链路上就可以开始传送数据了.每一个处于监听(Listen)状态的端口,都有自己的监听队列.监听队列的长度与如somaxconn参数和使用该端口的程序中listen()函数有关。somaxconn定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128,对于一个经常处理新连接的高负载 web服务环境来说,默认的 128 太小了。大多数环境这个值建议增加到 1024 或者更多。大的侦听队列对防止拒绝服务 DoS 攻击也会有所帮助。
net.core.netdev_max_backlog = 262144 :每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.ipv4.tcp_max_syn_backlog = 262144 :这个参数标示TCP三次握手建立阶段接受SYN请求队列的最大长度,默认为1024,将其设置得大一些可以使出现Nginx繁忙来不及accept新连接的情况时,Linux不至于丢失客户端发起的连接请求。
net.ipv4.tcp_rmem = 10240 87380 12582912 :这个参数定义了TCP接受缓存(用于TCP接受滑动窗口)的最小值、默认值、最大值。
net.ipv4.tcp_wmem = 10240 87380 12582912:这个参数定义了TCP发送缓存(用于TCP发送滑动窗口)的最小值、默认值、最大值。
net.core.rmem_default = 6291456:这个参数表示内核套接字接受缓存区默认的大小。
net.core.wmem_default = 6291456:这个参数表示内核套接字发送缓存区默认的大小。
net.core.rmem_max = 12582912:这个参数表示内核套接字接受缓存区的最大大小。
net.core.wmem_max = 12582912:这个参数表示内核套接字发送缓存区的最大大小。
net.ipv4.tcp_syncookies = 1:该参数与性能无关,用于解决TCP的SYN攻击。

location的优先级

location优先级:(location =) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 完整路径) > (location 部分起始路径) > (/)

rewrite 中 redirect,permanent, break和last区别

redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求,状态码:301
break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用,跳过后面所有rewrite模块指令
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户

如何获取客户端真实IP

客户端IP穿透
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
配置访问日志,之后就可以在访问日志中查看.客户端真实访问地址

nginx的常见模块

ngx_http_core_module  #nginx核心模块
ngx_http_api_module #   #http api模块
ngx_http_fastcgi_module  #fastcgi模块应用于php程序fastcgi协议通信
ngx_http_gzip_module   #nginx压缩资源提升性能用gzip
ngx_http_index_module   #索引
ngx_http_proxy_module  #可以实现http协议反向代理
ngx_http_rewrite_module #相当于重定向
ngx_http_referer_module  #实现防盗链
ngx_http_ssl_module   #开启ssl功能
ngx_http_upstream_module   #负载均衡
ngx_http_auth_basic_module  #账户认证
ngx_stream_upstream_module #四层反向代理
echo-nginx-module #变量打印模块
nginx-module-vts  #流量监控模块
gx_http_limit_req_module.html #限制请求数
ngx_http_limit_conn_module #限制连接数
ngx_http_autoindex_module.html #模块处理以斜杠字符 "/" 结尾的请求,并生成目录列表,可以做为下载服务
ngx_http_access_module #四层访问限制
ngx_http_stub_status_module #状态页
ngx_http_log_module #日志模块

nginx的反向代理的调度算法

RR 轮询算法(默认)
RW 权重算法 weight=number
ip_hash 源地址24位算法
least_conn 最少连接调度算法
hash KEY [consistent]; 一致性
hash $request_uri consistent; #基于用户请求的uri做hash,可以实现调度到后端缓存服务器功能
hash $remote_addr consistent; #则是对全部32bit的IPv4进行一致性hash计算
hash $cookie_sessionid #基于cookie中的sessionid这个key进行hash调度,实现会话绑定

http的常见的响应码


200: 成功,请求数据通过响应报文的entity-body部分发送;OK

301: 请求的URL指向的资源已经被删除;但在响应报文中通过首部Location指明了资源现在所处的新位置;Moved Permanently
302: 响应报文Location指明资源临时新位置 Moved Temporarily
304: 客户端发出了条件式请求,但服务器上的资源未曾 发生改变,则通过响应此响应状态码通知客户端;Not Modified,但无需再发送原始数据即实体给客户端
307: 浏览器内部重定向,而无需再向服务器发送请求

401: 需要输入账号和密码认证方能访问资源;Unauthorized
403: 请求被禁止;Forbidden,一般是因为权限错误或主页文件不存在
404: 服务器无法找到客户端请求的资源;Not Found
413: 上传的资源超过了最大限制值
499:客户端主动断开连接。然而在实际业务开发中,当出现 HTTP 499 状态码时,大部分都是由于服务端请求时间过长,导致客户端等的“不耐烦”了,因此断开了连接。比如:慢SQL问题,499是客户端读超时关闭连接造成的,推荐从超时时间或者优化响应速度入手,web服务器发现客户端主动关闭连接后,记录到access日志中的。可能是客户端接收响应超时了,可以先在客户端统计下是不是这个原因,再调查为什么会导致超时

500: 服务器内部错误;Internal Server Error,比如:cgi程序没有执行权限,或连接数据库失败,rewrite死循环
502:Bad Gateway,代理服务器从后端服务器收到了一条错误响应,如无法连接到网关;Bad Gateway,比如:后端服务端口没有打开,或后端服务不可用,iptable -j REJECT
504:Gateway Timeout,网关超时,或者后端服务器无回应报文,比如:服务端口虽然打开,但服务返回结果时间过长,iptable -j DROP

访问web页面时出现502和504错误,请简述—下排查思路

1.ping查看是否能ping通域名,查看域名解析是否正常;
2.去代理服务器或者负载均衡服务器查看日志情况是否完成代理和负载;
3.查看应用服务器日志,是否接收到访问请求;

有同事反应,网站访问速度很慢,有时候会出现打不开网站的情况,刷新等待好长时间后又正常打开,请分析并说一说故障排查思路

浏览器F12查看是获取什么资源导致网站访问慢,查看是否是静态资源访问慢,如果是就对代理负载均衡的服务器做优化
如果是动态资源请求慢,就去观察应用服务器的日志,判断是代码逻辑原因导致还是获取数据库数据慢
如果是代码运行慢就联系开发进行优化
如果发现是数据库获取慢就去看数据库的慢日志找到慢的sql语句进行优化

Tomcat

JVM的组成

类加载子系统: 使用Java语言编写.java Source Code文件,通过javac编译成.class Byte Code文件。class loader类加载器将所需所有类加载到内存,必要时将类实例化成实例
运行时数据区: 最消耗内存的空间,需要优化
执行引擎: 包括JIT (JustInTimeCompiler)即时编译器, GC垃圾回收器
本地方法接口: 将本地方法栈通过JNI(Java Native Interface)调用Native Method Libraries, 比如:C,C++库等,扩展Java功能,融合不同的编程语言为Java所用

JVM的常见垃圾回收器

1.8版本及以前(例如8)
serial 串行 年轻代(效率低不适用)
serial Old 串行 老年代(效率低不适用)
parNew 并行 提高交互感受 年轻代
PS 并行 提高吞吐量 年轻代
Parallel Old 并行 提高吞吐量
CMS 并行(老年代)
1.8以后(例如11)
G1

JVM的常见启动参数

JAVA程序出现OOM,如何解决

使用监控检测工具查看OOM的原因.如果是内存分配不够就重新调参分配内存,如果监测是代码问题,就提给开发就行优化修改
JProfiler是一款功能强大的Java开发分析工具,它可以快速的帮助用户分析出存在的错误,软件还可对需要的显示类进行标记,包括了内存的分配情况和信息的视图等
JProfiler官网:http://www.ej-technologies.com/products/jprofiler/overview.html

Tomcat的优化方法

JVM最大内存分配不要超过32G,因为超过后不会提升性能反而会降低,例如ELK的内存设置文档明确写明了不能超过32g
-Xms1024  设定heap初始内存(生产建议与最大内存一致)
-Xmx1024  设定heap最大内存(生产建议与初始内存一致)
配置垃圾回收器

线程池调整
[root@centos8 ~]#vim /usr/local/tomcat/conf/server.xml
......
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000"
redirectPort="8443" maxThreads="2000"/>
......

生产环境配置案例
[root@centos8 ~]#vim /usr/local/tomcat/bin/catalina.sh
JAVA_OPTS="-server -Xms4g -Xmx4g -Xss512k -Xmn1g -
XX:CMSInitiatingOccupancyFraction=65 -XX:+AggressiveOpts -XX:+UseBiasedLocking -
XX:+DisableExplicitGC -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -
XX:PermSize=128m -XX:MaxPermSize=512m -XX:CMSFullGCsBeforeCompaction=5 -
XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -
XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -
XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods"
       

Zabbix

添加1台需要监控的主机流程是什么?

1.被监控端安装agent或agent2
2.修改配置文件指向zabbix服务端
3.zabbix管理界面创建主机
4.关联模板
5.等待数据同步,zbx标签变绿

添加100台需要监控的主机如何实现?

第一步同步自动化运维工具批量部署安装agent例如使用ansible
方法1:启用自动发现功能(影响zabbix服务器性能)
方法2:使用zabbix的API接口,通过脚本添加主机

简述zabbix的部署架构和工作原理(或者其他监控报警系统)

zabbix服务端
zabbix-agent/zabbix-agent2 被控端
zabbix-prosy 跨网络监控
SNMP协议监控硬件
JMX监控java应用

zabbix工作模式分主被动
主动模式由被监控端主动汇总信息发给zabbix服务端
被动模式由zabbix服务端主动发送请求获取被监控端信息
zabbix-proxy 汇总不同网段主机的信息发送给服务端实现跨网段监控

zabbix可以配置微信,邮件,短信,钉钉报警
可以搭配grafana展示界面

有100个机器内存大小不一致想获取内存监控项,然后超过某个指标将报警,如何操作

1.配置好内存查询变量,通过自动化运维工具,发送给100台机器
1.管理界面创建模板
2.管理界面在模板内创建监控项
3.管理界面在模板内创建触发器
4.然后通过自动化手段添加100台主机,并分配在相同分组下,该分组关联创建好的模板
5.若需要实现发送信息报警,就创建报警媒介,关联用户创建动作

Zabbix 如何添加自定义监控,有哪些告警方式,如何实现

邮件
微信
钉钉
短信

可以通过关联脚本,实现告警

1.告警媒介
2.用户关联
3.动作

Zabbix监控哪些指标?

Zabbix有过哪些报警,你怎么处理的?

Zabbix都监控那些服务,监控项都有那些?

Zabbix主动和被动模式什么区别?

主动模式由被监控端主动汇报信息给server服务端(可以减轻服务端压力,但配置时需要配置Serveractive,注意Serverhost配置要与管理界面上一致)
被动模式由server服务端请求被监控端获取数据信息(当体量较大时服务端性能压力增大)

Zabbix监控脚本怎么写?

例如:监控tcp的是一种状态连接情况
[root@jpress2 ~]#vim /etc/zabbix/zabbix_agent2.d/mem.conf
UserParameter=tcp_state_[*],netstat -ant|grep -c $1

Zabbix出现 0ut Of Memory,将原本2G内存加到8G还是Out 0f Memor

zabbix的server配置文件中做了内存限制需要修改后重启服务才能生效
[root@zabbix-server ~]#grep -i cache /etc/zabbix/zabbix_server.conf
### Option: VMwareCacheSize
# Size of VMware cache, in bytes.
# VMwareCacheSize=8M
### Option: CacheSize
# Size of configuration cache, in bytes.
# CacheSize=8M #此值不能太小,否则Zabbix Server 可能无法启动
### Option: CacheUpdateFrequency
# How often Zabbix will perform update of configuration cache, in seconds.
# CacheUpdateFrequency=60
### Option: HistoryCacheSize
# Size of history cache, in bytes.
# HistoryCacheSize=16M
### Option: HistoryIndexCacheSize
# Size of history index cache, in bytes.
# Shared memory size for indexing history cache.
# HistoryIndexCacheSize=4M
### Option: TrendCacheSize
# Size of trend cache, in bytes.
# TrendCacheSize=4M
### Option: ValueCacheSize
# Size of history value cache, in bytes.
# Setting to 0 disables value cache.
# ValueCacheSize=8M

Dokcer

Docker组成

Namespcae
Control groups(Cgroups)
隔离类型功能系统调用参数内核版本
MNT Namespace(mount)提供磁盘挂载点和文件系统的隔离能力CLONE_NEWNS2.4.19
IPC Namespace(Inter-Process Communication)提供进程间通信的隔离能力,包括信号量,消息队列和共享内存CLONE_NEWIPC2.6.19
UTS Namespace(UNIXTimesharing System)提供内核,主机名和域名隔离能力CLONE_NEWUTS2.6.19
PID Namespace(ProcessIdentification)提供进程隔离能力CLONE_NEWPID2.6.24
Net Namespace(network)提供网络隔离能力,包括网络设备,网络栈,端口等CLONE_NEWNET2.6.29
User Namespace(user)提供用户隔离能力,包括用户和组CLONE_NEWUSER3.8

Docker优缺点

docker优点
快速部署: 短时间内可以部署成百上千个应用,更快速交付到线上
高效虚拟化: 不需要额外hypervisor支持,基于linux内核实现应用虚拟化,相比虚拟机大幅提高性能和效率
节省开支: 提高服务器利用率,降低IT支出
简化配置: 将运行环境打包保存至容器,使用时直接启动即可
环境统一: 将开发,测试,生产的应用运行环境进行标准化和统一,减少环境不一样带来的各种问题
快速迁移和扩展: 可实现跨平台运行在物理机、虚拟机、公有云等环境,良好的兼容性可以方便将应用从A宿主机迁移到B宿主机,甚至是A平台迁移到B平台
更好的实现面向服务的架构,推荐一个容器只运行一个应用,实现分布的应用模型,可以方便的进行横向扩展,符合开发中高内聚,低耦合的要求,减少不同服务之间的相互影响

docker缺点
多个容器共用宿主机的内核,各应用之间的隔离不如虚拟机彻底
由于和宿主机之间的进程也是隔离的,需要进入容器查看和调试容器内进程等资源,变得比较困难和繁琐
如果容器内进程需要查看和调试,需要在每个容器内都需要安装相应的工具,这也造成存储空间的重复浪费

docker 打镜像时需不需要对容器内操作系统进行内核参数优化?

不需要做优化,因为容器使用的内核是宿主机的内核

Dockerfile有哪些指令?

Dockerfile文件指令解释
FROM: 指定基础镜像
LABEL: 指定镜像元数据
RUN: 执行 shell命令
ENV: 设置环境变量
COPY: 复制文本
ADD: 复制和解包文件
CMD: 容器启动命令
ENTRYPOINT: 入口点
ARG: 构建参数
VOLUME: 匿名卷
EXPOSE: 暴露端口
WORKDIR: 指定工作目录
ONBUILD: 子镜像引用父镜像的指令
USER: 指定当前用户
HEALTHCHECK: 健康检查

docker 有哪些常用指令?

docker run 
docker ps 
dockerimages
docker build
docker network
docker pull
docker push
docker search
#很多博客里都有记录

两个服务器装了docker,双方的容器之间如何实现通信,有几种方式,不同主机的两个容器之间能够通信吗,怎么实现?

两种方式
    方式1: 利用桥接实现跨宿主机的容器间互联
    方式2: 利用NAT实现跨主机的容器间互联

docker 的网络模式有几种?

五种方式
bridge
host
none
container
自定义

Haproxy

HAProxy调度算法

#静态
static-rr--------->tcp/http
first------------->tcp/http
#动态
roundrobin-------->tcp/http
leastconn--------->tcp/http
random------------>tcp/http
#以下静态和动态取决于hash_type是否consistent
source------------>tcp/http
Uri--------------->http
url_param--------->http
hdr--------------->http
rdp-cookie-------->tcp
#各种算法使用场景
first #使用较少
static-rr #做了session共享的 web 集群
roundrobin
random
leastconn #数据库
source #基于客户端公网 IP 的会话保持
Uri--------------->http #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http #可以实现session保持
hdr #基于客户端请求报文头部做下一步处理
rdp-cookie #基于Windows主机,很少使用

ACL使用与报文修改

#修改请求host首部,默认host首部会保留客户端原首部haproxy不会修改
http-request set-header host www.wangxiaochun.com
#添加向后端服务器发送的请求报文首部
http-request add-header <name> <fmt> [ { if | unless } <condition> ]
#示例:http-request add-header X-Haproxy-Current-Date %T
#删除向后端服务器发送的请求报文首部
http-request del-header <name> [ { if | unless } <condition> ]
#修改响应首部
http-response set-header server wangserver
#添加向客户端发送的响应报文首部
http-response add-header <name> <fmt> [ { if | unless } <condition> ]
#删除向客户端发送的响应报文首部
http-response del-header <name>
#示例:http-response del-header Server

动静分离(根据文件后缀或URL)

#基于ACL实现
acl acl_static path_end -i .jpg .jpeg .png .gif .css .js .html #基于文件后缀名的ACL
acl acl_php path_end -i .php
use_backend hosts01 if acl_static
use_backend hosts02 if acl_php

客户端源IP透传

#四层穿透
"$proxy_protocol_addr"

#七层穿透
defaults
option forwardfor  #此为默认值,首部字段默认为:X-Forwarded-For

#后端日志
"$proxy_add_x_forwarded_for"; #显示每一层的地址
"$http_x_forwarded_For"; #只显示源地址

服务器动态下线编写shell脚本,实现能够基于参数传递 Real Server 服务器IP,并实现将其从多个HAProxy进程下线与上线

#!/bin/bash
WEB_SERVERS="
10.0.0.101
10.0.0.102
"
for i in $WEB_SERVERS;do
echo "set server www.wang.org_nginx/$i state maint" | socat stdio /var/lib/haproxy/haproxy.sock
ssh $i docker rm -f nginx
ssh $i "echo DOCKER $i WEBSITE $1 > /data/www/index.html"
ssh $i docker run -d -p 80:80 -v /data/www:/usr/share/nginx/html --name nginx nginx
sleep 10
echo "set server www.wang.org_nginx/$i state ready" | socat stdio /var/lib/haproxy/haproxy.sock
done

比较LVS,haproxy,nginx三者的特性和调度算法区别(面试题)

#LVS四层代理,基于内核实现,所以使用ss命令是看不见端口的,不支持keepalive,ECS不支持lvs.
#nginx七层代理,伪四层代理,web服务器,占用内存少,模块多,健康检测只能通过端口检测不能通过url检测容易误报web的健康性;
#haproxy七层代理,伪四层代理,会话保持功能比nginx好,健康性检测支持url;

四层控流量
七层控负载

使用场景:nginx一般用于七层的负载
Haproxy和lvs一般用于四层作为主入口控制流量

Redis

Redis 做什么的,即在哪些场景下使用

缓存:缓存RDBMS中数据,比如网站的查询结果、商品信息、微博、新闻、消息
Session 共享:实现Web集群中的多服务器间的session共享
计数器:商品访问排行榜、浏览数、粉丝数、关注、点赞、评论等和次数相关的数值统计场景
社交:朋友圈、共同好友、可能认识他们等
地理位置: 基于地理信息系统GIS(Geographic Information System)实现摇一摇、附近的人、外卖等功能
消息队列:ELK等日志系统缓存、业务的订阅/发布系统

如果监控 Redis 是否出现故障

[root@Redis-Slave3 ~]#redis-cli -a 123456 ping 
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
PONG

Redis客户端timeout报错突然增加,排查思路是怎样的?

先查外因:

1、网络层面是否有抖动;

     物理层面是否有网络丢包:ifconfig查看Drop

     网卡层面,查看是否被打满,网卡打满会导致严重的超时

2、服务器负载:查看CPU和Load是否有异常

3、Redis是不是使用了Swap空间。

再看内因:

4、Redis-Server 的慢查询,特别是简单命令中的大key情况(注意慢查询不包括排队等待的时间);

5、超时的时刻是否由AOF重写或者Bgsave操作;Redis 在持续高写入的时候,开了AOF功能会导致响应时间明显变慢。

6、Redis本身使用的CPU情况。

7、以上是原理层面分析超时问题;如果排查不出来问题,就需要进行抓包分析;

请简单描述pipeline功能,为什么pipeline功能会提升redis性能?

PIPELINE原理
将多个命令打包组成命令块
将命令块一次性批量发送给服务端
服务端依此处理完后将结果集打包
批量返回所有结果

pipeline可以有效的减少带宽的消耗

本地redis-client访问远程Redis服务出错,说出几种常见的错误?

1.对方开启了保护模式,且没有设置密码
2.对方只监听了本机的端口
3.对方修改了默认监听端口
4.对方从网络上拒绝了远程访问,例如防火墙iptables规则

key-value的大小超大或单key的qps超高,会对Redis本身造成什么样的影响、会对访问Redis的其他客户端造成什么样的影响?

1.内存不均:单value较大时,可能会导致节点之间的内存使用不均匀,间接地影响key的部分和负载不均匀;
2.阻塞请求:redis为单线程,单value较大读写需要较长的处理时间,会阻塞后续的请求处理;
3.阻塞网络:单value较大时会占用服务器网卡较多带宽,可能会影响该服务器上的其他Redis实例或者应用。

Zabbix 监控 Redis 哪些监控项

1、监控redis端口状态
2、监控redis活跃连接数、最大连接数
3、监控redis已用内存,系统最大支持内存
4.监控主从情况
5.监控集群情况

RDB和AOF持久化区别

RDB的优点
1.体积更小:相同的数据量rdb数据比aof的小,因为rdb是紧凑型文件
2.恢复更快:因为rdb是数据的快照,基本上就是数据的复制,不用重新读取再写入内存
3.性能更高:父进程在保存rdb时候只需要fork一个子进程,无需父进程的进行其他io操作,也保证了服务器的性能。

RDB的缺点
1.故障丢失:因为rdb是全量的,我们一般是使用shell脚本实现30分钟或者1小时或者每天对redis进行rdb备份,但是最少也要5分钟进行一次的备份,所以当服务死掉后,最少也要丢失5分钟的数据。
2.耐久性差:相对aof的异步策略来说,因为rdb的复制是全量的,即使是fork的子进程来进行备份,当数据量很大的时候对磁盘的消耗也是不可忽视的,尤其在访问量很高的时候,fork的时间也会延长,导致cpu吃紧,耐久性相对较差。

aof的优点
1.数据保证:我们可以设置fsync策略,一般默认是everysec,也可以设置每次写入追加,所以即使服务死掉了,咱们也最多丢失一秒数据
2.自动缩小:当aof文件大小到达一定程度的时候,后台会自动的去执行aof重写,此过程不会影响主进程,重写完成后,新的写入将会写到新的aof中,旧的就会被删除掉。但是此条如果拿出来对比rdb的话还是没有必要算成优点,只是官网显示成优点而已。

aof的缺点
1.性能相对较差:它的操作模式决定了它会对redis的性能有所损耗
2.体积相对更大:尽管是将aof文件重写了,但是毕竟是操作过程和操作结果仍然有很大的差别,体积也毋庸置疑的更大。
3.恢复速度更慢

最后的总结
redis有两种持久化方式,aof和rdb,aof相当于日志记录操作命令,rdb相当于数据的快照。安全性来讲由于aof的记录能够精确到秒级追加甚至逐条追加,而rdb只能是全量复制,aof明显高于rdb。但是从性能来讲rdb就略胜一筹,rdb是redis性能最大化的体现,它不用每秒监控是否有数据写入,当达到触发条件后就自动fork一个子进程进行全量更新,速度也很快。容灾回复方面rdb更是能够快速的恢复数据,而aof需要读取再写入,相对慢了很多。

docker拉取一个Redis如何实现数据持久化保存

将存放rdb和aof的持久化目录用docker的持久化命令挂载到宿主机上实现容器的持久化保存

Redis 支持哪些数据类型

string
list
set
sorted set
hash

Redis 如何实现消息队列

生产者和消费者模式
发布者订阅模式

描述下常见的redis集群架构有哪些,他们之间的优缺点对比

主从模式  master/slave
哨兵模式  sentinel
集群模式  cluster

主从复制工作原理

从总体上来说,Redis主从复制的策略就是:当主从服务器刚建立连接的时候,进行全量同步;全量复制结束后,进行增量复制。当然,如果有需要,slave 在任何时候都可以发起全量同步。

Redis 如何实现高可用

哨兵模式
集群模式

哨兵工作原理

专门的Sentinel 服务进程是用于监控redis集群中Master工作的状态,当Master主服务器发生故障的时
候,可以实现Master和Slave的角色的自动切换,从而实现系统的高可用性
Sentinel是一个分布式系统,即需要在多个节点上各自同时运行一个sentinel进程,Sentienl 进程通过流
言协议(gossip protocols)来接收关于Master是否下线状态,并使用投票协议(Agreement Protocols)来
决定是否执行自动故障转移,并选择合适的Slave作为新的Master
每个Sentinel进程会向其它Sentinel、Master、Slave定时发送消息,来确认对方是否存活,如果发现某
个节点在指定配置时间内未得到响应,则会认为此节点已离线,即为主观宕机Subjective Down,简称
为 SDOWN
如果哨兵集群中的多数Sentinel进程认为Master存在SDOWN,共同利用 is-master-down-by-addr 命令
互相通知后,则认为客观宕机Objectively Down, 简称 ODOWN
接下来利用投票算法,从所有slave节点中,选一台合适的slave将之提升为新Master节点,然后自动修
改其它slave相关配置,指向新的master节点,最终实现故障转移failover
Redis Sentinel中的Sentinel节点个数应该为大于等于3且最好为奇数
客户端初始化时连接的是Sentinel节点集合,不再是具体的Redis节点,即 Sentinel只是配置中心不是代
理。
Redis Sentinel 节点与普通 Redis 没有区别,要实现读写分离依赖于客户端程序
Sentinel 机制类似于MySQL中的MHA功能,只解决master和slave角色的自动故障转移问题,但单个
Master 的性能瓶颈问题并没有解决

Redis 集群的工作原理

redis的集群是分布式的,数据分散在各个节点.
将集群内的数据进行分区,redis集群通过虚虚拟槽分区的方式,将集群分出16384个槽位即0~16383,每个槽映射一个数据子集,通过hash函数,将数据存放在不同的槽
位中,每个集群的节点保存一部分的槽。
每个key存储时,先经过哈希函数CRC16(key)得到一个整数,然后整数与16384取余,得到槽的数值,然后找到对应的节点,将数据存放入对应的槽中。
每次客户端访问集群不一定能一次搜索到所需的数据,例如访问node1时没有所需数据,但node1或返回信息告诉你所需数据在哪个节点.所以搜索数据保证了最多两次就能搜到所需数据,着这样的功能是通过集群通信实现的

集群的可以实现扩缩容但需要涉及的到槽位的迁移,因为槽位数量16384是固定的,新增成员或减少成员都必然涉及槽位的再分配及数据迁移

集群同样具备了故障转移的功能,类似于哨兵的机制,在主节点客观下线后,就开始让对应的从节点上线了.与哨兵机制不同的点在于,集群的从节点,无法像哨兵机制里的从节点一样分担读的压力,集群从节点是不可读的

Redis 集群如何避免脑裂

基数的主节点数量,每个主节点都配置从节点
例如3+3,5+5,7+7.....

Redis 集群最少几个节点为什么?

最少6个节点,三主三从

Redis的集群槽位多少个

16384

Redis集群中某个节点缺少一个槽位是否能使用

集群可以使用,但是会导致有些key无法使用因为他找不到对应的槽位,但如果不使用那部分key那就不影响数据的存储,因为数据分配槽位与具体的value无关与key有关

Redis数据写入的时候是怎么在各个节点槽位分配数据的

每个key存储时,先经过哈希函数CRC16(key)得到一个整数,然后整数与16384取余,得到槽的数值,然后找到对应的节点,将数据存放入对应的槽中

Redis的数据存储是以什么样的方式存储

redis是数据是存在内存中的,但也可以通过持久化的方式保存在磁盘中

Redis集群的各槽位和总槽位之间什么关系

k8s

网络原理

pod内的容器间通信通过localhost
pod间通信,在同一node市通过docker0
在不同node时通过网络插件给他们分配唯一的IP地址,由ectd记录具体的IP分配,再通过物理网卡通信(overlay)