以下内容由网络收集整理,部分内容不是我整理的,红色重中之重。

一,TCP/IP

简述TCP三次握手的过程?
       在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认。第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态。第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。完成三次握手,客户端与服务器开始传送数据简版:首先A向B发SYN(同步请求),然后B回复SYN+ACK(同步请求应答),最后A回复ACK确认,这样TCP的一次连接(三次握手)的过程就建立了。

为什么连接的时候是三次握手,关闭的时候却是四次握手?
这是因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。
但是关闭连接时,当Client端发送FIN报文仅仅表示它不再发送数据了但是还能接收数据,Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
在这里插入图片描述
在这里插入图片描述

二,HTTP

HTTP–Hyper Text Transfer Protocol,超文本传输协议,是一种建立在TCP上的无状态连接,整个基本的工作流程是客户端发送一个HTTP请求,说明客户端想要访问的资源和请求的动作,服务端收到请求之后,服务端开始处理请求,并根据请求做出相应的动作访问服务器资源,最后通过发送HTTP响应把结果返回给客户端。其中一个请求的开始到一个响应的结束称为事务,当一个事物结束后还会在服务端添加一条日志条目。

2.1 HTTP请求

       HTTP请求是客户端往服务端发送请求动作,告知服务器自己的要求。
       HTTP请求由状态行、请求头、请求正文三部分组成:
状态行:包括请求方式Method、资源路径URL、协议版本Version;
请求头:包括一些访问的域名、用户代理、Cookie等信息;
请求正文:就是HTTP请求的数据。
注:请求方式Method一般有GET、POST、PUT、DELETE,含义分别是获取、修改、上传、删除,其中GET方式仅仅为获取服务器资源,方式较为简单,因此在请求方式为GET的HTTP请求数据中,请求正文部分可以省略,直接将想要获取的资源添加到URL中。下图所示就是GET的请求,没有请求正文。详细的说明在下边。

现在大多数协议版本为http/1.1
在这里插入图片描述下图所示为POST请求的格式,有状态行、请求头、请求正文三部分。
在这里插入图片描述

2.2 HTTP响应

响应数据格式
       服务器收到了客户端发来的HTTP请求后,根据       HTTP请求中的动作要求,服务端做出具体的动作,将结果回应给客户端,称为HTTP响应。
       HTTP响应由三部分组成:状态行、响应头、响应正文;
状态行:包括协议版本Version、状态码Status Code、回应短语;
响应头:包括搭建服务器的软件,发送响应的时间,回应数据的格式等信息;
响应正文:就是响应的具体数据。
       注:我们主要关心并且能够在客户端浏览器看得到的是三位数的状态码,不同的状态码代表不同的含义,其中

1XX表示HTTP请求已经接受,继续处理请求
2XX表示HTTP请求已经处理完成
3XX表示把请求访问的URL重定向到其他目录
4XX表示客户端出现错误
5XX表示服务端出现错误

具体HTTP响应实例如下图:在这里插入图片描述
常见状态码

状态码含义
200请求已经正常处理完毕
301请求永久重定向
302请求临时重定向
304请求被重定向到客户端本地缓存
400客户端请求存在语法错误
401客户端请求没有经过授权
403客户端的请求被服务器拒绝,一般为客户端没有访问权限
404客户端请求的URL在服务端不存在
500服务端永久错误
503服务端发生临时错误

HTTP响应模型
       服务器收到HTTP请求之后,会有多种方法响应这个请求,下面是HTTP响应的四种模型:
       单进程I/O模型
服务端开启一个进程,一个进程仅能处理一个请求,并且对请求顺序处理;
       多进程I/O模型
服务端并行开启多个进程,同样的一个进程只能处理一个请求,这样服务端就可以同时处理多个请求;
       复用I/O模型
服务端开启一个进程,但是呢,同时开启多个线程,一个线程响应一个请求,同样可以达到同时处理多个请求,线程间并发执行;
       复用多线程I/O模型
服务端并行开启多个进程,同时每个进程开启多个线程,这样服务端可以同时处理进程数M*每个进程的线程数N个请求。

2.3 HTTP报文格式

       HTTP报文是HTTP应用程序之间传输的数据块,HTTP报文分为HTTP请求报文和HTTP响应报文,但是无论哪种报文,他的整体格式是类似的,大致都是由起始、首部、主体三部分组成,起始说明报文的动作,首部说明报文的属性,主体则是报文的数据。接下来具体说明。

HTTP请求报文
在这里插入图片描述 请求报文的起始由请求行构成(有些资料称为状态行,名字不一样而已,都是指的一个东西),用来说明该请求想要做什么,由、、 三个字段组成,注意每个字段之间都有一个空格。
其中字段有不同的值:
       GET — 访问服务器的资源

       POST — 向服务器发送要修改的数据

       HEAD — 获取服务器文档的首部

       PUT — 向服务器上传资源

       DELETE— 删除服务器的资源

URL 字段表示服务器的资源目录定位
Version 字段表示使用的http协议版本
首部部分由多个请求头(也叫首部行)构成,那些首部字段名有如下,不全:
       Accept 指定客户端能够接收的内容格式类型
       Accept-Language 指定客户端能够接受的语言类型
       Accept-Ecoding 指定客户端能够接受的编码类型
       User-Agent 用户代理,向服务器说明自己的操作系统、浏览器等信息
       Connection 是否开启持久连接(keepalive)
        Host 服务器域名
主体部分就是报文的具体数据。

HTTP响应报文
在这里插入图片描述       响应报文的起始由状态行构成,用来说明服务器做了什么,由、、Phrase三个字段组成,同样的每个字段之间留有空格;
       Status-Code 上边已经说明;
       首部由多个响应头(也叫首部行)组成, 首部字段名如下,不全:
       Server 服务器软件名,Apache/Nginx
       Date 服务器发出响应报文的时间
       Last-Modified 请求资源的最后的修改时间
       主体部分是响应报文的具体数据。

2.4 HTTP协议版本更换

HTTP/0.9
       HTTP协议的最初版本,功能简陋,仅支持请求方式GET,并且仅能请求访问HTML格式的资源。
HTTP/1.0
       在0.9版本上做了进步,增加了请求方式POST和HEAD;不再局限于0.9版本的HTML格式,根据Content-Type可以支持多种数据格式,即MIME多用途互联网邮件扩展,例如text/html、image/jpeg等;同时也开始支持cache,就是当客户端在规定时间内访问统一网站,直接访问cache即可。
       但是1.0版本的工作方式是每次TCP连接只能发送一个请求,当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持keepalive。
HTTP/1.1
       解决了1.0版本的keepalive问题,1.1版本加入了持久连接,一个TCP连接可以允许多个HTTP请求; 加入了管道机制,一个TCP连接同时允许多个请求同时发送,增加了并发性;新增了请求方式PUT、PATCH、DELETE等。
       但是还存在一些问题,服务端是按队列顺序处理请求的,假如一个请求处理时间很长,则会导致后边的请求无法处理,这样就造成了队头阻塞的问题;同时HTTP是无状态的连接,因此每次请求都需要添加重复的字段,降低了带宽的利用率。
HTTP/2.0
       为了解决1.1版本利用率不高的问题,提出了HTTP/2.0版本。增加双工模式,即不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求,解决了队头堵塞的问题;HTTP请求和响应中,状态行和请求/响应头都是些信息字段,并没有真正的数据,因此在2.0版本中将所有的信息字段建立一张表,为表中的每个字段建立索引,客户端和服务端共同使用这个表,他们之间就以索引号来表示信息字段,这样就避免了1.0旧版本的重复繁琐的字段,并以压缩的方式传输,提高利用率。
       另外也增加服务器推送的功能,即不经请求服务端主动向客户端发送数据。
当前主流的协议版本还是HTTP/1.1版本。

2.5 HTTP网站访问量

       IP IP访问量
相同的公网IP计算一次,就是同一个局域网内的所有用户访问一个网站,但是他们都是借助一个公网IP去访问那个网站的(NAT),因此这也只能算作一个IP访问量。换一次公网IP则会加1。
        PV 网页访问量
用户访问的页面数就是PV访问量,同一个局域网的不同用户,而且就算是同一个用户,只要刷新一次网站页面,PV访问量就加1,三个访问量的值往往数PV的值最大。
       UV 访客访问量
这里的访客不是用户,而是电脑,一台电脑算一个访客,即使是同一台电脑的不同用户,访问同一个网站UV也只能加1,只有更换电脑才会使UV加1,因为服务端会记录客户端电脑的信息。

三,SHELL

为你的面试准备选择了 70 个你可能遇到的 shell 脚本面试问题及解答。了解脚本或至少知道基础知识对系统管理员来说至关重要,它也有助于你在工作环境中自动完成很多任务。在过去的几年里,我们注意到所有的 linux 工作职位都要求脚本技能。

  1. 如何向脚本传递参数 ?
./script argument
	
	例子: 显示文件名称脚本
	
	./show.sh file1.txt
	cat show.sh
	#!/bin/bash
	echo $1
	(LCTT 译注:谢谢某匿名访客的提醒,原题有误,修改之。)
  1. 如何在脚本中使用参数 ?
第一个参数 : $1,第二个参数 : $2
例子 : 脚本会复制文件(arg1) 到目标地址(arg2)
 
./copy.sh file1.txt /tmp/
cat copy.sh
#!/bin/bash
cp $1 $2
  1. 如何计算传递进来的参数 ?
    $#

  2. 如何在脚本中获取脚本名称 ?
    $0

  3. 如何检查之前的命令是否运行成功 ?
    $?

  4. 如何获取文件的最后一行 ?
    tail-1

  5. 如何获取文件的第一行 ?
    head-1

  6. 如何获取一个文件每一行的第三个元素 ?
    awk'{print $3}'

  7. 假如文件中每行第一个元素是 FIND,如何获取第二个元素
    awk'{ if ($1 == "FIND") print $2}'

  8. 如何调试 bash 脚本

将 -xv 参数加到 #!/bin/bash 后
例子:
#!/bin/bash –xv
  1. 举例如何写一个函数 ?
function example {
echo "Hello world!"
}
  1. 如何向连接两个字符串 ?
V1="Hello"
V2="World"
V3=${V1}${V2}
echo $V3

输出HelloWorld

  1. 如何进行两个整数相加 ?
V1=1
V2=2
let V3=$V1+$V2
echo $V3

输出3

据 @kashu 的意见,本题的更佳回答为:
两个整数相加,还有若干种方法实现:

A=5
B=6
echo $(($A+$B)) # 方法 2
echo $[$A+$B]  # 方法 3
expr $A + $B   # 方法 4
echo $A+$B | bc # 方法 5
awk 'BEGIN{print '"$A"'+'"$B"'}'  # 方法 6
  1. 如何检查文件系统中是否存在某个文件 ?
if [ -f /var/log/messages ]
then
echo "File exists"
fi
  1. 写出 shell 脚本中所有循环语法 ?
    for 循环 :
foriin$(ls);do
echo item:$i
done

while 循环 :

#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 10 ]; do
echo The counter is $COUNTER
let COUNTER=COUNTER+1
done

until 循环 :

#!/bin/bash
COUNTER=20
until [ $COUNTER -lt 10 ]; do
echo COUNTER $COUNTER
let COUNTER-=1
done
  1. 每个脚本开始的 #!/bin/sh 或 #!/bin/bash 表示什么意思 ?
    这一行说明要使用的 shell#!/bin/bash 表示脚本使用 /bin/bash。对于 python 脚本,就是
    #!/usr/bin/python
  2. 如何获取文本文件的第 10 行 ?
    head -10 file|tail -1
  3. bash 脚本文件的第一个符号是什么
    #
  4. 命令:[ -z “” ] && echo 0 || echo 1 的输出是什么
    0
  5. 命令 “export” 有什么用 ?
    使变量在子 shell 中可用。
  6. 如何在后台运行脚本 ?
    在脚本后面添加“&”
    据 @kashu 的意见,更好的答案是:
    nohup command&
    大部分时间我们可能是远程使用Linux,我碰到过由于网络断线使得在后台运行的command &没了…
  7. “chmod 500 script” 做什么 ?
使脚本所有者拥有可执行权限。
  1. “>” 做什么 ?
重定向输出流到文件或另一个流。
  1. & 和 && 有什么区别
& - 希望脚本在后台运行的时候使用它
&& - 当前一个脚本成功完成才执行后面的命令/脚本的时候使用它
  1. 什么时候要在 [ condition ] 之前使用 “if” ?
    当条件满足时需要运行多条命令的时候。
  2. 命令: name=John && echo ‘My name is $name’ 的输出是什么
    variable
  3. bash shell 脚本中哪个符号用于注释 ?
    #
  4. 命令: echo ${new:-variable} 的输出是什么
    variable
  5. ’ 和 " 引号有什么区别 ?
  • ' - 当我们不希望把变量转换为值的时候使用它。
  • "- 会计算所有变量的值并用值代替。
  1. 如何在脚本文件中重定向标准输出和标准错误流到 log.txt 文件 ?
    在脚本文件中添加"exec >log.txt 2>&1"命令。
  2. 如何只用 echo 命令获取字符串变量的一部分 ?
echo ${variable:x:y}
x - 起始位置
y - 长度
例子:
variable="My name is Petras, and I am developer."
echo ${variable:11:6} # 会显示 Petras
  1. 如果给定字符串 variable=“User:123:321:/home/dir”,如何只用 echo 命令获取 home_dir ?

