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:[email protected]: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 下頁 最后頁 [ 顯示模式: 摘要 | 列表 ]
一级a做爰片_免费一级特黄大片_日本一级特黄大片 <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>