面试1

1、如何实现Nginx代理节点访问日志记录客户的ip而不是代理IP;

   nginx代理设置:

    upstream bbs_real_servers {
        #ip_hash;
         server 10.10.70.80:80  weight=15;
         server 10.10.70.82:80  weight=15;
    }
    server {
       listen       80;
       server_name  bbs.etiantian.org;
       location / {
        proxy_pass http://bbs_real_servers;
        proxy_set_header host $host ;
        proxy_set_header X-Forwarded-For $remote_addr;
      }
    }


    #如果后端web服务器上的程序需要获取用户的ip.从该header头获取。需调整web的

    web节点设置:

    

    apache:

    #202  LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

    #注意虚拟主机的日志格式

    nginx:

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    # 日志格式:"10.10.70.64" - - [03/Jan/2015:09:20:31 +0800] "GET / HTTP/1.0" 200 14 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0"


2、 /var/log/messages 日志出现 kernel: nf_conntrack: table full, dropping packet.请问是什么原因导致的?如何解决?

    /var/log/messages 出现kernel:nf_conntrack:table full,dropping packet  是因为业务访问慢造成的
    优化:
         net.nf_conntrack_max = 25000000
         net.netfilter.nf_conntrack_max = 25000000
    #表池调大
        net.netfilter.nf_conntrack_tcp_timeout_established = 180
        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
    #超时时间调小
   



3、linux 系统 nginx php 环境,如果 PHP-FPM 进程高,请问可能的原因,以及如何解决\排查?

   1、进程跟踪
    # top //找出CPU使用率高的进程PID
    # strace -p PID //跟踪进程
    # ll /proc/PID/fd //查看该进程在处理哪些文件
    将有可疑的PHP代码修改之,如:file_get_contents没有设置超时时间。
   2、内存分配
    如果进程跟踪无法找到问题所在,再从系统方面找原因,会不会有可能内存不够用?据说一个较为干净的PHP-CGI打开大概20M-30M左右的内存,决定于PHP模块开启多少。
    通过pmap指令查看PHP-CGI进程的内存使用情况
    # pmap   -q -d 4958

    按输出的结果,结合系统的内存大小,配置PHP-CGI的进程数(max_children)
  3、通过监控与自动恢复的脚本保证服务的正常运转。
    只要一个php-cgi进程占用的内存超过 %1 就把它kill掉
    #!/bin/sh
    PIDS=`ps aux|grep php-cgi|grep -v grep|awk’{if($4>=1)print $2}’`
    for PID in $PIDS
    do
    echo `date +%F….%T`>>/data/logs/phpkill.log
    echo $PID >> /data/logs/phpkill.log
    kill -9 $PID
    done


    检测php-fpm进程
    #!/bin/bash
    netstat -tnlp | grep “php-cgi” >> /dev/null #2&> /data/logs/php_fasle.log
   if [ "$?" -eq "1" ];then #&& [ `netstat -tnlp | grep 9000 | awk '{ print $4}' | awk -F ":" '{print $2}'` -eq "1" ];then
    /usr/local/webserver/php/sbin/php-fpm start
    echo `date +%F….%T` “System memory OOM.Kill php-cgi. php-fpm service start. ” >> /data/logs/php_monitor.log
    fi

   通过http检测php执行
    #!/bin/bash
    status=`curl -s –head “http://127.0.0.1:8080/chk.php” | awk ‘/HTTP/ {print $2}’`
    if [ $status != "200" -a $status != "304" ]; then
    /usr/local/webserver/php/sbin/php-fpm restart
    echo `date +%F….%T` “php-fpm service restart” >> /data/logs/php_monitor.log
    fi


 

4、 一主多从,主库宕机,如何切换到从库(两个),其他的从库如何处理?

        