echo ${variable#*:*:*:}echo ${variable##*:}

  1. 如何从上面的字符串中获取 “User” ?
    echo ${variable%:*:*:*}echo ${variable%%:*}
  2. 如何使用 awk 列出 UID 小于 100 的用户 ?
    awk -F: '$3<100' /etc/passwd
  3. 写程序为用户计算主组数目并显示次数和组名
cat /etc/passwd|cut -d: -f4|sort|uniq -c|while read c g
do
{ echo $c; grep :$g: /etc/group|cut -d: -f1;}|xargs -n 2
done
  1. 如何在 bash shell 中更改标准的域分隔符为 “:” ?
    IFS=":"
  2. 如何获取变量长度 ?
    ${#variable}
  3. 如何打印变量的最后 5 个字符 ?
    echo ${variable: -5}
  4. ${variable:-10} 和 v a r i a b l e : − 10 有 什 么 区 别 ? ‘ {variable: -10} 有什么区别? ` variable:10?{variable:-10} - 如果之前没有给 variable 赋值则输出 10;如果有赋值则输出该变量
    ${variable: -10} - 输出 variable 的最后 10 个字符`
  5. 如何只用 echo 命令替换字符串的一部分 ?
    echo ${variable//pattern/replacement}
  6. 哪个命令将命令替换为大写 ?
    tr '[:lower:]' '[:upper:]'
  7. 如何计算本地用户数目 ?
    wc -l /etc/passwd|cut -d" " -f1 或者 cat /etc/passwd|wc -l
  8. 不用 wc 命令如何计算字符串中的单词数目 ?
set ${string}
echo $#
  1. “export $variable” 或 “export variable” 哪个正确 ?
    export variable
  2. 如何列出第二个字母是 a 或 b 的文件 ?
    ls -d ?[ab]*
  3. 如何将整数 a 加到 b 并赋值给 c ?
    c=$((a+b))c=expr $a + $bc=echo "$a+$b"|bc
  4. 如何去除字符串中的所有空格 ?
    echo $string|tr -d " "
  5. 重写这个命令,将输出变量转换为复数: item=“car”; echo “I like $item” ?
    item="car"; echo "I like ${item}s"
  6. 写出输出数字 0 到 100 中 3 的倍数(0 3 6 9 …)的命令 ?
    for i in {0..100..3}; do echo $i; done

    for (( i=0; i<=100; i=i+3 )); do echo "Welcome $i times"; done
  7. 如何打印传递给脚本的所有参数 ?
    echo $*echo $@
  8. [ $a == $b ] 和 [ $a -eq $b ] 有什么区别
    [ $a == $b ] - 用于字符串比较
    [ $a -eq $b ] - 用于数字比较
  9. = 和 == 有什么区别
    = - 用于为变量赋值
    == - 用于字符串比较
  10. 写出测试 $a 是否大于 12 的命令 ?
    [ $a -gt 12 ]
  11. 写出测试 $b 是否小于等于 12 的命令 ?
    [ $b -le 12 ]
  12. 如何检查字符串是否以字母 “abc” 开头 ?
    [[ $string == abc* ]]
  13. [[ $string == abc* ]] 和 [[ $string == “abc*” ]] 有什么区别
    [[ $string == abc* ]] - 检查字符串是否以字母 abc 开头
    [[ $string == "abc" ]] - 检查字符串是否完全等于 abc
  14. 如何列出以 ab 或 xy 开头的用户名 ?
    egrep "^ab|^xy" /etc/passwd|cut -d: -f1
  15. bash 中 $! 表示什么意思 ?
    后台最近执行命令的 PID.
  16. $? 表示什么意思 ?
    前台最近命令的结束状态。
  17. 如何输出当前 shell 的 PID ?
    echo $$
  18. 如何获取传递给脚本的参数数目 ?
    echo $#
    (LCTT 译注:和第3题重复了。)
    62) $ @ 有 什 么 区 别 ∗ ‘ @ 有什么区别* ` @*- 以一个字符串形式输出所有传递到脚本的参数$@` - 以 $IFS 为分隔符列出所有传递到脚本中的参数
  19. 如何在 bash 中定义数组 ?
    array=("Hi" "my" "name" "is")
  20. 如何打印数组的第一个元素 ?
    echo ${array[0]}
  21. 如何打印数组的所有元素 ?
    echo ${array[@]}
  22. 如何输出所有数组索引 ?
    echo ${!array[@]}
  23. 如何移除数组中索引为 2 的元素 ?
    unset array[2]
  24. 如何在数组中添加 id 为 333 的元素 ?
    array[333]="New_element"
  25. shell 脚本如何获取输入的值 ?
    a) 通过参数
    ./script param1 param2
    b) 通过 read 命令
    read -p "Destination backup Server : " desthost
  26. 在脚本中如何使用 “expect” ?
/usr/bin/expect << EOD
spawn rsync -ar ${line} ${desthost}:${destpath}
expect "*?assword:*"
send "${password}\r"
expect eof
EOD

四,命令

top(了解top每一个字段意思)
grep,sed,awk

五,Apache

在这一节涵盖了25个有趣的Apache工作面试中会提出的问题,并附带有它们的答案,因此你可以方便的理解也许你之前从来没有见到过的一些有关于Apache的新事物.

在你开始阅读这篇文章之前,我们强烈建议你不要去死记硬背,万事首先都要尝试去放在实际场景中理解.
1. 什么是Apache web服务器?
答案:Apache web 服务器 HTTP 是一个非常流行、功能强大并且开源,用于管理web站点并向网络提供web文件服务. 它基于 HTTP 超文本传输协议运行, 这一协议提供了服务器和客户端web浏览器通信的标准. 它支持 SSL, CGI 文件, 虚拟主机还有许多其它的功能特性.

2. 如果检查 Apache 及其版本?
答案:首先,使用rpm命令来检查Apache是否已经安装. 如果已经安装好了,那就使用httpd -v 命令来检查它的版本.

[root@tecmint ~]# rpm -qa | grep httpd
httpd-devel-2.2.15-29.el6.centos.i686
httpd-2.2.15-29.el6.centos.i686
httpd-tools-2.2.15-29.el6.centos.i686

[root@tecmint ~]# httpd -v
Server version: Apache/2.2.15 (Unix)
Server built:   Aug 13 2013 17:27:11

3.Apache 以那个用户运行? 主配置文件的位置在哪里?.
答案: Apache 以“nobody”用户和httpd守护进程运行. Apache 主要的配置文件在: /etc/httpd/conf/httpd.conf (CentOS/RHEL/Fedora) 还有 /etc/apache2.conf (Ubuntu/Debian).

4.Apache 侦听 http 和 https 请求?
答案:Apache 默认在80端口侦听http,在443端口侦听https(需要SSL整数). 你也可以使用 netstat 命令 来检查端口.

[root@tecmint ~]# netstat -antp | grep http

tcp        0      0 :::80       :::*        LISTEN     1076/httpd          
tcp        0      0 :::443      :::*        LISTEN     1076/httpd

5. 如何在你的Linux机器上安装Apache服务器?
答案:很简单, 你可以使用任何诸如(RHEL/CentOS/Fedora)上的yum以及(Debian/Ubuntu)上的apt-get来在你的Linux上安装Apache服务器.

[root@tecmint ~]# yum install httpd
 
[root@tecmint ~]# apt-get install apache2

6. 你可以在哪里找到Apache Web服务器的所有配置路径?
答案:Apache默认的配置路径放在: (RHEL/CentOS/Fedora) 中是在 /etc/httpd/ on 而(Debian/Ubuntu) 是在/etc/apache2下 .

[root@tecmint ~]# cd /etc/httpd/
[root@tecmint httpd]# ls -l
total 8
drwxr-xr-x. 2 root root 4096 Dec 24 21:44 conf
drwxr-xr-x. 2 root root 4096 Dec 25 02:09 conf.d
lrwxrwxrwx  1 root root   19 Oct 13 19:06 logs -> ../../var/log/httpd
lrwxrwxrwx  1 root root   27 Oct 13 19:06 modules -> ../../usr/lib/httpd/modules
lrwxrwxrwx  1 root root   19 Oct 13 19:06 run -> ../../var/run/httpd
---------------------------------------------------------------------------
[root@tecmint ~]# cd /etc/apache2
[root@tecmint apache2]# ls -l
total 84
-rw-r--r-- 1 root root  7113 Jul 24 16:15 apache2.conf
drwxr-xr-x 2 root root  4096 Dec 16 11:48 conf-available
drwxr-xr-x 2 root root  4096 Dec 16 11:45 conf.d
drwxr-xr-x 2 root root  4096 Dec 16 11:48 conf-enabled
-rw-r--r-- 1 root root  1782 Jul 21 02:14 envvars
-rw-r--r-- 1 root root 31063 Jul 21 02:14 magic
drwxr-xr-x 2 root root 12288 Dec 16 11:48 mods-available
drwxr-xr-x 2 root root  4096 Dec 16 11:48 mods-enabled
-rw-r--r-- 1 root root   315 Jul 21 02:14 ports.conf
drwxr-xr-x 2 root root  4096 Dec 16 11:48 sites-available
drwxr-xr-x 2 root root  4096 Dec  6 00:04 sites-enabled	

7.Apache 可以被TCP封装器固定吗?
答案:不可以,它不可以被TCP封装器固定下来,因为它不支持Linux的libwrap.a库.

8.如何在Apache中改变默认的端口,以及如何侦听其中的指令工作?
答案:在httpd.conf文件中有一个指令“Listen”可以让我们改变默认的Apache端口. 在Listen 指令的帮助下我们可以在不同的端口还有不同的接口进行Apache侦听.

       假设你拥有多个IP注册到了你的Linux机器,并且想要Apache在一个特殊的以太网端口或接口接收HTTP请求, 即使是这种要求也可以用Listen指令做到.

       为了改变Apache的默认端口,请使用打开你的Apache主配置文件 httpd.conf 或者 apache2.conf .

[root@tecmint ~]# vi /etc/httpd/conf/httpd.conf
[root@tecmint ~]# vi /etc/apache2/apache2.conf

查找”Listen”这个单词, 注释原来的那一行并且在那一行下面写上你自己的指令.

# Listen 80
Listen 8080
OR
Listen 172.16.16.1:8080

保存文件并重启web服务器.

[root@tecmint ~]# service httpd restart

[root@tecmint ~]# service apache2 restart

9.我们可以一台机器上放两个Apache Web服务器么?
答案:可以,我们在一台Linux机器上同时运行两个不同的Apache服务器, 但条件是它们应该在不同的端口上侦听,而我们可以使用Apache的Listen指令来改变端口.

10. 你知道Apache的DocumentRoot是啥意思么?
答案:DocumentRoot 的 Apache 意思是服务器上web文件的存储位置, 默认的DocumentRoot是 /var/www/html 或者 /var/www. 这是可以被修改的,只要修改主机中的虚拟主机配置 “DocumentRoot”就行了.

11. 如何在不同的文件夹下面管理文件,还有什么是 Alias 指令?
答案:是的,这可以借助于主Apache配置文件中的Alias指令做到. Alias 指令可以对文件系统中的资源按图索骥, 它使用一个URL 路径,并且使用重定向到系统上的一个文件或目录来替换它.

       使用Alias指令,它是Apache的 mod_alias 模块的一部分. Alias指令的默认语法是:

Alias /images /var/data/images/

       上面的示例中, 放在/var/data/images 前缀前面的 /images url的意思是客户端请求“http://www.example.com/images/sample-image.png” 会让Apache从服务器上的/var/data/images/sample-image.png 取 “sample-image.png” 文件. 它也被称为URL 映射.
12. 对于“DirectoryIndex”你是怎么理解的?
答案:DirectoryIndex 是当有一个来自主机的请求时Apache首先会去查找的文件. 例如: 客户端发送请求www.example.com, Apache 对此将到站点的文件根目录查找index文件 (首先要展示的文件).
       DirectoryIndex 的默认设置是 .html index.html index.php, 如果不是这个名字, 你需要对 httpd.conf 或者 apache2.conf 中的 DirectoryIndex 值做出修改,以将其展示在你的客户端浏览器上.

#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
# The index.html.var file (a type-map) is used to deliver content-
# negotiated documents.  The MultiViews Option can be used for the
# same purpose, but it is much slower.
#
DirectoryIndex index.html index.html.var index.cgi .exe

13. 当index文件丢失时如何使目录列表失效?
答案: 如果站点根目录中的主index文件失效, 那么Apache将会在浏览器上列出所有内容类似的文件,以替换站点主页.

       为了关闭Apache目录列表, 你可以在主配置文件中全局的设置,或者在.htaccess文件中部分的设置如下规则.

<Directory /var/www/html>
   Options -Indexes
</Directory>

14.Apache Web 服务器有些什么不同的日志文件?
答案:Apache Web 服务器的默认日志文件是访问日志 “/var/log/httpd/access_log” 和错误日志:/var/log/httpd/error_log”.

15. 你是怎样理解错误日志中的“connection reset by peer”的?
答案:当服务器正在向请求提供服务时终端用户中断连接, 我们就会在错误日志中看到“connection reset by peer“.

16. 什么是Apache的虚拟主机?
答案:虚拟主机部分包含的信息包括站点名称,文档根路径,目录索引,服务器管理员邮箱,错误日志文件路径等等。

       你可以随意为你的域添加你需要的指令,但是要运行一个站点,至少要配置量个参数服务器名称和文档根目录。 在Linux机器上,通常我们在httpd.conf文件的末尾来设定我们的虚拟主机部分的相关配置。

虚拟主机示例

<VirtualHost *:80>
   ServerAdmin webmaster@dummy-host.example.com
   DocumentRoot /www/docs/dummy-host.example.com
   ServerName dummy-host.example.com
   ErrorLog logs/dummy-host.example.com-error_log
   CustomLog logs/dummy-host.example.com-access_log common
</VirtualHost>
  • ServerAdmin : 通常是指站点拥有者的电子邮箱,错误和通知可以发到里面。
  • DocumentRoot : web文件在服务器上存放位置(必须配置).
  • ServerName : 通过浏览器访问站点时的域名(必须配置).
  • ErrorLog : 日志文件的位置,里面记录了所有与该站点相关的日志。

