A. C語言分布式系統中的進程標識
本文假定一台機器 (host) 只有一個 IP,不考慮 multihome 的情況。同時假定分布式系統中的每一台機器都正確運行了 NTP,各台機器的時間大體同步。
「進程 process」是操作系統的兩大基本概念之一,指的是在內存中運行的程序。在日常交流中,「進程」這個詞通常不止這一個意思。有時候我們會說 「httpd 進程」或者「mysqld 進程」,指的其實是 program,而不一定是特指某一個「進程」——某一次 fork() 系統調用的產物。一個「httpd 進程」重啟了,它還是「一個 httpd 進程」。本文討論的是,如何為一個程序每次運行 的進程取一個唯一標識符。也就是說,httpd 程序第一次運行,進程是 httpd_1,它原地重啟了,進程是 httpd_2。
本文所指的「進程標識符」是用來唯一標識一個程序的「一次運行」的。每次啟動一個進程,這個進程應該被賦予一個唯一的標識符,與當前正在運行的所有進程都不同;不僅如此,它應該與歷史上曾經運行過,目前已消亡的進程也都不同(這兩條的直接推論是,與將來可能運行的進程也都不同)。「為每個進程命名」在分布式系統中有相當大的實際意義,特別是在考慮 failover 的時候。因為一個程序重啟之後的新進程和它的「前世進程」的狀態通常不一樣,凡是與它打交道的其他進程(s)最好能通過它的進程標識符變更來很容易地判斷該程序已經重啟,而採取必要的救災措施,防止搭錯話。
本文先假定每個服務端程序的埠是靜態分配的,在公司內部有一個公用 wiki 來記錄埠和程序的對應關系(然後通過 NIS 或 DNS 發布)。比如埠 11211 始終對應 memcached,其他程序不會使用 11211 端咐遲口;3306 始終留給 mysqld;3690 始終留給 svnserve。在分布式系統的初級階段,這是通常的做法;到了高級階段,多半會用動態分配埠號,因為埠號只有 6 萬多個,是稀缺資源,在公司內部也有分配完的一天。本文只考慮 TCP 協議,不考慮 UDP 協議,「埠」都指的是 TCP 埠。
另外,我們假定在一台機器上,一個 listening port 同時只能由一個進程使用,不考慮古老的 listen() + fork() 模型(多個進程可以 accept 同一個埠上進來的連接),關於這點陳碩已經寫的很多,見《linux 新增系統調用的啟示 》《多線程伺服器的適用場合 》。
錯誤做法
在分布式系統中,如何指涉(refer to)某一個進程呢,或者說一個進程如衡答李何取得自己的全局標識符 (以下簡稱 gpid)?容易想到的有兩種做法:
*ip:port (port 是這個進程對外提供網路服務的埠號,一般就是它的 tcp listening port)
*host:pid
而這兩種做法都有問題。為什麼?
如果進程本身是無狀態的,或者重啟了也沒有關系,那麼用 ip:port 來標識一個「服務」是沒問題的,比如常見的 httpd 和 memcached 都可以用它們的慣用 port (80 和 11211)來標識。我們可以在其他程序里安全地引用(refer to)「運行在 10.0.0.5:80 的那個 http 伺服器」,或者「10.0.0.6:11211 的 memcached」,就算這兩個 service 重啟了,也不會有太惡劣的後果,大不了客戶端重試一下,或者自動切換到備用地址。
如果服務是有狀態的,那麼 ip:port 這種標識方法就有大問題,因為客戶端無法區分從頭到尾和自己打交道的是一個進程還是先後多個進程。在開發服務端程序的時候,為了能快速重啟,我們一般都會設置 SO_REUSEADDR,這樣的結果是前一秒鍾站在 10.0.0.7:8888 後面的進程和後一秒鍾占據 10.0.0.7:8888 的進程可能不相同——服務端程序快速重啟了。
比方說,考慮一個類似 GFS 的分布式文件系統的 master,如果它僅以 ip:port 來標識自己,然後它舉冊向 shadows (不是 chunk server)下達同步指令,那麼 shadows 如何得知 master 是不是已經重啟呢?發指令的是 master 的「前世」還是「今生」?是不是應該拒絕「前世」的遺命?
如果考慮改成 host:pid 這種標識方式會不會好一點?我認為換湯不換葯,因為 pid 的狀態空間很小,重復的概率比較大。比如 Linux 的 pid 的最大值是 32768 (/proc/sys/kernel/pid_max),一個程序重啟之後,獲得與「前世」相同 pid 的概率是 1/32768。或許有讀者不相信重啟之後 pid 會重復,因為 pid 是遞增的,遇到上限再回到目前空閑的最小 pid。考慮一個服務端程序 A,它的 pid 是 1234,它已經穩定運行了好幾天,這期間,pid 已經增長了幾個輪回(因為這台機器時常會啟動一些 scripts 執行一些輔助工作)。在 A 崩潰的前一刻,最近被使用的 pid 已經回到了 1232,當 A 崩潰之後,某個守護進程啟動一個腳本(pid = 1233)來清理 A 的 log,然後再重啟 A 程序;這樣一來,重啟之後的 A 程序的 pid 碰巧和它的前世相同,都是 1234。也就是說,用 host:pid 不能唯一標識進程。
那麼合在一起,用 ip:port:pid 呢?也不能做到唯一。它和 host:pid 面臨的問題是一樣的,因為 ip:port 這部分在重啟之後不會變,pid 可能輪回。
我猜這時有人會想,建一個中心伺服器,專門分配系統的 gpid 好了,每個進程啟動的時候向它詢問自己的 gpid。這錯得更遠:這個全局 pid 分配器的 gpid 由誰來定?如何保證它分配的 gpid 不重復(考慮這個程序也可能意外重啟)?它是不是成為系統的 single point of failure?如果要對該 gpid 分配器做容錯,是不是面臨分布式系統的基本問題:狀態遷移?
還有一種辦法,用一個足夠強的隨機數做 gpid,這樣一來確實不會重復,但是這個 gpid 本身也沒有多大額外的意義,不便於管理和維護(比方說根據 gpid 找到是哪個機器上運行的哪個進程)。
正確做法:以四元組 ip:port:start_time:pid 作為分布式系統中進程的 gpid,其中 start_time 是 64-bit 整數,表示進程的啟動時刻(UTC 時區,muo::Timestamp)。理由如下:
*容易保證唯一性。如果程序短時間重啟,那麼兩個進程的 pid 必定不重復(還沒有走完一個輪回:就算每秒創建 1000 個進程,也要 30 多秒才會輪回,而以這么高的速度創建進程的話,伺服器已基本癱瘓了。);如果程序運行了相當長一段時間再重啟,那麼兩次啟動的 start_time 必定不重復。(見下文關於時間重復的解釋)
*產生這種 gpid 的成本很低(幾次低成本系統調用),沒有用到全局伺服器,不存在 single point of failure。
*gpid 本身有意義,根據 gpid 立刻就能知道是什麼進程(port),運行在哪台機器(ip),是什麼時間啟動的,在 /proc 目錄中的位置 (/proc/pid) 等,進程的資源使用情況也可以通過運行在那台機器上的監控程序報告出來。
*gpid 具有歷史意義,便於將來追溯。比方說進程 crash,那麼我知道它的 gpid,就可以去歷史記錄中查詢它 crash 之前的 cpu/mem 負載有多大。
如果僅以 ip:port:start_time 作為 gpid,則不能保證唯一性,如果程序短時間重啟(間隔一秒或幾秒),start_time 可能會往回跳變(NTP 在調時間)或暫停(正好處於閏秒期間)。關於時間跳變的問題留給下一篇博客《〈程序中的日期與時間〉第二章:計時與定時》,簡單地說,計算機上的時鍾不一定是單調遞增的。
沒有 port 怎麼辦?一般來說,一個網路服務程序會偵聽某個埠來提供服務,如果它是個純粹的客戶端,只主動發起連接,沒有主動偵聽埠,gpid 該如何分配呢?根據陳碩在《分布式系統的工程化開發方法 》一文中的觀點「在程序里內置 http 伺服器」,分布式系統中的每個長期運行的、會與其他機器打交道的進程都應該提供一個管理介面,對外提供一個維修探查通道,可以查看進程的全部狀態。這個管理介面就是一個 TCP server,它會偵聽某個 port。
使用這樣的維修通道的一個額外好處是,可以自動防止重復啟動程序。因為如果重復啟動,bind 到那個運維 port 的時候會出錯(埠已被佔用),程序會立刻退出。更妙的是,不用擔心進程 crash 沒來得及清理鎖(如果用跨進程的 mutex 就有這個風險),進程關閉的時候操作系統會自動把它打開的 port 都關上,下一個進程可以順利啟動。
進一步,還可以把程序的名稱和版本號作為 gpid 的一部分,這起到錦上添花的作用。
TCP 協議的啟示
我在《分布式系統的工程化開發方法 》中提到「從 TCP 協議能學到什麼?」,今天講的這個 gpid 其實也是由 TCP 協議啟發而來。TCP 用 ip:port 來表示 endpoint,兩個 endpoint 構成一個 socket。這似乎符合一開始提到的以 ip:port 來標識進程的做法。其實不然。在發起 TCP 連接的時候,為了防止前一次同樣地址的連接(相同的 local_ip:local_port:remote_ip:remote_port)的干擾(稱為 wandering plicates ,即流浪的 packets),TCP 協議使用 seq 號碼(這種在 SYN packet 里第一次發送的 seq 號碼稱為 initial sequence number, ISN)來區分本次連接和以往的連接。TCP 的這種思路與我們防止進程的「前世」干擾「今生」很相像。內核每次新建 TCP 連接的時候會設法遞增 ISN 以確保與上次連接最後使用的 seq 號碼不同。相當於說把 start_time 加入到了 endpoint 之中,這就很接近我們後面提到的「正確的 gpid」做法了。(當然,原始 BSD 4.4 的 ISN 生成演算法有安全漏洞,會導致 TCP sequence prediction attack,Linux 內核已經採用更安全的辦法來生成 ISN。)
B. linux 下如何啟動SVN服務。
先轉到SVN的安裝目錄,比如,你安裝在/home/svn 下面。然後轉到bin目錄下,在這里可以看見一個叫svnserve的文件,我們需要用這個來啟動SVN服務。
C. 版本控制在軟體開發中由誰管理
svn版本控制器安裝 分類:學習園地Subversion 系統
多年來,並發版本系統(CVS)一直是在Linux上管理代碼或者文本的標准。作為基於RCS上建立但卻允許多用戶沒宏協作的系統而言,CVS記錄所有文件的修改信息。這對於程序開發者、網路設計者和系統管理員而言,是非常有用的。
然亮基而,CVS逐漸顯示出它的衰老,出現了相似的源代碼管理軟體。然而大多這種東西都是以牟利為主要目的的。
Subversion就是一種相對新鮮的源代碼管理系統。雖然事實敬察謹上它還在不斷的反展之中,但是Subversion已經是一個非常穩定而且成熟的產品。它是一個全新的系統,其功能可以和CVS媲美,同時,它要比CVS更直觀,更容易操作。本文就Subversion的安裝和一些特殊功能作一個介紹。
安裝伺服器端
第一步:下載Apache和SVN源碼包
從官方網站台下載httpd-2.0.52.tar.gz,subversion-1.2.3.tar.gz
(因為redhat 9默認安裝的Apache沒有並包含--enable-so選項,所以無法產生mod_dav_svn.沒有這個模塊,SVN就無法採用http方式運行,所以必須重新編譯新的Apache)
以root身份執行:
#tar zxvf httpd-2.2.0.tar.gz
#cd httpd-2.2.0
#./configure --enable-dav --enable-so --enable-maintainer-mode
#make
#make install
此時會產生/usr/local/apache2目錄,接著執行:
#tar zxvf subversion-1.2.3.tar.gz
#./configure --with-apxs=/usr/local/apache2/bin/apxs
# rm /usr/local/lib/libsvn*
# make clean && make && make install
此時會自動在/usr/local/apache2/conf/httpd.conf添加
LoadMole dav_svn_mole moles/mod_dav_svn.so
安裝完成後,運行svnserver --version確認版本號1.2.3。
SVN伺服器安裝結束.
第二步,創建倉庫 svnadmin create /home/svnrepo
/root/svnrepo為所創建倉庫的路徑,理論上可以是任何目錄
第三步,修改配置文件/home/svnrepo/conf/svnserve.conf
代碼
#去掉#[general]前面的#號
[general]
#匿名訪問的許可權,可以是read,write,none,默認為read
anon-access = none
#認證用戶的許可權,可以是read,write,none,默認為write
auth-access = write
#密碼資料庫的路徑,去掉前面的#
password-db = passwd
注意:所有的行都必須頂格,否則報錯。
建議:為了防止不必要的錯誤,建議你直接用我上面的內容覆蓋掉文件原來的內容
第四步,修改配置文件passwd。
代碼
[users]
sxy = sxy
注意
1. 一定要去掉[users]前面的#,否則svn只能以匿名用戶登錄,客戶端不會出現登錄窗口,除非你的anon不為none,否則將返回一個錯誤。
2. 這里的密碼都是沒有加密的,我按照一些教程所說的用htpasswd生成的密碼無法使用。
第五步,啟動svn服務
對於單個代碼倉庫
啟動命令 svnserve -d -r /home/svnrepo --listen-host 192.168.100.200
其中-d表示在後台運行,-r指定伺服器的根目錄,這樣訪問伺服器時就可以直接用svn://伺服器ip來訪問了。如果伺服器有多ip的話--listen-host來指定監聽的ip地址.
我們可以在svn客戶端中通過svn://192.168.100.200來訪問svn伺服器
對於多個代碼倉庫,我們在啟動時也可以用-r選項來指定伺服器根目錄,但訪問時需要寫上每個倉庫相對於svn根目錄的相對路徑.
比如,我們有兩個代碼倉庫/home/repoa和/home/repob,我們用svnserve -d -r /home --listen-host 192.168.100.200來啟動,那麼在客戶端訪問時可以用svn://192.168.100.200/repoa和svn://192.168.1.200/repob來分別訪問兩個項目
啟動完成以後,我們可以用ps aux|grep svnserv來查看是否存在svnserve進程.
第六步 開放伺服器埠
svn默認埠是3690,你需要在防火牆上開放這個埠。
/sbin/iptables -A INPUT -i eth0 -p tcp --dport 3690 -j ACCEPT
/sbin/service iptables save
你也可以通過svnserve的--listen-port選項來指定一個已經開放的其他埠,不過這樣的話客戶端使用也必須家上埠,如svn://192.168.100.200:9999/.
第七步,使用svn客戶端導入項目
推薦使用客戶端 http://tortoisesvn.tigris.org/
eclipse插件 http://subclipse.tigris.org/
附:svnserve [選項]
有效選項:
-d [--daemon] : 後台模式
--listen-port arg : 監聽埠(後台模式)
--listen-host arg : 監聽主機名或IP地址(後台模式)
--foreground : 在前台運行(調試時有用)
-h [--help] : 顯示這個幫助
--version : 顯示版本信息
-i [--inetd] : inetd 模式
-r [--root] arg : 服務根目錄
-R [--read-only] : 不贊成;使用檔案庫配置文件
-t [--tunnel] : 隧道模式
--tunnel-user arg : 隧道用戶名(模式是當前用戶UID的名字)
-T [--threads] : 使用線程代替進程
-X [--listen-once] : 監聽一次(調試時有用)
安裝客戶機端
window客戶機:
直接安裝TortoiseSVN-1.1.1-UNICODE_svn-1.1.1.msi,方法同一般軟體安裝相同。
Linux客戶機:
方法輿安裝伺服器相同。
(注意redhat 9默認安裝的SVN版本為0.17.1,它的客戶端命令svn無法輿新的SVN伺服器通訊,必須重新安裝)
我是從「上海全鼎軟體學院」畢業的————————
D. linux 查看使用了多少SOCKET
Linux系統中,ss命令可用於查看系統的socket的狀態。
1、命令格式:
ss [參數]
ss [參數] [過濾]
2、命令功能:
ss(Socket Statistics的縮寫)命令可以用來獲取 socket統計信息,此命令輸出的結果類似於
netstat輸出的內容,但它能顯示更多更詳細的 TCP連接狀態的信息,且比 netstat 更快速高效。它使用了 TCP協議棧中
tcp_diag(是一個用於分析統計的模塊),能直接從獲得第一手內核信息,這就使得 ss命令快捷高效。在沒有
tcp_diag,ss也可以正常運行。
3、命令參數:
-h, --help 幫助信息
-V, --version 程序版本信息
-n, --numeric 不解析服務名稱
-r, --resolve 解析主機名
-a, --all 顯示所有套接字(sockets)
-l, --listening 顯示監聽狀態的套接字(sockets)
-o, --options 顯示計時器信息
-e, --extended 顯示詳細的套接字(sockets)信息
-m, --memory 顯示套接字(socket)的內存使用情況
-p, --processes 顯示使用套接字(socket)的進程
-i, --info 顯示 TCP內部信息
-s, --summary 顯示套接字(socket)使用概況
-4, --ipv4 僅顯示IPv4的套接字(sockets)
-6, --ipv6 僅顯示IPv6的套接字(sockets)
-0, --packet 顯示 PACKET 套接字(socket)
-t, --tcp 僅顯示 TCP套接字(sockets)
-u, --udp 僅顯示 UCP套接字(sockets)
-d, --dccp 僅顯示 DCCP套接字(sockets)
-w, --raw 僅顯示 RAW套接字(sockets)
-x, --unix 僅顯示 Unix套接字(sockets)
-f, --family=FAMILY 顯示 FAMILY類型的套接字(sockets),FAMILY可選,支持 unix, inet, inet6, link, netlink
-A, --query=QUERY, --socket=QUERY
QUERY := {all|inet|tcp|udp|raw|unix|packet|netlink}[,QUERY]
-D, --diag=FILE 將原始TCP套接字(sockets)信息轉儲到文件
-F, --filter=FILE 從文件中都去過濾器信息
FILTER := [ state TCP-STATE ] [ EXPRESSION ]
4、使用實例:
顯示TCP連接
命令:ss -t -a
輸出:
代碼如下:
[root@localhost ~]# ss -t -a
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 0 127.0.0.1:smux *:*
LISTEN 0 0 *:3690 *:*
LISTEN 0 0 *:ssh *:*
ESTAB 0 0 192.168.120.204:ssh 10.2.0.68:49368
[root@localhost ~]#
E. Linux怎麼使用ss命令查看系統的socket狀態
ss是Socket Statistics的縮寫。顧名思義,ss命令可以用來獲取socket統計信息,它可以顯示和netstat類似的內容。但ss的優勢在於它能夠顯示更多更詳細的有關TCP和連接狀態的信息,而且比netstat更快速更高效。當伺服器的socket連接數量變得非常大時,無論是使用netstat命令還是直接cat /proc/net/tcp,執行速度都會很慢。可能你不會有切身的感受,但請相信我,當伺服器維持的連接達到上萬個的時候,使用netstat等於浪費 生命,而用ss才是節省時間。天下武功唯快不破。ss快的秘訣在於,它利用到了TCP協議棧中tcp_diag。tcp_diag是一個用於分析統計的模塊,可以獲得Linux 內核中第一手的信息,這就確保了ss的快捷高效。當然,如果你的系統中沒有tcp_diag,ss也可以正常運行,只是效率會變得稍慢。(但仍然比 netstat要快。)
命令格式:
ss [參數]
ss [參數] [過濾]
2.命令功能:
ss(Socket Statistics的縮寫)命令可以用來獲取 socket統計信息,此命令輸出的結果類似於 netstat輸出的內容,但它能顯示更多更詳細的 TCP連接狀態的信息,且比 netstat 更快速高效。它使用了 TCP協議棧中 tcp_diag(是一個用於分析統計的模塊),能直接從獲得第一手內核信息,這就使得 ss命令快捷高效。在沒有 tcp_diag,ss也可以正常運行。
3.命令參數:
-h, --help 幫助信息
-V, --version 程序版本信息
-n, --numeric 不解析服務名稱
-r, --resolve 解析主機名
-a, --all 顯示所有套接字(sockets)
-l, --listening 顯示監聽狀態的套接字(sockets)
-o, --options 顯示計時器信息
-e, --extended 顯示詳細的套接字(sockets)信息
-m, --memory 顯示套接字(socket)的內存使用情況
-p, --processes 顯示使用套接字(socket)的進程
-i, --info 顯示 TCP內部信息
-s, --summary 顯示套接字(socket)使用概況
-4, --ipv4 僅顯示IPv4的套接字(sockets)
-6, --ipv6 僅顯示IPv6的套接字(sockets)
-0, --packet 顯示 PACKET 套接字(socket)
-t, --tcp 僅顯示 TCP套接字(sockets)
-u, --udp 僅顯示 UCP套接字(sockets)
-d, --dccp 僅顯示 DCCP套接字(sockets)
-w, --raw 僅顯示 RAW套接字(sockets)
-x, --unix 僅顯示 Unix套接字(sockets)
-f, --family=FAMILY 顯示 FAMILY類型的套接字(sockets),FAMILY可選,支持 unix, inet, inet6, link, netlink
-A, --query=QUERY, --socket=QUERY
QUERY := {all|inet|tcp|udp|raw|unix|packet|netlink}[,QUERY]
-D, --diag=FILE 將原始TCP套接字(sockets)信息轉儲到文件
-F, --filter=FILE 從文件中都去過濾器信息
FILTER := [ state TCP-STATE ] [ EXPRESSION ]
4.使用實例:
實例1:顯示TCP連接
命令:ss -t -a
輸出:
代碼如下:
[root@localhost ~]# ss -t -a
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 0 127.0.0.1:smux *:*
LISTEN 0 0 *:3690 *:*
LISTEN 0 0 *:ssh *:*
ESTAB 0 0 192.168.120.204:ssh 10.2.0.68:49368
[root@localhost ~]#
實例2:顯示 Sockets 摘要
命令:ss -s
輸出:
代碼如下:
[root@localhost ~]# ss -s
Total: 34 (kernel 48)
TCP: 4 (estab 1, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 3《/p》 《p》Transport Total IP IPv6
* 48 - -
RAW 0 0 0
UDP 5 5 0
TCP 4 4 0
INET 9 9 0
FRAG 0 0 0
[root@localhost ~]#
說明:列出當前的established, closed, orphaned and waiting TCP sockets
實例3:列出所有打開的網路連接埠
命令:ss -l
輸出:
代碼如下:
[root@localhost ~]# ss -l
Recv-Q Send-Q Local Address:Port Peer Address:Port
0 0 127.0.0.1:smux *:*
0 0 *:3690 *:*
0 0 *:ssh *:*
[root@localhost ~]#
實例4:查看進程使用的socket
命令:ss -pl
輸出:
代碼如下:
[root@localhost ~]# ss -pl
Recv-Q Send-Q Local Address:Port Peer Address:Port
0 0 127.0.0.1:smux *:* users:((「snmpd」,2716,8))
0 0 *:3690 *:* users:((「svnserve」,3590,3))
0 0 *:ssh *:* users:((「sshd」,2735,3))
[root@localhost ~]#
實例5:找出打開套接字/埠應用程序
命令:ss -lp | grep 3306
輸出:
代碼如下:
[root@localhost ~]# ss -lp|grep 1935
0 0 *:1935 *:* users:((「fmsedge」,2913,18))
0 0 127.0.0.1:19350 *:* users:((「fmsedge」,2913,17))
[root@localhost ~]# ss -lp|grep 3306
0 0 *:3306 *:* users:((「mysqld」,2871,10))
[root@localhost ~]#
實例6:顯示所有UDP Sockets
命令:ss -u -a
輸出:
代碼如下:
[root@localhost ~]# ss -u -a
State Recv-Q Send-Q Local Address:Port Peer Address:Port
UNCONN 0 0 127.0.0.1:syslog *:*
UNCONN 0 0 *:snmp *:*
ESTAB 0 0 192.168.120.203:39641 10.58.119.119:domain
[root@localhost ~]#
實例7:顯示所有狀態為established的SMTP連接
命令:ss -o state established 『( dport = :smtp or sport = :smtp )』
輸出:
代碼如下:
[root@localhost ~]# ss -o state established 『( dport = :smtp or sport = :smtp )』
Recv-Q Send-Q Local Address:Port Peer Address:Port
[root@localhost ~]#
實例8:顯示所有狀態為Established的HTTP連接
命令:ss -o state established 『( dport = :http or sport = :http )』
輸出:
代碼如下:
[root@localhost ~]# ss -o state established 『( dport = :http or sport = :http )』
Recv-Q Send-Q Local Address:Port Peer Address:Port
0 0 75.126.153.214:2164 192.168.10.42:http
[root@localhost ~]#
實例9:列舉出處於 FIN-WAIT-1狀態的源埠為 80或者 443,目標網路為 193.233.7/24所有 tcp套接字
命令:ss -o state fin-wait-1 『( sport = :http or sport = :https )』 dst 193.233.7/24
實例10:用TCP 狀態過濾Sockets:
命令:
代碼如下:
ss -4 state FILTER-NAME-HERE
ss -6 state FILTER-NAME-HERE
輸出:
代碼如下:
[root@localhost ~]#ss -4 state closing
Recv-Q Send-Q Local Address:Port Peer Address:Port
1 11094 75.126.153.214:http 192.168.10.42:4669
說明:
FILTER-NAME-HERE 可以代表以下任何一個:
代碼如下:
established
syn-sent
syn-recv
fin-wait-1
fin-wait-2
time-wait
closed
close-wait
last-ack
listen
closing
all : 所有以上狀態
connected : 除了listen and closed的所有狀態
synchronized :所有已連接的狀態除了syn-sent
bucket : 顯示狀態為maintained as minisockets,如:time-wait和syn-recv.
big : 和bucket相反。
實例11:匹配遠程地址和埠號
命令:
代碼如下:
ss dst ADDRESS_PATTERN
ss dst 192.168.1.5
ss dst 192.168.119.113:http
ss dst 192.168.119.113:smtp
ss dst 192.168.119.113:443
輸出:
代碼如下:
[root@localhost ~]# ss dst 192.168.119.113
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 192.168.119.103:16014 192.168.119.113:20229
ESTAB 0 0 192.168.119.103:16014 192.168.119.113:61056
ESTAB 0 0 192.168.119.103:16014 192.168.119.113:61623
ESTAB 0 0 192.168.119.103:16014 192.168.119.113:60924
ESTAB 0 0 192.168.119.103:16050 192.168.119.113:43701
ESTAB 0 0 192.168.119.103:16073 192.168.119.113:32930
ESTAB 0 0 192.168.119.103:16073 192.168.119.113:49318
ESTAB 0 0 192.168.119.103:16014 192.168.119.113:3844
[root@localhost ~]# ss dst 192.168.119.113:http
State Recv-Q Send-Q Local Address:Port Peer Address:Port
[root@localhost ~]# ss dst 192.168.119.113:3844
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 192.168.119.103:16014 192.168.119.113:3844
[root@localhost ~]#
實例12:匹配本地地址和埠號
命令:
代碼如下:
ss src ADDRESS_PATTERN
ss src 192.168.119.103
ss src 192.168.119.103:http
ss src 192.168.119.103:80
ss src 192.168.119.103:smtp
ss src 192.168.119.103:25
輸出:
代碼如下:
[root@localhost ~]# ss src 192.168.119.103:16021
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 192.168.119.103:16021 192.168.119.201:63054
ESTAB 0 0 192.168.119.103:16021 192.168.119.201:62894
ESTAB 0 0 192.168.119.103:16021 192.168.119.201:63055
ESTAB 0 0 192.168.119.103:16021 192.168.119.201:2274
ESTAB 0 0 192.168.119.103:16021 192.168.119.201:44784
ESTAB 0 0 192.168.119.103:16021 192.168.119.201:7233
ESTAB 0 0 192.168.119.103:16021 192.168.119.103:58660
ESTAB 0 0 192.168.119.103:16021 192.168.119.201:44822
ESTAB 0 0 192.168.119.103:16021 10.2.1.206:56737
ESTAB 0 0 192.168.119.103:16021 10.2.1.206:57487
ESTAB 0 0 192.168.119.103:16021 10.2.1.206:56736
ESTAB 0 0 192.168.119.103:16021 10.2.1.206:64652
ESTAB 0 0 192.168.119.103:16021 10.2.1.206:56586
ESTAB 0 0 192.168.119.103:16021 10.2.1.206:64653
ESTAB 0 0 192.168.119.103:16021 10.2.1.206:56587
[root@localhost ~]#
實例13:將本地或者遠程埠和一個數比較
命令:
代碼如下:
ss dport OP PORT
ss sport OP PORT
輸出:
代碼如下:
[root@localhost ~]# ss sport = :http
[root@localhost ~]# ss dport = :http
[root@localhost ~]# ss dport \》 :1024
[root@localhost ~]# ss sport \》 :1024
[root@localhost ~]# ss sport \《 :32000
[root@localhost ~]# ss sport eq :22
[root@localhost ~]# ss dport != :22
[root@localhost ~]# ss state connected sport = :http
[root@localhost ~]# ss \( sport = :http or sport = :https \)
[root@localhost ~]# ss -o state fin-wait-1 \( sport = :http or sport = :https \) dst 192.168.1/24
說明:
ss dport OP PORT 遠程埠和一個數比較;ss sport OP PORT 本地埠和一個數比較。
OP 可以代表以下任意一個:
《= or le : 小於或等於埠號
》= or ge : 大於或等於埠號
== or eq : 等於埠號
!= or ne : 不等於埠號
《 or gt : 小於埠號
》 or lt : 大於埠號
實例14:ss 和 netstat 效率對比
命令:
代碼如下:
time netstat -at
time ss
輸出:
代碼如下:
[root@localhost ~]# time ss
real 0m0.739s
user 0m0.019s
sys 0m0.013s
[root@localhost ~]#
[root@localhost ~]# time netstat -at
real 2m45.907s
user 0m0.063s
sys 0m0.067s
[root@localhost ~]#
說明:
用time 命令分別獲取通過netstat和ss命令獲取程序和概要佔用資源所使用的時間。在伺服器連接數比較多的時候,netstat的效率完全沒法和ss比。
F. p2v遷移Linux主機報錯,出現了常規系統錯誤:由於目標主機積極拒絕,無
問題是伺服器未啟動Subversion服務,或改變埠所致。多數因為安裝的時候選用了埠,加上埠即可(80、8080、43等)。Windows下通過任務管理器查看svnserve.exe進程是否運行,如有則記錄 PID,然後在命令行中運行netstat -ano,查看對應PID的埠號(Subversion服務的默認埠號為3690)。如是埠改變,則需要在SVN檢出URL中增加埠號。增加並運行Subversion服務。
G. windows svn 客戶端連不上linux svn server
能ping通只說兄明明網路通了,並不說明你的SVN服務啟動了。
從你截圖看,至少url就不對,url最後肯定要指向你新建的版本庫,也就是說末尾肯定不會是3690,3690是你指定的埠號。你前面已經用httpd了,那肯定是用http協議了,怎麼還用御嘩在svn協羨拆告議?如果改成http協議,那3690前面也應該是冒號而不是/號。
如果是剛接觸SVN,建議你用Collabnet SVN Edge來架設SVN伺服器吧,安裝配置比較省心,可以省去很多麻煩
H. windows下svn遷移到linux
將windows上svn遷移到linux上
實現svn方式和http方式訪問
進入conf目錄
authz :負責test3庫的賬號許可權管理,控制賬號是否讀寫許可權
passwd :負責test3庫的賬號和密碼管理,注意密碼是明文的
svnserve.conf :svn伺服器配置文件
示例:
啟動:
埠:3690 注意打開防火牆
訪問:
svn://192.168.1.206:3690/test3
用mod_dav_svn模塊實現Apache服務進行訪問svn倉庫,mod_dav_svn是Apache和svn之間的介面
SVNParentPath /svn/svndir
指如果有多個版本庫建議使用SVNParentPath不使用SVNPath,/svn/svndir 版本庫位置
AuthUserFile /svn/svndir/passwd
指後面使用apache的htpasswd創建的用戶名密扒櫻碼
AuthzSVNAccessFile /svn/svndir/authz
指許可權文件
創建用戶並設置密碼
此時可以通過
http://192.168.1.206/svn/test3
在瀏覽器中輸入用戶名密碼訪問
直接將windows下Repositories目錄下的數據打包遷移到linux下的Repositories即可訪問,但是用戶名和密碼不可以遷移,需要重建
1 注意許可權為問題,如果/svn/svndir屬主不是apache,會一直訪問拒絕訪問
2 svn協助與http協議
svn協議,用於客戶端使用svn://方式訪問版本庫,而mod_authz_svn模塊讓客戶端可通過Apache訪問版本庫,它們分別使用不同的服務:svnserve、httpd進行訪問。由於用戶、組許可權不同,許可權管理方式也不相同,因此沒此游,不建議同時啟動兩種訪問方式。
而易用性,管理方便的角度來分析,Apache以,mod_authz_svn模塊的方式訪問版本庫會更多人選擇。(mod_authz_svn方式,使用80埠訪問,並且提供https等加密傳輸,用於用戶信息驗證的密碼枯銷保存方式不是明文的)
I. 如何在windows上安裝部署設置SVN伺服器
一、准備工作
1、SVN伺服器:解壓縮包,可以從官方網站下載最新版本。
2、SVN客戶端:TortoiseSVN,即常說的小烏龜,是一個客戶端程序,用來與伺服器端通訊。
二、安裝伺服器和客戶端程序
1、SVN伺服器:直接解壓縮到某個文件夾下即可。示例路徑:c:\svn\
備註:如果下載的是msi程序,直接運行按提示安裝即可。
2、SVN客戶端:直接運行按提示安裝即可。示例路徑:C:\Program
Files\Subversion
三、建立版本庫(Repository):示例路徑:e:\svnroot。建立版本庫有兩種方法:
方法一,建立空目錄e:\svnroot\repos1,進入repos1文件夾,在空白處點擊右鍵,選擇「TortoiseSVN->Create
Repositoryhere...」,
方法二,建立空目錄e:\svnroot\repos2,進入DOS命令行,輸入如下命令:
svnadmincreate
e:\svnroot\repos2
四、運行SVN伺服器,啟動服務。啟動服務有兩種方法:
方法一,臨時啟動服務,在DOS下輸入如下命令:
svnserve
-d
-r
e:\svnroot\repos1
--listen-host
ip地址
--listen-port=埠號
說明:「listen-host」和「listen-port」可選。默認埠是3690,如果埠已經被佔用,可以通過選項listen-port指定埠號。
注意:請不要關閉命令行窗口,關閉窗口會把
svn服務就停止了。
方法二,啟動SVN服務為後台運行程序:
sc
create
svnserve
binPath=
"c:\svn\bin\svnserve.exe
--service
-r
e:\svnroot\repos1"
displayname=
"Subversion"
depend=Tcpip
start=
auto
說明一:
(1)sc是windows自帶的服務配置程序。svnserve是服務的名稱,可根據需求取名。
(2)參數binPath表示svnserve可執行文件的安裝路徑。
(3)--service表示以windows服務的形式運行,--r指明svnrepository的位置,service參數與r參數都作為binPath的一部分,因此與svnserve.exe的路徑一起被包含在一對雙引號當中。
(4)displayname表示在windows服務列表中顯示的名字,depend=Tcpip表示svnserve服務的運行需要tcpip服務,start=auto表示開機後自動運行。安裝服務後,svnserve要等下次開機時才會自動運行。
說明二:
(1)binPath的等號前面無空格,等號後面有空格。displayname、depend、start也一樣,service前面是--,不是-
,而r前面是-。
(2)若要卸載svn服務,則執行
sc
delete
svnserve
即可。
(3)從「sc」到「auto」是在同一個命令sc,必須寫在同一行。
(4)啟動服務命令:netstart
svnserve,停止服務命令:net
start
svnserve,也可以進入Windows提供的界面操作SVNService服務了,即控制面板—>服務。
(5)如果路徑中包括空格,一定要用「\」處理「"」號,例如上面的例子中如果svnserve.exe在「c:\programfiles\svn\」中,則命令應該寫為「binpath="\"c:\programfiles\svn\bin\svnserve.exe\"
五、配置用戶和許可權
(1)修改svnserve.conf,在e:\svn\repos1\conf目錄下,用文本編輯器打開svnserve.conf:
將:
#
anon-access
=
read
#
auth-access
=
write
#
password-db
=
passwd
改為
anon-access
=
read
auth-access
=
write
password-db
=
passwd
注意說明:
anon-access等列前面是沒有空格的。
anon-access
=
read表示沒通過用戶名密碼登錄的訪問只有讀的許可權,如果改為none則沒有用戶名密碼不能訪問
auth-access
=
write表示通過用戶名密碼登錄的有寫的許可權(當然讀的許可權也就有了)
password-db
=
passwd表示可以通過
用戶名
=
密碼
的方式在passwd文件中添加用戶
(2)修改同目錄的passwd文件,增加用戶帳號:
將:
[users]
#
harry
=
harryssecret
#
sally
=
sallyssecret
添加帳號:
[users]
#
harry
=
harryssecret
#
sally
=
sallyssecret
admin
=
admin
添加一個admin賬戶,密碼是admin。
6
六、初始化SVN,導入數據
選中要上傳SVN的文件夾,「右鍵
->TortoiseSVN
->
Import...」
,在彈出對話框的「URL
of
repository」輸入「svn://localhost/project1/」。在「Importmessage」輸入注釋,點擊OK,要求輸入帳號,輸入賬戶admin和密碼admin。
7
七,測試SVN
本地測試:新建一空文件夾test1,單擊右鍵,選擇「SVN
Checkout」,在「URL
of
repository」中輸入「svn://localhost/project1」。
其他機器測試:如果運行svnserve的主機IP地址是1.2.3.4,則URL輸入的內容就是「svn://1.2.3.4/project1」。
J. 在linux下 查看埠是否打開 ,輸入netstat -an | grep 3690 後什麼都沒顯示 是代表什麼意識 沒打開嗎
什麼都沒顯示的話那就代表3690埠未打開。
我個人netstat後面加的習慣參數是:anptlu
eg:netstat -anptlu | grep 埠號
補充如下:
netstat [選項]
命令中各選項的含義如下:
-a 顯示所有socket,包括正在監聽的。
-c 每隔1秒就重新顯示一遍,直到用謹山戶中斷它。
-i 顯示所有網路介面的信息,格式同「ifconfig -e」。
-n 以網路IP地址代替名稱,顯示出網路連接情形。
-r 顯示攜或核心路由表,格式同「route -e」。
-t 顯示TCP協議的連接情況。
-u 顯示UDP協議的連接情況。
-v 顯示正在進行的工作。
-A 顯示任何關聯的協議控制塊的地址。主要用於調試
-a 顯示所有套接字的狀態。在一般情況下不顯示與伺服器進程相關聯的套接字
-i 顯示自動配置介面的狀態。那些在系統初始引導後配置的介面狀態不在輸出之列
-m 列印網路存儲器的使用情況
-n 列印實際地址,而不是對地址的解釋或者顯示主機辯晌伍,網路名之類的符號
-r 列印路由選擇表
-f address -family對於給出名字的地址簇列印統計數字和控制塊信息。到目前為止,唯一支持的地址簇是inet
-I interface 只列印給出名字的介面狀態
-p protocol-name 只列印給出名字的協議的統計數字和協議控制塊信息
-s 列印每個協議的統計數字
-t 在輸出顯示中用時間信息代替隊列長度信息。