1、  选择:

    1)查看另外两个的:cat /data/master.info

    #观察哪一个binlog数值最大,表示数据丢的是最少的,是最新的甚至是一致的;

     #把最快的最为主库

    2)如果是半同步,另一个从库就是主库

    3)#如果主库可以登陆直接把binlog拉取补全;

    2、确保relay_log 跟新完毕:show processlist;

        State: Wait for master tosend evnts  IO              #等待master发送

        State:Has read all relaylog; waiting for the slave I/o thread to update it  Sql  #relay读取完毕,等待IO 跟新

    3、stop slave ;

     retset master ;

    4、删除rm –fr master.inforelay-log.info

       #检查授权表 ,read-only等参数;

       开启log-bin

    #如果存在log-slave-update read-only等一定要注释掉;

    5、重启从库

    6、其它从库的操作:

       Stop slave ;

       Change master to master……

   Start slave ;

   Show slave status;

    #如果不同步,分析主库新生成的binlog ,或者change master 指定位置;

6、修改程序配置文件,从主数据35 指向32 ,平时访问数据库用域名,直接修改host即可

    7、主机如果有计划的切换:主库锁表后查看从库状态一致后,直接重新change master ;


 
5、误操作 drop 语句导致数据破坏,请给出恢复思想及实际步骤。

    思想:

    法1:  1、通过防火墙禁止web等应用向主库写数据或者锁表,让数据库停止跟新。

                  ##检查全备及binlog日志 ;

           2、将全被恢复;

              mysqlbinlog -d databasename mysql-bin.000014 > bin.sql

           3、将所有binlog汇总,转成sql语句,剔除drop语句,恢复数据;

              mysql -uroot -p123456 databasename < bin.sql

              (注意数据的备份,不要破坏原始数据)

           4、后续:(数据无法写入)所以无需恢复。

              5、如果是update语句(也需要停止访问)

    法2:1、如果主库持续有数据写入;

         2、停止一个从库;然后在主库刷新binlog;

          3、把mysql-bin.000014恢复成bin.sql(去掉drop语句);

          4、把全备数据sql及操作前的增量bin.sql恢复到从库。

          5、停止主库;把主库刷新后的binlog解析为sql恢复到从库;

          5、切换为从库提供服务;

          #法2可能会有主键冲突等其它的问题,可以通过修改id或者延迟解决,尽量使用法1停库解决;

         #平时工作要注意数据库的权限管理及流程管理,防患于未然。


6、磁盘报错“No space left on device” ,但是 df -h 查看磁盘空间没满,请问为什么? 

原因分析:系统中cron执行的程序有输出内容,输出内容会以邮件形式发给cron的用户,而sendmail没有启动所以就产生了这些文件;
查看:用df -i  显示 /var 已占用100%,如果inode耗尽,则系统上将不能创建文件。

             在/var/spoo/clientmqueue/下有超多的文件 ls 半天没反应
            用rm -rf * 会自动跳出root,用xargs来解决。

            # cd /var/spool/clientmqueue

            # ls | xargs rm -f

解决办法:  将crontab里面的命令后面加上> /dev/null 2>&1


 
7、磁盘空间满了,删除了一部分 nginx access 日志,但是,发现磁盘空间还是满的,请问
为什么?更改当前 apache 日志的 access.log 为 kong.log,请问程序写新日志会写到
kong.log 么? 

    i_count:当前文件使用者(或被调用)的数量,

    i_nlink :介质连接的数量(硬链接的数量);
   可以理解为i_count是内存引用计数器,i_nlink是磁盘的引用计数器。

    linux下文件删除的原理:Linux是通过link的数量来控制文件删除的,只有当一个文件不存在任何link的时候,这个文件才会被删除。一般来说,每个文件都有2个link计数器:i_count 和 i_nlink。
    lsof | grep 删除的文件名  查看占用  (把进程停止可以释放)
rm 操作只是将文件的i_nlink减少了,如果没其它的链接i_nlink就为0了;但由于该文件依然被进程引用,因此,此时文件对应的i_count并不 为0,所以即使执行rm操作,但系统并没有真正删除这个文件,当只有i_nlink及i_count都为0的时候,这个文件才会真正被删除。也就是说,还 需要解除该进程的对该文件的调用才行。

    所以删除access日志,磁盘空间还是满的,即使更改为kong.log也不会写入。


 

