运维工程师面试总结

前言:

最近在面试找工作,整理一下遇到的面试题.大公司更倾向于基础,小公司更偏向于业务处理,但整体上遇到的面试问题大部分都会围绕于你简历中写了哪些技术.
写下这些面试题,权且当做对用到的技术做概念上的梳理.当然其中一些答案有的是我摘自别人的,可能存在不严谨的情况,建议自行验证

Django

讲一下Django的生命周期

浏览器发起请求>>WSGI创建socket服务端,接收请求(Httprequest)>>中间件处理请求>>url路由,根据当前请求的URL找到视图函数>>view视图,进行业务处理>>中间件处理响应>>WSGI返回响应(HttpResponse)>>浏览器渲染

说一下用过哪些中间件
  • 缓存中间件: django.middleware.cache.UpdateCacheMiddleware django.middleware.cache.FetchFromCacheMiddleware 开启全站范围的缓存。 如果开启了这些缓存,任何一个由Django提供的页面将会被缓存,缓存时长在CACHE_MIDDLEWARE_SECONDS中配置定义。

  • 会话中间件 django.contrib.sessions.middleware.SessionMiddleware 开启会话支持,session支持中间件,加入这个中间件,会在数据库中生成一个django_session的表。

  • 通用中间件: django.middleware.common.CommonMiddleware 通用中间件,会处理一些URL,比如baidu.com会自动的处理成www.baidu.com。比如/blog/111会处理成/blog/111/自动加上反斜杠。

  • CSRF保护中间件 django.middleware.csrf.CsrfViewMiddleware 跨域请求伪造中间件。加入这个中间件,在提交表单的时候会必须加入csrf_token,cookie中也会生成一个名叫csrftoken的值,也会在header中加入一个HTTP_X_CSRFTOKEN的值来放置CSRF攻击。

  • 用户授权中间件: django.contrib.auth.middleware.AuthenticationMiddleware 他会在每个HttpRequest对象到达view之前添加当前登录用户的user属性,也就是你可以在view中通过request访问user。

  • 消息中间件 django.contrib.messages.middleware.MessageMiddleware 展示一些后台信息给前端页面。如果需要用到消息,还需要在INSTALLED_APPS中添加django.contrib.message才能有效。如果不需要,可以把这两个都删除。

  • XFrameOptionsMiddleware中间件 django.middleware.clickjacking.XFrameOptionsMiddleware 防止通过浏览器页面跨Frame出现clickjacking(欺骗点击)攻击出现。

Python

python中俩个列表如何取交集

获取两个list 的交集

  • 方法一:
a=[2,3,4,5]
b=[2,5,8]
tmp = [j for j in a if j in b] #列表推导式求的两个列表的交集
print(tmp)
  • 方法二:
print(list(set(a).intersection(set(b)))) # #列用集合的取交集方法
  • 方法三:
lst = []
for i in a:
if i in b :
lst.append(i)
print(lst)

拓展:
获取两个 list 的差集
方法一:
ret = list(set(a)-set(b))
print(ret)
方法二:
print(list(set(b).difference(set(a)))) # b中有而a中没有的
获取两个 list 的并集
方法一:
ret = list(set(a)-set(b))
print(ret)
方法二:
print(list(set(b).difference(set(a)))) # b中有而a中没有的

python全局变量应用场景

Python 允许在所有函数的外部定义变量,这样的变量称为全局变量(Global Variable)
全局变量的默认作用域是整个程序,即全局变量既可以在各个函数的外部使用,也可以在各函数内部使用
globals() 函数为 Python 的内置函数,它可以返回一个包含全局范围内所有变量的字典,该字典中的每个键值对,键为变量名,值为该变量的值
locals() 函数也是 Python 内置函数之一,通过调用该函数,我们可以得到一个包含当前作用域内所有变量的字典。这里所谓的“当前作用域”指的是,在函数内部调用 locals() 函数,会获得包含所有局部变量的字典;而在全局范文内调用 locals() 函数,其功能和 globals() 函数相同

