勤加練習,必能得心應手!不期速成,日拱一卒?!
態度決定一切 |
1. 什么是尋址空間
尋址空間一般指的是CPU對于內存尋址的能力。通俗地說,就是能最多用到多少內存的一個問題
2. 我們經常聽說32位操作系統最多能用4G內存。大部分情況下,這個上限都達不到。例如我的機器,雖然是4G物理內存,但實際上識別的只有3G。有的朋友說是可以識別到3.2G或者3.5G不等,我想這跟人品是沒有什么關系的
那么,這剩下的1個G左右的內存不是浪費了嗎?可不是嘛,太心痛了。所有很多朋友都用一個軟件將這部分內存轉換為硬盤用
http://blog.miniasp.com/post/2008/04/Useful-tools-Gavotte-Ramdisk.aspx
【備注】我自己還沒有這么用,要想試用該功能的同學,自己需要慎重。如果你用的好,記得反饋一下給我,呵呵
3. 為什么說只能尋址到這個大小呢?我今天是要從程序的角度來解說一下
首先說什么是32位?32位是針對CPU的一個術語
對于程序員來說,這表示了我們在與計算機打交道的時候,能夠使用的最大數字是2的32次方。這等于多少呢?
那么這個數字是什么為單位呢?bit ,也可以稱為比特,或者位。這是計算機可以理解的東西。這個bit里面包含的值,只有兩個,就是0和1
好了,那么這個bit怎么樣能轉換為GB呢,很簡單:將它連續除以3次1024.
4294967296/1024/1024/1024
結果等于多少呢?
為什么除3次?第一次轉換為KB,第二次轉換為MB,第三次就轉換為GB了
4. 那么64位的CPU的尋址空間可以到多大呢?
我算一算,可以到多少GB呢?
額的神啊,根據摩爾定律的計算,我想我的有生之年是不需要擔心內存不夠用的問題的
感覺防火墻可能不能完美的保護主機,比如ping措施,這時,就需要使用iptables來進行配置。
使用Iptables的內置firewall機制,是通過kernel中的netfilter 模塊實現的,Linux kernel使用netfilter對進出數據包進行過濾,netfilter由三個規則表組成,每個表又有許多內建的鏈組成。使用iptables命令可以對這些表鏈進行操作,如添加、刪除、列出規則等。
Netfilter 規則表 --- filter nat managle
filter用于路由網絡數據包。是默認的,也就是說如果沒有指定-t參數,當創建一條新規則時,他默認存放到該表內。
INPUT 網絡數據包流向服務器
OUTPUT 網絡數據包從服務器流出
FORWARD 網絡數據包經服務器路由
nat 用于NAT表 Net Address Translation 是一種IP地址轉換方法
PREROUTING 網絡數據包到達服務器時可以被修改
POSTROUTING 網絡數據包在即將從服務器發出時可以被修改
managle 用于修改網絡數據包的表
配置iptables
當數據包進入服務器時,Linux kernel會查找對應的鏈,直到找到一條規則與數據包匹配。如果該規則的target是ACCEPT,就會跳過剩下的規則,數據包會繼續被傳送。如果該規則target是DROP,該數據包會被攔截掉,kernel不會在參考其他規則。
Note:如果從始至終都沒有一條規則與數據包匹配,而且表末尾有沒有drop all規則,那么該數據包會被accept。Cisco則相反,在表末尾會因含deny all的規則。
1) iptables命令選項
iptables [-t iptables ] command option parameter target
-A 在鏈尾添加一條規則
-C 將規則添加到用戶定義鏈之前對其進行檢查
-D 從鏈中刪除一條規則
-E重命名用戶定義的鏈,不改變鏈本身
-F 清空鏈,刪除鏈上的所有規則
-I在鏈中插入一條規則
-L 列出某個鏈上的規則,如:iptables –L INPUT 列出INPUT鏈上的規則
-N 創建一個新鏈
-P 定義某個鏈的默認策略
-R替換鏈上的某條規則
-X 刪除某個用戶相關的鏈
-Z 將所有表的所有鏈的字節和數據包統計數器清零
2) Iptables的命令參數
-p protocol
應用于數據包的協議類型,可以是TCP UDP ICMP 或 ALL ! 也可以
當使用-p tcp時,還可使用其他可選項,一邊允許進一步定義規則,選項如下:
-sport 允許指定匹配數據包源端口 port1:port2表示port1和port2之間的所有端口
-dport目的端口,和sport雷同
當使用-p !udp 時,也有特殊的選項供使用
-sport和-dport與-p tcp相同,只不過用于UDP包
使用-p icmp參數時,只有一個選項可用
-icmp-type 允許在過濾規則中指定icmp類型
-s source 指定數據包包的源地址,該參數后跟一個IP地址,一個帶有sub-net mask的網絡地址,或者一個主機名(不建議使用主機名)
-d destination 數據包的目的地址 同-s
-j jump 用于指定一個target,告訴規則將該匹配的數據包發送到該target。Target可以是ACCEPT,DROP,QUEIE,PETURN。如果沒有-j,那么不會對數據包進行任何操作,只是將計數器加1
-I in-interface 對于INPUT FOREARD PREROUTING鏈,指定數據包到達服務器時所使用的端口
-o out-interface 對于OUTPUT FORWARD POSTROUTING鏈,該參數指定數據包離開服務器時使用的端口
3)Iptables的命令target
創建規則最后一步是指定iptables對數據包的操作。只要某一規則匹配該數據包,就不會再有別的規則的操作。內建的target有:ACCEPT 允許數據包通過 ,到達目的地
DROP 拒絕數據包通過,丟棄該包
QUEUE 將數據包發送回到用戶應用程序處理
RETURN 不再根據當前鏈的其他規則來檢查數據包,而是直接返回,繼續被發送到其目的地址,或下一個鏈。
2、示例:
允許www
Iptables –A INPUT –p tcp –dport 80 –j ACCEPT
該規則被調價到filter表的INPUT鏈,允許目的端口為80的數據包通過
在內部接口上允許DHCP
Iptables –A INPUT –I eth0 –p tcp - - sport - - dport 67 ACCEPT
Iptables –A INPUT –I eth0 –p udp - - sport - - dport 67 ACCEPT
同時允許tcp和udp協議
3、保存和修改iptables
使用iptables-save 可將現行的iptables規則保存
恢復iptables
使用iptables-restore可從配置文檔恢復iptables表到現行iptables表。
這么多年來,數據壓縮對我們來說是非常有用的。無論是在郵件中發送的圖片用的zip文件 還是在服務器壓縮數據文件,我們都可以讓下載更容易或者有效的節約磁盤空間。某些壓縮格式有時允許我們以60%的比率(甚至更高)壓縮文件。下面我將會給 大家演示如何用這些命令在Linux下面去壓縮文件或者目錄。我們將學習zip, tar, tar.gz和tar.bz2等壓縮格式的基本用法。這幾個是在Linux里面常用的壓縮格式。
在我們探究這些用法之前,我想先跟大家分享一下使用不同壓縮格式的經驗。當然,我這里講到的只是其中的一些用法,除我講到的之外,他們還有更多的地 方值得我們探討。我已經意識到我需要了解兩到三種壓縮格式,才能更好的使用他們。zip格式是第一個需要了解的格式。因為它實際上已成為壓縮文件的標準選 擇,而且它在windows上也能使用。我經常用zip格式壓縮那些需要共享給windows用戶的文件。如果只是共享給linux用戶或者Mac用戶, 那我偏向于選擇tar.gz格式。
ZIP
zip可能是目前使用得最多的文檔壓縮格式。它最大的優點就是在不同的操作系統平臺,比如Linux, Windows以及Mac OS,上使用。缺點就是支持的壓縮率不是很高,而tar.gz和tar.gz2在壓縮率方面做得非常好。閑話少說,我們步入正題吧:
我們可以使用下列的命令壓縮一個目錄:
下面是如果解壓一個zip文檔:
TAR
Tar是在Linux中使用得非常廣泛的文檔打包格式。它的好處就是它只消耗非常少的CPU以及時間去打包文件,他僅僅只是一個打包工具,并不負責壓縮。下面是如何打包一個目錄:
如何解包:
上面這個解包命令將會將文檔解開在當前目錄下面。當然,你也可以用這個命令來捏住解包的路徑:
TAR.GZ
這種格式是我使用得最多的壓縮格式。它在壓縮時不會占用太多CPU的,而且可以得到一個非常理想的壓縮率。使用下面這種格式去壓縮一個目錄:
解壓縮:
上面這個解包命令將會將文檔解開在當前目錄下面。當然,你也可以用這個命令來捏住解包的路徑:
TAR.BZ2
這種壓縮格式是我們提到的所有方式中壓縮率最好的。當然,這也就意味著,它比前面的方式要占用更多的CPU與時間。這個就是你如何使用tar.bz2進行壓縮。
上面這個解包命令將會將文檔解開在當前目錄下面。當然,你也可以用這個命令來捏住解包的路徑:
數據壓縮是非常有用的,尤其是對于備份來說。所以,你現在應該考慮在你的備份腳本中使用你在這里學到的壓縮方式備份你基本的規則文件以減小你備份文件的大小。
過段時間之后,你就會意識到,在壓縮率與CPU占用時間上會有一個平衡,你也要學會如何去權衡什么時候你需要一個快但是壓縮率低,什么時候需要一個壓縮率高但是CPU點用高的壓縮方式,然后你才能避免無謂的空間與時間。
來自http://www.novell.com/
XEN遷移/保存/掛起都要保存虛擬機狀態快照,只要對于該虛擬機的memory、deviceI/O states、network connecitions and the contents of the virtual CPU registers.XEN有能力來保存所有這些信息到一個磁盤中,然后再所遷移的節點上重啟該虛擬機。
1、 SAVE & RESTORE MIGRATION
當你保存或掛起虛擬機時,對應的虛擬機資源不會再分配著,會返回給domain0(host server)。這些資源會被節點上運行著的虛擬機所使用。也就意味著保存或掛起的虛擬機的網絡連接同樣也丟失了。
虛擬機保存和恢復功能可以被用于很多用途包括測試、調試、遷移虛擬機、系統崩潰快速恢復。例如如果一個虛擬機宕機了,可以快速恢復到一個已知的工作狀態。
熱遷移:xm migrate
1、 首先檢查目的服務器上是否有足夠的資源來運行指定的虛擬機。
2、 執行虛擬機內存的初始拷貝,并將其傳輸到目的地服務器。
3、 每次連續迭代,初始拷貝之后,只有內存在內傳輸到目的地服務器過度中是變化的。
4、 當內存頁變化足夠低時或者剩余的頁數傳輸并沒有漸減當隨著虛擬機被傳輸到目的地服務器最終的狀態時。
5、 虛擬機控制器被傳輸到指定的主機服務器上。
你的環境中實現熱遷移需檢查如下:
1、 對于遷移兩個XEN主機服務器的之間需正確的被配置。
2、 兩個主機之間要有一個快速穩定的網絡連接,兩個服務器都必須在相同的第2層網絡和IP子網,這樣準許網絡連接遷移到虛擬機。
3、 兩個主機服務器通過共享存儲方式來訪問,強烈推薦指定虛擬機的磁盤鏡像和配置文件要放到共享存儲。
4、 在兩臺主機之間XEN版本相同。
對于遷移工作,現在執行一些初始設置。
1、 Edit xend the configuration file
Xend-config.sxp是主要的配置文件對于XEN daemon(XEN守護進程)
Using a text editor such as vi or gedit open /etc/xen/xend-config.sxp.
詳細檢查該文件,確認下面這行沒有被注釋掉。
設置如下所示的值
(xend-relocation-server yes)
(xend-relocation-port 8002)
(xend-relocation-address ‘’)
(xend-relocation-hosts-allow ‘’)
The xend-relocation-address操作允許你指定IP地址,XEN daemon監聽遷移請求,保留空白設置表示讓該服務器監聽所有端口,The xend-relocation-hosts-allow 允許選項,限制哪些主機可以聯系遷移請求的服務器,理想情況下你應該限制對服務器的訪問,使用該選項,以提供更好的安全性。
如果你的運行的服務器開放了防火墻,則你要確保你網卡指定IP上的8002端口被打開。
2、 Migrate a virtual machine
遷移虛擬機格式是非常簡單的,xm migrate DomainId destHostID
Eg: xm migrate 1 10.0.0.56
可以在目的地服務器上執行xm list確認主機是否成功被遷移。
正規執行遷移命令是不帶任何參數的,xm migrate
我們可以添加-live 選項執行遷移操作,xm migrate –live 1 10.0.0.56,此時是用的熱方法,很好的測試方式是通過ping 虛擬機的IP地址,看看有多少包丟失了。
軟件系統的并發控制一般是通過加鎖(有樂觀鎖和悲觀鎖兩種)來實現,樂觀鎖是一種事后補救措施,是通過程序的邏輯控制版本來實現的,而悲觀鎖是事前的一種預防措施,它利用數據庫的鎖機制來實現。
雖然樂觀鎖能夠提高系統的性能,但它是對發生沖突的訪問進行事后的補救,應用在用戶輸入數據量很少的場合比較適合,但如果在企業ERP,用戶與系統交互涉及大量數據在頁面表單上錄入,如果事后提交失敗后才提示用戶要重新錄入是很不現實的,所以有必要進行事前控制,這就要采用悲觀鎖。
在多個客戶端可能讀取同一筆數據或同時更新一筆數據的情況下,防止同一個數據被修改而造成混亂,最簡單的手段就是在讀取時對數據進行鎖定,其它客戶端不能對同一筆數據進行更新的讀取動作。
一個典型的倚賴數據庫的悲觀鎖調用:
select * from account where name=”John” for update
這條 sql 語句鎖定了 account 表中所有符合檢索條件(name=”Erica”)的記錄。本次事務提交之前(事務提交時會釋放事務過程中的鎖),外界無法修改這些記錄。Hibernate 的悲觀鎖,也是基于數據庫的鎖機制實現。
下面的代碼實現了對查詢記錄的加鎖:
String hqlStr ="from TUser as user where user.name='John'";
Query query = session.createQuery(hqlStr);
query.setLockMode("user",LockMode.UPGRADE); // 加鎖
List userList = query.list();// 執行查詢,獲取數據
query.setLockMode 對查詢語句中,特定別名所對應的記錄進行加鎖(我們為TUser 類指定了一個別名 “user” ),這里也就是對返回的所有 user 記錄進行加鎖。
觀察運行期 Hibernate 生成的 SQL 語句:
select tuser0_.id as id, tuser0_.name as name, tuser0_.group_id
as group_id, tuser0_.user_type as user_type, tuser0_.sex as sex
from t_user tuser0_ where (tuser0_.name='John' ) for update
這里 Hibernate 通過使用數據庫的 for update 子句實現了悲觀鎖機制。
Hibernate 的加鎖模式有:
LockMode.NONE : 無鎖機制。
LockMode.WRITE : Hibernate 在 Insert 和 Update 記錄的時候會自動獲取。
LockMode.READ : Hibernate 在讀取記錄的時候會自動獲取。
以上這三種鎖機制一般由 Hibernate 內部使用,如 Hibernate 為了保證 Update過程中對象不會被外界修改,會在 save 方法實現中自動為目標對象加上 WRITE 鎖。
LockMode.UPGRADE :利用數據庫的 for update 子句加鎖。
LockMode. UPGRADE_NOWAIT : Oracle 的特定實現,利用 Oracle 的 for update nowait 子句實現加鎖。
上面這兩種鎖機制是我們在應用層較為常用的,加鎖一般通過以下方法實現:
Criteria.setLockMode
Query.setLockMode
Session.lock
注意,只有在查詢開始之前(也就是 Hiberate 生成 SQL 之前)設定加鎖,才會真正通過數據庫的鎖機制進行加鎖處理,否則,數據已經通過不包含 for update 子句的 Select SQL 加載進來,所謂數據庫加鎖也就無從談起。
package com.sinovatech.unicom.efb.common;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
/**
*
* 目的:FTP文件類
* <br/>
*
* FTP上傳文件、下載文件
*
* *
*/
public class FTPUtil {
private static final Log log = LogFactory.getLog(FTPUtil.class);
public static int download(String ip,int port,String userName,String password,FileFilter filter,String localFilePath) throws SocketException, IOException{
return download(ip, port, userName, password, null,filter, localFilePath);
}
public static int download(String ip,int port,String userName,String password,String ftpPath,FileFilter filter,String localFilePath) throws SocketException, IOException{
FTPClient ftp = new FTPClient();
int i=0;
try {
// 不為空連接 通過IP 和端口
ftp.connect(ip, port);
// 登陸
if (ftp.login(userName, password)) {
ftp.enterLocalPassiveMode();
// 獲取FTP登陸目錄下的所有文件
if(ftpPath!=null){
if(!ftp.changeWorkingDirectory(ftpPath)){
throw new RuntimeException("找不到該目錄:"+ftpPath);
}
}
FTPFile[] files = ftp.listFiles();
for (FTPFile file : files) {
String fileName = file.getName();
if (filter.accept(fileName)) {
BufferedOutputStream out = null;
try {
// IO流下載文件到本地
out = new BufferedOutputStream(
new FileOutputStream(new File(localFilePath
,fileName)));
// 開始下載
ftp.retrieveFile(file.getName(), out);
log.info("下載文件:" + file.getName() + "到本地路徑:"
+ localFilePath);
i++;
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
log.error("", e);
}
}
}
}
} else {
i = -1;
}
} finally {
if(ftp != null&&ftp.isConnected()){
try {
log.info("關閉ftp連接");
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return i;
}
public static int download(String ip,int port,String userName,String password,String ftpPath,final String fileName,String localFilePath)throws SocketException, IOException{
return download(ip, port, userName, password,ftpPath,new FileFilter(){
public boolean accept(String fileName1) {
return fileName.equalsIgnoreCase(fileName1);
}
}, localFilePath);
}
public static int download(String ip,int port,String userName,String password,final String fileName,String localFilePath)throws SocketException, IOException{
return download(ip, port, userName, password,null,fileName, localFilePath);
}
/**
* ftp上傳文件至服務器
* @throws SocketException
* @throws IOException
*/
public static void uploadFile(String ip, int port, String userName, String password, String localFile)
throws SocketException, IOException{
log.info("上傳本地文件: " + localFile);
File file = new File(localFile);
InputStream in = null;
FTPClient ftpClient = null;
if(file != null){
try {
ftpClient = new FTPClient();
in = new FileInputStream(file);
ftpClient.connect(ip,port);
if(ftpClient.login(userName, password)){
ftpClient.enterLocalPassiveMode();
boolean flag= ftpClient.appendFile(file.getName(), in);
log.info("上傳文件成功:" + flag);
}
}catch (SocketException e) {
log.error("ftp上傳文件失敗:", e);
throw e;
}catch (IOException e) {
log.error("ftp上傳文件失敗:", e);
throw e;
} finally{
if(in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ftpClient != null){
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public static void upload(String ip, int port, String userName, String password, String path,String remotePath)
throws SocketException, IOException{
upload(ip, port, userName, password, new File(path), remotePath);
}
/**
* ftp上傳文件至服務器
* @throws SocketException
* @throws IOException
*/
public static void upload(String ip, int port, String userName, String password, File localFile,String remotePath)
throws SocketException, IOException{
log.info("上傳本地文件: " + localFile.getName());
InputStream in = null;
FTPClient ftpClient = null;
if(localFile != null){
try {
ftpClient = new FTPClient();
in = new FileInputStream(localFile);
ftpClient.connect(ip,port);
if(ftpClient.login(userName, password)){
ftpClient.enterLocalPassiveMode();
if(remotePath!=null){
if(!ftpClient.changeWorkingDirectory(remotePath)){
ftpClient.makeDirectory(remotePath);
ftpClient.changeWorkingDirectory(remotePath);
}
}
boolean flag= ftpClient.storeFile(localFile.getName(), in);
log.info("上傳文件成功:" + flag);
}
}catch (SocketException e) {
log.error("ftp上傳文件失敗:", e);
throw e;
}catch (IOException e) {
log.error("ftp上傳文件失敗:", e);
throw e;
} finally{
if(in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ftpClient != null){
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
25 | 26 | 27 | 28 | 29 | 30 | 31 | |||
1 | 2 | 3 | 4 | 5 | 6 | 7 | |||
8 | 9 | 10 | 11 | 12 | 13 | 14 | |||
15 | 16 | 17 | 18 | 19 | 20 | 21 | |||
22 | 23 | 24 | 25 | 26 | 27 | 28 | |||
29 | 30 | 1 | 2 | 3 | 4 | 5 |