8、请利用 shell 开发一个 rsync 服务的启动停止脚本并通过 chkconfig 进行开关机管理。 

#!/bin/bash
# File: rsync.sh
# Usage:  ./rsync.sh {start|stop|restart}
# Description: Rsync Admin
# Version: 0.1
# Create Date: 2014/11/20 15:11:12
# Modified: 2014/11/20 15:11:12
# Author EMail: [email protected]
# chkconfig: 345 90 44
. /etc/init.d/functions
rsyncstatus=`ss -lntup | grep 873 | wc -l`


function Start ()
{
    rsync --daemon &>/dev/null
    if [ $? -eq 0 ]; then
        action "Starting" /bin/true
    else
        action "Starting" /bin/false
    fi
}    # ----------  end of function Start  ----------

function Stop ()
{
    
    if [ $rsyncstatus -ge 1 ]; then
        pkill rsync
            if [ $? -eq 0 ]; then
                action "Stoping" /bin/true
            else
                action "Stoping" /bin/false
            fi
    else
        echo "Rsync not running"
    fi
}    # ----------  end of function Stop  ----------


function Restart ()
{
    Stop
    sleep 2
    Start
}    # ----------  end of function Restart  ----------


case $1 in
    start|START)
        Start
        ;;
    stop|STOP)
        Stop
        ;;
    restart|RESTART)
        Restart
        ;;
    *)
        echo "Usage: rsync.sh  {start|stop|restart}"
        exit 1
        ;;

esac    # --- end of case ---


9、apache 服务的常用工作模式及对应特点,企业如何选择对应模式。

    apache的工作模式有:beos,event,worker,prefork,mpmt_os2。

    查看:http –l
          apachectl –l

    beos工作模式(跟linux关系不大,或者暂时用不上)
    在Beos系统上的工作模式,使用一个单独的控制线程来创建和控制处理请求的工作线程
 

    event工作模式(不太稳定,或者说暂时用不上)
    event 模式由于把服务进程从链接中分离出来,在开启KeepAlive场合下相对worker模式能够承受的了更高的负载。event模式为 worker开发的变种模式,配置以及指令与worker完全相同。不过event模式不能很好的支持https的访问,有时还会出现一系列的问题。


    worker工作模式(与php配合不好)
     worker模式由于使用线程来进行处理请求,所以能够处理海量请求,而系统资源的开销要小于基于进程的服务器。同时worker模式也使用了多进程,每个进程又有着多个线程,以获得基于进程服务器的稳定性。

       
    mpmt_os2工作模式(很少用,或者说暂时用不上)
 
    mpmt_os2是专门针对OS/2优化过的混合多进程多线程多路处理模块(MPM) 。 


    重点:prefork工作模式。
    1、编译的时候使用#–with-mpm=prefork对应的工作模式名称来修改工作模式。
    2、prefork工作模式是linux下apache安装时候的默认工作模式,是使用最普遍的工作模式。
    3、原理:有一台正在运行的apache服务器,用户A访问该apache的时候apache建立一个新的进程1处理用户A的请求。
                             这时又有一个用户B访问该apache,apache又建立一个新的进程2处理用户B的请求。
                             后来又有用户C,D,E访问该apache,apache又建立三个进程3,4,5处理他们的请求。
                             如果每当一个新用户访问该apache,apache再建立一个新的进程处理用户的请求,是不是太慢了呢?
                             所以apache的prefork模式在apache第一次启动的时候就建立5个进程,等待用户的连接请求,有一个用户访问,就有一个进程处理他的请求。
                             那么如果有5个用户同时访问apache,apache第一次建立的5个进程全部用光了,所以apache就再从新在建立5个进程,等待下一批用户的请求。
                
prefork模式会根据服务器的硬件情况,设定apache最多只能同时建立256个进程。再多的请求就只能等待前面的进程处理完毕在进行处理。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章