美文网首页
运维工程师面试总结

运维工程师面试总结

作者: 早_wsm | 来源:发表于2021-08-13 14:37 被阅读0次

    前言:

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

    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)的方式,向其所有子孙后代传递数据;缺点:无法监听数据修改的来源,不支持响应式。

    • 通过属性root /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需要怎么排查

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

    写一下你们现有的架构

    自己写

    相关文章

      网友评论

          本文标题:运维工程师面试总结

          本文链接:https://www.haomeiwen.com/subject/taarcltx.html