面試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個進程。再多的請求就只能等待前面的進程處理完畢在進行處理。


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