17. 和之间有什么区别?
答案:

<Location> 是用来设定和URL/ web服务器的地址栏相关的元素的。
<Directory> 是指服务器上某对象在文件系统中的位置

18. 什么是Apache虚拟托管?
答案:Apache虚拟托管是指,在单个web服务器上托管多个web站点。Apache 可以设定两种类型的虚拟主机:基于名称的虚拟托管和基于IP的虚拟主机托管。

更多相关信息,请参阅 如何在Apache中创建基于Name/IP的虚拟主机。

19. 你怎么理解Apache的MPM?
答案: MPM意思是Multi Processing Modules,实际上是指Apache遵循的一些机制,用来接受和完成对web服务器的请求。

20. Worker 和 Prefork MPM之间的区别是什么?
答案:它们都是MPM, Worker 和 prefork 有它们各自在Apache上的运行机制. 它们完全依赖于你想要以哪一种模式启动你的Apache.

Worker 和 MPM基本的区别在于它们产生子进程的处理过程. 在Prefork MPM中, 一个主httpd进行被启动,这个主进程会管理所有其它子进程为客户端请求提供服务. 而在worker MPM中一个httpd进程被激活,则会使用不同的线程来为客户端请求提供服务.
Prefork MPM 使用多个子进程,每一个进程带有一个线程而 worker MPM 使用多个子进程,每一个进程带有多个线程.
Prefork MPM中的连接处理, 每一个进程一次处理一个连接而在Worker mpm中每一个线程一次处理一个连接.
内存占用 Prefork MPM 占用庞大的内存, 而Worker占用更小的内存.

21. “LimitRequestBody”的应用是什么,还有如何在你的上传中加入限制?
答案:LimitRequestBody 指令被用来在上传大小上做一个限制.
22. mod_perl 和 mod _php 是什么?
答案:

  • mod_perl 是一个随同Apache一起编译的Apache模块,用来做Perl脚本的简单集成并提升其性能.
  • mod_php 用来做web服务器PHP脚本的简单集成, 它在Apache进程中嵌入了PHP解释器. 它强制Apache子进程使用更多的内存,并且只能在Apache上使用,但是仍然很流行.

23. Mod_evasive是什么?
答案:它是一个保护你的web服务器不受像DDOS之类的web攻击的第三方模块,因为它一次只执行一个任务,所有执行得很不错.
更多信心,请阅读这篇文章, 它会指导你 如何在Apache中安装并配置mod_evasive.

24. httpd.conf文件中的Loglevel调试是什么?
答案: 在Loglevel Debug 选项的帮助下, 我们可以在错误日志中获取或者记录更多的信息,以帮助我们调试问题.

25. mod_ssl 有什么用以及SSL在Apache中如何工作?
答案:Mod_ssl 是一个Apache模块, 它使Apache可以在一个安全的加密环境中建立连接和传输数据。 使用SSL证书,所有的登录信息和其他重要的保密信息都会以加密的方式在Internet上进行传输,这会防止我们的数据被窃取或IP欺骗。

  • 怎样在Apache中使用SSL
  • 每当https请求到达,Apache都会执行以下三步:
  • Apache生成它的私钥并且将私钥转换为.CSR 文件 (证书签发请求).
  • 然后Apache发送 .csr 文件给 CA (证书管理中心).
  • CA 收到.csr 文件 并转换为 .crt (证书) 然后再发回给Apache 来完成https连接请求.

六,Tomcat

Tomcat是一个JSP/Servlet容器。其作为Servlet容器,有三种工作模式:独立的Servlet容器、进程内的Servlet容器和进程外的Servlet容器。

进入Tomcat的请求可以根据Tomcat的工作模式分为如下两类:

Tomcat作为应用程序服务器:请求来自于前端的web服务器,这可能是Apache, IIS, Nginx等;

Tomcat作为独立服务器:请求来自于web浏览器;

6.1Tomcat顶层架构

先上一张Tomcat的顶层结构图(图A),如下:
在这里插入图片描述Tomcat中最顶层的容器是Server,代表着整个服务器,从上图中可以看出,一个Server可以包含至少一个Service,用于具体提供服务。

Service主要包含两个部分:Connector和Container。从上图中可以看出 Tomcat 的心脏就是这两个组件,他们的作用如下:

1、Connector用于处理连接相关的事情,并提供Socket与Request和Response相关的转化;
2、Container用于封装和管理Servlet,以及具体处理Request请求;

一个Tomcat中只有一个Server,一个Server可以包含多个Service,一个Service只有一个Container,但是可以有多个Connectors,这是因为一个服务可以有多个连接,如同时提供Http和Https链接,也可以提供向相同协议不同端口的连接,示意图如下(Engine、Host、Context下边会说到):在这里插入图片描述多个 Connector 和一个 Container 就形成了一个 Service,有了 Service 就可以对外提供服务了,但是 Service 还要一个生存的环境,必须要有人能够给她生命、掌握其生死大权,那就非 Server 莫属了!所以整个 Tomcat 的生命周期由 Server 控制。

另外,上述的包含关系或者说是父子关系,都可以在tomcat的conf目录下的server.xml配置文件中看出,下图是删除了注释内容之后的一个完整的server.xml配置文件(Tomcat版本为8.0)

在这里插入图片描述详细的配置文件文件内容可以到Tomcat官网查看:http://tomcat.apache.org/tomcat-8.0-doc/index.html

上边的配置文件,还可以通过下边的一张结构图更清楚的理解:
在这里插入图片描述Server标签设置的端口号为8005,shutdown=”SHUTDOWN” ,表示在8005端口监听“SHUTDOWN”命令,如果接收到了就会关闭Tomcat。一个Server有一个Service,当然还可以进行配置,一个Service有多个,Service左边的内容都属于Container的,Service下边是Connector。

6.2Tomcat顶层架构小结:

  • 1)Tomcat中只有一个Server,一个Server可以有多个Service,一个Service可以有多个Connector和一个Container;
  • 2) Server掌管着整个Tomcat的生死大权;
  • 4)Service 是对外提供服务的;
  • 5)Connector用于接受请求并将请求封装成Request和Response来具体处理;
  • 6)Container用于封装和管理Servlet,以及具体处理request请求;

       知道了整个Tomcat顶层的分层架构和各个组件之间的关系以及作用,对于绝大多数的开发人员来说Server和Service对我们来说确实很远,而我们开发中绝大部分进行配置的内容是属于Connector和Container的,所以接下来介绍一下Connector和Container。

6.3Connector和Container的微妙关系

       由上述内容我们大致可以知道一个请求发送到Tomcat之后,首先经过Service然后会交给我们的Connector,Connector用于接收请求并将接收的请求封装为Request和Response来具体处理,Request和Response封装完之后再交由Container进行处理,Container处理完请求之后再返回给Connector,最后在由Connector通过Socket将处理的结果返回给客户端,这样整个请求的就处理完了!

       Connector最底层使用的是Socket来进行连接的,Request和Response是按照HTTP协议来封装的,所以Connector同时需要实现TCP/IP协议和HTTP协议!

       Tomcat既然处理请求,那么肯定需要先接收到这个请求,接收请求这个东西我们首先就需要看一下Connector!

6.4Connector架构分析

       Connector用于接受请求并将请求封装成Request和Response,然后交给Container进行处理,Container处理完之后在交给Connector返回给客户端。

因此,我们可以把Connector分为四个方面进行理解:

(1)Connector如何接受请求的?
(2)如何将请求封装成Request和Response的?
(3)封装完之后的Request和Response如何交给Container进行处理的?
(4)Container处理完之后如何交给Connector并返回给客户端的?

首先看一下Connector的结构图(图B),如下所示:
在这里插入图片描述Connector就是使用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型,比如:Http11Protocol使用的是普通Socket来连接的,Http11NioProtocol使用的是NioSocket来连接的。

其中ProtocolHandler由包含了三个部件:Endpoint、Processor、Adapter。

(1)Endpoint用来处理底层Socket的网络连接,Processor用于将Endpoint接收到的Socket封装成Request,Adapter用于将Request交给Container进行具体的处理。

(2)Endpoint由于是处理底层的Socket网络连接,因此Endpoint是用来实现TCP/IP协议的,而Processor用来实现HTTP协议的,Adapter将请求适配到Servlet容器进行具体的处理。

(3)Endpoint的抽象实现AbstractEndpoint里面定义的Acceptor和AsyncTimeout两个内部类和一个Handler接口。Acceptor用于监听请求,AsyncTimeout用于检查异步Request的超时,Handler用于处理接收到的Socket,在内部调用Processor进行处理。

至此,我们应该很轻松的回答(1)(2)(3)的问题了,但是(4)还是不知道,那么我们就来看一下Container是如何进行处理的以及处理完之后是如何将处理完的结果返回给Connector的?

6.5 Container架构分析

Container用于封装和管理Servlet,以及具体处理Request请求,在Connector内部包含了4个子容器,结构图如下(图C):

在这里插入图片描述4个子容器的作用分别是:

(1)Engine:引擎,用来管理多个站点,一个Service最多只能有一个Engine;
(2)Host:代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点;
(3)Context:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件;
(4)Wrapper:每一Wrapper封装着一个Servlet;

下面找一个Tomcat的文件目录对照一下,如下图所示:在这里插入图片描述Context和Host的区别是Context表示一个应用,我们的Tomcat中默认的配置下webapps下的每一个文件夹目录都是一个Context,其中ROOT目录中存放着主应用,其他目录存放着子应用,而整个webapps就是一个Host站点。

我们访问应用Context的时候,如果是ROOT下的则直接使用域名就可以访问,例如:www.ledouit.com

看到这里我们知道Container是什么,但是还是不知道Container是如何进行处理的以及处理完之后是如何将处理完的结果返回给Connector的?别急!下边就开始探讨一下Container是如何进行处理的!

6.6 Container如何处理请求的

Container处理请求是使用Pipeline-Valve管道来处理的!(Valve是阀门之意)

Pipeline-Valve是责任链模式,责任链模式是指在一个请求处理的过程中有很多处理者依次对请求进行处理,每个处理者负责做自己相应的处理,处理完之后将处理后的请求返回,再让下一个处理着继续处理。
在这里插入图片描述但是!Pipeline-Valve使用的责任链模式和普通的责任链模式有些不同!区别主要有以下两点:

(1)每个Pipeline都有特定的Valve,而且是在管道的最后一个执行,这个Valve叫做BaseValve,BaseValve是不可删除的;

(2)在上层容器的管道的BaseValve中会调用下层容器的管道。

我们知道Container包含四个子容器,而这四个子容器对应的BaseValve分别在:StandardEngineValve、StandardHostValve、StandardContextValve、StandardWrapperValve。

Pipeline的处理流程图如下(图D): 在这里插入图片描述(1)Connector在接收到请求后会首先调用最顶层容器的Pipeline来处理,这里的最顶层容器的Pipeline就是EnginePipeline(Engine的管道);

(2)在Engine的管道中依次会执行EngineValve1、EngineValve2等等,最后会执行StandardEngineValve,在StandardEngineValve中会调用Host管道,然后再依次执行Host的HostValve1、HostValve2等,最后在执行StandardHostValve,然后再依次调用Context的管道和Wrapper的管道,最后执行到StandardWrapperValve。

(3)当执行到StandardWrapperValve的时候,会在StandardWrapperValve中创建FilterChain,并调用其doFilter方法来处理请求,这个FilterChain包含着我们配置的与请求相匹配的Filter和Servlet,其doFilter方法会依次调用所有的Filter的doFilter方法和Servlet的service方法,这样请求就得到了处理!

(4)当所有的Pipeline-Valve都执行完之后,并且处理完了具体的请求,这个时候就可以将返回的结果交给Connector了,Connector在通过Socket的方式将结果返回给客户端。

6.7 总结

至此,我们已经对Tomcat的整体架构有了大致的了解,从图A、B、C、D可以看出来每一个组件的基本要素和作用。我们在脑海里应该有一个大概的轮廓了!如果你面试的时候,让你简单的聊一下Tomcat,上面的内容你能脱口而出吗?当你能够脱口而出的时候,这位面试官一定会对你刮目相看的!

七,负载均衡

7.1负载均衡算法

Haproxy有8种负载均衡算法(balance),分别如下:

  • 1.balance roundrobin # 轮询,软负载均衡基本都具备这种算法
  • 2.balance static-rr # 根据权重,建议使用
  • 3.balance leastconn # 最少连接者先处理,建议使用
  • 4.balance source # 根据请求源IP,建议使用
  • 5.balance uri # 根据请求的URI
  • 6.balance url_param,# 根据请求的URl参数’balance url_param’ requires an URL parameter name
  • 7.balance hdr(name) # 根据HTTP请求头来锁定每一次HTTP请求
  • 8.balance rdp-cookie(name) # 根据据cookie(name)来锁定并哈希每一次TCP请求

会话保持

由于负载请求分发到不同服务器,可能导致Session会话不同步的问题,若想实现会话共享或保持,可采用如下3种方式:

1.用户IP 识别
haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx 的IP hash 指令)
配置指令:balance source

2.Cookie 识别
haproxy 将WEB服务端发送给客户端的cookie中插入(或添加加前缀)haproxy定义的后端的服务器COOKIE ID。

配置指令例举:cookie SESSION_COOKIE insert indirect nocache

用firebug可以观察到用户的请求头的cookie里 有类似” Cookie jsessionid=0bc588656ca05ecf7588c65f9be214f5; SESSION_COOKIE=app1” SESSION_COOKIE=app1就是haproxy添加的内容

3.Session 识别
haproxy 将后端服务器产生的session和后端服务器标识存在haproxy中的一张表里。客户端请求时先查询这张表。
配置指令例举:appsession JSESSIONID len 64 timeout 5h request-learn

7.2什么是负载均衡

