摘要: 分類:計算機技術 字號: 大大  中中  小小 [文章作者:張宴 本文版本:v4.10 最后修改:2008.12.23 轉載請注明原文鏈接:http://blog.s135.com/post/366.htm]   前言:本文是我撰寫的關于搭建“Nginx + PHP(FastCGI)”Web服務器的第4篇文章。本系列文章作為國內最早詳細...  閱讀全文
          posted @ 2009-03-06 12:21 小馬歌 閱讀(334) | 評論 (1)編輯 收藏
           

          1,啟動和控制

          /etc/rc.d/init.d/lighttpd start [stop] [restart]

          2,如果沒有啟動起來,手工命令行敲一下:

          /usr/local/lighttpd/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf

          根據提示處理。

          3,如果是提示關于{ 之類符號的,很可能是perl沒有起作用。configure的–with-pcre,如果找不到pcre-devel是不報錯的。rpm -q pcre-devel 看一下就知道了。

          安裝PHP:

          官方下載PHP,configure 時候加上:’–enable-fastcgi’ ‘–enable-force-cgi-redirect’ ‘–enable-discard-path’,其他按實際需要。

          我的例子:’./configure’ ‘–prefix=/usr/local/php’ ‘–with-gd’ ‘–with-mysql’ ‘–with-zlib’ ‘–with-freetype-dir=/usr/local/lib’ ‘–with-jpeg-dir=/usr/lib’ ‘–with-iconv’ ‘–with-curl’ ‘–enable-fastcgi’ ‘–enable-force-cgi-redirect’ ‘–enable-discard-path’

          注意: 不能有’–with-apxs=/www/bin/apxs’之類的。

          檢查一下是否正確:/usr/local/php/bin/php -v

          如果有(cgi-fcgi) 則安裝正確,如果是(cli)那就沒有安裝對。

          最好安上eaccelarator,教程很多,不累述。
          調整lighttpd配置:

          server.modules = (
          “mod_rewrite”,
          “mod_redirect”,
          # “mod_alias”,
          “mod_access”,
          “mod_status”,
          # “mod_setenv”,
          “mod_fastcgi”,
          # “mod_proxy”,
          “mod_simple_vhost”,
          # “mod_cgi”,
          “mod_compress”,
          “mod_expire”,
          “mod_accesslog” )

          fastcgi.server = ( “.php” =>
          ( “localhost” =>
          (
          “socket” => “/tmp/php-fastcgi.socket”,
          “bin-path” => “/usr/local/php/bin/php”
          )
          )
          )

          復制安裝目錄下的文件:

          cp spawn-php.sh /usr/local/lighttpd/bin/

          調整設置:

          cd /usr/local/lighttpd/bin
          vi spawn-php.sh

          修改下述變量為正確值:

          SPAWNFCGI=”/usr/local/lighttpd/bin/spawn-fcgi”
          FCGIPROGRAM=”/usr/local/php/bin/php”
          FCGI_WEB_SERVER_ADDRS=”192.168.133.17″
          USERID=nobody
          GROUPID=nobody

          運行一次:

          [bin]$ ./spawn-php.sh
          spawn-fcgi.c.207: child exited with: 0, Success

          成功了,啟動lighttpd
          [bin]$ /etc/rc.d/init.d/lighttpd start
          OK !

          posted @ 2009-03-06 12:19 小馬歌 閱讀(1365) | 評論 (0)編輯 收藏
           
          2008-08-27 10:00

          這里我們先來區分兩種填寫表單的方法:
          第一種,用鼠標在表單項中切換。這是我們經常用的,他們會先找到需要填寫的第一項,用鼠標點上去,然后右手移到鍵盤上(我們暫且不管你的左手放在什么地方),填寫信息,接著右手移到鼠標上,點選第二項,再把右手移到鍵盤上,填寫信息……不斷重復,直到表單填寫完,最后用鼠標點擊“提交表單”按鈕。這樣做起來非常不方便,尤其是用戶體驗上。
          第二種,用Tab鍵切換。在填寫表單時只在填第一項時用鼠標點選,該項填寫完成后用Tab鍵切換至下一項,最后用回車鍵送出表單。整個填寫過程中,雙手只停留在鍵盤上,不用摸鼠標。
          哪種方法的效率高?大家一定都有相同的答案。
          有沒有辦法修正這一點呢?答案就是使用tabindex屬性。


          tabindex屬性設置按下tab鍵時的響應順序。它的值是一個數字,越小的數字響應順序越靠前,最小為1。在未設置tabindex屬性時,tab鍵將從頁面的第一個鏈接或者表單項開始切換(這里要說明一個情況,IE瀏覽器中第一次按下tab鍵時,選中的是地址欄)。
          利用tabindex的這一特性,我們就可以給表單里的各項添加相應的屬性。比如一個登錄表單,第一個表單項是“用戶名”,我們就可以在這一項上添加tabindex=”1”,并依次為后面的項賦值。這樣,在訪問這個頁面時,按下tab鍵后光標就停在“用戶名”的文本輸入框上,從而完全實現了無鼠標參與的表單填寫。
          此外,在某些網站的注冊頁面,部分表單項后面會跟著一個鏈接或者按鈕,用來對當前項的需要輸入的內容進行解釋或驗證。在未添加tabindex屬性的頁面,tab鍵會經過這些鏈接或按鈕。熟練的tab鍵用戶往往會在這上面犯錯誤——他們以為光標已經進入下一個文本框了,可實際卻停在一個鏈接上。最糟的情況時,他們就完全找不到光標了,從而需要重新拿起鼠標來點選下一項。使用tabindex屬性就可以很好的避免這一點。為每個表單項都添加tabindex,tab鍵就不會進入非填寫區域了。
          不過我很遺憾的發現,在我訪問過的網站中,沒有一家使用tabindex屬性。

          最后,我提供一段代碼供您測試tabindex屬性的作用。

          <form id=”form” name=”form” method=”post” action=”">
          <p><a href=”www.trade.cn”> 貿易視點網</a></p>
          <p>第二項:
          <label>
          <input type=”text” tabindex=”2″ name=”textfield” />
          </label>
          </p>
          <p>第一項:
          <label>
          <input type=”text” tabindex=”1″ name=”textfield2″ />
          </label>
          </p>
          <p>第三項:
          <label>
          <input type=”text” tabindex=”3″ name=”textfield3″ />
          </label>
          </p>
          </form>

          posted @ 2009-03-04 12:02 小馬歌 閱讀(428) | 評論 (0)編輯 收藏
           
          2008-08-26 11:27

               主要介紹如何在 Linux 系統上安裝高性能的 HTTP 服務器 —— Nginx、并在不改變原有網站結構的條件下用 Nginx 來提升網站的訪問速度。

          Nginx 簡介

          Nginx("engine x") 是一個高性能的 HTTP 和 反向代理 服務器,也是一個 IMAP/POP3/SMTP 代理服務器。 Nginx是由 Igor Sysoev 為俄羅斯訪問量第二的 Rambler.ru 站點開發的,它已經在該站點運行超過兩年半了。 Igor 將源代碼以類BSD 許可證的形式發布。盡管還是測試版,但是,Nginx 已經因為它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名了。

          根據最新一期(08 年 6 月份)的 NetCraft 調查報告顯示,已經有超過兩百萬的主機使用了 Nginx,這個數字超過了另外一個輕量級的 HTTP 服務器 lighttpd, 排名第四,并且發展迅速。下面是這份報告的前幾名的報表:

          以下為引用的內容:
          產品          網站數                    
          Apache 84,309,103
          IIS 60,987,087
          Google GFE 10,465,178
          Unknown 4,903,174
          nginx 2,125,160
          Oversee 1,953,848
          lighttpd 1,532,952

                      
          關于這期調查報告的更詳細信息請看下面鏈接:

          http://survey.netcraft.com/Reports/200806/           

          下圖是最近幾個月使用 Nginx 和 lighttpd 的網站數比較


                                     
          圖 1. 最近幾個月使用 Nginx 和 lighttpd 的網站數比較
                                     

          使用 Nginx 前必須了解的事項
                     
          目前官方 Nginx 并不支持 Windows,您只能在包括 Linux、UNIX、BSD 系統下安裝和使用;
          Nginx 本身只是一個 HTTP 和反向代理服務器,它無法像 Apache 一樣通過安裝各種模塊來支持不同的頁面腳本,例如 PHP、CGI 等;
          Nginx 支持簡單的負載均衡和容錯;
          支持作為基本 HTTP 服務器的功能,例如日志、壓縮、Byte ranges、Chunked responses、SSL、虛擬主機等等,應有盡有。
                      在 Linux 下安裝 Nginx
                      為了確保能在 Nginx 中使用正則表達式進行更靈活的配置,安裝之前需要確定系統是否安裝有 PCRE(Perl Compatible Regular Expressions)包。您可以到 ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/ 下載最新的 PCRE 源碼包,使用下面命令下載編譯和安裝 PCRE 包

          # wget ftp://ftp.csx.cam.ac.uk/pub/soft ... cre/pcre-7.7.tar.gz
          # tar zxvf pcre-7.7.tar.gz
          # cd pcre-7.7
          # ./configure
          # make
          # make install
                                  

                      接下來安裝 Nginx,Nginx 一般有兩個版本,分別是穩定版開發版,您可以根據您的目的來選擇這兩個版本的其中一個,下面是把 Nginx 安裝到 /opt/nginx 目錄下的詳細步驟:
                     

          # wget http://sysoev.ru/nginx/nginx-0.6.31.tar.gz
          # tar zxvf nginx-0.6.31.tar.gz


          # cd nginx-0.6.31
          # ./configure --with-http_stub_status_module –prefix=/opt/nginx
          # make
          # make install
                                  

                      其中參數 --with-http_stub_status_module 是為了啟用 nginx 的 NginxStatus 功能,用來監控 Nginx 的當前狀態。
                      安裝成功后 /opt/nginx 目錄下有四個子目錄分別是:conf、html、logs、sbin 。其中 Nginx 的配置文件存放于conf/nginx.conf,Nginx 只有一個程序文件位于 sbin 目錄下的 nginx 文件。確保系統的 80端口沒被其他程序占用,運行 sbin/nginx 命令來啟動 Nginx,打開瀏覽器訪問此機器的 IP,如果瀏覽器出現 Welcome tonginx! 則表示 Nginx 已經安裝并運行成功。
                      常用的 Nginx 參數和控制
                      程序運行參數
                      Nginx 安裝后只有一個程序文件,本身并不提供各種管理程序,它是使用參數和系統信號機制對 Nginx 進程本身進行控制的。 Nginx 的參數包括有如下幾個:
                                      -c <path_to_config>:使用指定的配置文件而不是 conf 目錄下的 nginx.conf 。
                                      -t:測試配置文件是否正確,在運行時需要重新加載配置的時候,此命令非常重要,用來檢測所修改的配置文件是否有語法錯誤。
                                      -v:顯示 nginx 版本號。

          -V:顯示 nginx 的版本號以及編譯環境信息以及編譯時的參數。

          例如我們要測試某個配置文件是否書寫正確,我們可以使用以下命令

          sbin/nginx – t – c conf/nginx2.conf

          通過信號對 Nginx 進行控制

          Nginx 支持下表中的信號:

          信號名                                             作用描述                    

          TERM, INT 快速關閉程序,中止當前正在處理的請求

          QUIT 處理完當前請求后,關閉程序

          HUP 重新加載配置,并開啟新的工作進程,關閉就的進程,此操作不會中斷請求

          USR1 重新打開日志文件,用于切換日志,例如每天生成一個新的日志文件

          USR2 平滑升級可執行程序

          WINCH 從容關閉工作進程

          有兩種方式來通過這些信號去控制 Nginx,第一是通過 logs 目錄下的 nginx.pid 查看當前運行的 Nginx 的進程 ID,通過 kill – XXX <pid> 來控制 Nginx,其中 XXX 就是上表中列出的信號名。如果您的系統中只有一個 Nginx 進程,那您也可以通過 killall 命令來完成,例如運行 killall – s HUP nginx 來讓 Nginx 重新加載配置。

          配置 Nginx

          先來看一個實際的配置文件:

          以下為引用的內容:
                      user nobody;# 工作進程的屬主
          worker_processes 4;# 工作進程數,一般與 CPU 核數等同

          #error_log logs/error.log;
          #error_log logs/error.log notice;
          #error_log logs/error.log info;

          #pid        logs/nginx.pid;

          events {
              use epoll;#Linux 下性能最好的 event 模式
              worker_connections 2048;# 每個工作進程允許最大的同時連接數
          }

          http {
              include       mime.types;
              default_type application/octet-stream;

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

              #access_log off;
              access_log logs/access.log;# 日志文件名

              sendfile        on;
              #tcp_nopush     on;
              tcp_nodelay     on;

              keepalive_timeout 65;

              include          gzip.conf;
             
              # 集群中的所有后臺服務器的配置信息
              upstream tomcats {
                   server 192.168.0.11:8080 weight=10;
                   server 192.168.0.11:8081 weight=10;
                   server 192.168.0.12:8080 weight=10;
                   server 192.168.0.12:8081 weight=10;
                   server 192.168.0.13:8080 weight=10;
                   server 192.168.0.13:8081 weight=10;
              }

              server {
                  listen       80;#HTTP 的端口
                  server_name localhost;

                  charset utf-8;

                  #access_log logs/host.access.log main;

                   location ~ ^/NginxStatus/ {
                      stub_status on; #Nginx 狀態監控配置
                      access_log off;
                   }

                   location ~ ^/(WEB-INF)/ {
                      deny all;
                   }
                 

                   location ~ \.(htm|html|asp|php|gif|jpg|jpeg|png|bmp|ico|rar|css|js|
                   zip|java|jar|txt|flv|swf|mid|doc|ppt|xls|pdf|txt|mp3|wma)$ {
                       root /opt/webapp;
                      expires 24h;
                  }

                  location / {
                      proxy_pass http://tomcats;# 反向代理
                      include proxy.conf;
                  }

                  error_page 404 /html/404.html;

                  # redirect server error pages to the static page /50x.html
                  #
                   error_page 502 503 /html/502.html;
                  error_page 500 504 /50x.html;
                  location = /50x.html {
                      root   html;
                  }
              }
          }

          Nginx 監控

          上面是一個實際網站的配置實例,其中灰色文字為配置說明。上述配置中,首先我們定義了一個 location ~^/NginxStatus/,這樣通過 http://localhost/NginxStatus/ 就可以監控到 Nginx的運行信息,顯示的內容如下:

          以下為引用的內容:
          Active connections: 70
          server accepts handled requests
          14553819 14553819 19239266
          Reading: 0 Writing: 3 Waiting: 67

          NginxStatus 顯示的內容意思如下:
                     
          active connections – 當前 Nginx 正處理的活動連接數。

          erveraccepts handled requests -- 總共處理了 14553819 個連接 , 成功創建 14553819 次握手 (證明中間沒有失敗的 ), 總共處理了 19239266 個請求 ( 平均每次握手處理了 1.3 個數據請求 )。

          reading -- nginx 讀取到客戶端的 Header 信息數。

          writing -- nginx 返回給客戶端的 Header 信息數。

          waiting -- 開啟 keep-alive 的情況下,這個值等于 active - (reading + writing),意思就是 Nginx 已經處理完正在等候下一次請求指令的駐留連接。

          靜態文件處理

          通過正則表達式,我們可讓 Nginx 識別出各種靜態文件,例如 images 路徑下的所有請求可以寫為:

          以下為引用的內容:
                      location ~ ^/images/ {
              root /opt/webapp/images;
          }
                                  

                      而下面的配置則定義了幾種文件類型的請求處理方式。
                      location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|ico|css|js|txt)$ {
              root /opt/webapp;
              expires 24h;
          }

          對于例如圖片、靜態 HTML 文件、js 腳本文件和 css 樣式文件等,我們希望 Nginx 直接處理并返回給瀏覽器,這樣可以大大的加快網頁瀏覽時的速度。因此對于這類文件我們需要通過 root 指令來指定文件的存放路徑,同時因為這類文件并不常修改,通過 expires 指令來控制其在瀏覽器的緩存,以減少不必要的請求。 expires 指令可以控制 HTTP 應答中的“ Expires ”和“ Cache-Control ”的頭標(起到控制頁面緩存的作用)。您可以使用例如以下的格式來書寫 Expires:

          以下為引用的內容:
          expires 1 January, 1970, 00:00:01 GMT;
          expires 60s;
          expires 30m;
          expires 24h;
          expires 1d;
          expires max;
          expires off;

          動態頁面請求處理

          Nginx本身并不支持現在流行的 JSP、ASP、PHP、PERL 等動態頁面,但是它可以通過反向代理將請求發送到后端的服務器,例如Tomcat、Apache、IIS 等來完成動態頁面的請求處理。前面的配置示例中,我們首先定義了由 Nginx直接處理的一些靜態文件請求后,其他所有的請求通過 proxy_pass 指令傳送給后端的服務器(在上述例子中是 Tomcat)。最簡單的 proxy_pass 用法如下:

          以下為引用的內容:
                      location / {
              proxy_pass        http://localhost:8080;
              proxy_set_header X-Real-IP $remote_addr;
          }

          這里我們沒有使用到集群,而是將請求直接送到運行在 8080 端口的 Tomcat 服務上來完成類似 JSP 和 Servlet 的請求處理。

          當頁面的訪問量非常大的時候,往往需要多個應用服務器來共同承擔動態頁面的執行操作,這時我們就需要使用集群的架構。 Nginx 通過 upstream 指令來定義一個服務器的集群,最前面那個完整的例子中我們定義了一個名為 tomcats 的集群,這個集群中包括了三臺服務器共 6 個 Tomcat 服務。而 proxy_pass 指令的寫法變成了:

          以下為引用的內容:
                      location / {
              proxy_pass        http://tomcats;
              proxy_set_header X-Real-IP $remote_addr;
          }

          在 Nginx 的集群配置中,Nginx 使用最簡單的平均分配規則給集群中的每個節點分配請求。一旦某個節點失效時,或者重新起效時,Nginx 都會非常及時的處理狀態的變化,以保證不會影響到用戶的訪問。

          總結

          盡管整個程序包只有五百多 K,但麻雀雖小、五臟俱全。 Nginx官方提供的各種功能模塊應有盡有,結合這些模塊可以完整各種各樣的配置要求,例如:壓縮、防盜鏈、集群、FastCGI、流媒體服務器、Memcached 支持、URL 重寫等等,更關鍵的是 Nginx 擁有 Apache 和其他 HTTP服務器無法比擬的高性能。您甚至可以在不改變原有網站的架構上,通過在前端引入 Nginx 來提升網站的訪問速度。

          posted @ 2009-03-04 12:01 小馬歌 閱讀(221) | 評論 (0)編輯 收藏
           
          分支,標簽,與合并幾乎是所有版本控制系統的基本概念.如果你不熟悉這些功能,我們在這章提供了一個很好
          的介紹.如果你非常熟悉了,也能很好的讓你看看Subversion是如何實現這些功能的.
          分支是版本控制的一項基本的功能.如果你將要使用Subversion來管理你的數據.這是一個特色你將最終依賴
          它.這章要求你已經對Subversion的基本概念比較熟悉.

          什么是分支?
          假設你需要在你的電腦上維護一份被分離的文檔,一個手冊或是別的什么.某天要求你對同份文檔做一個不同
          的修改分離,但分離后他們兩者只有一小部分不同,因此只有輕微的不同.
          你將怎么解決這種處境?顯而易見的方法是不是:可以再拷貝這份文檔,然后保存兩個不同的分離版本.當某個
          部分要進行修改時,只要寫入對應的文件就可以了.
          經常需要對兩個拷貝版本進行同樣的修改.例如:如果發現一個打印錯誤在第一個文件里,這也很可能存在第二
          個拷貝文件里.這兩個文件是相同的的.
          這就是分支的基本概念,一條基于另外一條開發線存在的分支.并共享在分離之前的日志.一個分支就象一個拷
          貝的存在,并從那里離開,并具有自己的歷史.
          圖:Figur 4.1. Branches of development
          Subversion提供了一些功能來保持文件或目錄分支的平行性.允許通過拷貝數據來創建分支,并記錄與源文件
          的關系.也能幫助你將一個分支的修改復制到另外其他的支流上.總的來說,能夠映射出不同的工作拷貝.這樣
          就可以在不同的分支上進行工作.

          使用分支
          圖:Figure 4.2. Starting repository layout
          假設Sally與你同時擁有"calc"項目的工作副本,并都有/calc/trunk的工作副本.所有項目相關的文件都
          在/calc目錄下,因為你們的團隊已經商定/calc/trunk用于存放開發主線.
          此時你被要求完成一個任務就是新增項目的一個基本新特性.這將需要很長的時間來完成,并可能回影響到項
          目中的大部分晚間.問題是你不想與Sally有任何沖突,她正在修改項目中的一些存在的小BUG.并依賴于最新發
          布的項目版本,這里(/calc/trunk)主線版本是最有效的.如果你提交修改那么肯定會打亂Sally的修改工作.
          一種策略就是進入一個空洞:你和Sally在一到兩周內停止共享信息.那就是開始獲取整頓在你工作副本的所有
          文件,并不做任何提交一直到你完成工作任務.這個方案存在著很多問題,第一,這樣一來做不安全.很多人喜歡
          頻繁的將工作結果上傳到版本庫,已防止工作副本被突發事件破壞引起的后果.第二,不夠容易.如果你在不同
          的機器上工作,你就需要手工的將工作副本進行拷貝修改.最后,當你完成你的所有修改后,你將發現很難將你
          的工作合并到主線項目的代碼中去.
          更好的解決方法就是創,建所有你自己的分支.能頻繁的提交工作在不與其他人的沖突下.也能有選擇性的共享
          信息.

          創建一個分支
          創建一個分支非常簡單-只需要用svn copy命令拷貝項目就可以.Subversion不單支持單文件,也支持整個文件
          目錄的分支創建.在此例中,我們要拷貝/calc/trunk文件夾.那么應該把拷貝放在那里呢?任何地方你想要放置
          的地方.這里需要提到項目的策略在庫中有/calc/branches目錄空間,并你想要拷貝的目錄名重命名為my-
          calc-branch.
          有兩種不同的方法來進行拷貝.首先介紹有些麻煩的方法.只是為了讓概念清晰一點.首先,檢出版本庫./calc.
          使用svn copy命令拷貝要進行分支的文件目錄.
          $ cd bigwc
          $ svn copy trunk branches/my-calc-branch
          $ svn status
          A  +   branches/my-calc-branch
          在這個例自立,拷貝命令遞歸拷貝trunk下的文件到新的工作目錄.branches/my-calc-branch.你可以從svn
          status 命令,心得目錄被添加版本庫中.同時注意"+"符號前面的字母A.他表明添加的列表是一些數據的拷貝,
          并不是新添加的版本庫的數據.當年提交修改后,版本庫就會創建/calc/branches/my-calc-branch在版本庫中
          通過拷貝/calc/trunk,而不是通過工作副本將數據傳送到版本庫.
          $ svn commit -m "Creating a private branch of /calc/trunk."
          Adding         branches/my-calc-branch
          Committed revision 341.
          現在介紹一種簡單的創建分支的方法,那就是可以通過給svn copy 命令傳入兩個URL路徑來實現.
          $ svn copy http://svn.example.com/repos/calc/trunk \
                     http://svn.example.com/repos/calc/branches/my-calc-branch \
                -m "Creating a private branch of /calc/trunk."
          Committed revision 341.
          從版本庫的角度來看,實際上這兩種方法并無任何區別.注意區別只在與本地客戶端,后者可以立即執行分支任
          務,簡單,并不需要你檢出龐大的工作副本.這種方法是最常用的.
          圖 4.3. Repository with new copy

          廉價的拷貝
          Subversion的庫經過特別的設計.當你拷貝一個文件目錄是,你不需要擔心會占用大量的版本庫容量-實際上版
          本庫并不會真正的拷貝數據.取而代之的是建立一個新的目錄路口來指向已存在的目錄樹.如果你是UNIX的用
          戶,這與磁盤連接的概念是相同的.后面對文件或是目錄的修改也是影響被拷貝文件目錄.任何能夠使用該概念
          的地方Subversion都會利用該理念.
          這也是為什么聽到廉價拷貝這個詞.我們不需要擔心文件目錄有多大-拷貝的花費都是非常微小的.這種特性也
          是每次提交所做的事,每個版本都是一次廉價拷貝.除了很少的一點修改數據進行保存.
          當然,這些機制或數據共享對于用戶都是隱藏不可見的.我們能簡單的看到拷貝目錄.主要點就是拷貝是非常廉
          價的,無論是時間還是空間.如果你用這種方法拷貝是非常快的.當然可以隨心所欲的進行分支.

          使用分支進行工作
          現在我們建立了項目的一個份支,我們就可以檢出該分支并開始工作使用它.
          $ svn checkout http://svn.example.com/repos/calc/branches/my-calc-branch
          A  my-calc-branch/Makefile
          A  my-calc-branch/integer.c
          A  my-calc-branch/button.c
          Checked out revision 341.
          這個工作副本并無任何特別之處;只是簡單鏡像了一個庫中項目.當你提交修改后,Sally并不期望當她更新工
          作副本的時候看到這些修改.因為她的工作副本是/calc/trunk.
          讓我們假設看看一個星期里所發生的事
                You make a change to /calc/branches/my-calc-branch/button.c, which creates revision 342.
                You make a change to /calc/branches/my-calc-branch/integer.c, which creates revision 343.
                Sally makes a change to /calc/trunk/integer.c, which creates revision 344.
          現在這里有兩條獨立的開發線
          圖Figure 4.4. The branching of one file's history

          分支背后的關鍵概念
          這里有兩點重要的內容需要在這里記住.第一,Subversion并沒有沖突分支的概念-它只知道怎么去進行拷貝.
          當你拷貝一個目錄是,結果就是目錄是一個獨立的分支.你可能回想像一個不同的目錄被建立或被處理.但對于
          Subversion只是平常的目錄控制區別只是再擴展一個歷史日志信息.第二,因為這種拷貝機制,Subversion的分
          支只是平常的存儲在版本庫中,而不像其他的版本控制系統,分支是真正存儲了目錄文件.
          注意,Subversion并不支持不同版本庫之間拷貝也使用映射機制,所以他只能在同版本庫下工作.
          posted @ 2009-03-04 11:38 小馬歌 閱讀(809) | 評論 (0)編輯 收藏
           
          1. 請問交換機和路由器分別的實現原理是什么?分別在哪個層次上面實現的?

          將網絡互相連接起來要使用一些中間設備(或中間系統),ISO的術語稱之為中繼(re
          lay)系統。根據中繼系統所在的層次,可以有以下五種中繼系統:
          1)       物理層(即常說的第一層、層L1)中繼系統,即轉發器(repeater)。
          2)       數據鏈路層(即第二層,層L2),即網橋或橋接器(bridge)。
          3)       網絡層(第三層,層L3)中繼系統,即路由器(router)。
          4)       網橋和路由器的混合物橋路器(brouter)兼有網橋和路由器的功能。
          5)       在網絡層以上的中繼系統,即網關(gateway).
          當中繼系統是轉發器時,一般不稱之為網絡互聯,因為這僅僅是把一個網絡擴大了,而這
          仍然是一個網絡。高層網關由于比較復雜,目前使用得較少。因此一般討論網絡互連時都
          是指用交換機和路由器進行互聯的網絡。本文主要闡述交換機和路由器及其區別。  
          2.  第二層交換機和路由器的區別:
          傳統交換機從網橋發展而來,屬于OSI第二層即數據鏈路層設備。它根據MAC地址尋
          址,通過站表選擇路由,站表的建立和維護由交換機自動進行。路由器屬于OSI第三層
          即網絡層設備,它根據IP地址進行尋址,通過路由表路由協議產生。因特網的路由選擇
          協議:內部網關協議IGP和外部網關協議EGP
          3. 第三層交換機和路由器的區別:
          在第三層交換技術出現之前,幾乎沒有必要將路由功能器件和路由器區別開來,他們完全
          是相同的:提供路由功能正在路由器的工作,然而,現在第三層交換機完全能夠執行傳統
          路由器的大多數功能。
          綜上所述,交換機一般用于LAN-WAN的連接,交換機歸于網橋,是數據鏈路層的設
          備,有些交換機也可實現第三層的交換。路由器用于WAN-WAN之間的連接,可以解
          決異性網絡之間轉發分組,作用于網絡層。他們只是從一條線路上接受輸入分組,然后向
          另一條線路轉發。這兩條線路可能分屬于不同的網絡,并采用不同協議。相比較而言,路
          由器的功能較交換機要強大,但速度相對也慢,價格昂貴,第三層交換機既有交換機線速
          轉發報文能力,又有路由器良好的控制功能,因此得以廣播應用。

          ----------------------------------------------------------------------

          2.1    OSI和TCP/IP
          1.  七層網絡結構功能及特點--OSI
          1)   物理層:為數據鏈路層提供物理連接,在其上串行傳送比特流,即所傳送數據的單位
          是比特。此外,該層中還具有確定連接設備的電氣特性和物理特性等功能。
          2)   數據鏈路層:負責在網絡節點間的線路上通過檢測、流量控制和重發等手段,無差錯
          地傳送以幀為單位的數據。為做到這一點,在每一幀中必須同時帶有同步、地址、差錯控
          制及流量控制等控制信息。
          3)   網絡層:為了將數據分組從源(源端系統)送到目的地(目標端系統),網絡層的任
          務就是選擇合適的路由和交換節點,使源的傳輸層傳下來的分組信息能夠正確無誤地按照
          地址找到目的地,并交付給相應的傳輸層,即完成網絡的尋址功能。
          4)   傳輸層:傳輸層是高低層之間銜接的接口層。數據傳輸的單位是報文,當報文較長時
          將它分割成若干分組,然后交給網絡層進行傳輸。傳輸層是計算機網絡協議分層中的最關鍵
          一層,該層以上各層將不再管理信息傳輸問題。
          5)   會話層:該層對傳輸的報文提供同步管理服務。在兩個不同系統的互相通信的應用進
          程之間建立、組織和協調交互。例如,確定是雙工還是半雙工工作。
          6)   表示層:該層的主要任務是把所傳送的數據的抽象語法變換為傳送語法,即把不同計
          算機內部的不同表示形式轉換成網絡通信中的標準表示形式。此外,對傳送的數據加密(
          或解密)、正文壓縮(或還原)也是表示層的任務。
          7)   應用層:該層直接面向用戶,是OSI中的最高層。它的主要任務是為用戶提供應用的
          接口,即提供不同計算機間的文件傳送、訪問與管理,電子郵件的內容處理,不同計算機
          通過網絡交互訪問的虛擬終端功能等。
          2. TCP/IP功能及特點
          1)   網絡接口層:這是TCP/IP協議的最低一層,包括有多種邏輯鏈路控制和媒體訪問協議
          。網絡接口層的功能是接收IP數據報并通過特定的網絡進行傳輸,或從網絡上接收物理幀
          ,抽取出IP數據報并轉交給網際層。
          2)   網際網層(IP層):該層包括以下協議:IP(網際協議)、ICMP(Internet Contro
          l Message Protocol,因特網控制報文協議)、ARP(Address Resolution Protocol,地址
          解析協議)、RARP(Reverse Address Resolution Protocol,反向地址解析協議)。該層
          負責相同或不同網絡中計算機之間的通信,主要處理數據報和路由。在IP層中,ARP協議用
          于將IP地址轉換成物理地址,RARP協議用于將物理地址轉換成IP地址,ICMP協議用于報告差
          錯和傳送控制信息。IP協議在TCP/IP協議組中處于核心地位。
          3)   傳輸層:該層提供TCP(傳輸控制協議)和UDP(User Datagram Protocol,用戶數據
          報協議)兩個協議,它們都建立在IP協議的基礎上,其中TCP提供可靠的面向連接服務,U
          DP提供簡單的無連接服務。傳輸層提供端到端,即應用程序之間的通信,主要功能是數據
          格式化、數據確認和丟失重傳等。
          4)   應用層:TCP/IP協議的應用層相當于OSI模型的會話層、表示層和應用層,它向用戶
          提供一組常用的應用層協議,其中包括:Telnet、SMTP、DNS等。此外,在應用層中還包含
          有用戶應用程序,它們均是建立在TCP/IP協議組之上的專用程序。
          3. OSI參考模型和TCP/IP參考模型的區別:
          1)   OSI模型有7層,TCP/IP只有4層;
          2)   OSI先于協議出現,因此不會偏向于任何一組特定的協議,通用性更強,但有些功能
          不知該放哪一層上,因此不得不加入一些子層;TCP/IP后于協議出現,僅是將已有協議的
          一個描述,因此兩者配合的非常好;但他不適合其他的協議棧,不容易描述其他非TCP/IP
          的網絡;
          3)   OSI中網絡層同時支持無連接和面向連接的通信,但在傳輸層上只支持面向連接的通
          信;TCP/IP中網絡層只支持無連接通信,傳輸層同時支持兩種通信;
          4)   在技術發生變化時,OSI模型比TCP/IP模型中的協議更容易被替換。
          4.         請你詳細的解釋一下IP協議的定義,在哪個層上面,主要有什么作用? TCP與
          UDP呢? 
          解:與IP協議配套使用的還有三個協議:
          ARP-地址解析協議
          RARP-逆地址解析協議
          ICMP-因特網控制報文協議ICMP
          IP協議-網際協議
          IP地址、IP包頭

          posted @ 2009-03-02 18:05 小馬歌 閱讀(687) | 評論 (0)編輯 收藏
           
          本文以RedHat9.0和i386平臺為例,剖析了從用戶打開電源直到屏幕出現命令行提示符的整個Linux啟動過程。并且介紹了啟動中涉及到的各種文件。

            閱讀Linux源代碼,無疑是深入學習Linux的最好方法。在本文對Linux啟動過程的介紹中,我們也嘗試從源代碼的視角來更深入的剖析Linux的啟動過程,所以其中也簡單涉及到部分相關的Linux源代碼,Linux啟動這部分的源碼主要使用的是C語言,也涉及到了少量的匯編。而啟動過程中也執行了大量的shell(主要是bash shell)所寫腳本。為了方便讀者閱讀,筆者將整個Linux啟動過程分成以下幾個部分逐一介紹,大家可以參考下圖:

            當用戶打開PC的電源,BIOS開機自檢,按BIOS中設置的啟動設備(通常是硬盤)啟動,接著啟動設備上安裝的引導程序lilo或grub開始引導Linux,Linux首先進行內核的引導,接下來執行init程序,init程序調用了rc.sysinit和rc等程序,rc.sysinit和rc當完成系統初始化和運行服務的任務后,返回init;init啟動了mingetty后,打開了終端供用戶登錄系統,用戶登錄成功后進入了Shell,這樣就完成了從開機到登錄的整個啟動過程。

           

           

              下面就將逐一介紹其中幾個關鍵的部分:


            第一部分:內核的引導(核內引導)

            Red Hat9.0可以使用lilo或grub等引導程序開始引導Linux系統,當引導程序成功完成引導任務后,Linux從它們手中接管了CPU的控制權,然后CPU就開始執行Linux的核心映象代碼,開始了Linux啟動過程。這里使用了幾個匯編程序來引導Linux,這一步泛及到Linux源代碼樹中的“arch/i386/boot”下的這幾個文件:bootsect.S、setup.S、video.S等。

            其中bootsect.S是生成引導扇區的匯編源碼,它完成加載動作后直接跳轉到setup.S的程序入口。setup.S的主要功能就是將系統參數(包括內存、磁盤等,由BIOS返回)拷貝到特別內存中,以便以后這些參數被保護模式下的代碼來讀取。此外,setup.S還將video.S中的代碼包含進來,檢測和設置顯示器和顯示模式。最后,setup.S將系統轉換到保護模式,并跳轉到 0x100000。

            那么0x100000這個內存地址中存放的是什么代碼?而這些代碼又是從何而來的呢?

            0x100000這個內存地址存放的是解壓后的內核,因為Red Hat提供的內核包含了眾多驅動和功能而顯得比較大,所以在內核編譯中使用了“makebzImage”方式,從而生成壓縮過的內核,在RedHat中內核常常被命名為vmlinuz,在Linux的最初引導過程中,是通過"arch/i386/boot/compressed/"中的head.S利用misc.c中定義的decompress_kernel()函數,將內核vmlinuz解壓到0x100000的。

            當CPU跳到0x100000時,將執行"arch/i386/kernel/head.S"中的startup_32,它也是vmlinux的入口,然后就跳轉到start_kernel()中去了。start_kernel()是"init/main.c"中的定義的函數,start_kernel()中調用了一系列初始化函數,以完成kernel本身的設置。start_kernel()函數中,做了大量的工作來建立基本的Linux核心環境。如果順利執行完start_kernel(),則基本的Linux核心環境已經建立起來了。

            在start_kernel()的最后,通過調用init()函數,系統創建第一個核心線程,啟動了init過程。而核心線程init()主要是來進行一些外設初始化的工作的,包括調用do_basic_setup()完成外設及其驅動程序的加載和初始化。并完成文件系統初始化和root文件系統的安裝。

            當do_basic_setup()函數返回init(),init()又打開了/dev/console設備,重定向三個標準的輸入輸出文件stdin、stdout和stderr到控制臺,最后,搜索文件系統中的init程序(或者由init=命令行參數指定的程序),并使用 execve()系統調用加載執行init程序。到此init()函數結束,內核的引導部分也到此結束了,

              第二部分:運行init


            init的進程號是1,從這一點就能看出,init進程是系統所有進程的起點,Linux在完成核內引導以后,就開始運行init程序,。init程序需要讀取配置文件/etc/inittab。inittab是一個不可執行的文本文件,它有若干行指令所組成。在Redhat系統中,inittab的內容如下所示(以“###"開始的中注釋為筆者增加的):

            #
            # inittab       This file describes how the INIT process should set up
            #               the system in a certain run-level.
            #
            # Author:       Miquel van Smoorenburg,

            #               Modified for RHS Linux by Marc Ewing and Donnie Barnes
            #

            # Default runlevel. The runlevels used by RHS are:
            #   0 - halt (Do NOT set initdefault to this)
            #   1 - Single user mode
            #   2 - Multiuser, without NFS (The same as 3, if you do not havenetworking)
            #   3 - Full multiuser mode
            #   4 - unused
            #   5 - X11
            #   6 - reboot (Do NOT set initdefault to this)
            #
            ###表示當前缺省運行級別為5(initdefault);
            id:5:initdefault:

            ###啟動時自動執行/etc/rc.d/rc.sysinit腳本(sysinit)
            # System initialization.
            si::sysinit:/etc/rc.d/rc.sysinit

            l0:0:wait:/etc/rc.d/rc 0
            l1:1:wait:/etc/rc.d/rc 1
            l2:2:wait:/etc/rc.d/rc 2
            l3:3:wait:/etc/rc.d/rc 3
            l4:4:wait:/etc/rc.d/rc 4
            ###當運行級別為5時,以5為參數運行/etc/rc.d/rc腳本,init將等待其返回(wait)
            l5:5:wait:/etc/rc.d/rc 5
            l6:6:wait:/etc/rc.d/rc 6

            ###在啟動過程中允許按CTRL-ALT-DELETE重啟系統
            # Trap CTRL-ALT-DELETE
            ca::ctrlaltdel:/sbin/shutdown -t3 -r now

            # When our UPS tells us power has failed, assume we have a few minutes
            # of power left.  Schedule a shutdown for 2 minutes from now.
            # This does, of course, assume you have powerd installed and your
            # UPS connected and working correctly.
            pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"

            # If power was restored before the shutdown kicked in, cancel it.
            pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"

            ###在2、3、4、5級別上以ttyX為參數執行/sbin/mingetty程序,打開ttyX終端用于用戶登錄,
            ###如果進程退出則再次運行mingetty程序(respawn)
            # Run gettys in standard runlevels
            1:2345:respawn:/sbin/mingetty tty1
            2:2345:respawn:/sbin/mingetty tty2
            3:2345:respawn:/sbin/mingetty tty3
            4:2345:respawn:/sbin/mingetty tty4
            5:2345:respawn:/sbin/mingetty tty5
            6:2345:respawn:/sbin/mingetty tty6

            ###在5級別上運行xdm程序,提供xdm圖形方式登錄界面,并在退出時重新執行(respawn)
            # Run xdm in runlevel 5
            x:5:respawn:/etc/X11/prefdm -nodaemon

          以上面的inittab文件為例,來說明一下inittab的格式。其中以#開始的行是注釋行,除了注釋行之外,每一行都有以下格式:
            id:runlevel:action:process

            對上面各項的詳細解釋如下:

            1. id

            id是指入口標識符,它是一個字符串,對于getty或mingetty等其他login程序項,要求id與tty的編號相同,否則getty程序將不能正常工作。

            2. runlevel

            runlevel是init所處于的運行級別的標識,一般使用0-6以及S或s。0、1、6運行級別被系統保留:其中0作為shutdown動作,1作為重啟至單用戶模式,6為重啟;S和s意義相同,表示單用戶模式,且無需inittab文件,因此也不在inittab中出現,實際上,進入單用戶模式時,init直接在控制臺(/dev/console)上運行/sbin/sulogin。在一般的系統實現中,都使用了2、3、4、5幾個級別,在Redhat系統中,2表示無NFS支持的多用戶模式,3表示完全多用戶模式(也是最常用的級別),4保留給用戶自定義,5表示XDM圖形登錄方式。7-9級別也是可以使用的,傳統的Unix系統沒有定義這幾個級別。runlevel可以是并列的多個值,以匹配多個運行級別,對大多數action來說,僅當runlevel與當前運行級別匹配成功才會執行。

            3. action

            action是描述其后的process的運行方式的。action可取的值包括:initdefault、sysinit、boot、bootwait等:

            initdefault是一個特殊的action值,用于標識缺省的啟動級別;當init由核心激活以后,它將讀取inittab中的initdefault項,取得其中的runlevel,并作為當前的運行級別。如果沒有inittab文件,或者其中沒有initdefault項,init將在控制臺上請求輸入runlevel。

            sysinit、boot、bootwait等action將在系統啟動時無條件運行,而忽略其中的runlevel。

            其余的action(不含initdefault)都與某個runlevel相關。各個action的定義在inittab的man手冊中有詳細的描述。

            4. process

            process為具體的執行程序。程序后面可以帶參數。

            第三部分:系統初始化

            在init的配置文件中有這么一行:

            si::sysinit:/etc/rc.d/rc.sysinit

            它調用執行了/etc/rc.d/rc.sysinit,而rc.sysinit是一個bash shell的腳本,它主要是完成一些系統初始化的工作,rc.sysinit是每一個運行級別都要首先運行的重要腳本。它主要完成的工作有:激活交換分區,檢查磁盤,加載硬件模塊以及其它一些需要優先執行任務。

            rc.sysinit約有850多行,但是每個單一的功能還是比較簡單,而且帶有注釋,建議有興趣的用戶可以自行閱讀自己機器上的該文件,以了解系統初始化所詳細情況。由于此文件較長,所以不在本文中列出來,也不做具體的介紹。

            當rc.sysinit程序執行完畢后,將返回init繼續下一步。


          第四部分:啟動對應運行級別的守護進程


            在rc.sysinit執行后,將返回init繼續其它的動作,通常接下來會執行到/etc/rc.d/rc程序。以運行級別3為例,init將執行配置文件inittab中的以下這行:

            l5:5:wait:/etc/rc.d/rc 5

            這一行表示以5為參數運行/etc/rc.d/rc,/etc/rc.d/rc是一個Shell腳本,它接受5作為參數,去執行/etc/rc.d/rc5.d/目錄下的所有的rc啟動腳本,/etc/rc.d/rc5.d/目錄中的這些啟動腳本實際上都是一些鏈接文件,而不是真正的rc啟動腳本,真正的rc啟動腳本實際上都是放在/etc/rc.d/init.d/目錄下。而這些rc啟動腳本有著類似的用法,它們一般能接受start、stop、restart、status等參數。

            /etc/rc.d/rc5.d/中的rc啟動腳本通常是K或S開頭的鏈接文件,對于以以S開頭的啟動腳本,將以start參數來運行。而如果發現存在相應的腳本也存在K打頭的鏈接,而且已經處于運行態了(以/var/lock/subsys/下的文件作為標志),則將首先以stop為參數停止這些已經啟動了的守護進程,然后再重新運行。這樣做是為了保證是當init改變運行級別時,所有相關的守護進程都將重啟。

            至于在每個運行級中將運行哪些守護進程,用戶可以通過chkconfig或setup中的"System Services"來自行設定。常見的守護進程有:

            amd:自動安裝NFS守護進程
            apmd:高級電源管理守護進程
            arpwatch:記錄日志并構建一個在LAN接口上看到的以太網地址和IP地址對數據庫
            autofs:自動安裝管理進程automount,與NFS相關,依賴于NIS
            crond:Linux下的計劃任務的守護進程
            named:DNS服務器
            netfs:安裝NFS、Samba和NetWare網絡文件系統
            network:激活已配置網絡接口的腳本程序
            nfs:打開NFS服務
            portmap:RPC portmap管理器,它管理基于RPC服務的連接
            sendmail:郵件服務器sendmail
            smb:Samba文件共享/打印服務
            syslog:一個讓系統引導時起動syslog和klogd系統日志守候進程的腳本
            xfs:X Window字型服務器,為本地和遠程X服務器提供字型集
            Xinetd:支持多種網絡服務的核心守護進程,可以管理wuftp、sshd、telnet等服務

            這些守護進程也啟動完成了,rc程序也就執行完了,然后又將返回init繼續下一步。

              第五部分:建立終端


            rc執行完畢后,返回init。這時基本系統環境已經設置好了,各種守護進程也已經啟動了。init接下來會打開6個終端,以便用戶登錄系統。通過按Alt+Fn(n對應1-6)可以在這6個終端中切換。在inittab中的以下6行就是定義了6個終端:

            1:2345:respawn:/sbin/mingetty tty1
            2:2345:respawn:/sbin/mingetty tty2
            3:2345:respawn:/sbin/mingetty tty3
            4:2345:respawn:/sbin/mingetty tty4
            5:2345:respawn:/sbin/mingetty tty5
            6:2345:respawn:/sbin/mingetty tty6

            從上面可以看出在2、3、4、5的運行級別中都將以respawn方式運行mingetty程序,mingetty程序能打開終端、設置模式。同時它會顯示一個文本登錄界面,這個界面就是我們經常看到的登錄界面,在這個登錄界面中會提示用戶輸入用戶名,而用戶輸入的用戶將作為參數傳給login程序來驗證用戶的身份。

            第六部分:登錄系統,啟動完成

            對于運行級別為5的圖形方式用戶來說,他們的登錄是通過一個圖形化的登錄界面。登錄成功后可以直接進入KDE、Gnome等窗口管理器。而本文主要講的還是文本方式登錄的情況:

            當我們看到mingetty的登錄界面時,我們就可以輸入用戶名和密碼來登錄系統了。

            Linux的賬號驗證程序是login,login會接收mingetty傳來的用戶名作為用戶名參數。然后login會對用戶名進行分析:如果用戶名不是root,且存在/etc/nologin文件,login將輸出nologin文件的內容,然后退出。這通常用來系統維護時防止非root用戶登錄。只有/etc/securetty中登記了的終端才允許root用戶登錄,如果不存在這個文件,則root可以在任何終端上登錄。/etc/usertty文件用于對用戶作出附加訪問限制,如果不存在這個文件,則沒有其他限制。

            在分析完用戶名后,login將搜索/etc/passwd以及/etc/shadow來驗證密碼以及設置賬戶的其它信息,比如:主目錄是什么、使用何種shell。如果沒有指定主目錄,將默認為根目錄;如果沒有指定shell,將默認為/bin/bash。

            login程序成功后,會向對應的終端在輸出最近一次登錄的信息(在/var/log/lastlog中有記錄),并檢查用戶是否有新郵件(在/usr/spool/mail/的對應用戶名目錄下)。然后開始設置各種環境變量:對于bash來說,系統首先尋找/etc/profile腳本文件,并執行它;然后如果用戶的主目錄中存在.bash_profile文件,就執行它,在這些文件中又可能調用了其它配置文件,所有的配置文件執行后后,各種環境變量也設好了,這時會出現大家熟悉的命令行提示符,到此整個啟動過程就結束了。

            希望通過上面對Linux啟動過程的剖析能幫助那些想深入學習Linux用戶建立一個相關Linux啟動過程的清晰概念,進而可以進一步研究Linux接下來是如何工作的。

          posted @ 2009-03-02 18:03 小馬歌 閱讀(129) | 評論 (0)編輯 收藏
           
          [文章作者:張宴 本文版本:v1.0 最后修改:2007.11.16 轉載請注明出處:http://blog.s135.com]

            最近遇到一個問題,Linux下的PHP命令行程序作為守護進程,需要從隊列文件中讀一行數據,通過TCP協議發送給外地的接收服務器,再讀下一行數據,再發送。當本地與外地的網絡狀況不好時,有時候發送一條數據所耗費的時間就較長,累積起來容易造成隊列堵塞和延遲。

            于是,我準備用該PHP命令行程序生成多個子進程,將串行處理變成并行處理。最簡單的方法就是在PHP中用exec()或popen()函數將一個shell命令行推到后臺去執行,例如:
          <?php
          exec("/bin/sh /opt/zhangyan.sh &");
          ?>
            最后的&表示將shell腳本推到后臺去執行。

            但是這樣會有一個問題,如果推到后臺的進程太多,可能會導致服務器系統資源耗盡而崩潰,所以必須控制進程數量。



            我寫了一個PHP程序(/opt/zhangyan.php)、一個shell程序(/opt/zhangyan.sh)作為測試用例。

            程序的邏輯:
            1、設置/opt/zhangyan.php最多允許生成500個子進程;
            2、當/opt/zhangyan.php讀取到一條數據后,將允許生成的子進程數減1(空閑進程數$p_number=500-1=499),然后將數據交給/opt/zhangyan.sh去后臺處理,不等待/opt/zhangyan.sh處理結束,繼續讀取下一條數據;
            3、當允許生成的子進程數減至0時(空閑進程數$p_number=0),/opt/zhangyan.php會等待1秒鐘,然后檢查后臺還有多少個/opt/zhangyan.sh子進程尚未處理結束;
            4、如果1秒鐘之后/opt/zhangyan.php發現后臺的/opt/zhangyan.sh子進程數還是500(空閑進程數$p_number=0),會繼續等待1秒鐘,如此反復;
            5、如果/opt/zhangyan.php發現后臺尚未處理結束的/opt/zhangyan.sh子進程數減少到300個了(空閑進程數$p_number=500-300=200),那么/opt/zhangyan.php會再往后臺推送200個/opt/zhangyan.sh子進程;



          /opt/zhangyan.php代碼如下:
          1. <?php   
          2. function run($input)   
          3. {   
          4.     global $p_number;   
          5.     if ($p_number <= 0)   
          6.     {   
          7.         $p_number = worker_processes($p_number);   
          8.     }   
          9.     $p_number = $p_number - 1;   
          10.     $out = popen("/bin/sh /opt/zhangyan.sh \"{$input}\" &""r");   
          11.     pclose($out);   
          12. }   
          13.   
          14. function worker_processes($p_number)   
          15. {   
          16.     $limit = 500;//允許推到后臺的最大進程數   
          17.     while ($p_number <= 0)   
          18.     {   
          19.         $cmd = popen("ps -ef | grep \"/opt/zhangyan.sh\" | grep -v grep | wc -l""r");   
          20.         $line = fread($cmd, 512);   
          21.         pclose($cmd);   
          22.         $p_number = $limit - $line;   
          23.         if ($p_number <= 0)   
          24.         {   
          25.             sleep(1);//暫停1秒鐘   
          26.         }   
          27.     }   
          28.     return $p_number;   
          29. }   
          30.   
          31. $input = "http://blog.s135.com"; //模擬從隊列文件中讀取到的數據   
          32. for ($i = 1; $i <= 1000; $i++)   
          33. {   
          34.     run($input);   
          35.     echo "Idle process number: " . $p_number . "\n";   
          36. }   
          37. ?>  
            (/opt/zhangyan.php程序用來模擬從隊列文件中讀取1000行數據,交給子進程/opt/zhangyan.sh去處理。)



          /opt/zhangyan.sh代碼如下:
          1. #!/bin/sh   
          2. echo $(date -d "today" +"%Y-%m-%d %H:%M:%S"$1 >> /opt/zhangyan.log   
          3. sleep_time=$(expr $RANDOM % 4 + 1)   
          4. sleep $sleep_time  
            (/opt/zhangyan.sh腳本用來模擬向外地接收服務器發送數據。其中的$(expr $RANDOM % 4 + 1)用來生成1~5之間的隨機數,用來使程序暫停1~5秒鐘。暫停1秒表示網絡狀況好,發送數據順暢;暫停2~6秒表示網絡狀況不好,發送過程需要1~5秒。)



           執行程序:
          /usr/local/php/bin/php /opt/zhangyan.php

           (/usr/local/php/bin/php因PHP解析器所在的路徑)

           查看/opt/zhangyan.sh打下的日志文件的第一行和最后一行:
          head -n 1 /opt/zhangyan.log
           2007-11-16 07:54:13 http://blog.s135.com
          tail -n 1 /opt/zhangyan.log
           2007-11-16 07:54:18 http://blog.s135.com

            可以看出,500進程并發處理這1000條數據只耗費5秒鐘。而按照原來的串行模式,處理每條數據即使只耗費最短的1秒鐘,也需要1000秒,約合16分鐘才能完成。



           PS:將PHP程序作為Linux守護進程的方法:
          nohup /usr/local/php/bin/php /opt/zhangyan.php 2>&1 > /dev/null &

           (nohup命令可以在用戶退出終端后仍然執行程序,“2>&1 > /dev/null”表示不顯示標準輸出和錯誤輸出,最后的&表示推到后臺執行。)
          posted @ 2009-03-02 18:03 小馬歌 閱讀(212) | 評論 (0)編輯 收藏
           

          1.刪除0字節文件
          find -type f -size 0 -exec rm -rf {} \;

          2.查看進程
          按內存從大到小排列
          ps -e   -o "%C   : %p : %z : %a"|sort -k5 -nr

          3.按cpu利用率從大到小排列
          ps -e   -o "%C   : %p : %z : %a"|sort   -nr

          4.打印說cache里的URL
          grep -r -a   jpg /data/cache/* | strings | grep "http:" | awk -F'http:' '{print "http:"$2;}'

          5.查看http的并發請求數及其TCP連接狀態
          netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'


          6. sed -i '/Root/s/no/yes/' /etc/ssh/sshd_config   sed在這個文里Root的一行,匹配Root一行,將no替換成yes.

          7.1.如何殺掉mysql進程:
          ps aux|grep mysql|grep -v grep|awk '{print $2}'|xargs kill -9 (從中了解到awk的用途)

          killall -TERM mysqld

          kill -9 `cat /usr/local/apache2/logs/httpd.pid`   試試查殺進程PID



          8.顯示運行3級別開啟的服務:
          ls /etc/rc3.d/S* |cut -c 15-   (從中了解到cut的用途,截取數據)

          9.如何在編寫SHELL顯示多個信息,用EOF
          cat << EOF
          +--------------------------------------------------------------+
          |       === Welcome to Tunoff services ===                |
          +--------------------------------------------------------------+
          EOF

          10. for 的巧用(如給mysql建軟鏈接)
          cd /usr/local/mysql/bin
          for i in *
          do ln /usr/local/mysql/bin/$i /usr/bin/$i
          done

          11. 取IP地址:
          ifconfig eth0 |grep "inet addr:" |awk '{print $2}'|cut -c 6-   或者

          ifconfig   | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'

          12.內存的大小:
          free -m |grep "Mem" | awk '{print $2}'


          13.
          netstat -an -t | grep ":80" | grep ESTABLISHED | awk '{printf "%s %s\n",$5,$6}' | sort

          14.查看Apache的并發請求數及其TCP連接狀態:
          netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

          15.因為同事要統計一下服務器下面所有的jpg的文件的大小,寫了個shell給他來統計.原來用xargs實現,但他一次處理一部分,搞的有多個總和....,下面的命令就能解決啦.
          find / -name *.jpg -exec wc -c {} \;|awk '{print $1}'|awk '{a+=$1}END{print a}'


          CPU的數量(多核算多個CPU,cat /proc/cpuinfo |grep -c processor)越多,系統負載越低,每秒能處理的請求數也越多。

          --------------------------------------------------------------------------------------------------------------------
          16   CPU負載   # cat /proc/loadavg
          檢查前三個輸出值是否超過了系統邏輯CPU的4倍。  

          18   CPU負載   #mpstat 1 1
          檢查%idle是否過低(比如小于5%)

          19   內存空間   # free
          檢查free值是否過低   也可以用 # cat /proc/meminfo

          20   swap空間   # free
          檢查swap used值是否過高   如果swap used值過高,進一步檢查swap動作是否頻繁:
          # vmstat 1 5
          觀察si和so值是否較大

          21   磁盤空間   # df -h
          檢查是否有分區使用率(Use%)過高(比如超過90%)   如發現某個分區空間接近用盡,可以進入該分區的掛載點,用以下命令找出占用空間最多的文件或目錄:
          # du -cks * | sort -rn | head -n 10

          22   磁盤I/O負載   # iostat -x 1 2
          檢查I/O使用率(%util)是否超過100%

          23   網絡負載   # sar -n DEV
          檢查網絡流量(rxbyt/s, txbyt/s)是否過高

          24   網絡錯誤   # netstat -i
          檢查是否有網絡錯誤(drop fifo colls carrier)   也可以用命令:# cat /proc/net/dev

          25 網絡連接數目   # netstat -an | grep -E “^(tcp)” | cut -c 68- | sort | uniq -c | sort -n

          26   進程總數   # ps aux | wc -l
          檢查進程個數是否正常 (比如超過250)

          27   可運行進程數目   # vmwtat 1 5
          列給出的是可運行進程的數目,檢查其是否超過系統邏輯CPU的4倍


          28   進程   # top -id 1
          觀察是否有異常進程出現

          29   網絡狀態   檢查DNS, 網關等是否可以正常連通

          30   用戶   # who | wc -l
          檢查登錄用戶是否過多 (比如超過50個)   也可以用命令:# uptime

          31   系統日志   # cat /var/log/rflogview/*errors
          檢查是否有異常錯誤記錄   也可以搜尋一些異常關鍵字,例如:
          # grep -i error /var/log/messages
          # grep -i fail /var/log/messages

          32   核心日志   # dmesg
          檢查是否有異常錯誤記錄

          33   系統時間   # date
          檢查系統時間是否正確

          34   打開文件數目   # lsof | wc -l
          檢查打開文件總數是否過多

          35   日志   # logwatch –print   配置/etc/log.d/logwatch.conf,將 Mailto 設置為自己的email 地址,啟動mail服務 (sendmail或者postfix),這樣就可以每天收到日志報告了。
          缺省logwatch只報告昨天的日志,可以用# logwatch –print –range all 獲得所有的日志分析結果。
          可以用# logwatch –print –detail high 獲得更具體的日志分析結果(而不僅僅是出錯日志)。

          36.殺掉80端口相關的進程
          lsof -i :80|grep -v "PID"|awk '{print "kill -9",$2}'|sh

          37.清除僵死進程。
          ps -eal | awk '{ if ($2 == "Z") {print $4}}' | kill -9

          38.tcpdump 抓包 ,用來防止80端口被人攻擊時可以分析數據
          # tcpdump -c 10000 -i eth0 -n dst port 80 > /root/pkts

          39.然后檢查IP的重復數 并從小到大排序 注意 "-t\ +0"   中間是兩個空格
          # less pkts | awk {'printf $3"\n"'} | cut -d. -f 1-4 | sort | uniq -c | awk {'printf $1" "$2"\n"'} | sort -n -t\ +0

          40.查看有多少個活動的php-cgi進程
          netstat -anp | grep php-cgi | grep ^tcp | wc -l

          chkconfig --list | awk '{if ($5=="3:on") print $1}'
          41.kudzu查看網卡型號
          kudzu --probe --class=network
          posted @ 2009-03-02 18:02 小馬歌 閱讀(324) | 評論 (0)編輯 收藏
           

          curl是一個利用URL語法在命令行方式下工作的文件傳輸工具。本文介紹了它的簡單用法。 ************************************************************************************

          curl是一個利用URL語法在命令行方式下工作的文件傳輸工具。 它支持很多協議:FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及 LDAP。 curl同樣支持HTTPS認證,HTTP POST方法, HTTP PUT方法, FTP上傳, kerberos認證, HTTP上傳, 代理服務器, cookies, 用戶名/密碼認證, 下載文件斷點續傳, 上載文件斷點續傳, http代理服務器管道( proxy tunneling), 甚至它還支持IPv6, socks5代理服務器, 通過http代理服務器上傳文件到FTP服務器等等,功能十分強大。 Windows操作系統下的網絡螞蟻,網際快車(FlashGet)的功能它都可以做到。準確的說,curl支持文件的上傳和下載,所以是一個綜合傳輸工具,但是按照傳統,用戶習慣稱curl為下載工具。 curl是瑞典curl組織開發的,您可以訪問: http://curl.haxx.se/ 獲取它的源代碼和相關說明。 鑒于curl在Linux上的廣泛使用,IBM在AIX Linux Toolbox的光盤中包含了這個軟件,并且您可以訪問IBM網站: http://www- 1.ibm.com/servers/aix/products/aixos/linux/altlic.html     下載它。 curl的最新版本是 7.18.0,IBM網站上提供的版本為7.9.3。 在AIX下的安裝很簡單,IBM網站上下載的rpm格式的包。 在 http://curl.haxx.se/docs/ ,您可以下載到UNIX格式的man幫助,里面有詳細的curl工具的使用說明。 curl的用法為:curl [options] [URL...] 其中options是下載需要的參數,大約有80多個,curl的各個功能完全是依靠這些參數完成的。具體參數的使用,用戶可以參考curl的man幫助。下面,本文就將結合具體的例子來說明怎樣利用curl進行下載。

          1、獲得一張頁面
          使用命令:curl http://curl.haxx.se 這是最簡單的使用方法。用這個命令獲得了http://curl.haxx.se指向的頁面,同樣,如果這里的URL指向的是一個文件或者一幅圖都可以直接下載到本地。如果下載的是HTML文檔,那么缺省的將不顯示文件頭部,即HTML文檔的header。要全部顯示,請加參數 -i,要只顯示頭部,用參數 -I。任何時候,可以使用 -v 命令看curl是怎樣工作的,它向服務器發送的所有命令都會顯示出來。為了斷點續傳,可以使用-r參數來指定傳輸范圍。
          2、表單(Form)的獲取
          在WEB頁面設計中,form是很重要的元素。Form通常用來收集并向網站提交信息。提交信息的方法有兩種,GET方法和POST方法。先討論GET方法,例如在頁面中有這樣一段: <form method="GET" action="junk.cgi"> <input type=text name="birthyear"> <input type=submit name=press value="OK"> </form> 那么瀏覽器上會出現一個文本框和一個標為“OK”的按鈕。按下這個按鈕,表單就用GET方法向服務器提交文本框的數據。例如原始頁面是在 www.hotmail.com/when/birth.html看到的,然后您在文本框中輸入1905,然后按OK按鈕,那么瀏覽器的URL現在應該是:“www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK” 對于這種網頁,curl可以直接處理,例如想獲取上面的網頁,只要輸入: curl "www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK" 就可以了。 表單用來提交信息的第二種方法叫做POST方法,POST方法和GET方法的區別在于GET方法使用的時候,瀏覽器中會產生目標URL,而POST不會。類似GET,這里有一個網頁: <form method="POST" action="junk.cgi"> <input type=text name="birthyear"> <input type=submit name=press value="OK"> </form> 瀏覽器上也會出現一個文本框和一個標為“OK”的按鈕。按下這個按鈕,表單用POST方法向服務器提交數據。 這時的URL是看不到的,因此需要使用特殊的方法來抓取這個頁面: curl -d "birthyear=1905&press=OK" www.hotmail.com/when/junk.cgi 這個命令就可以做到。 1995年年末,RFC 1867定義了一種新的POST方法,用來上傳文件。主要用于把本地文件上傳到服務器。此時頁面是這樣寫的: <form method="POST" enctype='multipart/form-data' action="upload.cgi"> <input type=file name=upload> <input type=submit name=press value="OK"> </form> 對于這種頁面,curl的用法不同: curl -F upload=@localfilename -F press=OK URL 這個命令的實質是將本地的文件用POST上傳到服務器。有關POST還有不少用法,用戶可以自己摸索。
          3、使用PUT方法。
          HTTP協議文件上傳的標準方法是使用PUT,此時curl命令使用-T參數: curl -T uploadfile www.uploadhttp.com/receive.cgi
          4、有關認證。
          curl可以處理各種情況的認證頁面,例如下載用戶名/密碼認證方式的頁面(在IE中通常是出現一個輸入用戶名和密碼的輸入框): curl -u name:password www.secrets.com 如果網絡是通過http代理服務器出去的,而代理服務器需要用戶名和密碼,那么輸入: curl -U proxyuser:proxypassword http://curl.haxx.se 任何需要輸入用戶名和密碼的時候,只在參數中指定用戶名而空著密碼,curl可以交互式的讓用戶輸入密碼。
          5、引用。
          有些網絡資源訪問的時候必須經過另外一個網絡地址跳轉過去,這用術語來說是:referer,引用。對于這種地址的資源,curl也可以下載: curl -e http://curl.haxx.se daniel.haxx.se
          6、指定用戶客戶端。
          有些網絡資源首先需要判斷用戶使用的是什么瀏覽器,符合標準了才能夠下載或者瀏覽。此時curl可以把自己“偽裝”成任何其他瀏覽器: curl -A "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" URL 這個指令表示curl偽裝成了IE5.0,用戶平臺是Windows 2000。(對方服務器是根據這個字串來判斷客戶端的類型的,所以即使使用AIX也無所謂)。使用: curl -A "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" URL 此時curl變成了Netscape,運行在PIII平臺的Linux上了。
          7、COOKIES
          Cookie是服務器經常使用的一種記憶客戶信息的方法。如果cookie被記錄在了文件中,那么使用命令: curl -b stored_cookies_in_file www.cookiesite.com curl可以根據舊的cookie寫出新cookie并發送到網站: curl -b cookies.txt -c newcookies.txt www.cookiesite.com
          8、加密的HTTP——HTTPS。
          如果是通過OpenSSL加密的https協議傳輸的網頁,curl可以直接訪問: curl https://that.secure.server.com
          9、http認證。
          如果是采用證書認證的http地址,證書在本地,那么curl這樣使用: curl -E mycert.pem https://that.secure.server.com
          參考讀物和注意事項:
          curl非常博大,用戶要想使用好這個工具,除了詳細學習參數之外,還需要深刻理解http的各種協議與URL的各個語法。這里推薦幾個讀物: RFC 2616 HTTP協議語法的定義。 RFC 2396 URL語法的定義。 RFC 2109 Cookie是怎樣工作的。 RFC 1867 HTTP如何POST,以及POST的格式。

          這東西現在已經是蘋果機上內置的命令行工具之一了,可見其魅力之一斑!

          1)二話不說,先從這里開始吧!

          curl http://www.yahoo.com

          回車之后,www.yahoo.com 的html就稀里嘩啦地顯示在屏幕上了~~~~~

          2)嗯,要想把讀過來頁面存下來,是不是要這樣呢?
          curl http://www.yahoo.com > page.html

          當然可以,但不用這么麻煩的!
          用curl的內置option就好,存下http的結果,用這個option: -o
          curl -o page.html http://www.yahoo.com

          這樣,你就可以看到屏幕上出現一個下載頁面進度指示。等進展到100%,自然就OK咯

          3)什么什么?!訪問不到?肯定是你的proxy沒有設定了。
          使用curl的時候,用這個option可以指定http訪問所使用的proxy服務器及其端口: -x
          curl -x 123.45.67.89:1080 -o page.html http://www.yahoo.com

          4)訪問有些網站的時候比較討厭,他使用cookie來記錄session信息。
          像IE/NN這樣的瀏覽器,當然可以輕易處理cookie信息,但我們的curl呢?..
          我們來學習這個option: -D <– 這個是把http的response里面的cookie信息存到一個特別的文件中去
          curl -x 123.45.67.89:1080 -o page.html -D cookie0001.txt http://www.yahoo.com

          這樣,當頁面被存到page.html的同時,cookie信息也被存到了cookie0001.txt里面了

          5)那么,下一次訪問的時候,如何繼續使用上次留下的cookie信息呢?要知道,很多網站都是靠監視你的cookie信息,來判斷你是不是不按規矩訪問他們的網站的。
          這次我們使用這個option來把上次的cookie信息追加到http request里面去: -b
          curl -x 123.45.67.89:1080 -o page1.html -D cookie0002.txt -b cookie0001.txt http://www.yahoo.com

          這樣,我們就可以幾乎模擬所有的IE操作,去訪問網頁了!

          6)稍微等等~~~~~我好像忘記什么了~~~~~
          對了!是瀏覽器信息~~~~

          有些討厭的網站總要我們使用某些特定的瀏覽器去訪問他們,有時候更過分的是,還要使用某些特定的版本~~~~
          NND,哪里有時間為了它去找這些怪異的瀏覽器呢!?

          好在curl給我們提供了一個有用的option,可以讓我們隨意指定自己這次訪問所宣稱的自己的瀏覽器信息: -A
          curl -A “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)” -x 123.45.67.89:1080 -o page.html -D cookie0001.txt http://www.yahoo.com

          這樣,服務器端接到訪問的要求,會認為你是一個運行在Windows 2000上的IE6.0,嘿嘿嘿,其實也許你用的是蘋果機呢!

          而”Mozilla/4.73 [en] (X11; U; Linux 2.2; 15 i686″則可以告訴對方你是一臺PC上跑著的Linux,用的是Netscape 4.73,呵呵呵

          7)另外一個服務器端常用的限制方法,就是檢查http訪問的referer。比如你先訪問首頁,再訪問里面所指定的下載頁,這第二次訪問的referer地址就是第一次訪問成功后的頁面地址。這樣,服務器端只要發現對下載頁面某次訪問的referer地址不 是首頁的地址,就可以斷定那是個盜連了~~~~~

          討厭討厭~~~我就是要盜連~~~~~!!
          幸好curl給我們提供了設定referer的option: -e
          curl -A “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)” -x 123.45.67.89:1080 -e “mail.yahoo.com” -o page.html -D cookie0001.txt http://www.yahoo.com

          這樣,就可以騙對方的服務器,你是從mail.yahoo.com點擊某個鏈接過來的了,呵呵呵

          8)寫著寫著發現漏掉什么重要的東西了!—– 利用curl 下載文件

          剛才講過了,下載頁面到一個文件里,可以使用 -o ,下載文件也是一樣。
          比如, curl -o 1.jpg
          這里教大家一個新的option: -O
          大寫的O,這么用: curl -O
          這樣,就可以按照服務器上的文件名,自動存在本地了!

          再來一個更好用的。
          如果screen1.JPG以外還有screen2.JPG、screen3.JPG、.、screen10.JPG需要下載,難不成還要讓我們寫一個script來完成這些操作?
          不干!
          在curl里面,這么寫就可以了:
          curl -O http://cgi2.tky.3web.ne.jp/~zzh/screen[1-10].JPG

          呵呵呵,厲害吧?!~~~

          9)再來,我們繼續講解下載!
          curl -O http://cgi2.tky.3web.ne.jp/~{zzh,nick}/[001-201].JPG

          這樣產生的下載,就是
          ~zzh/001.JPG
          ~zzh/002.JPG

          ~zzh/201.JPG
          ~nick/001.JPG
          ~nick/002.JPG

          ~nick/201.JPG

          夠方便的了吧?哈哈哈

          咦?高興得太早了。
          由于zzh/nick下的文件名都是001,002,201,下載下來的文件重名,后面的把前面的文件都給覆蓋掉了~~~

          沒關系,我們還有更狠的!
          curl -o #2_#1.jpg http://cgi2.tky.3web.ne.jp/~{zzh,nick}/[001-201].JPG

          –這是..自定義文件名的下載?
          –對頭,呵呵!

          #1是變量,指的是{zzh,nick}這部分,第一次取值zzh,第二次取值nick
          #2代表的變量,則是第二段可變部分—[001-201],取值從001逐一加到201
          這樣,自定義出來下載下來的文件名,就變成了這樣:
          原來: ~zzh/001.JPG —> 下載后: 001-zzh.JPG
          原來: ~nick/001.JPG —> 下載后: 001-nick.JPG

          這樣一來,就不怕文件重名啦,呵呵

          繼續講下載
          我們平時在windows平臺上,flashget這樣的工具可以幫我們分塊并行下載,還可以斷線續傳。
          curl在這些方面也不輸給誰,嘿嘿

          比如我們下載screen1.JPG中,突然掉線了,我們就可以這樣開始續傳
          curl -c -O

          當然,你不要拿個flashget下載了一半的文件來糊弄我~~~~別的下載軟件的半截文件可不一定能用哦~~~

          分塊下載,我們使用這個option就可以了: -r

          舉例說明
          比如我們有一個 http://cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 要下載(趙老師的電話朗誦)

          我們就可以用這樣的命令:
          curl -r 0-10240 -o “zhao.part1″ http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &
          curl -r 10241-20480 -o “zhao.part1″ http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &
          curl -r 20481-40960 -o “zhao.part1″ http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &
          curl -r 40961- -o “zhao.part1″ http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3

          這樣就可以分塊下載啦。
          不過你需要自己把這些破碎的文件合并起來
          如果你用UNIX或蘋果,用 cat zhao.part* > zhao.mp3就可以
          如果用的是Windows,用copy /b 來解決吧,呵呵

          上面講的都是http協議的下載,其實ftp也一樣可以用。
          用法嘛,
          curl -u name:passwd ftp://ip:port/path/file
          或者大家熟悉的
          curl ftp://name:passwd@ip/path/file

          10)說完了下載,接下來自然該講上傳咯
          上傳的option是 -T

          比如我們向ftp傳一個文件: curl -T localfile -u name:passwd ftp://upload_site/path/

          當然,向http服務器上傳文件也可以
          比如 curl -T localfile http://cgi2.tky.3web.ne.jp/~zzh/abc.cgi
          注意,這時候,使用的協議是HTTP的PUT method

          剛才說到PUT,嘿嘿,自然讓老服想起來了其他幾種methos還沒講呢!
          GET和POST都不能忘哦。

          http提交一個表單,比較常用的是POST模式和GET模式

          GET模式什么option都不用,只需要把變量寫在url里面就可以了
          比如:
          curl http://www.yahoo.com/login.cgi?user&password=12345

          而POST模式的option則是 -d

          比如,curl -d “user=nickwolfe&password=12345″ http://www.yahoo.com/login.cgi
          就相當于向這個站點發出一次登陸申請~~~~~

          到底該用GET模式還是POST模式,要看對面服務器的程序設定。

          一點需要注意的是,POST模式下的文件上的文件上傳,比如

          <input type=”file” name=”upload”><input type=”submit” name=”nick” value=”go”>

          這樣一個HTTP表單,我們要用curl進行模擬,就該是這樣的語法:
          curl -F upload=@localfile -F nick=go http://cgi2.tky.3web.ne.jp/~zzh/up_file.cgi

          羅羅嗦嗦講了這么多,其實curl還有很多很多技巧和用法
          比如 https的時候使用本地證書,就可以這樣
          curl -E localcert.pem https://remote_server

          再比如,你還可以用curl通過dict協議去查字典~~~~~
          curl dict://dict.org/d:computer

          posted @ 2009-03-02 18:01 小馬歌 閱讀(324) | 評論 (0)編輯 收藏
          僅列出標題
          共95頁: First 上一頁 70 71 72 73 74 75 76 77 78 下一頁 Last 
           
          主站蜘蛛池模板: 罗源县| 黄骅市| 云南省| 泰顺县| 玉山县| 镶黄旗| 新宾| 甘南县| 牙克石市| 四平市| 五原县| 从化市| 咸宁市| 体育| 汽车| 汝州市| 长武县| 北川| 祁东县| 威远县| 盐津县| 深水埗区| 巨野县| 依兰县| 大埔区| 昭觉县| 上栗县| 明星| 潮安县| 临沂市| 屏边| 札达县| 上林县| 香港 | 凭祥市| 阜宁县| 那曲县| 林甸县| 青岛市| 民勤县| 乌审旗|