<menu id="gmukm"><object id="gmukm"></object></menu>
  • <tt id="gmukm"><blockquote id="gmukm"></blockquote></tt>
    <bdo id="gmukm"><button id="gmukm"></button></bdo>

    lighttpd日志切分

    [| 不指定 2012/03/09 18:56]
        之前在讀代碼的時候發現lighttpd在收到SIGHUP信號后會把日志重新打開一下,一直沒有理解這么做的意義是什么。今天終于用到了這個功能。
        一個新模塊沒有使用cronlog等日志切分工具,直接打印日志到文件,(使用管道切分日志有風險,被打印程序一旦hang住,lighttpd也就卡住了),但如何切分日志文件就變成了一個問題。mv的話由于不改變inode,還是往同一個文件打。cp代價太大。直接清空日志的話又太粗暴。這里就用到了sighup功能。只要將文件mv到新名字,然后用killall -s SIGHUP lighttpd,這樣lighttpd就會自動重新打開lighttpd.log打印了。
    Tags: , ,
    之前安裝了redmine,確實功能多、使用簡單,但ror架構實在是吃內存,小vps根本hold不住,于是還是選用python寫的trac。豐富的插件使trac只要配置得當,功能還是很強大的。

    首先安裝setuptools。這個可以用apt或yum安裝,也是一個類似于apt的包管理器,是針對python的。安裝后可使用easy_install命令
    然后配置PYTHONPATH,使用easy_install默認是安裝到系統路徑下的。需要root權限。不推薦使用這種方式,這樣會把文件放到用戶不可控的位置,為以后的升級備份帶來困難。所以就需要--install-dir參數(使用--prefix參數無效,不知為何),但單純使用該參數會報指定目錄不在PYTHONPATH里。這是easy_install會推薦去看一個網頁,我看了下,講的幾個方法都很繁瑣,也沒什么理由。其實只需要export PYTHONPATH=${PYTHONPATH}:your_dir即可。在.bash_profile里設置一下,避免每次都要手動。
    這里建議在.bash_profile里設置一下alias easy_install='easy_install --install-dir=your_dir',這樣就不用每次安裝時都手動輸入一大坨地址了。
    設置完后source .bash_profile生效一下。
    然后開始安裝,先執行:easy_install Babel==0.9.5   這個一定要裝,否則安裝后的trac沒有中文。
    然后easy_install Trac
    ok,trac的安裝就完成了。

    現在需要建立項目,trac需要為每個項目建立一個實例。這時在your_dir里找到trac-admin,這個是用來管理項目實例的工具。
    運行:trac-admin your_proj_dir initenv
    會提示項目名和使用的數據源。
    在數據源那里我使用官方推薦的:mysql://name:password@localhost:3306/test報錯:trac TypeError: unsupported operand type(s) for /: 'int' and 'NoneType'   看了下代碼,是數據庫沒有配成utf8字符集導致的。配了一下,ok了
    建立數據庫時要使用:CREATE DATABASE IF NOT EXISTS test default charset utf8 COLLATE utf8_general_ci;
    建好項目后就可以登陸進行進一步設置了。
    首先配置用戶具有admin權限:
    trac-admin your_proj_dir permission add user TRAC_ADMIN
    然后指定使用web auth進行用戶驗證:
    ./tracd --port 8000 --auth="*,/your_dir/user.htdigest,trac" /your_dir
    user.htdigest文件是用戶名密碼文件,需要自己生成,比較麻煩,反正也是臨時使用,這里貼個成品:

    user:trac:fb05f80adf782a74f48a5acdc71dba65
    這個的文件名和密碼分別是“user”,“password”
    啟動后進入控制臺
    進入管理,插件,開啟TracAccountManager 0.3.2
    修改trac.ini,
    [components]下添加trac.web.auth.loginmodule = disabled
    然后在account配置里SessionStore選一個1,(為啥不知道),但不開這個就不能注冊
    然后手動添加管理員賬戶
    然后可以用./tracd --port 8000  /your_dir   啟動了。
    用permission add給剛才添加的用戶加上管理員權限。然后ok了。可以使用web登陸了

    然后添加git支持:
    easy_install http://github.com/hvr/trac-git-plugin/tarball/master
    暫時沒找到支持遠程git的方法

    Tags: ,
        前幾天把一個函數的返回值由int改為size_t了。當時心想就是改個類型的問題,邏輯沒啥要動的。反正都是算數。
    編譯器什么也沒報。似乎沒什么問題。
        后來湊巧又改了一下另外一個程序的相同函數,結果編譯的時候報了error,說試圖轉換-1到unsigned。一檢查,果然程序中的異常分支返回了-1.急忙改了過來。
        所以在返回值是size_t類型的函數中,異常處理要注意。(主要是c程序,因為沒有異常)
    Tags:

    為nginx生成自簽名ssl證書

    [| 不指定 2012/03/03 00:00]
        今天要搭一個ssl加密的站點,由于是自用,所以就準備自簽發一張證書。之前搞過幾次,比較復雜,早忘光了。找到一篇不錯的文章,留下備份。
    http://blog.duyao.de/posts/to-generate-an-ssl-certificate-for-nginx-in-linux.html

    這里說下Linux 系統怎么通過openssl命令生成 證書。

    首先執行如下命令生成一個key

    openssl genrsa -des3 -out ssl.key 1024
    然后他會要求你輸入這個key文件的密碼。不推薦輸入。因為以后要給nginx使用。每次reload nginx配置時候都要你驗證這個PAM密碼的。

    由于生成時候必須輸入密碼。你可以輸入后 再刪掉。

    mv ssl.key xxx.key
    openssl rsa -in xxx.key -out ssl.key
    rm xxx.key
    然后根據這個key文件生成證書請求文件

    openssl req -new -key ssl.key -out ssl.csr
    以上命令生成時候要填很多東西 一個個看著寫吧(可以隨便,畢竟這是自己生成的證書)

    最后根據這2個文件生成crt證書文件

    openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt
    這里365是證書有效期 推薦3650哈哈。這個大家隨意。最后使用到的文件是key和crt文件。

    如果需要用pfx 可以用以下命令生成

    openssl pkcs12 -export -inkey ssl.key -in ssl.crt -out ssl.pfx
    在需要使用證書的nginx配置文件的server節點里加入以下配置就可以了。

    ssl on;
    ssl_certificate /home/ssl.crt;
    ssl_certificate_key /home/ssl.key;
    ssl_session_timeout 5m;
    ssl_protocols SSLv2 SSLv3 TLSv1;
    ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers on;
    然后重啟nginx就大功告成了
    Tags: ,

    strncpy和snprintf

    [| 不指定 2012/02/29 19:06]
        之前用strncpy總是感覺比較惡,老是要考慮最后\0的問題,今天仔細看了下,發現如果源串長度大于等于最大長度的話,strncpy會直接拷貝最大長度,不在后面加\0,也就是說在用一個字符串覆蓋另一個字符串一部分的時候用strncpy是很不錯的,但全覆蓋的話比較麻煩,很容易出bug。
        而snprintf會拷貝最大長度-1的字符數,并在后面加\0,使用一個字符串覆蓋另一個時很不錯。
        看了一下資料,發現snprintf的效率也要高于strncpy。
        日常字符串拷貝還是推薦snprintf。
    Tags: ,
        最近有一個困擾近兩個月的bug終于解決了,心情愉快。503問題之前一直沒找到頭緒,壓力一大就開始有,越大就越多。剛開始一直認為503是正常現象,后端負載能力不足的必然結果。加之之前后端用的自己寫的模擬server,性能什么的沒什么保證。所以一直在看是不是程序邏輯上有什么漏洞會導致封禁所有后端,一直找不到頭緒。

        周五測試同學突然說:現在用的后端server肯定能力要強于前邊這個啊,怎么可能會因為負載力不足導致503呢?一想確實啊,肯定是流量調度部分的問題。開gdb仔細一找,結果大跌眼鏡,原來是跟后端的連接池的最大允許并發連接數開的太小了。。

        之前那個值設置的比較小是有道理的,因為php是每個進程處理一個請求的,所以并發數肯定不會超過啟動的php進程數。但現在后端改用了lighttpd,lighttpd可以承載的并發數是很多的,這樣的話在高并發請求的情況下后端連接池很容易就用完了。

        由此有兩個感觸,一是不同場景下配置項一定要仔細想想如何調優。二是bug并不都是邏輯錯誤導致的,還有可能是配置錯了。。。。
    Tags:
        今天qa說http請求host字段最后以"."結尾時會有問題,看了下發現lighttpd自動把點號去掉了,試了試nginx,也是這樣。查了很多rfc,沒找到為什么,跑到群里問,有人說是根域的問題,回想起來配dns的cname記錄時,最后必須是有“點”結尾的,于是搜索了下。原來真正完整的域名最后是帶點的,com、net、cn這都是頂級域名,點后面的“”是根域名。dns解析最頂部是找到根域,然后再找頂級域。之前以為com就是根域,由跟域名服務器解析。現在看是錯的
    Tags: , ,

    lighttpd的超時參數詳解

    [| 不指定 2012/02/14 21:00]
    Lighttpd配置中,關于超時的參數有如下幾個(篇幅考慮,只寫讀超時,寫超時參數同理):


    server.max-keep-alive-idle = 5
    server.max-read-idle = 60
    server.read-timeout = 0
    server.max-connection-idle = 360


    這幾個參數意思相近,配置的時候很容易搞混。




    對于一個keep-alive連接上的連續請求,發送第一個請求內容的最大間隔由參數max-read-idle決定,從第二個請求起,發送請求內容的最大間隔由參數max-keep-alive-idle決定。請求間的間隔超時也由max-keep-alive-idle決定。發送請求內容的總時間超時由參數read-timeout決定。Lighttpd與后端交互數據的超時由max-connection-idle決定。



    例子:


    下面是模擬客戶端代碼:


    $fp = fsockopen("127.0.0.1", 8902, $errno, $errstr, 30);

    fwrite($fp, "GET / HTTP/1.1\r\n");
    sleep(3);                                             //$1這個時間必須小于max-read-idle,否則會超時
    fwrite($fp, "Host: a.com\r\n");
    sleep(3);                                             //$2這個時間必須小于max-read-idle,否則會超時。且$1+$2時間之和必須小于read-timeout,否則超時
    fwrite($fp, "Connection: Keep-Alive\r\n\r\n");
    echo fread($fp, 1024);



    sleep(7);                                             //$3 這個時間必須小于max-keep-alive-idle,否則超時



    fwrite($fp, "GET / HTTP/1.1\r\n");
    fwrite($fp, "Host: a.com\r\n");
    sleep(15);                                           //$4  這個時間必須小于max-keep-alive-idle,否則超時,可以大于max-read-idle,但仍然不能超過read-timeout
    fwrite($fp, "Connection: Keep-Alive\r\n\r\n");
    echo fread($fp, 1024);
    fclose($fp);

                                                      //以上時間均不受max-connection-idle限制


    下面是模擬后端server代碼:



    $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    if($sock == NULL)
    {
        echo "can't create socket";
        exit;
    }
    if(!socket_bind($sock, "0.0.0.0", 8904))
    {
        echo "can't bind socket";
        exit;
    }
    socket_listen($sock, 100);

    while(1)
    {
        if($new_conn = socket_accept($sock))
        {  
            $recv = socket_read($new_conn, 100000);
            //echo $recv;
            echo "begin sleep\n";
            sleep(10);                                                                                  //這個時間必須小于max-connection-idle,否則會超時
            echo "end sleep\n";
            socket_write($new_conn, "HTTP/1.1 200 OK\r\nDate: Tue, 01 Nov 2011 05:58:25 GMT\r\nServer: TestServer/1.0\r\nContent-Length: 1\r\nContent-Type: text/html;charset=gb2312\r\nConnection: Keep-Alive\r\n\r\na");
        }
        else
        {
            echo "accept failed!";
        }
    }




    下面是lighttpd中關于這幾個參數實現的代碼:

    if (con->recv->is_closed) {                                                                        
                                                                     if (srv->cur_ts - con->read_idle_ts > con->conf.max_connection_idle) {                                              //對于客戶端已經發送完請求數據的情況下,超時時間max-connection-idle
                                                                               /* time - out */
    #if 1
                                                                               WARNING("(connection process timeout) [%s]", SAFE_BUF_STR(con->dst_addr_buf));
    #endif
                                                                               connection_set_state(srv, con, CON_STATE_ERROR);
                                                                               changed = 1;
                                                                     }
                                                            }
                                                            else {

                                                                     if (con->request_count == 1) {                  
                                                                               if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {                                              //對于第一個請求,發送的數據最大時間間隔:max_read_idle
                                                                                        /* time - out */
    #if 1
                                                                                        if (con->conf.log_timeouts) {
                                                                                                 WARNING("(initial read timeout) [%s]", SAFE_BUF_STR(con->dst_addr_buf));
                                                                                        }
    #endif
                                                                                        connection_set_state(srv, con, CON_STATE_ERROR);
                                                                                        changed = 1;
                                                                               }
                                                                     } else {                                                                                               //從第二個請求開始,發送的數據最大時間間隔:keep_alive_idle
                                                                               if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
                                                                                        /* time - out */
    #if 1
                                                                                        if (con->conf.log_timeouts) {
                                                                                                 DEBUG("(keep-alive read timeout) [%s]", SAFE_BUF_STR(con->dst_addr_buf));
                                                                                        }
    #endif
                                                                                        connection_set_state(srv, con, CON_STATE_ERROR);
                                                                                        changed = 1;
                                                                               }
                                                                     }

                                                                     if (con->conf.read_timeout > 0 && con->read_start_ts > 0)                                                    //在read_timeout設置不為0的情況下,發送數據的最大總時間:read_timeout
                                                                     {
                                                                               used_time = srv->cur_ts - con->read_start_ts;
                                                                               if (used_time > con->conf.read_timeout)
                                                                               {
                                                                                        WARNING ("read timeout, client[%s], time=%lu",
                                                                                                 SAFE_BUF_STR(con->dst_addr_buf), used_time);
                                                                                        connection_set_state(srv, con, CON_STATE_ERROR);
                                                                                        changed = 1;
                                                                               }
                                                                     }
                                                            }
        今天程序出了一個core,是strcmp的時候有一個參數沒有判斷為NULL導致的,當我編寫了一個小程序:

    引用
    #include
    int main()
    {
    strcmp(NULL, "“);
    return 1;
    }

    測試的時候發現程序跑的毫無問題。
    編譯參數是gcc -g -O0,沒有開任何優化。

    gdb進去后發現strcmp根本沒有被執行,改成int a = strcmp(NULL, "");后,出core了。

    看來編譯器默認還是提供一定優化的。

    另外需要注意strcmp不會檢查參數(效率考慮),所以需要自己檢查。

    run-parts命令的用法及原理

    [| 不指定 2012/02/01 22:10]
        在很多系統中,用戶目錄下都有cron.daily之類的文件夾,里面的可執行文件每天都會被執行一次。也就是說如果想添加一個每天都被執行的任務的話,在目錄下放置該任務的腳本即可。使用很方便,原理是什么呢,就是run-parts命令。

        在centos5下,run-parts命令位于/usr/bin/run-parts,內容是很簡單的一個shell腳本,就是遍歷目標文件夾,執行第一層目錄下的可執行權限的文件。
        

    #!/bin/bash

    # run-parts - concept taken from Debian

    # keep going when something fails
    set +e

    if [ $# -lt 1 ]; then
        echo "Usage: run-parts <dir>"
        exit 1
    fi

    if [ ! -d $1 ]; then
        echo "Not a directory: $1"
        exit 1
    fi

    # Ignore *~ and *, scripts
    for i in $1/*[^~,] ; do
        [ -d $i ] && continue
        # Don't run *.{rpmsave,rpmorig,rpmnew,swp} scripts
        [ "${i%.rpmsave}" != "${i}" ] && continue
            [ "${i%.rpmorig}" != "${i}" ] && continue
            [ "${i%.rpmnew}" != "${i}" ] && continue
            [ "${i%.swp}" != "${i}" ] && continue
        [ "${i%,v}" != "${i}" ] && continue

        if [ -x $i ]; then
            $i 2>&1 | awk -v "progname=$i" \
                      'progname {
                       print progname ":\n"
                       progname="";
                       }
                       { print; }'
        fi
    done

    exit 0

         在ubuntu下,該文件位于/bin/run-parts,是個二進制文件,功能更為強大,支持--test等參數。
    Tags:
    分頁: 10/33 第一頁 上頁 5 6 7 8 9 10 11 12 13 14 下頁 最后頁 [ 顯示模式: 摘要 | 列表 ]
    色琪琪av男人的天堂-琪琪see色原网色原网站-天天谢天天谢天天要-欧美成人视频 <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>