负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据【均匀】分摊到多个操作单元上执行,负载均衡的关键在于【均匀】。
常见的负载均衡方案
在这里插入图片描述常见互联网分布式架构如上,分为客户端层、反向代理nginx层、站点层、服务层、数据层。可以看到,每一个下游都有多个上游调用,只需要做到,每一个上游都均匀访问每一个下游,就能实现“将请求/数据【均匀】分摊到多个操作单元上执行”。
在这里插入图片描述【客户端层】到【反向代理层】的负载均衡,是通过“DNS轮询”实现的:DNS-server对于一个域名配置了多个解析ip,每次DNS解析请求来访问DNS-server,会轮询返回这些ip,保证每个ip的解析概率是相同的。这些ip就是nginx的外网ip,以做到每台nginx的请求分配也是均衡的。
【反向代理层->站点层】的负载均衡
在这里插入图片描述
【反向代理层】到【站点层】的负载均衡,是通过“nginx”实现的。通过修改nginx.conf,可以实现多种负载均衡策略:
1.请求轮询: 和DNS轮询类似,请求依次路由到各个web-server
2.最少连接路由: 哪个web-server的连接少,路由到哪个web-server
3.ip哈希: 照访问用户的ip哈希值来路由web-server,只要用户的ip分布是均匀的,请求理论上也是均匀的,ip哈希均衡方法可以做到,同一个用户的请求固定落到同一台web-server上,此策略适合有状态服务,例如session(58沈剑备注:可以这么做,但强烈不建议这么做,站点层无状态是分布式架构设计的基本原则之一,session最好放到数据层存储)
在这里插入图片描述【站点层】到【服务层】的负载均衡,是通过“服务连接池”实现的。
上游连接池会建立与下游服务多个连接,每次请求会“随机”选取连接来访问下游服务。

7.3《数据层》的负载均衡

在数据量很大的情况下,由于数据层(db,cache)涉及数据的水平切分,所以数据层的负载均衡更为复杂一些,它分为“数据的均衡”,与“请求的均衡”。

数据的均衡是指: 水平切分后的每个服务(db,cache),数据量是差不多的。
请求的均衡是指: 水平切分后的每个服务(db,cache),请求量是差不多的。
业内常见的水平切分方式有这么几种:

一、按照range水平切分
在这里插入图片描述
每一个数据服务,存储一定范围的数据,上图为例:

user0服务,存储uid范围1-1kw

user1服务,存储uid范围1kw-2kw

这个方案的好处是:

(1)规则简单,service只需判断一下uid范围就能路由到对应的存储服务
(2)数据均衡性较好

(3)比较容易扩展,可以随时加一个uid[2kw,3kw]的数据服务

不足是:

(1)请求的负载不一定均衡,一般来说,新注册的用户会比老用户更活跃,大range的服务请求压力会更大

二、按照id哈希水平切分
在这里插入图片描述
每一个数据服务,存储某个key值hash后的部分数据,上图为例:

user0服务,存储偶数uid数据

user1服务,存储奇数uid数据

这个方案的好处是:
(1)规则简单,service只需对uid进行hash能路由到对应的存储服务
(2)数据均衡性较好
(3)请求均匀性较好
不足是:
(1)不容易扩展,扩展一个数据服务,hash方法改变时候,可能需要进行数据迁移

7.4 总结

负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据【均匀】分摊到多个操作单元上执行,负载均衡的关键在于【均匀】。
(1)【客户端层】到【反向代理层】的负载均衡,是通过“DNS轮询”实现的
(2)【反向代理层】到【站点层】的负载均衡,是通过“nginx”实现的
(3)【站点层】到【服务层】的负载均衡,是通过“服务连接池”实现的
(4)【数据层】的负载均衡,要考虑“数据的均衡”与“请求的均衡”两个点,常见的方式有“按照范围水平切分”与“hash水平切分”

八,Haproxy

简介

       HAproxy:HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的web服务器不被暴露到网络上。

特点
1)HAProxy 也是支持虚拟主机的。
2)HAProxy 的优点能够补充 Nginx 的一些缺点,比如支持 Session 的保持,Cookie的引导;同时支持通过获取指定的 url 来检测后端服务器的状态。
3)HAProxy 跟 LVS 类似,本身就只是一款负载均衡软件;单纯从效率上来讲HAProxy 会比 Nginx 有更出色的负载均衡速度,在并发处理上也是优于 Nginx 的。
4)HAProxy 支持 TCP 协议的负载均衡转发,可以对 MySQL 读进行负载均衡,对后端的 MySQL 节点进行检测和负载均衡,大家可以用 LVS+Keepalived 对 MySQL主从做负载均衡。

九,Keepalived

Keepalived:Keepalived是一个保证集群高可用的服务软件,用来防止单点故障,使用VRRP协议实现。在master和backup之间通过master主动降低自己的权值或者backup检测到master出现故障时,backup将会接管master的工作,继续服务。

9.1 keeplived 工作原理

什么是Keepalived呢,keepalived观其名可知,保持存活,在网络里面就是保持在线了,也就是所谓的高可用或热备,用来防止单点故障(单点故障是指一旦某一点出现故障就会导致整个系统架构的不可用)的发生,Keepalived通过请求一个vip来达到请求真是IP地址的功能,而VIP能够在一台机器发生故障时候,自动漂移到另外一台机器上,从来达到了高可用HA功能

Keepalived工作在TCP/IP 参考模型的 三层、四层、五层,也就是分别为:网络层,传输层和应用层,根据TCP、IP参数模型隔层所能实现的功能,Keepalived运行机制如下:

在网络层:我们知道运行这4个重要的协议,互联网络IP协议,互联网络可控制报文协议ICMP、地址转换协议ARP、反向地址转换协议RARP,在网络层Keepalived在网络层采用最常见的工作方式是通过ICMP协议向服务器集群中的每一个节点发送一个ICMP数据包(有点类似与Ping的功能),如果某个节点没有返回响应数据包,那么认为该节点发生了故障,Keepalived将报告这个节点失效,并从服务器集群中剔除故障节点。

在传输层:提供了两个主要的协议:传输控制协议TCP和用户数据协议UDP,传输控制协议TCP可以提供可靠的数据输出服务、IP地址和端口,代表TCP的一个连接端,要获得TCP服务,需要在发送机的一个端口和接收机的一个端口上建立连接,而Keepalived在传输层里利用了TCP协议的端口连接和扫描技术来判断集群节点的端口是否正常,比如对于常见的WEB服务器80端口。或者SSH服务22端口,Keepalived一旦在传输层探测到这些端口号没有数据响应和数据返回,就认为这些端口发生异常,然后强制将这些端口所对应的节点从服务器集群中剔除掉。

在应用层:可以运行FTP,TELNET,SMTP,DNS等各种不同类型的高层协议,Keepalived的运行方式也更加全面化和复杂化,用户可以通过自定义Keepalived工作方式,例如:可以通过编写程序或者脚本来运行Keepalived,而Keepalived将根据用户的设定参数检测各种程序或者服务是否允许正常,如果Keepalived的检测结果和用户设定的不一致时,Keepalived将把对应的服务器从服务器集群中剔除

9.2 keeplived 有哪些模块

keepalived主要有三个模块,分别是core、check和vrrp

9.3解释一下vrrp 协议

虚拟路由冗余协议,可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的vip(该路由器所在局域网内其他机器的默认路由为该vip),master会发组播,当backup收不到vrrp包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master。这样的话就可以保证路由器的高可用了。

9.4keepalived作用

keepalived长和lvs搭配使用,进行负载均衡。

十,MySQL面试题

主从、主主、性能调优、数据备份恢复

详述MySQL主从复制原理及配置主从的完整步骤

主从复制的原理如下:
主库开启binlog功能并授权从库连接主库,从库通过change master得到主库的相关同步信息,然后连接主库进行验证,主库IO线程根据从库slave线程的请求,从master.info开始记录的位置点向下开始取信息,同时把取到的位置点和最新的位置与binlog信息一同发给从库IO线程,从库将相关的sql语句存放在relay-log里面,最终从库的sql线程将relay-log里的sql语句应用到从库上,至此整个同步过程完成,之后将是无限重复上述过程

完整步骤如下:

   1、主库开启binlog功能,并进行全备,将全备文件推送到从库服务器上
   2、show master status\G 记录下当前的位置信息及二进制文件名
   3、登陆从库恢复全备文件
   4、执行change master to 语句
   5、执行start slave and show slave status\G

10.1 基础笔试命令考察

1.开启MySQL服务

/etc/init.d/mysqld start
service mysqld start
systemctl start mysqld

2.检测端口是否运行

lsof -i :3306
netstat -lntup |grep 3306

3.为MySQL设置密码或者修改密码

设置密码
mysql -uroot -ppassword -e “set passowrd for root = passowrd(‘passowrd’)”
mysqladmin -uroot passowrd “NEWPASSWORD”

更改密码
mysqladmin -uroot passowrd oldpassowrd “NEWPASSWORD”
use mysql;
update user set passowrd = PASSWORD(‘newpassword’) where user = ‘root’;flush privileges;
msyql 5.7以上版本修改默认密码命令
alter user ‘root’@‘localhost’ identified by ‘root’

4.登陆MySQL数据库

mysql -uroot -ppassword

5.查看当前数据库的字符集

show create database DB_NAME;

6.查看当前数据库版本

mysql -V
mysql -uroot -ppassowrd -e “use mysql;select version();”

7.查看当前登录的用户

select user();

8.创建GBK字符集的数据库mingongge,并查看已建库完整语句

create database mingongge DEFAULT CHARSET GBK COLLATE gbk_chinese_ci;

9.创建用户mingongge,使之可以管理数据库mingongge

grant all on mingongge.* to ‘mingongge’@‘localhost’ identified by ‘mingongge’;

10.查看创建的用户mingongge拥有哪些权限

show grants for mingongge@localhost

11.查看当前数据库里有哪些用户

select user from mysql.user;

12.进入mingongge数据库

use mingongge

13.创建一innodb GBK表test,字段id int(4)和name varchar(16)

create table test (
     id int(4),
     name varchar(16)
     )ENGINE=innodb DEFAULT CHARSET=gbk;

14.查看建表结构及表结构的SQL语句

desc test;
show create table test\G

15.插入一条数据“1,mingongge”

insert into test values(‘1’,‘mingongge’);

16.再批量插入2行数据 “2,民工哥”,“3,mingonggeedu”

insert into test values(‘2’,‘民工哥’),(‘3’,‘mingonggeedu’);

17.查询名字为mingongge的记录

select * from test where name = ‘mingongge’;

18.把数据id等于1的名字mingongge更改为mgg

update test set name = ‘mgg’ where id = ‘1’;

19.在字段name前插入age字段,类型tinyint(2)

alter table test add age tinyint(2) after id;

20.不退出数据库,完成备份mingongge数据库

system mysqldump -uroot -pMgg123.0. -B mingongge >/root/mingongge_bak.sql
/root/mingongge_bak.sql

21.删除test表中的所有数据,并查看

delete from test;
select * from test;

22.删除表test和mingongge数据库并查看

drop table test;
show tables;
drop database mingongge;
show databases;

23.不退出数据库恢复以上删除的数据

system mysql -uroot -pMgg123.0. </root/mingongge_bak.sql

24.把库表的GBK字符集修改为UTF8

alter database mingongge default character set utf8;

alter table test default character set utf8;

25.把id列设置为主键,在Name字段上创建普通索引

alter table test add primary key(id);

create index mggindex on test(name(16));

26.在字段name后插入手机号字段(shouji),类型char(11)

alter table test add shouji char(11);
#默认就是在最后一列后面插入新增列

27.所有字段上插入2条记录(自行设定数据)

insert into test values(‘4’,‘23’,‘li’,‘13700000001’),(‘5’,‘26’,‘zhao’,‘13710000001’);

28.在手机字段上对前8个字符创建普通索引

create index SJ on test(shouji(8));

29.查看创建的索引及索引类型等信息

show index from test;
show create table test\G

#下面的命令也可以查看索引类型

show keys from test\G

30.删除Name,shouji列的索引

drop index SJ on test;
drop index mggindex on test;

31.对Name列的前6个字符以及手机列的前8个字符组建联合索引

create index lianhe on test(name(6),shouji(8));

32.查询手机号以137开头的,名字为zhao的记录(提前插入)

select * from test where shouji like ‘137%’ and name = ‘zhao’;

33.查询上述语句的执行计划(是否使用联合索引等)

explain select * from test where name = ‘zhao’ and shouji like ‘137%’\G

34.把test表的引擎改成MyISAM

alter table test engine=MyISAM;

35.收回mingongge用户的select权限

revoke select on mingongge.* from mingongge@localhost;

36.删除mingongge用户

drop user migongge@localhost;

37.删除mingongge数据库

drop database mingongge

38.使用mysqladmin关闭数据库

mysqladmin -uroot -pMgg123.0. shutdown
lsof -i :3306

39.MySQL密码丢了,请找回?

mysqld_safe --skip-grant-tables & #启动数据库服务

mysql -uroot -ppassowrd -e “use mysql;update user set passowrd = PASSWORD(‘newpassword’) where user = ‘root’;flush privileges;”

10.2MySQL运维基础知识面试问答题

面试题001:请解释关系型数据库概念及主要特点?
关系型数据库模型是把复杂的数据结构归结为简单的二元关系,对数据的操作都是建立一个或多个关系表格上,最大的特点就是二维的表格,通过SQL结构查询语句存取数据,保持数据一致性方面很强大

面试题002:请说出关系型数据库的典型产品、特点及应用场景?

1、mysql 互联网企业常用
2、oracle 大型传统企业应用软件
3、 如数据备份、复杂连接查询、一致性数据存储等,还是使用MySQL或者其他传统的关系型数据库最合适