python可变数据类型有哪些

  • 可变数据类型:list(列表)、dict(字典)、set(集合,不常用)

  • 不可变数据类型:数值类型(int、float、bool)、string(字符串)、tuple(元组)

可变数据类型:当该数据类型对应的变量的值发生了变化时,如果它对应的内存地址不发生改变,那么这个数据类型就是 可变数据类型。

不可变数据类型:当该数据类型对应的变量的值发生了变化时,如果它对应的内存地址发生了改变,那么这个数据类型就是 不可变数据类型。

总结:可变数据类型更改值后,内存地址不发生改变。不可变数据类型更改值后,内存地址发生改变。

装饰器用过吗,写一个简单的装饰器

用自己的话总结一下
装饰器可完成对原函数的扩展,可传递函数做为参数

# 一个简单的装饰器
def wsm(f):
    def wzj(*args,**kwargs):
        s = time.time()
        res = f(*args,**kwargs)
        e = time.time()
        h = (e -s)
        print(f'当前耗时{h}秒')
        return res
    return wzj

@wsm
def func():
    time.sleep(2)
    list1 = [1,2,2,3]
    list2 =  list(set(list1))

    print(list2)
func()

Docker

Dockerfile中ENTRYPOINT和CMD的区别:
  • CMD命令设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换
  • ENTRYPOINT配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行 docker run时指定了其他命令)

总结:CMD和ENTRYPOINT可指定容器启动运行的参数,但是真实启动时如果RUN后面修改了启动参数,那以RUN修改的参数优先,而ENTRYPOINT比较倔,就不改

ADD和COPY的区别:
  • ADD支持从远程URL获取资源
  • COPY只能从本地获取
docker的几种网络模型
  • host模式:net=host 容器和宿主机共享network namespace
  • container模式:net=container:NAME_or_ID 容器之间共享Network namespace,k8s中的pod就是多个容器共享一个Network namespace
  • none模式:net=none 容器有独立的Network namespace,但并没有对其进行热河网络设置,如分配veth pair和网桥连接配置ip等
  • bridge模式:net=bridge 默认为该模式

K8S

k8s的工作原理

用户创建pod请求信息>>存到etcd中>>scheduler查询分配未使用的node创建pod>>kubelet接收创建指令,实时汇报pod信息>>contrller-manager通过apiserver监控集群状态,确保集群处于预期工作中
用户通过kubectl或者APIserver的rest api接口提交需要运行的docker容器(创建pod请求)
api server将创建pod相关请求数据存储至etcd中
scheduler监听API server,查询还未分配的Node的pod,然后根据调度策略为这些pod分配节点
kubelet负责在所在的node节点上接收主节点发来的指令,管理pod及pod中的容器,并定时向master主节点汇报节点资源的使用情况及容器的情况
controller-manager则通过api-server监控整个集群的状态,并确保集群处于预期的工作

k8s中的常用组件
  • etcd:提供数据库服务保存了整个集群的状态
  • kube-apiserver:提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制
  • kube-controller-manager:负责维护集群的状态,比如故障检测、自动扩展、滚动更新等
  • cloud-controller-manager:是与底层云计算服务商交互的控制器
  • kub-scheduler:负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上
  • kubelet:负责维护容器的生命周期,同时也负责Volume和网络的管理
  • kube-proxy:负责为Service提供内部的服务发现和负载均衡,并维护网络规则
  • container-runtime:是负责管理运行容器的软件,比如docker
k8s的网络模式

k8s 网络模型要符合四个基础原则、三个网络要求原则、一个架构原则、一个 IP 原则。
每个 Pod 都拥有一个独立的 IP 地址,而且假定所有 Pod 都在一个可以直接连通的、扁平的网络空间中,不管是否运行在同一 Node 上都可以通过 Pod 的 IP 来访问。
k8s 中的 Pod 的 IP 是最小粒度 IP。同一个 Pod 内所有的容器共享一个网络堆栈,该模型称为 IP-per-Pod 模型。

  • Pod 由 docker0 实际分配的 IP。
  • Pod 内部看到的 IP 地址和端口与外部保持一致。
  • 同一个 Pod 内的不同容器共享网络,可以通过localhost来访问对方的端口,类似同一个虚拟机内不同的进程。
    IP-per-Pod 模型从端口分配、域名解析、服务发现、负载均衡、应用配置等角度看,Pod 可以看做是一台独立的虚拟机或物理机。
  • 所有容器都可以不用 NAT 的方式同别的容器通信。
  • 所有节点都可以在不同 NAT 方式下同所有容器通信,反之亦然。
  • 容器的地址和别人看到的地址是同一个地址。