面试题003:请解释非关系型数据库概念及主要特点?

非关系型数据库也被称为NoSQL数据库,数据存储不需有特有固定的表结构
特点:高性能、高并发、简单易安装

面试题004:请说出非关系型数据库的典型产品、特点及应用场景?

1、memcaced 纯内存
2、redis 持久化缓存
3、mongodb 面向文档

如果需要短时间响应的查询操作,没有良好模式定义的数据存储,或者模式更改频繁的数据存储还是用NoSQL

面试题005:请详细描述SQL语句分类及对应代表性关键字。

sql语句分类如下

DDL 数据定义语言,用来定义数据库对象:库、表、列
代表性关键字:create alter drop

DML 数据操作语言,用来定义数据库记录
代表性关键字:insert delete update

DCL 数据控制语言,用来定义访问权限和安全级别
代表性关键字:grant deny revoke

DQL 数据查询语言,用来查询记录数据
代表性关键字:select

面试题006:请详细描述char(4)和varchar(4)的差别

char长度是固定不可变的,varchar长度是可变的(在设定内)比如同样写入cn字符,char类型对应的长度是4(cn+两个空格),但varchar类型对应长度是2

面试题007:如何创建一个utf8字符集的数据库mingongge?

create database mingongge default character utf8 collate utf8_general_ci;

面试题008:如何授权mingongge用户从172.16.1.0/24访问数据库。

grant all on . to mingongge@‘172.16.1.0/24’ identified by ‘123456’;

面试题009:什么是MySQL多实例,如何配置MySQL多实例?

mysql多实例就是在同一台服务器上启用多个mysql服务,它们监听不同的端口,运行多个服务进程,它们相互独立,互不影响的对外提供服务,便于节约服务器资源与后期架构扩展

多实例的配置方法有两种:

1、一个实例一个配置文件,不同端口
2、同一配置文件(my.cnf)下配置不同实例,基于mysqld_multi工具

面试题010:如何加强MySQL安全,请给出可行的具体措施?

1、删除数据库不使用的默认用户
2、配置相应的权限(包括远程连接)
3、不可在命令行界面下输入数据库的密码
4、定期修改密码与加强密码的复杂度

面试题011:MySQL root密码忘了如何找回?

参考前面的回答

面试题012:delete和truncate删除数据的区别?

前者删除数据可以恢复,它是逐条删除速度慢
后者是物理删除,不可恢复,它是整体删除速度快

面试题013:MySQL Sleep线程过多如何解决?

1、可以杀掉sleep进程,kill PID
2、修改配置,重启服务

[mysqld]
wait_timeout = 600
interactive_timeout=30

#如果生产服务器不可随便重启可以使用下面的方法解决

set global wait_timeout=600
set global interactive_timeout=30;

面试题014:sort_buffer_size参数作用?如何在线修改生效?

在每个connection(session)第一次连接时需要使用到,来提访问性能
set global sort_buffer_size = 2M

面试题015:如何在线正确清理MySQL binlog?

MySQL中的binlog日志记录了数据中的数据变动,便于对数据的基于时间点和基于位置的恢复
但日志文件的大小会越来越大,点用大量的磁盘空间,因此需要定时清理一部分日志信息

手工删除:

首先查看主从库正在使用的binlog文件名称
show master(slave) status\G

删除之前一定要备份
purge master logs before’2017-09-01 00:00:00’;

#删除指定时间前的日志
purge master logs to’mysql-bin.000001’;

#删除指定的日志文件

自动删除:

通过设置binlog的过期时间让系统自动删除日志

show variables like ‘expire_logs_days’;
et global expire_logs_days = 30;

#查看过期时间与设置过期时间

面试题016:Binlog工作模式有哪些?各什么特点,企业如何选择?

1.Row(行模式);

日志中会记录成每一行数据被修改的形式,然后在slave端再对相同的数据进行修改

2.Statement(语句模式)

每一条修改的数据都会完整的记录到主库master的binlog里面,在slave上完整执行在master执行的sql语句

3.mixed(混合模式)

结合前面的两种模式,如果在工作中有使用函数 或者触发器等特殊功能需求的时候,使用混合模式
数据量达到比较高时候,它就会选择 statement模式,而不会选择Row Level行模式

面试题017:误操作执行了一个drop库SQL语句,如何完整恢复?

1、停止主从复制,在主库上执行锁表并刷新binlog操作,接着恢复之前的全备文件(比如0点的全备)

2、将0点时的binlog文件与全备到故障期间的binlog文件合并导出成sql语句
mysqlbinlog --no-defaults mysql-bin.000011 mysql-bin.000012 >bin.sql

3、将导出的sql语句中drop语句删除,恢复到数据库中
mysql -uroot -pmysql123 < bin.sql

面试题018:mysqldump备份使用了-A -B参数,如何实现恢复单表?

-A 此参数作用是备份所有数据库(相当于–all-databases)
-B databasename 备份指定数据(单库备份使用)

面试题019:详述MySQL主从复制原理及配置主从的完整步骤

主从复制的原理如下:

主库开启binlog功能并授权从库连接主库,从库通过change master得到主库的相关同步信息,然后连接主库进行验证,主库IO线程根据从库slave线程的请求,从master.info开始记录的位置点向下开始取信息,同时把取到的位置点和最新的位置与binlog信息一同发给从库IO线程,从库将相关的sql语句存放在relay-log里面,最终从库的sql线程将relay-log里的sql语句应用到从库上,至此整个同步过程完成,之后将是无限重复上述过程

完整步骤如下:

1、主库开启binlog功能,并进行全备,将全备文件推送到从库服务器上
2、show master status\G 记录下当前的位置信息及二进制文件名
3、登陆从库恢复全备文件
4、执行change master to 语句
5、执行start slave and show slave status\G

面试题020:如何开启从库的binlog功能?

修改配置文件加上下面的配置
log_bin=slave-bin
log_bin_index=slave-bin.index
需要重启服务生效

面试题021:MySQL如何实现双向互为主从复制,并说明应用场景?

双向同步主要应用于解决单一主库写的压力,具体配置如下

主库配置
[mysqld]
auto_increment_increment = 2 #起始ID
auto_increment_offset = 1 #ID自增间隔
log-slave-updates

从库配置
[mysqld]
auto_increment_increment = 2 #起始ID
auto_increment_offset = 2 #ID自增间隔
log-slave-updates

主从库服务器都需要重启mysql服务

面试题022:MySQL如何实现级联同步,并说明应用场景?

级联同步主要应用在从库需要做为其它数据库的主库
在需要做级联同步的数据库配置文件增加下面的配置即可

log_bin=slave-bin
log_bin_index=slave-bin.index

面试题023:MySQL主从复制故障如何解决?

登陆从库

1、执行stop slave;停止主从同步
2、然后set global sql_slave_skip_counter = 1;跳过一步错误
3、最后执行 start slave;并查看主从同步状态

需要重新进行主从同步操作步骤如下

进入主库
1、进行全备数据库并刷新binlog,查看主库此的状态
2、恢复全备文件到从库,然后执行change master
3、开启主从同步start slave;并查看主从同步状态

面试题024:如何监控主从复制是否故障?

mysql -uroot -ppassowrd -e “show slave status\G” |grep -E “Slave_IO_Running|Slave_SQL_Running”|awk ‘{print $2}’|grep -c Yes

通过判断Yes的个数来监控主从复制状态,正常情况等于2

面试题025:MySQL数据库如何实现读写分离?

1、通过开发程序实现
2、通过其它工具实现(如mysql-mmm)

面试题026:生产一主多从从库宕机,如何手工恢复?

1、执行stop slave 或者停止服务
2、修复好从库数据库
3、然后重新操作主库同步

面试题027:生产一主多从主库宕机,如何手工恢复?

1、登陆各个从库停止同步,并查看谁的数据最新,将它设置为新主库让其它从库同步其数据
2、修复好主库之后,生新操作主从同步的步骤就可以了

#需要注意的新的主库如果之前是只读,需要关闭此功能让其可写
#需要在新从库创建与之前主库相同的同步的用户与权限
#其它从库执行change master to master_port=新主库的端口,start slave

面试题028:工作中遇到过哪些数据库故障,请描述2个例子?

1、开发使用root用户在从库上写入数据造成主从数据不一致,并且前端没有展示需要修改的内容(仍旧是老数据)
2、内网测试环境服务器突然断电造成主从同步故障

面试题029:MySQL出现复制延迟有哪些原因?如何解决?

1、需要同步的从库数据太多
2、从库的硬件资源较差,需要提升
3、网络问题,需要提升网络带宽
4、主库的数据写入量较大,需要优配置和硬件资源
5、sql语句执行过长导致,需要优化

面试题030:给出企业生产大型MySQL集群架构可行备份方案?

1、双主多从,主从同步的架构,然后实行某个从库专业做为备份服务器
2、编写脚本实行分库分表进行备份,并加入定时任务
3、最终将备份服务推送至内网专业服务器,数据库服务器本地保留一周
4、备份服务器根据实际情况来保留备份数据(一般30天)

面试题031:什么是数据库事务,事务有哪些特性?企业如何选择?

数据库事务是指逻辑上的一组sql语句,组成这组操作的各个语句,执行时要么成功,要么失败
特点:具有原子性、隔离性、持久性、一致性

面试题032:请解释全备、增备、冷备、热备概念及企业实践经验?

全备:数据库所有数据的一次完整备份,也就是备份当前数据库的所有数据
增备:就在上次备份的基础上备份到现在所有新增的数据
冷备:停止服务的基础上进行备份操作
热备:实行在线进行备份操作,不影响数据库的正常运行

全备在企业中基本上是每周或天一次,其它时间是进行增量备份

热备使用的情况是有两台数据库在同时提供服务的情况,针对归档模式的数据库

冷备使用情况有企业初期,数据量不大且服务器数量不多,可能会执行某些库、表结构等重大操作时

面试题033:MySQL的SQL语句如何优化?

建立主键与增加索引

面试题034:企业生产MySQL集群架构如何设计备份方案?

1、集群架构可采用双主多从的模式,但实际双主只有一主在线提供服务,两台主之间做互备
2、另外的从可做读的负载均衡,然后将其中一台抽出专业做备份

面试题035:开发有一堆数据发给dba执行,DBA执行需注意什么?

1、需要注意语句是否有格式上的错误,执行会出错导致过程中断
2、还需要注意语句的执行时间是否过长,是否会对服务器负载产生压力影响实际生产

面试题036:如何调整生产线中MySQL数据库的字符集。

1、首先导出库的表结构 -d 只导出表结构,然后批量替换
2、导出库中的所有数据(在不产生新数据的前提下)
3、然后全局替换set names = xxxxx
4、删除原有库与表,并新创建出来,再导入建库与建表语句与所有数据

面试题037:请描述MySQL里中文数据乱码原理,如何防止乱码?

服务器系统、数据库、客户端三方字符集不一致导致,需要统一字符b

1、提升服务器硬件资源与网络带宽
2、优化mysql服务配置文件
3、开启慢查询日志然后分析问题所在

面试题039:MySQL高可用方案有哪些,各自特点,企业如何选择?

高可用方案有
1、主从架构
2、MySQL+MMM
3、MySQL+MHA
4、mysql+haproxy+drbd
5、mysql+proxy+amoeba

面试题040:如何批量更改数据库表的引擎?

通过mysqldump命令备份出一个sql文件,再使用sed命令替换
或者执行下面的脚本进行修改
#!/bin/sh
user=root
passwd=123456
cmd="mysql -u u s e r − p user -p userppasswd "
dump=“mysqldump -u u s e r − p user -p userppasswd”
for database in $cmd -e "show databases;"|sed '1,2d'|egrep -v "mysql|performance_schema"
do
for tables in dump -e "show tables from $databses;"|sed '1d'
do
$cmd “alter table d a t a b a s e . database. database.tables engine = MyISAm;”
done
done

面试题041:如何批量更改数据库字符集?

通过mysqldump命令备份出一个sql文件,再使用sed命令替换sed -i ‘s/GBK/UTF8/g’

面试题042:网站打开慢,请给出排查方法,如是数据库慢导致,如何排查并解决,请分析并举例?

1、可以使用top free 等命令分析系统性能等方面的问题
2、如是因为数据库的原因造成的,就需要查看慢查询日志去查找并分析问题所在

十四,Ansible、Jenkins

14.1 Ansible

14.2 Jenkins

1.jenkins是什么
Jenkins是一个开源的、可扩展的持续集成、交付、部署(软件/代码的编译、打包、部署)的基于web界面的平台。允许持续集成和持续交付项目,无论用的是什么平台,可以处理任何类型的构建或持续集成。

2.为什么使用jenkins
Jenkins是一种使用Java编程语言编写的开源持续集成软件工具,用于实时测试和报告较大代码库中的孤立更改。 Jenkins软件使开发人员能够快速找到并解决代码库中的缺陷,并自动进行构建测试。

3.CI/CD是什么
CI(Continuous integration,中文意思是持续集成)是一种软件开发时间。持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。

CD(Continuous Delivery, 中文意思持续交付)是在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境(类生产环境)中。比如,我们完成单元测试后,可以把代码部署到连接数据库的Staging环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境。

4.集中常见的CI工具
以下是前8种持续集成工具的列表:
Jenkins
TeamCity
Travis
CIGo
CDBamboo
GitLabCI
CircleCI
Codeship

5.什么是Jenkins pipeline
Pipeline,简而言之,就是一台运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排与可视化。
Jenkins Pipeline是一组插件,让Jenkins可以实现持续交付管道的落地和实施。

6.为什么在jenkins中使用管道
Pipeline在Jenkins上添加了一套强大的自动化工具,支持从简单的持续集成到全面的持续交付管道的用例。 通过对一系列相关任务进行建模,用户可以利用Pipeline的许多功能: 代码:流水线是用代码实现的,通常会检查到源代码管理中,从而使团队能够编辑,查看和迭代其交付流水线。耐用:管道可以在Jenkins主服务器的计划内和计划外重启中生存。可暂停:管道可以选择停止并等待人工输入或批准,然后再继续管道运行。多功能:管道支持复杂的现实世界中的连续交付需求,包括加入,循环和并行执行工作的能力。

7.什么是jenkinsfile?为什么使用jenkinsfile
Jenkinsfile是一个文本文件,其中包含Jenkins Pipeline的定义,并已签入源代码管理
虽然用于定义管道的脚本语法和jenkinsfile类似,但通常认为在项目中定义管道Jenkinsfile并检查源代码管理是最佳实践。

为所有分支和请求自动创建一个管道构建过程。
管道上的代码审查/迭代。
审核追踪管道

8.什么是Blue Ocean
Blue Ocean是pipeline的可视化UI。同时他兼容经典的自由模式的job。Jenkins Pipeline从头开始设计,但仍与自由式作业兼容,Blue Ocean减少了经典模式下的混乱并为团队中的每个成员增加了清晰度。Blue Ocean的主要特点包括:

连续交付(CD)管道的复杂可视化,可以让您快速直观地理解管道状态。
管道编辑器 - 通过引导用户通过直观和可视化的过程来创建管道,从而使管道的创建变得平易近人。
个性化以适应团队中每个成员的基于角色的需求。
在需要干预和/或出现问题时确定精确度。Blue Ocean显示的标注了关键步骤,促进异常处理和提高生产力。

9.如何在jenkins中备份和复制文件
创建备份,需要做的就是定期备份JENKINS_HOME目录。 这包含所有构建作业配置,从属节点配置以及构建历史记录。 要创建Jenkins设置的备份,只需复制此目录。

10.jenkins的优势是什么

Jenkins的优势包括:

在开发环境的早期阶段, 错误跟踪很容易。
提供大量的插件支持。
对代码的迭代改进。
构建失败会在集成阶段进行缓存。
对于每个代码提交更改, 都会生成一个自动生成报告通知。
为了将构建报告的成功或失败通知开发人员, 它与LDAP邮件服务器集成在一起。
实现持续集成的敏捷开发和测试驱动的开发。
通过简单的步骤, 即可自动完成maven发布项目。

11.Jenkins主要整合了两个组成部分?
Jenkins与以下两个组件集成在一起:
GIT, SVN等版本控制系统
并构建诸如Apache Maven之类的工具。

12.Jenkins中一些由用的插件
下面我将提到一些重要插件:
Maven 2 project
Amazon EC2
HTML publisher
Copy artifact
Join
Green Balls

十二,Docker

12.1 什么是容器

容器是对应用程序及其依赖关系的封装。

容器的优点

  • 容器与主机的操作系统共享资源,提高了效率,性能损耗低
  • 容器具有可移植性
  • 容器是轻量的,可同时运行数十个容器,模拟分布式系统
  • 不必花时间在配置和安装上,无需担心系统的改动,以及依赖关系是否满足

容器与虚拟机
运行在同一主机的3个虚拟机
在这里插入图片描述
运行在同一主机的3个容器
在这里插入图片描述
区别:
A.容器只能运行与主机一样的内核
B.程序库可以共用
C.容器中执行的进程与主机的进程等价(没有虚拟机管理程序的损耗)
D.隔离能力,虚拟机更高(将容器运行在虚拟机中)

容器与Docker
Docker利用现有的Linux容器技术,以不同方式将其封装及扩展(通过提供可移植的镜像及友好的接口),来创建及发布方案。

两部分:

  • 负责创建与运行容器的Docker引擎
  • 用来发布容器的云服务Docker Hub

12.2 Docker是个什么东西

Docker是PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。
Docker是通过内核虚拟化技术(namespace以及cgroups等)来提供容器的资源隔离与安全保障。由于Docker通过操作系统层的虚拟化实现隔离,所以
Docker容器在运行时,不需要类似虚拟机( VM)额外的操作系统开销,提高资源利用率。
Docker是一个程序运行、测试、交付的开放平台,Docker被设计为能够使你快速地交付应用。
在Docker中,你可以将你的程序分为不同的基础部分,对于每一个基础部分都可以当做一个应用程序来管理。
Docker能够帮助你快速地测试、快速地编码、快速地交付,并且缩短你从编码到运行应用的周期。
Docker使用轻量级的容器虚拟化平台,并且结合工作流和工具,来帮助你管理、部署你的应用程序。
Docker在其核心,Docker实现了让几乎任何程序都可以在一个安全、隔离的容器中运行。安全和隔离可以使你可以同时在机器上运行多个容器。
Docker容器轻量级的特性,意味着你可以得到更多的硬件性能。

围绕着Docker容器的虚拟化工具和平台,可以在以下几个方面为你提供帮助:
1)帮助你把应用程序(包括其余的支持组件)放入到Docker容器中。
2)分发和转移你的容器至你的团队其它成员来进行进一步的开发和测试。
3)部署这些应用程序至你的生产环境,不论是本地的数据中心还是云平台。

原理:建立–>传送–>运行
在这里插入图片描述

12.3 Docker架构

1.总架构
在这里插入图片描述主要模块:
DockerClient(与Daemon建立通信,发起容器的管理请求)
DockerDaemon(接收Client请求,处理请求)
Docker Regisrty(镜像管理)
Graph(存储镜像)
Drvier(镜像管理驱动)
libcontainer(系统内核特性,提供完整、明确的接口给Daemon)
Docker Container

2.各模块功能及实现
1)Docker Client
Docker架构中用户与Docker Daemon建立通信的客户端。
用户可以使用可执行文件docker作为Docker Client,发起Docker容器的管理请求。

三种方式建立通信:
tcp://host:port
unix://path_to_socket
fd://socketfd

Docker Client发送容器管理请求后,请求由Docker Daemon接收并处理,当Docker Client接收到返回的请求响应并做简单处理后,Docker Client一次完整的生命周期就结束了。

2)Docker Daemon
常驻在后台的系统进程。在这里插入图片描述主要作用:
接收并处理Docker Client发送的请求
管理所有的Docker容器

Docker Daemon运行时,会在后台启动一个Server,Server负责接收Docker Client发送的请求;接收请求后,Server通过路由与分发调度,找到相应的Handler来处理请求。

三部分组成:
A.Docker Server       专门服务于Docker Client,接收并调度分发Client请求。
在这里插入图片描述Server通过包gorilla/mux创建mux。Router路由器,提供请求的路由功能,每一个路由项由HTTP请求方法(PUT、POST、GET、DELETE)、URL和Handler组成。

每一个Client请求,Server均会创建一个全新的goroutine来服务,在goroutine中,Server首先读取请求内容,然后做请求解析工作,接着匹配相应的路由项,随后调用相应的Handler来处理,最后Handler处理完请求后给Client回复响应。

B.Engine
核心模块,运行引擎。
存储着大量容器信息,管理着Docker大部分Job的执行。

handlers对象:
存储众多特定Job各自的处理方法handler。
例如:
{“create”:daemon.ContainerCreate,}
当执行名为"create"的Job时,执行的是daemon.ContainerCreate这个handler。

C.Job
Engine内部最基本的执行单元,Daemon完成的每一项工作都体现为一个Job。

3)Docker Registry
存储容器镜像(Docker Image)的仓库。
Docker Image是容器创建时用来初始化容器rootfs的文件系统内容。

主要作用:

  • 搜索镜像
  • 下载镜像
  • 上传镜像

方式:

  • 公有Registry
  • 私有Registry

4)Graph
容器镜像的保管者。
在这里插入图片描述5)Driver
驱动模块,通过Driver驱动,Docker实现对Docker容器运行环境的定制,定制的维度包括网络、存储、执行方式。在这里插入图片描述
作用:
将与Docker容器有关的管理从Daemon的所有逻辑中区分开。

实现:
A.graphdriver
用于完成容器镜像管理。

初始化前的四种文件系统或类文件系统的驱动在Daemon中注册:
aufs、btrfs、devmapper用于容器镜像的管理
vfs用于容器volume的管理
在这里插入图片描述B.networkdriver
完成Docker容器网络环境的配置。 在这里插入图片描述C.execdriver
执行驱动,负责创建容器运行时的命名空间,负责容器资源使用的统计与限制,负责容器内部进程的真正运行等。
Daemon启动过程中加载ExecDriverflag参数在配置文件中默认设为native。

在这里插入图片描述
6)libcontainer
使用Go语言设计的库,不依靠任何依赖,直接访问内核中与容器相关的系统调用。
在这里插入图片描述

7)Docker Container
服务交付的最终体现。

用户对Docker容器的配置:

  • 通过指定容器镜像,使得Docker容器可以自定义rootfs等文件系统;
  • 通过指定物理资源的配额,使得Docker容器使用受限的资源;
  • 通过配置容器网络及其安全策略,使得Docker容器拥有独立且安全的网络环境;
  • 通过指定容器的运行命令,使得Docker容器执行指定的任务

12.4 Docker的用途

1)快速交付你的应用程序
Docker可以为你的开发过程提供完美的帮助。Docker允许开发者在本地包含了应用程序和服务的容器进行开发,之后可以集成到连续的一体化和部署工作流中。

举个例子,开发者们在本地编写代码并且使用Docker和同事分享其开发栈。当开发者们准备好了之后,他们可以将代码和开发栈推送到测试环境中,在该环境进行一切所需要的测试。从测试环境中,你可以将Docker镜像推送到服务器上进行部署。 

2)开发和拓展更加简单
Docker的以容器为基础的平台允许高度可移植的工作。Docker容器可以在开发者机器上运行,也可以在实体或者虚拟机上运行,也可以在云平台上运行。

Docker的可移植、轻量特性同样让动态地管理负载更加简单。你可以用Docker快速地增加应用规模或者关闭应用程序和服务。Docker的快速意味着变动几乎是实时的。
 
3)达到高密度和更多负载
Docker轻巧快速,它提供了一个可行的、符合成本效益的替代基于虚拟机管理程序的虚拟机。这在高密度的环境下尤其有用。例如,构建你自己的云平台或者PaaS,在中小的部署环境下同样可以获取到更多的资源性能。

12.5 Docker的主要组成

Docker有两个主要的部件:

  • Docker: 开源的容器虚拟化平台。
  • Docker Hub: 用于分享、管理Docker容器的Docker SaaS平台。

12.6 Docker的架构 C/S架构

  • Docker使用客户端-服务器(client-server)架构模式。
  • Docker 客户端会与Docker守护进程进行通信。Docker 守护进程会处理复杂繁重的任务,例如建立、运行、发布你的 Docker 容器。
  • Docker 客户端和守护进程可以运行在同一个系统上,当然也可以使用Docker客户端去连接一个远程* 的 Docker 守护进程。
  • Docker 客户端和守护进程之间通过socket或者RESTful API进行通信。
    在这里插入图片描述

1)Docker守护进程
如上图所示,Docker守护进程运行在一台主机上。用户并不直接和守护进程进行交互,而是通过 Docker 客户端间接和其通信。
2)Docker 客户端
Docker 客户端,实际上是 docker 的二进制程序,是主要的用户与 Docker 交互方式。它接收用户指令并且与背后的 Docker 守护进程通信,如此来回往复。
3)Docker 内部
要理解 Docker 内部构建,需要理解以下三种部件:
Docker 镜像 - Docker images
Docker 仓库 - Docker registeries
Docker 容器 - Docker containers

12.7 Docker的组件

  • Docker 镜像
    Docker 镜像是Docker容器运行时的只读模板,每一个镜像由一系列的层 (layers) 组成。Docker 使用 UnionFS 来将这些层联合到单独的镜像中。UnionFS 允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。正因为有了这些层的存在,Docker 是如此的轻量。当你改变了一个 Docker 镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新 的层被添加或升级了。现在你不用重新发布整个镜像,只需要升级,层使得分发 Docker 镜像变得简单和快速。
  • Docker 仓库
    Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。公有的 Docker 仓库名字是 Docker Hub。Docker Hub 提供了庞大的镜像集合供使用。这些镜像可以是自己创建,或者在别人的镜像基础上创建。Docker 仓库是 Docker 的分发部分。
  • Docker 容器
    Docker 容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台,Docker 容器是 Docker 的运行部分。

4)libcontainer
Docker 从 0.9 版本开始使用 libcontainer 替代 lxc,libcontainer 和 Linux 系统的交互图如下:
在这里插入图片描述
5)命名空间「Namespaces」

1)pid namespace
不同用户的进程就是通过pid namespace隔离开的,且不同 namespace 中可以有相同 PID。
具有以下特征:
每个namespace中的pid是有自己的pid=1的进程(类似 /sbin/init 进程)
每个 namespace 中的进程只能影响自己的同一个 namespace 或子 namespace 中的进程
因为 /proc 包含正在运行的进程,因此在 container 中的 pseudo-filesystem 的 /proc 目录只能看到自己namespace 中的进程
因为 namespace 允许嵌套,父 namespace 可以影响子 namespace 的进程,所以子 namespace 的进程可以在父namespace中看到,但是具有不同的 pid

2)mnt namespace
类似 chroot,将一个进程放到一个特定的目录执行。mnt namespace 允许不同namespace的进程看到的文件结构不同,这样每个namespace 中的进程所看到的文件目录就被隔离开了。同 chroot 不同,每个 namespace 中的 container 在 /proc/mounts 的信息只包含所在namespace的mount point。 

3)net namespace
网络隔离是通过 net namespace 实现的, 每个 net namespace 有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每个 container 的网络就能隔离开来。 docker 默认采用 veth 的方式将 container 中的虚拟网卡同 host 上的一个 docker bridge 连接在一起。

4)uts namespace
UTS ("UNIX Time-sharing System") namespace 允许每个 container 拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 Host 上的一个进程。