pod有几种状态
  • Pending:Pod创建已经提交给k8s,但是因为某种原因不能顺利创建,例如下载镜像慢,调度不成功等
  • Running:Pod已经绑定到一个节点上了,并且已经创建了所有容器。只是有一个容器正在运行,或者在启动中。
  • Secceeded:Pod中的所有容器都已经成功终止,不能重新启动。
  • Failed: Pod中所有的容器均已经终止,且至少有一个容器已经在故障中终止。
  • Unkown:由于某中原因apiserver无法获取到Pod的状态。通常是由于Master与pod所在的主机失去连接了
pod服务启动失败有哪些原因及排查:
# 获取信息
kubectl describe pod 资源id
# 查看日志
kubectl logs 资源id
# 进入资源中
kubectl exec -it 资源id bash

常见故障

  • Pod状态 一直处于Pending

    Pending状态意味着Pod的YAML文件已经提交给Kubernetes,API对象已经被创建并保存在Etcd当中。但是,这个Pod里有些容器因为某种原因而不能被顺利创建。比如,调度不成功(可以通过kubectl describe pod 命令查看到当前Pod的事件,进而判断为什么没有调度)。可能原因:资源不足(集群内所有的Node都不满足该Pod请求的CPU、内存、GPU等资源);HostPort已被占用(通常推荐使用Service对外开放服务端口

  • Pod状态 一直处于Waiting

    首先还是通过kubectl describe pod 命令查看当前Pod的事件。可能的原因有:

    1、镜像拉取失败,比如镜像地址配置错误、拉取不了国外镜像源(gcr.io)、私有镜像密钥配置错误、镜像太大导致拉取超时(可以适当调整kubelet的-image-pull-progress-deadline和-runtime-request-timeout选项)等。

    2、CNI网络错误,一般需要检查CNI网络插件的配置,比如:无法配置Pod网络、无法分配IP地址。

    3、容器无法启动,需要检查是否打包了正确的镜像或者是否配置了正确的容器参数

    4、Failed create pod sandbox,查看kubelet日志,原因可能是磁盘坏道(input/output error)

  • Pod状态 一直处于ContainerCreating

    处理方法同Waiting

  • Pod状态 处于ImagePullBackOff

    通常是镜像名称配置错误或者私有镜像的密钥配置错误导致。这种情况可以使用docker pull来验证镜像是否可以正常拉取

  • Pod状态 处于CrashLoopBackOff

    此状态说明容器曾经启动了,但又异常退出。这时可以先查看一下容器的日志

  • Pod状态 处于Error

    通常处于Error状态说明Pod启动过程中发生了错误。常见的原因:依赖的ConfigMap、Secret或PV等不存在;请求的资源超过了管理员设置的限制,比如超过了LimitRange等;违反集群的安全策略,比如违反了PodSecurityPolicy等;容器无法操作集群内的资源,比如开启RDAC后,需要为ServiceAccount配置角色绑定

  • Pod状态 一直处于Terminating

    从v1.5开始,Kubernetes不会因为Node失联而删除其上正在运行的Pod,而是将其标记为Terminating 或 Unknown 状态。想要删除这些状态的Pod有三种方法:

    1、从集群中删除Node。使用公有云时,kube-controller-manager会在VM删除后自动删除对应的Node。而在物理机部署的集群中,需要管理员手动删除Node(kubectl delete node)。

    2、Node恢复正常。kubelet会重新跟kube-apiserver通信确认这些Pod的期待状态,进而再决定删除或者继续运行这些Pod。用户强制删除,用户可以执行(kubectl delete pods pod-name --grace-period=0 --force)强制删除Pod。除非明确知道Pod的确处于停止状态(比如Node所在VM或物理机已经关机),否则不建议使用该方法。特别是StatefulSet 管理的Pod,强制删除容易导致脑裂或数据丢失等问题。

    3、Pod行为异常,这里所说的行为异常是指Pod没有按预期的行为执行,比如没有运行podSpec 里面设置的命令行参数。这一般是podSpec yaml文件内容有误,可以尝试使用 --validate 参数重建容器,比如(kubectl delete pod mypod 和 kubectl create --validate -f mypod.yaml);也可以查看创建后的podSpec是否是对的,比如(kubectl get pod mypod -o yaml);修改静态Pod的Manifest后未自动重建,kubelet 使用inotify 机制检测 /etc/kubernetes/manifests 目录(可通过 kubelet 的 -pod-manifest-path 选项指定)中静态Pod的变化,并在文件发生变化后重新创建相应的 Pod。但有时也会发现修改静态Pod的 Manifest后未自动创建新 Pod的情景,此时已过简单的修复方法是重启 Kubelet

  • Pod状态 处于Unknown

    这个异常状态意味着Pod的状态不能持续地被 kubelet汇报给 kube-apiserver,这很有可能是主从节点(Master 和 Kubelet)间的通信出现了问题

VUE

vue中组件间怎么传递数据:
  • 父组件向子组件传递数据,使用props属性;子组件向父组件中传递数据,在子组件中使用$emit派发事件,父组件中使用v-on
    监听事件;缺点:组件嵌套层次多的话,传递数据比较麻烦。

  • 祖先组件通过依赖注入(inject / provide)的方式,向其所有子孙后代传递数据;缺点:无法监听数据修改的来源,不支持响应式。

  • 通过属性parent / $children /
    ref,访问根组件、父级组件、子组件中的数据;缺点:要求组件之间要有传递性。

  • 通过事件总线(event
    bus)的方式,可以实现任意两个组件间进行数据传递;缺点:不支持响应式,这个概念是vue1.0版本中的,现在已经废弃。

  • 通过 VueJs 的状态管理模式 Vuex,实现多个组件进行数据共享,推荐使用这种方式进行项目中各组件间的数据传递。
    下面详细介绍数据传递的几种方式

vue中data内要return为什么:
  • 组件是一个可复用的实例,当你引用一个组件的时候,组件里的data是一个对象,所有用到这个组件的都引用的同一个对象,就会造成数据污染
  • 将data封装成函数后,在引用组件的时候,我们只是调用了data函数生成的数据副本,是一个新对象,避免了数据污染
vue组件的生命周期:

组件的生命周期就是一个组件创建、数据初始化、挂载、更新、销毁的整个过程,其中具体方法:

beforeCreate
// 在实例初始化之后,数据观测和event/watcher时间配置之前被调用
created
// 实例已经创建完成之后被调用。在这一步,实例已经完成以下的配置:数据观测,属性和方法的运算,watch/event事件回调。然而,挂载阶段还没开始,$el属性目前不可见
beforeMount
// 在挂载开始之前被调用:相关的render函数首次被调用。
// 该钩子在服务器端渲染期间不被调用
mounted (
// el被新创建的vm.$el替换,并挂在到实例上去之后调用该钩子函数。如果root实例挂载了一个文档内元素,当mounted被调用时vm.$el也在文档内。
// 该钩子在服务端渲染期间不被调用。
    beforeUpdate
   // 数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。
  // 你可以在这个钩子中进一步第更改状态,这不会触发附加的重渲染过程。
  // 该钩子在服务端渲染期间不被调用。
    updated
    // 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。
   // 当这个钩子被调用时,组件DOM已经更新,所以你现在可以执行依赖于DOM的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
   //该钩子在服务端渲染期间不被调用
)

beforeDestroy
// 实例销毁之间调用。在这一步,实例仍然完全可用。
// 该钩子在服务端渲染期间不被调用。
destroyed
// Vue实例销毁后调用。调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
// 该钩子在服务端渲染不会被调用

DevOps

jenkins的流程,怎么构建的
  1. 开发者开发代码
  2. 提交至git仓库
  3. jenkins从仓库拉取代码
  4. jenkins通过maven(ant,gradle等)构建项目推到docker仓库
  5. 生成一个在tomcat运行的项目的docker容器
  6. 测试人员测试
jenkins的webhook怎么配置

shell

使用脚本取公网ip和内网ip
  • 使用curl 获取本机公网ip

    curl cip.cc
    curl v4.ident.me
    curl myip.ipip.net
    
  • 使用正则匹配

    ip a|grep 'inet'|grep -v 'inet6'|awk '{print $2}'|cut -d '/' -f 1
    
  • 使用路由获取

    ip route show
    
  • 使用hostname获取

    题目有限制要求取所有内网ip,可以在取出所有ip后,使用grep过滤出内网IP

    hostname -I
    

还有很多其他方法....

strace命令可以获取一个程序调用哪些函数的整个过程,貌似是这个命令

使用脚本写出多块4T盘,格式化后分区挂载并添加自启动
for V in $(ls /dev/sd[b-z])
do
  echo -e "n\np\n\n\n\nw\n" |parted $V
  mkfs.xfs -i size=512 ${V}1 &>/dev/null
  sleep 1
  M=$(echo "$V" |awk -F "/" '{print $3}')
  mkdir -p /data/${M}1 &>/dev/null
  echo -e "${V}1 /data/${M}1 xfs defaults 0 0\n" >>/etc/fstab
  mount -a &>/dev/null
done
使用脚本监测一个程序每15秒的状态,如果15秒中未监测到进程,则视为程序退出了(还有其他需求,大致记得这么多)

一个简单思路,未做验证,还有语法可能不通

c = 1
while true
do
# 获取此程序pid
A = ps -ef|grep '程序'
    if '$A' == '';then
        sleep 3
        c += 1
        if [ $c -eq 5 ];then
            break
        fi
    else
        continue
    fi
done

其他

Linux开机启动顺序

我觉得不准确,再查一查

1、加载BIOS(包含了CPU的相关信息、设备启动顺序信息、硬盘信息、内存信息、时钟信息、PnP特性等)
2、读取MBR(硬盘上第0磁道第一个扇区)
3、Boot Loader(初始化硬件设备、建立内存空间的映射图)
4、加载内核
5、设定运行等级(init0-init6)
6、执行rc.sysinit
7、启动内核模块
8、执行不同运行级别的脚本
9、执行rc.local
10、执行/bin/login 进入登陆状态

Redis持久化
  • 默认为RDB(redis database),定时快照至硬盘,对应产生的数据文件为dump.rdb
  • AOF 持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据
Zabbix自动发现及分布式
  • 自动发现(server端轮询网段扫描发现agent)

  • 自动发现:server-->轮询扫描-->ip地址段

  • 自动发现:ip、ftp、ssh、web、pop3、imap、tcp

    • ip范文自动发现(两个阶段:发现-->动作)
      • zabbix-web自动发现定义自动监控的网段中的zabixx-agent(配置文件中server已经定义zabbix-server地址)
  • 自动发现所执行的动作

    • 发送消息
    • 添加/删除主机
    • 启用/禁用主机
    • 添加主机到组
    • 从组中删除主机
    • 将主机链接到模板/从模板中取消链接
    • 执行远程脚本命令
  • 主动注册(agent端主动告诉server端请求加入)

  • zabbix-server必须开启自动注册-->操作-->(通知|加入监控|套用模板)

软连接与硬链接的区别:
  • 软连接原文件与连接文件拥有不同的inode号,是俩个不同的文件,而硬链接是和链接文件共一个inode,是同一个文件
  • 软链接支持跨文件系统建立,硬链接不支持
  • 软链接的链接数目不会增加,文件大小是不一样的,硬链接显示的大小是和源文件一样的
僵尸进程和孤儿进程的区别:
  • 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
  • 僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
  • 僵尸进程危害场景:
    例如有个进程,它定期的产 生一个子进程,这个子进程需要做的事情很少,做完它该做的事情之后就退出了,因此这个子进程的生命周期很短,但是,父进程只管生成新的子进程,至于子进程 退出之后的事情,则一概不闻不问,这样,系统运行上一段时间之后,系统中就会存在很多的僵死进程,倘若用ps命令查看的话,就会看到很多状态为Z的进程。 严格地来说,僵死进程并不是问题的根源,罪魁祸首是产生出大量僵死进程的那个父进程。因此,当我们寻求如何消灭系统中大量的僵死进程时,答案就是把产生大 量僵死进程的那个元凶枪毙掉(也就是通过kill发送SIGTERM或者SIGKILL信号啦)。枪毙了元凶进程之后,它产生的僵死进程就变成了孤儿进 程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源,这样,这些已经僵死的孤儿进程 就能瞑目而去了
怎么查看僵尸进程:
  • 使用Top命令查找,当zombie前的数量不为0时,即系统内存在相应数量的僵尸进程
  • 使用命令ps -A -ostat,ppid,pid,cmd |grep -e '^[Zz]'定位僵尸进程以及该僵尸进程的父进程
  • 使用Kill -HUP僵尸进程ID来杀死僵尸进程,往往此种情况无法杀死僵尸进程,此时就需要杀死僵尸进程的父进程
    kill -HUP 僵尸进程父ID
Nginx中location的匹配规则:

「=」 修饰符:要求路径完全匹配
「~」修饰符:区分大小写的正则匹配
「~*」不区分大小写的正则匹配
「^~」修饰符:前缀匹配 如果该 location 是最佳的匹配,那么对于匹配这个 location 的字符串, 该修饰符不再进行正则表达式检测。注意,这不是一个正则表达式匹配,它的目的是优先于正则表达式的匹配

  • 精确匹配 =
  • 前缀匹配 ^~(立刻停止后续的正则搜索)
  • 按文件中顺序的正则匹配 ~~*
  • 匹配不带任何修饰的前缀匹配。
Nginx日志中出现499报错是怎么回事

后端处理请求时间过长,客户端等的不耐烦了,提前关闭了http连接.常见于后台接口处理时间比较长,而前端请求又自带有超时时间
排查方法:

  • 1、cpu(top)与内存(free -h)的使用
  • 2、后台程序
  • 3、 MySQL慢查询
Apche与Nginx的区别

简单来说apache是同步多进程处理业务,更稳定,nginx异步处理业务,面对高并发更快性能更好.
nginx适合静态服务

  • apache 的 rewrite 比 nginx 强大,在 rewrite 频繁的情况下,用 apache
  • apache 发展到现在,模块超多,基本想到的都可以找到
  • apache 更为成熟,少 bug ,nginx 的 bug 相对较多
  • apache 超稳定
  • apache 对 PHP 支持比较简单,nginx 需要配合其他后端用
  • apache 在处理动态请求有优势,nginx 在这方面是鸡肋,一般动态请求要 apache 去做,nginx 适合静态和反向。
  • apache 仍然是目前的主流,拥有丰富的特性,成熟的技术和开发社区
TCP连接的几种状态:
LISTEN:侦听来自远方的TCP端口的连接请求
SYN-SENT:再发送连接请求后等待匹配的连接请求(客户端)
SYN-RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认(服务器)
ESTABLISHED:代表一个打开的连接
FIN-WAIT-1:等待远程TCP连接中断请求,或先前的连接中断请求的确认
FIN-WAIT-2:从远程TCP等待连接中断请求
CLOSE-WAIT:等待从本地用户发来的连接中断请求
CLOSING:等待远程TCP对连接中断的确认
LAST-ACK:等待原来的发向远程TCP的连接中断请求的确认
TIME-WAIT:等待足够的时间以确保远程TCP接收到连接中断请求的确认
CLOSED:没有任何连接状态
常见状态码:
  • 400 客户端请求的语法错误,服务器无法理解
  • 401 请求要求用户的身份认证
  • 403 服务器理解请求客户端的请求,但是拒绝执行此请求
  • 404 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
  • 405 客户端请求中的方法被禁止
  • 500 服务器内部错误,无法完成请求
  • 501 服务器不支持请求的功能,无法完成请求
  • 502是报错类型代码 bad gate way 错误的网关。产生错误的原因是连接超时,我们向服务器发送请求,由于服务器当前 链接 太多,导致服务器方面无法给于正常的响应,产生此类报错
  • 504错误代表网关超时 (Gateway timeout),是指 服务器 作为网关或代理,但是没有及时从上游服务器收到请求。. 服务器(不一定是 Web 服务器)正在作为一个网关或代理来完成客户(如您的 浏览器 或我们的 CheckUpDown 机器人)访问所需网址的请求。. 为了完成您的 HTTP 请求, 该服务器访问一个上游服务器, 但没得到及时的响应。. 这通常意味着上游服务器已关闭(不响应 网关 / 代理),而不是上游服务器和网关/代理在交换数据的协议上不一致。. 正常情况下,是由于被请求服务器发送超时引起。
Ansible的使用:
ansible testservers -m copy -a 'src=/root/install.log dest=/tmp/install.log owner=testuser group=testgroup'
# 先进入somedir/ ,再在somedir/目录下让所有节点运行somescript.sh并把log输出到somelog.txt

ansible -i hosts all -m shell -a "somescript.sh >> somelog.txt" chdir=somedir/
LVS模式的几种及使用场景:

LVS工作模式分为NAT模式、TUN模式、以及DR模式

  • 常用DR模式:
    直接路由模式,数据环形传输,用户请求>>LVS>>分配请求给节点>>节点返回报文给用户
    DR模式修改目标MAC地址来完成负载分发实现
    场景:支持大并发,但不能修改端口,要求调度器与后端服务器必须在同一个局域网内,节点要绑定VIP,抑制ARP
  • TUN模式:
    与DR相似,也是环形传输数据,但是是以添加数据包头的实现完成数据传输分发到节点,对请求报文重新封装
    场景:请求报文不能太大
  • NAT模式:
    数据为往返式传输,LVS在中间完成网络地址转换的工作
    用户请求>>LVS>>节点>>LVS>>用户
灾备是如何做的(其实就是数据库备份)
列出服务器备份恢复策略
  • 全网备份服务器
  • 数据库完全备份
  • 数据库增量备份
  • 差异备份
  • 冷数据归档
  • 定时任务备份站点目录,配置文件等。 恢复策略
  • 数据库增量恢复,全量恢复
  • 站点目录,配置文件等故障后随时调取备份来备份
    mysql 主从备份,每日做一次增量备份
    每周一次完整备份异地备份
  • 增量备份
    rsync是Linux系统下的数据镜像备份工具,使用快速增量备份工具Remote Sync可以远程同步,支持本地复制,或者与其他SSH、rsync主机同步
Rsync 三种模式
  • 本地模式,类似于cp
  • 隧道模式:类似scp
  • 守护进程模式:以守护进程socket 的方式传输数据
    在使用 rsync首次全量同步后,结合 inotify对源目录进行实时监控,只要有文件变动或新文件产生,就会立刻同步到目标目录下,非常高效实用。
linux系统做过内核优化吗?

没有,但是知道是修改sysctl.conf文件其中存在比较多的参数可供优化,但是做过nginx等中间件的优化....

最大并发连接数
允许系统打开的端口范围
发送缓存区的最大值
发送缓存区的默认值
socket保持FN-WAIT-2状态的最大时间 
.......
并发翻倍,系统正在扩容中,但是扩容需要7分钟才可以完成,怎么用现有服务器抗住7分钟内的翻倍并发

我不知道
面试官答:是在代码中做了埋点,当并发大于某一阈值,会触发开关,此时业务上存在的部分功能不可用,比如微博上传视频此时不做转码等等,以牺牲部分功能延缓到扩容完成后(简单的讲就是业务降级)

系统出现504需要怎么排查

客户访问时,代理不能及时地从远程服务器获得应答给客户,此时要检查后端数据服务是否出现问题,为什么未及时返还数据

写一下你们现有的架构

自己写

你可能感兴趣的:(运维工程师面试总结)