5)ipc namespace
container 中进程交互还是采用 Linux 常见的进程间交互方法 (interprocess communication - IPC), 包括常见的信号量、消息队列和共享内存。然而同 VM 不同,container 的进程间交互实际上还是 host 上具有相同 pid namespace 中的进程间交互,因此需要在IPC资源申请时加入 namespace 信息 - 每个 IPC 资源有一个唯一的 32bit ID。

6)user namespace
每个 container 可以有不同的 user 和 group id, 也就是说可以以 container 内部的用户在 container 内部执行程序而非 Host 上的用户。

有了以上6种namespace从进程、网络、IPC、文件系统、UTS 和用户角度的隔离,一个 container 就可以对外展现出一个独立计算机的能力,并且不同container从OS层面实现了隔离。然而不同 namespace 之间资源还是相互竞争的,仍然需要类似ulimit 来管理每个container所能使用的资源。

所以最好使用Centos7.X系列的镜像,因为user namespace支持的内核版本是3.8,而Centos6.X系列的镜像的内核版本是2.6.X
6)资源配额「cgroups」

cgroups
实现了对资源的配额和度量。 cgroups 的使用非常简单,提供类似文件的接口,在 /cgroup 目录下新建一个文件夹即可新建一个 group,在此文件夹中新建 task 文件,并将 pid 写入该文件,即可实现对该进程的资源控制。具体的资源配置选项可以在该文件夹中新建子 subsystem ,{子系统前缀}.{资源项} 是典型的配置方法, 如 memory.usageinbytes 就定义了该 group 在 subsystem memory 中的一个内存限制选项。
另外,cgroups 中的 subsystem 可以随意组合,一个 subsystem 可以在不同的 group 中,也可以一个 group 包含多个 subsystem - 也就是说一个 subsystem。

memory
内存相关的限制

cpu
在 cgroup 中,并不能像硬件虚拟化方案一样能够定义 CPU 能力,但是能够定义 CPU 轮转的优先级,因此具有较高 CPU 优先级的进程会更可能得到 CPU 运算。 通过将参数写入 cpu.shares ,即可定义改 cgroup 的 CPU 优先级 - 这里是一个相对权重,而非绝对值

 blkio
block IO 相关的统计和限制,byte/operation 统计和限制 (IOPS 等),读写速度限制等,但是这里主要统计的都是同步 IO

 devices
设备权限限制

12.8 Docker的工作原理

  • 1)可以建立一个容纳应用程序的容器。
  • 2)可以从Docker镜像创建Docker容器来运行应用程序。
  • 3)可以通过Docker Hub或者自己的Docker仓库分享Docker镜像。

12.9 Docker镜像是如何工作的?

  • Docker镜像是Docker容器运行时的只读模板,每一个镜像由一系列的层(layers)组成;

  • Docker使用UnionFS(联合文件系统)来将这些层联合到一二镜像中,UnionFS文件系统允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。

  • 正因为有了这些层(layers)的存在,Docker才会如此的轻量。当你改变了一个Docker镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新的层被添加或升级了。所以你不用重新发布整个镜像,只需要升级。层使得分发Docker镜像变得简单和快速。

  • 每个镜像都是从一个基础的镜像开始的,比如ubuntu,一个基础的Ubuntu镜像,或者是Centos,一个基础的Centos镜像。你可以使用你自己的镜像作为新镜像的基础,例如你有一个基础的安装了Nginx的镜像,你可以使用该镜像来建立你的Web应用程序镜像。(Docker通常从Docker Hub获取基础镜像)

Docker镜像从这些基础的镜像创建,通过一种简单、具有描述性的步骤,我们称之为 指令(instructions)。
每一个指令会在镜像中创建一个新的层,指令可以包含这些动作:

  • 1)运行一个命令。

  • 2)增加文件或者文件夹。

  • 3)创建一个环境变量。

  • 4)当运行容器的时候哪些程序会运行。

  • 这些指令存储在Dockerfile文件中。当你需要建立镜像的时候,Docker可以从Dockerfile中读取这些指令并且运行,然后返回一个最终的镜像。

12.10 Docker仓库是如何工作的?

Docker仓库是Docker镜像的存储仓库。可以推送镜像到Docker仓库中,然后在Docker客户端,可以从Docker仓库中搜索镜像。

12.11 Docker容器是如何工作的?

一个Docker容器包含了一个操作系统、用户添加的文件和元数据(meta-data)。每个容器都是从镜像建立的,镜像告诉Docker容器内包含了什么,当容器启动时运行什么程序,还有许多配置数据。

Docker镜像是只读的,当Docker运行一个从镜像建立的容器,它会在镜像顶部添加一个可读写的层,应用程序可以在这里运行。

12.12 当运行docker容器时发生了什么?

使用docker命令时,Docker客户端都告诉Docker守护进程运行一个容器。

 docker run -i -t ubuntu /bin/bash
可以来分析这个命令,Docker客户端使用docker命令来运行,run参数表明客户端要运行一个新的容器。
Docker客户端要运行一个容器需要告诉Docker守护进程的最小参数信息是:
1)这个容器从哪个镜像创建,这里是ubuntu,基础的Ubuntu镜像。
2)在容器中要运行的命令,这里是/bin/bash,在容器中运行Bash shell。

那么运行这个命令之后在底层发生了什么呢?

按照顺序,Docker做了这些事情:
1)拉取ubuntu镜像: Docker检查ubuntu镜像是否存在,如果在本地没有该镜像,Docker会从Docker Hub下载。如果镜像已经存在,Docker会使用它来创建新的容器。
2)创建新的容器: 当Docker有了这个镜像之后,Docker会用它来创建一个新的容器。
3)分配文件系统并且挂载一个可读写的层: 容器会在这个文件系统中创建,并且一个可读写的层被添加到镜像中。
4)分配网络/桥接接口: 创建一个允许容器与本地主机通信的网络接口。
5)设置一个IP地址: 从池中寻找一个可用的IP地址并且服加到容器上。
6)运行你指定的程序: 运行指定的程序。
7)捕获并且提供应用输出: 连接并且记录标准输出、输入和错误让你可以看到你的程序是如何运行的。

由此你就可以拥有一个运行着的Docker容器了!从这里开始你可以管理你的容器,与应用交互,应用完成之后,可以停止或者删除你的容器。

12.13 Docker的底层技术

Docker使用Go语言编写,并且使用了一系列Linux内核提供的性能来实现我们已经看到的这些功能。

命名空间(Namespaces)(这个上面也详细说明了)
Docker充分利用了一项称为namespaces的技术来提供隔离的工作空间,我们称之为 container(容器)。当你运行一个容器的时候,Docker为该容器创建了一个命名空间集合。
这样提供了一个隔离层,每一个应用在它们自己的命名空间中运行而且不会访问到命名空间之外。
一些Docker使用到的命名空间有:
pid命名空间: 使用在进程隔离(PID: Process ID)。
net命名空间: 使用在管理网络接口(NET: Networking)。
ipc命名空间: 使用在管理进程间通信资源 (IPC: InterProcess Communication)。
mnt命名空间: 使用在管理挂载点 (MNT: Mount)。
uts命名空间: 使用在隔离内核和版本标识 (UTS: Unix Timesharing System)。

群组控制
Docker还使用到了cgroups技术来管理群组。使应用隔离运行的关键是让它们只使用你想要的资源。这样可以确保在机器上运行的容器都是良民(good multi-tenant citizens)。群组控制允许Docker分享或者限制容器使用硬件资源。例如,限制指定的容器的内容使用。

联合文件系统
联合文件系统(UnionFS)是用来操作创建层的,使它们轻巧快速。Docker使用UnionFS提供容器的构造块。Docker可以使用很多种类的UnionFS包括AUFS, btrfs, vfs, and DeviceMapper。

容器格式
Docker连接这些组建到一个包装中,称为一个 container format(容器格式)。默认的容器格式是libcontainer。Docker同样支持传统的Linux容器使用LXC。在未来,Docker也许会支持其它的容器格式,例如与BSD Jails 或 Solaris Zone集成。

12.14 Docker与VM的区别:

在这里插入图片描述

12.15 docker与Openstack的对比

在这里插入图片描述

12.16 Docker与虚拟机比较

作为一种轻量级的虚拟化方式,Docker在运行应用上跟传统的虚拟机方式相比具有显著优势:

Docker容器很快,启动和停止可以在秒级实现,这相比传统的虚拟机方式要快得多。

Docker容器对系统资源需求很少,一台主机上可以同时运行数千个Docker容器。

Docker通过类似Git的操作来方便用户获取、分发和更新应用镜像,指令简明,学习成本较低。

Docker通过Dockerfile配置文件来支持灵活的自动化创建和部署机制,提高工作效率。
在这里插入图片描述虚拟机实现了硬件上的虚拟,而Docker则实现了操作系统级别的虚拟。

12.17 Docker用途:

简单配置、代码流水线管理、开发效率、应用隔离、服务器整合、调试能力、多租户、快速部署
在这里插入图片描述

十三,Zabbix

1.zabbix官方的一句话描述zabbix:

  • 监视任何事情适用于任何IT基础架构,服务,应用程序和资源的解决方案
  • Monitor anythingSolutions for any kind of IT infrastructure, services, applications, resources

2.监控基础概论

  • zabbix并非监控,而是实现监控的工具
  • Zabbix-server是一个c/s和b/s结构
  • 安装zabbbix的服务器安装时和php7.1有冲突:若此机器上已经安装php7.1就安装不上zabbix

3.监控知识体系

  • 为什么要使用监控
    1.对系统不间断实时监控
    2.实时反馈系统当前状态
    3.保证服务可靠性安全性
    4.保证业务持续稳定运行

  • 如果去到一家新的公司,如何入手?
    1.硬件监控——路由器、交换机、防火墙
    2.系统监控——cpu、内存、磁盘、网络、进程、tcp
    3.服务监控——nginx、php、tomcat、redis、memcache、mysql
    4.web监控——响应时间、加载时间、渲染时间
    5.日志监控——ELK、(收集、存储、分析、展示)日志
    6.安全监控——firewalld、WAF(nginx+lua)、安全宝、牛盾云、安全狗

4.单机监控

  • 单机进程cpu查看负载和使用率
  • 单机内存查看
  • 单机磁盘查看
  • 单机查看网络

5.引入zabbix分布式监控系统

  • 使用shell脚本来监控服务器

6.安装zabbix

  • (单机)–> LAMP
  • (架构)–> LAP + MYSQL
  • 服务端端口:10051
  • 客户端端口:10050

7.基础模板
自定义监控阈值实战

自定义监控项

  • 单位
  • 值类型
  • 值映射

阈值的定义

  • 单条件
  • 多条件

自定义触发器(动作)

自定义报警(邮件|微信)邮件发送的信息内容可以使用系统自带的宏变量来对应修改(官方站点有宏变量的介绍)

自定义图形、聚合图形、幻灯片、网络拓扑图、Graphtree

自定义模板(给主机添加)

系统默认自带的监控项设置阈值要根据生产中的需求来进修修改(阈值的高低)

8.服务监控(监控的服务要求有状态页面查询)

  • nginx
  • PHP-fpm
  • mysql
  • tomcat
  • redis

9.web监控

  • 请求时间
  • 响应时间
  • 页面不是200–>触发报警

10.自动化监控:
自动发现(server端轮询网段扫描发现agent)
**自动发现:server–>轮询扫描–>ip地址段–> **
自动发现:ip、ftp、ssh、web、pop3、imap、tcp

  • ip范文自动发现(两个阶段:发现–>动作)

  • szabbix-web自动发现定义自动监控的网段中的zabixx-agent(配置文件中server已经定义zabbix-server地址)

自动发现所执行的动作

  • 发送消息
  • 添加/删除主机
  • 启用/禁用主机
  • 添加主机到组
  • 从组中删除主机
  • 将主机链接到模板/从模板中取消链接
  • 执行远程脚本命令

主动注册(agent端主动告诉server端请求加入)
zabbix-server必须开启自动注册–>操作–>(通知|加入监控|套用模板)
Agent(ServerActive=10.0.0.61)–>启动–>自动加入zabbix-server

11.zabbix-proxy分布式

  • Zabbix-proxy使用场景:
  • 监控远程位置,解决跨机房
  • 监控主机多,性能跟不上,延迟大
  • 解决网络不稳定

12.zabbix 是怎么实施监控的
一个监控系统运行的大概的流程是这样的:

agentd需要安装到被监控的主机上,它负责定期收集各项数据,并发送到zabbix server端,zabbix server将数据存储到数据库中,zabbix web根据数据在前端进行展现和绘图。这里agentd收集数据分为主动和被动两种模式:

*主动:agent请求server获取主动的监控项列表,并主动将监控项内需要检测的数据提交给server/proxy

被动:server向agent请求获取监控项的数据,agent返回数据。

  • 主动模式被动模式:默认为zabbix-agent被动模式
主动模式与被动模式主要是站在zabbix-agent身份来说
  • 1.被动模式(zabbix-server轮询检测zabbix-agent)
  • 2.主动模式(zabbix-agent主动上报给zabbix-server)优
zabbix主动模式与被动模式选择
  • 1.当(Queue)队列中有大量的延迟监控项
  • 2.当监控主机超过300+ ,建议使用主动模式

13.【主动监测】通信过程如下:
zabbix首先向ServerActive配置的IP请求获取active items,获取并提交active tiems数据值server或者proxy。很多人会提出疑问:zabbix多久获取一次active items?它会根据配置文件中的RefreshActiveChecks的频率进行,如果获取失败,那么将会在60秒之后重试。分两个部分:

获取ACTIVE ITEMS列表

Agent打开TCP连接(主动检测变成Agent打开)

Agent请求items检测列表

Server返回items列表

Agent 处理响应

关闭TCP连接

Agent开始收集数据

主动检测提交数据过程如下:

Agent建立TCP连接

Agent提交items列表收集的数据

Server处理数据,并返回响应状态

关闭TCP连接

14.【被动监测】通信过程如下:

Server打开一个TCP连接

Server发送请求agent.ping\n

Agent接收到请求并且响应

Server处理接收到的数据

关闭TCP连接

1、新建监控项目时,选择的是zabbix代理还是zabbix端点代理程式(主动式),前者是被动模式,后者是主动模式。
2、agentd配置文件中StartAgents参数的设置,如果为0,表示禁止被动模式,否则开启。一般建议不要设置为0,因为监控项目很多时,可以部分使用主动,部分使用被动模式。

15.zabbix 自定义发现是怎么做的
1、首先需要在模板当中创建一个自动发现的规则,这个地方只需要一个名称和一个键值。
2、过滤器中间要添加你需要的用到的值宏。
3、然后要创建一个监控项原型,也是一个名称和一个键值。
4、然后需要去写一个这样的键值的收集。
自动发现实际上就是需要首先去获得需要监控的值,然后将这个值作为一个新的参数传递到另外一个收集数据的item里面去。

16.zabbix 是怎么微信报警的 ----企业现在用的比较的多
1、首先,需要有一个微信企业号。(一个实名认证的[微信号]一个可以使用的[手机号]一个可以登录的[邮箱号]
2、下载并配置微信公众平台私有接口。
3、配置Zabbix告警,(增加示警媒介类型,添加用户报警媒介,添加报警动作)。

17.zabbix 怎么开启自定义监控
1、写一个脚本用于获取待监控服务的一些状态信息。
2、在zabbix客户端的配置文件zabbix_agentd.conf中添加上自定义的“UserParameter”,目的是方便zabbix调用我们上面写的那个脚本去获取待监控服务的信息。
3、在zabbix服务端使用zabbix_get测试是否能够通过第二步定义的参数去获取zabbix客户端收集的数据。
4、在zabbix服务端的web界面中新建模板,同时第一步的脚本能够获取什么信息就添加上什么监控项,“键值”设置成前面配置的“UserParameter”的值。
5、数据显示图表,直接新建图形并选择上一步的监控项来生成动态图表即可。

18.zabbix 监控了多少客户端 客户端是怎么进行批量安装的
根据实际公司台数回答。
1、使用命令生成密钥。
2、将公钥发送到所有安装zabbix客户端的主机。
3、安装 ansible 软件,(修改配置文件,将zabbix 客户机添加进组)。
4、创建一个安装zabbix客户端的剧本。
5、执行该剧本。
6、验证。

19.实战经验总结:
1.先查看文档中有没有对应的脚本和xml模板
2.在服务端导入模板,查看对应的监控项名称
3.测试脚本是否能取值,并存放置于/etc/zabbix/scripts目录下,一定要增加执行权限
4.编写xx.conf文件,里面主要存放的是如何定义监控项
5.最后重启zabbix-agent
6.使用服务端zabbix-get 获取 zabbix-agent对应的监控项的数据

范例:
公司未启用swap(swap也是公司中服务器不建议启用的,因为swap是将磁盘模拟内存使用,消耗cpu的性能,建议关闭swap。加大内存),随着客户的流量日益增大,导致将zabbix服务进程强制OOM, Zabbix服务进程被kill,有两种解决的方法,如果公司为了性能着想加大内存,如果公司资有限添加swap,如果是为了服务的效率建议使用添加内存的方式,

十四,乱七八糟

1.假如有人反应,调取后端接口时特别慢,你会如何排查?
笔者回答:其实这种问题都没有具体答案,只是看你回答的内容与面试官契合度有多高,能不能说到他想要的点上,主要是看你排查问题的思路。我是这么说的:问清楚反应的人哪个服务应用或者页面调取哪个接口慢,叫他把页面或相关的URL发给你,首先,最直观的分析就是用浏览器按F12,看下是哪一块的内容过慢(DNS解析、网络加载、大图片、还是某个文件内容等),如果有,就对症下药去解决(图片慢就优化图片、网络慢就查看内网情况等)。其次,看后端服务的日志,其实大多数的问题看相关日志是最有效分析,最好用tail -f 跟踪一下日志,当然你也要点击测试来访问接口日志才会打出来。最后,排除sql,,找到sql去mysql执行一下,看看时间是否很久,如果很久,就要优化SQL问题了,expain一下SQL看看索引情况啥的,针对性优化。数据量太大的能分表就分表,能分库就分库。如果SQL没啥问题,那可能就是写的逻辑代码的问题了,一行行审代码,找到耗时的地方改造,优化逻辑。

2.当一个网站访问慢时,你怎么去优化
翻译为: 当一个网站访问慢时, 你都是怎么去查找问题,和解决问题以达到优化效果的

第一,用5分钟排除网络因素,借助工具(如pagespeed)分析页面加载过程1. 某个元素或者图片加载过慢: 具体原因具体分析
2. DNS解析时长问题: 可以通过购买解析服务, 来让自己的域名在各地DNS更多缓存
3. 网络带宽瓶颈: 考虑增加带宽
4. 网络线路波动: 考虑CDN,或者镜像站第二,要考虑到服务器问题1. 是否有服务器过载: 考虑增加硬件
2. I/O操作:数据库的频繁读写,服务器的频繁请求(包括静态文件的读取,图片的读取)等都属于I/O问题。对于数据库的问题,首先要优化SQL,存储过程等。如果单表数据量过大要考虑做分割或者运用程序来控制分表。如果请求量过大,要考虑做集群。对于服务器(静态)文件的I/O问题,则可以考虑做CDN,这样也可以解决地域性问题。对于动态文件的访问,则涉及到代码优化及负载均衡两项。
3. 具体应用优化: nginx针对访问量修改配置文件,调高Buffers 调低keep alive空连接时间等第三,安全方面1. 查看web\mail等其它服务日志,是否存在被攻击现象: 针对安全方面加固
2. 是否有其它攻击存在DDOS,WEB CC等

14.1 简述一下DNS的解析过程

解答:
1、在浏览器中输入www.qq.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。

2、如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。

3、如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/IP参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。

4、如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。

5、如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找qq.com域服务器,重复上面的动作,进行查询,直至找到www.qq.com主机。

6、如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。

从客户端到本地DNS服务器是属于递归查询,而DNS服务器之间就是的交互查询就是迭代查询。

14.2 linux系统的启动过程

1.加载BIOS
2.读取MBR
3.Boot Loader
4.加载内核
5.用户层init根据inittab文件来设定运行级别
6.init进程执行rc.sysinit
7.启动内核模块
8.执行不同运行级别的脚本程序
9.执行/etc/rc.d/rc.local
10.执行/bi/login程序,进入登陆状态

14.3 FTP的主动模式和被动模式

FTP协议有两种工作方式:PORT方式和PASV方式,中文意思为主动式和被动式。

PORT(主动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请 求,服务器接受连接,建立一条命令链路。当需要传送数据时,客户端在命令链路上用PORT 命令告诉服务器:“我打开了XX端口,你过来连接我”。于是服务器从20端口向客户端的 XX端口发送连接请求,建立一条数据链路来传送数据。

PASV(被动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请 求,服务器接受连接,建立一条命令链路。当需要传送数据时,服务器在命令链路上用PASV 命令告诉客户端:“我打开了XX端口,你过来连接我”。于是客户端向服务器的XX端口 发送连接请求,建立一条数据链路来传送数据。

从上面可以看出,两种方式的命令链路连接方法是一样的,而数据链路的建立方法就完 全不同。

14.4 真题

1.top命令中每行有哪些字段,都是什么意思?(load average,Tasks…)在这里插入图片描述第一行:系统运行时间和平均负载
当前时间 系统已运行的时间 当前登录用户的数量
相应最近5、10和15分钟内的平均负载
第二行:任务
系统现在共有多少个进程,其中处于运行中的有多少个,多少个在休眠(sleep),停止状态的有几个,僵尸状态的有0个。
第三行:CPU状态
显示不同模式下所占cpu时间百分比
第四、五行:内存使用
第一行是物理内存使用,第二行是虚拟内存使用(交换空间)。
第六行 :各个进程的状态监控
当然ps,free等命令的字段意思最好也查一查,看一看

2.ansible中的常用模块及作用

 ping # 主机连通性测试
command # 在远程主机上执行命令,不支持管道
shell # 在远程主机上调用shell解析器,支持管道命令个
copy # 用于将文件复制到远程主机,支持设定内容和修改权限.
file # 创建文件,创建连接文件,删除文件等
fetch # 从远程复制文件到本地
cron # 管理cron计划任务
yum # 用于模块的安装
service # 管理服务
user # 管理用户账号
group # 用户组管理
script # 将本地的脚本在远端服务器运行
setup # 该模块主要用于收集信息,是通过调用facts组件来实现的,以变量形式存储主机上的信息

3.zabbix监控一个网站到触发报警流程
4.mysql性能优化
5.centos开机过程中,服务(/etc/init.d中的)因故障卡住,不能开机,怎么办?

解决方法:
卡住之后重启电脑(可按ctrl+alt+delete,如果这个被禁用了则想其他方法),然后进入开机启动画面按esc按键
进入之后按a,然后输入1,单用户启动。(利用单用户启动基本上不会启动任何守护进程的特性来跳过卡住的服务的启动过程)
利用chkconfig --list 服务名 命令来查看卡住的服务的错误原因并修复。如果短时间内无法修复,则先利用chkconfig 服务名 off 命令先关掉此服务开机启动,然后正常启动计算机
正常启动后再慢慢寻找原因修复服务,先保证计算机能启动并且提供其他的正常业务进行。

6.JAVA_OPTS="-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "相关参数意义

-vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M
-vmargs 说明后面是VM的参数,所以后面的其实都是JVM的参数了
-Xms128m JVM初始分配的堆内存
-Xmx512m JVM最大允许分配的堆内存,按需分配
-XX:PermSize=64M JVM初始分配的非堆内存
-XX:MaxPermSize=128M JVM最大允许分配的非堆内存,按需分配

7.docker容器时间跟本地时间不一致怎样解决
共享本地的/etc/localtime到容器
8.nginx中location匹配顺序
https://segmentfault.com/a/1190000013267839
首先先检查使用前缀字符定义的location,选择最长匹配的项并记录下来。
如果找到了精确匹配的location,也就是使用了=修饰符的location,结束查找,使用它的配置。
然后按顺序查找使用正则定义的location,如果匹配则停止查找,使用它定义的配置。
如果没有匹配的正则location,则使用前面记录的最长匹配前缀字符location。
9.编写个shell 脚本将/boot/grub/目录下大于100K 的文件转移到/opt 目录下
补充:find /boot/grub -size +100k -type f -exec mv {} /opt ;

#/bin/bash
cd /boot/grub
for file in `ls /boot/grub`;do
if [ -f $file ];then
 if [ `ls -l $file | awk '{print $5}'` -gt 102400 ];then
 mv $file /opt
 fi
fi
done

10

1.查看某进程所打开的所有文件
lsof -p pid
2.写一条命令查找最后创建时间是3天前,后缀是*.log的文件并删除
find / -mtime +3 -type f -name '*.log' |xargs rm -f
3.当时用touch test时报错分区磁盘已满,但利用df -h查看后只是用了60的磁盘空间,请解释原因
小文件过多,导致inode耗尽
4.将本地80端口的请求转发到8080端口,当前主机IP为172.20.2.133,其中本地网卡为eth0
iptables -t nat -A PREROUTING -i eth0 -d 172.20.2.133 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
5.发现系统中存在大量的TIME_WAIT,请分析原因并提出三条以上的优化建议
6.查看内存使用情况,如何定位使用内存高的进程
7.列出当前目录及子目录下,占磁盘空间最大的10个文件
8.请简述CDN工作原理,以及怎么实现动态加速的
9.如何查看内核日志
10.如何查看 iptables 的 nat 表
11.请简述nginx处理一个请求的过程
Nginx 使用一个多进程模型来对外提供服务,其中一个 master 进程,
多个 worker 进程。master 进程负责管理 Nginx 本身和其他 worker 进程。
worker 进程中有一个函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个 Nginx 服务被停止。
12.将test文本中的每三行合并成一行,实例及输出结果如下
1
2
3
4
5
6
输出结果:
1 2 3
4 5 6
7 8 9
sed 'N;N;s/\n/ /g' 1.txt

11

1.运用 shell 命令输出文本文件 log 第三列的内容,并进行去重和排序, log 内容示例如下:
 1 20 apple
2 25 banana
3 14 apple
4 33 pear
… … …
2.利用 shell 命令将文本 user.txt 中所有 apple 替换成 banana
3.编写 crontab,每周六、日凌晨3点的0,15,30,45分各执行一次由shell编写的脚本 /var/crontab.sh
4.如何查看CPU规格,内存大小,网卡规格,磁盘信息
5.查看机器负载状况,如何定位高CPU占用的进程
6.进程间通信主要哪几种方式
https://www.jianshu.com/p/c1015f5ffa74
7.请简述DNS工作原理及其解析过程
8.磁盘 IO 请求高的情况下如何判断哪个进程占据了大量 IO 资源
9.ngx rewrite规则中last、break、redirect、permanent的含义
10.请解释ngx upstream是怎么实现负载均衡算法的
轮询,weight,ip_hash
11.如何提高系统的并发能力,你可能想到的所有方案有哪些?
12.写一个脚本,实现判断192.168.16.0/22网络里,显示当前在线的IP有哪些,能ping通则认为在线。
13.打印菲波那切数列
1 1 2 3 5 8 13 21 34 55...

其他
http://www.magedu.com/74545.html
https://www.linuxidc.com/Linux/2018-08/153699.htm
https://www.cnblogs.com/sunyllove/p/9578620.html

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