
2009年4月16日
**
* <pre>
* Title: HttpRequestProxy.java
* Project: HP-Common
* Type: com.hengpeng.common.web.HttpRequestProxy
* Author: benl
* Create: 2007-7-3 上午03:07:07
* Copyright: Copyright (c) 2007
* Company:
* <pre>
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.log4j.Logger;
/**
* <pre>
* HTTP請求代理類
* </pre>
*
* @author benl
* @version 1.0, 2007-7-3
*/
public class HttpRequestProxy
{
/**
* 連接超時
*/
private static int connectTimeOut = 5000;
/**
* 讀取數(shù)據(jù)超時
*/
private static int readTimeOut = 10000;
/**
* 請求編碼
*/
private static String requestEncoding = "GBK";
private static Logger logger = Logger.getLogger(HttpRequestProxy.class);
/**
* <pre>
* 發(fā)送帶參數(shù)的GET的HTTP請求
* </pre>
*
* @param reqUrl HTTP請求URL
* @param parameters 參數(shù)映射表
* @return HTTP響應(yīng)的字符串
*/
public static String doGet(String reqUrl, Map parameters,
String recvEncoding)
{
HttpURLConnection url_con = null;
String responseContent = null;
try
{
StringBuffer params = new StringBuffer();
for (Iterator iter = parameters.entrySet().iterator(); iter
.hasNext();)
{
Entry element = (Entry) iter.next();
params.append(element.getKey().toString());
params.append("=");
params.append(URLEncoder.encode(element.getValue().toString(),
HttpRequestProxy.requestEncoding));
params.append("&");
}
if (params.length() > 0)
{
params = params.deleteCharAt(params.length() - 1);
}
URL url = new URL(reqUrl);
url_con = (HttpURLConnection) url.openConnection();
url_con.setRequestMethod("GET");
System.setProperty("sun.net.client.defaultConnectTimeout", String
.valueOf(HttpRequestProxy.connectTimeOut));// (單位:毫秒)jdk1.4換成這個,連接超時
System.setProperty("sun.net.client.defaultReadTimeout", String
.valueOf(HttpRequestProxy.readTimeOut)); // (單位:毫秒)jdk1.4換成這個,讀操作超時
// url_con.setConnectTimeout(5000);//(單位:毫秒)jdk
// 1.5換成這個,連接超時
// url_con.setReadTimeout(5000);//(單位:毫秒)jdk 1.5換成這個,讀操作超時
url_con.setDoOutput(true);
byte[] b = params.toString().getBytes();
url_con.getOutputStream().write(b, 0, b.length);
url_con.getOutputStream().flush();
url_con.getOutputStream().close();
InputStream in = url_con.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(in,
recvEncoding));
String tempLine = rd.readLine();
StringBuffer temp = new StringBuffer();
String crlf=System.getProperty("line.separator");
while (tempLine != null)
{
temp.append(tempLine);
temp.append(crlf);
tempLine = rd.readLine();
}
responseContent = temp.toString();
rd.close();
in.close();
}
catch (IOException e)
{
logger.error("網(wǎng)絡(luò)故障", e);
}
finally
{
if (url_con != null)
{
url_con.disconnect();
}
}
return responseContent;
}
/**
* <pre>
* 發(fā)送不帶參數(shù)的GET的HTTP請求
* </pre>
*
* @param reqUrl HTTP請求URL
* @return HTTP響應(yīng)的字符串
*/
public static String doGet(String reqUrl, String recvEncoding)
{
HttpURLConnection url_con = null;
String responseContent = null;
try
{
StringBuffer params = new StringBuffer();
String queryUrl = reqUrl;
int paramIndex = reqUrl.indexOf("?");
if (paramIndex > 0)
{
queryUrl = reqUrl.substring(0, paramIndex);
String parameters = reqUrl.substring(paramIndex + 1, reqUrl
.length());
String[] paramArray = parameters.split("&");
for (int i = 0; i < paramArray.length; i++)
{
String string = paramArray[i];
int index = string.indexOf("=");
if (index > 0)
{
String parameter = string.substring(0, index);
String value = string.substring(index + 1, string
.length());
params.append(parameter);
params.append("=");
params.append(URLEncoder.encode(value,
HttpRequestProxy.requestEncoding));
params.append("&");
}
}
params = params.deleteCharAt(params.length() - 1);
}
URL url = new URL(queryUrl);
url_con = (HttpURLConnection) url.openConnection();
url_con.setRequestMethod("GET");
System.setProperty("sun.net.client.defaultConnectTimeout", String
.valueOf(HttpRequestProxy.connectTimeOut));// (單位:毫秒)jdk1.4換成這個,連接超時
System.setProperty("sun.net.client.defaultReadTimeout", String
.valueOf(HttpRequestProxy.readTimeOut)); // (單位:毫秒)jdk1.4換成這個,讀操作超時
// url_con.setConnectTimeout(5000);//(單位:毫秒)jdk
// 1.5換成這個,連接超時
// url_con.setReadTimeout(5000);//(單位:毫秒)jdk 1.5換成這個,讀操作超時
url_con.setDoOutput(true);
byte[] b = params.toString().getBytes();
url_con.getOutputStream().write(b, 0, b.length);
url_con.getOutputStream().flush();
url_con.getOutputStream().close();
InputStream in = url_con.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(in,
recvEncoding));
String tempLine = rd.readLine();
StringBuffer temp = new StringBuffer();
String crlf=System.getProperty("line.separator");
while (tempLine != null)
{
temp.append(tempLine);
temp.append(crlf);
tempLine = rd.readLine();
}
responseContent = temp.toString();
rd.close();
in.close();
}
catch (IOException e)
{
logger.error("網(wǎng)絡(luò)故障", e);
}
finally
{
if (url_con != null)
{
url_con.disconnect();
}
}
return responseContent;
}
/**
* <pre>
* 發(fā)送帶參數(shù)的POST的HTTP請求
* </pre>
*
* @param reqUrl HTTP請求URL
* @param parameters 參數(shù)映射表
* @return HTTP響應(yīng)的字符串
*/
public static String doPost(String reqUrl, Map parameters,
String recvEncoding)
{
HttpURLConnection url_con = null;
String responseContent = null;
try
{
StringBuffer params = new StringBuffer();
for (Iterator iter = parameters.entrySet().iterator(); iter
.hasNext();)
{
Entry element = (Entry) iter.next();
params.append(element.getKey().toString());
params.append("=");
params.append(URLEncoder.encode(element.getValue().toString(),
HttpRequestProxy.requestEncoding));
params.append("&");
}
if (params.length() > 0)
{
params = params.deleteCharAt(params.length() - 1);
}
URL url = new URL(reqUrl);
url_con = (HttpURLConnection) url.openConnection();
url_con.setRequestMethod("POST");
System.setProperty("sun.net.client.defaultConnectTimeout", String
.valueOf(HttpRequestProxy.connectTimeOut));// (單位:毫秒)jdk1.4換成這個,連接超時
System.setProperty("sun.net.client.defaultReadTimeout", String
.valueOf(HttpRequestProxy.readTimeOut)); // (單位:毫秒)jdk1.4換成這個,讀操作超時
// url_con.setConnectTimeout(5000);//(單位:毫秒)jdk
// 1.5換成這個,連接超時
// url_con.setReadTimeout(5000);//(單位:毫秒)jdk 1.5換成這個,讀操作超時
url_con.setDoOutput(true);
byte[] b = params.toString().getBytes();
url_con.getOutputStream().write(b, 0, b.length);
url_con.getOutputStream().flush();
url_con.getOutputStream().close();
InputStream in = url_con.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(in,
recvEncoding));
String tempLine = rd.readLine();
StringBuffer tempStr = new StringBuffer();
String crlf=System.getProperty("line.separator");
while (tempLine != null)
{
tempStr.append(tempLine);
tempStr.append(crlf);
tempLine = rd.readLine();
}
responseContent = tempStr.toString();
rd.close();
in.close();
}
catch (IOException e)
{
logger.error("網(wǎng)絡(luò)故障", e);
}
finally
{
if (url_con != null)
{
url_con.disconnect();
}
}
return responseContent;
}
/**
* @return 連接超時(毫秒)
* @see com.hengpeng.common.web.HttpRequestProxy#connectTimeOut
*/
public static int getConnectTimeOut()
{
return HttpRequestProxy.connectTimeOut;
}
/**
* @return 讀取數(shù)據(jù)超時(毫秒)
* @see com.hengpeng.common.web.HttpRequestProxy#readTimeOut
*/
public static int getReadTimeOut()
{
return HttpRequestProxy.readTimeOut;
}
/**
* @return 請求編碼
* @see com.hengpeng.common.web.HttpRequestProxy#requestEncoding
*/
public static String getRequestEncoding()
{
return requestEncoding;
}
/**
* @param connectTimeOut 連接超時(毫秒)
* @see com.hengpeng.common.web.HttpRequestProxy#connectTimeOut
*/
public static void setConnectTimeOut(int connectTimeOut)
{
HttpRequestProxy.connectTimeOut = connectTimeOut;
}
/**
* @param readTimeOut 讀取數(shù)據(jù)超時(毫秒)
* @see com.hengpeng.common.web.HttpRequestProxy#readTimeOut
*/
public static void setReadTimeOut(int readTimeOut)
{
HttpRequestProxy.readTimeOut = readTimeOut;
}
/**
* @param requestEncoding 請求編碼
* @see com.hengpeng.common.web.HttpRequestProxy#requestEncoding
*/
public static void setRequestEncoding(String requestEncoding)
{
HttpRequestProxy.requestEncoding = requestEncoding;
}
public static void main(String[] args)
{
Map map = new HashMap();
map.put("actionType", "1");
// map.put("issueId", "33");
String temp = HttpRequestProxy.doPost("http://192.168.0.99/AgentPortal/autoHandler", map, "GBK");
System.out.println("返回的消息是:"+temp);
}
}
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/320994622009616102329953
posted @
2009-07-16 10:23 C.B.K 閱讀(1812) |
評論 (1) |
編輯 收藏
/*
下面的程序說明了怎樣實現(xiàn)對象序列化和反序列化。它由實例化一個MyClass類的對象開始。該對象有三個實例變量,它們的類型分別是String,int和double。這是我們希望存儲和恢復(fù)的信息。
FileOutputStream被創(chuàng)建,引用了一個名為“serial”的文件。為該文件流創(chuàng)建一個ObjectOutputStream。ObjectOutputStream 的writeObject( )方法用來序列化對象。對象的輸出流被刷新和關(guān)閉。
然后,引用名為“serial”的文件創(chuàng)建一個FileInputStream類并為該文件創(chuàng)建一個ObjectInputStream類。ObjectInputStream 的readObject( )方法用來反序列化對象。然后對象輸入流被關(guān)閉。
注意MyClass被定義成實現(xiàn)Serializable接口。如果不這樣做,將會引發(fā)一個NotSerializableException異常。試圖做一些把MyClass實例變量聲明成transient的實驗。那些數(shù)據(jù)在序列化過程中不被保存
*/
import java.io.*;
class MyClass implements Serializable{
String s;
int i;
double d;
public MyClass (String s,int i,double d){
this.s = s;
this.i = i;
this.d = d;
}
public String toString(){
return "s=" + s + "; i=" + i + "; d=" + d;
}
}
class SerializationDemo{
public static void main(String[] args){
//Object serialization.
try{
MyClass object1 = new MyClass("Evan",9,9.9e10);
System.out.println("object1 : " +object1);
FileOutputStream fos = new FileOutputStream("serial");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(object1);
oos.flush();
oos.close();
}catch(Exception e){
System.out.println("Exception during serialization :" + e);
System.exit(0);
}
//Object deserialization.
try{
MyClass object2 ;
FileInputStream fis = new FileInputStream("serial");
ObjectInputStream ois = new ObjectInputStream(fis);
object2 = (MyClass)ois.readObject();
ois.close();
System.out.println("object2 : " +object2);
}catch(Exception e){
System.out.println("Exception during serialization :" + e);
System.exit(0);
}
}
}
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/320994622009616101541196
posted @
2009-07-16 10:16 C.B.K 閱讀(175) |
評論 (0) |
編輯 收藏
Java的serialization提供了一種持久化對象實例的機(jī)制。當(dāng)持久化對象時,可能有一個特殊的對象數(shù)據(jù)成員,我們不想
用serialization機(jī)制來保存它。為了在一個特定對象的一個域上關(guān)閉serialization,可以在這個域前加上關(guān)鍵字transient。
transient是Java語言的關(guān)鍵字,用來表示一個域不是該對象串行化的一部分。當(dāng)一個對象被串行化的時候,transient型變量的值不包括在串行化的表示中,然而非transient型的變量是被包括進(jìn)去的。
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/3209946220096161094144
posted @
2009-07-16 10:09 C.B.K 閱讀(159) |
評論 (0) |
編輯 收藏
匹配中文字符的正則表達(dá)式: [\u4e00-\u9fa5]
匹配雙字節(jié)字符(包括漢字在內(nèi)): [^\x00-\xff]
應(yīng)用:計算字符串的長度(一個雙字節(jié)字符長度計2,ASCII字符計1)
String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}
匹配空行的正則表達(dá)式: \n[\s| ]*\r
匹配HTML標(biāo)記的正則表達(dá)式: /<(.*)>.*<\/>|<(.*) \/>/
匹配首尾空格的正則表達(dá)式: (^\s*)|(\s*$)
應(yīng)用:javascript中沒有像vbscript那樣的trim函數(shù),我們就可以利用這個表達(dá)式來實現(xiàn),如下:
String.prototype.trim = function() {
return this.replace(/(^\s*)|(\s*$)/g, "");
}
利用正則表達(dá)式分解和轉(zhuǎn)換IP地址:
下面是利用正則表達(dá)式匹配IP地址,并將IP地址轉(zhuǎn)換成對應(yīng)數(shù)值的javascript程序:
function IP2V(ip) {
re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //匹配IP地址的正則表達(dá)式
if(re.test(ip)) {
return RegExp.*Math.pow(255,3))+RegExp.*Math.pow(255,2))+RegExp.*255+RegExp.*1
}
else {
throw new Error("Not a valid IP address!")
}
}
不過上面的程序如果不用正則表達(dá)式,而直接用split函數(shù)來分解可能更簡單,程序如下:
var ip="10.100.20.168"
ip=ip.split(".")
alert("IP值是:"+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))
匹配Email地址的正則表達(dá)式: \w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
匹配網(wǎng)址URL的正則表達(dá)式: http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
利用正則表達(dá)式去除字串中重復(fù)的字符的算法程序:
var s="abacabefgeeii"
var s1=s.replace(/(.).*/g,"")
var re=new RegExp("["+s1+"]","g")
var s2=s.replace(re,"")
alert(s1+s2) //結(jié)果為:abcefgi
用正則表達(dá)式從URL地址中提取文件名的javascript程序,如下結(jié)果為page1
s="http://www.9499.net/page1.htm"
s=s.replace(/(.*\/)([^\.]+).*/ig,"")
alert(s)
利用正則表達(dá)式限制網(wǎng)頁表單里的文本框輸入內(nèi)容:
用正則表達(dá)式限制只能輸入中文:
onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')"
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))"
用正則表達(dá)式限制只能輸入全角字符:
onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,'')"
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))"
用正則表達(dá)式限制只能輸入數(shù)字:
onkeyup="value=value.replace(/[^\d]/g,'')
"onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"
用正則表達(dá)式限制只能輸入數(shù)字和英文:
onkeyup="value=value.replace(/[\W]/g,'')
"onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200961005220547
posted @
2009-07-10 12:52 C.B.K 閱讀(215) |
評論 (0) |
編輯 收藏
ant手冊中的ant配置classpath采用classpath標(biāo)簽,可是我發(fā)現(xiàn)這樣配置總是不好用,還是直接用path可以使用
設(shè)置classpath的方法有多種
<path id="project.classpath">
1<pathelement path="${basedir}/lib/aa.jar"/>
2<pathelement location="aa.jar"/>與1的區(qū)別在于location可以去當(dāng)前路徑,當(dāng)然可以使用絕對路徑
3<filelist id="file" dir="${basedir}/lin">
<file name="a.jar"/>
<file name="d:lib/b.jar"/>
</filelist>
4<fileset dir="d:/lib">
<include name="**/*.jar"/>
</fileset>
5手冊上說了dirset也好用,但是我測試了還是不要用的
</path>
下面說classpath的使用
樣例如下
<javac scdir="./src" destdir="./classes">
<classpath refid="project.classpath"/>
</javac>
下面是比較四種方式的優(yōu)缺點
第一種調(diào)用的需要設(shè)置絕對路徑適合第三方j(luò)ar包
第二種則適合jar包和build.xml文件在同一目錄下的情況,但是我覺得兩個文件放在一起本身就不合理,估計是用的情況不多。
前兩個都是設(shè)置單個jar包
第三種是一個文件集合適合引入不同路徑的jar包,但是需要輸入每個jar包的名字,比較繁瑣,適合于jar包屬于不同位置,比較分散但是不多的情況
第四種是一個文件夾,可以采用匹配模式來引入,這個適合在同一個文件夾下,文件名字比較多的情況下
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200961051533899
posted @
2009-07-10 05:16 C.B.K 閱讀(1649) |
評論 (0) |
編輯 收藏
ant的構(gòu)建文件中,有很多核心類型,這些核心類型都是XXXSet的形式,主要有以下幾個:PatternSet、DirSet、FileSet、PropertySet、ZipFileSet等。說下前三個的功能就應(yīng)該可以舉一反三了。
1.PatternSet
即模式集合。顧名思義,就是定義一個模式,他可以用來指定一個文件集合。常??梢员煌獠康膖arget引用,復(fù)用性很強(qiáng)。有includes、
includesfile、excludes、excludesfile屬性。每個屬性里面還可以嵌套name、if、unless等類型。
2.DirSet 即目錄集合。用來定義目錄的集合。有dir、casesensitive、followsymlinks和PatternSet也有的那4個屬性。上面說過PatternSet可以很好的復(fù)用。下面就是一個例子:
- <dirset dir="${build.dir}">
- <patternset id="non.test.classes">
- <include name="apps/**/classes"/>
- <exclude name="apps/**/*Test*"/>
- </patternset>
- </dirset>
<dirset dir="${build.dir}">
<patternset id="non.test.classes">
<include name="apps/**/classes"/>
<exclude name="apps/**/*Test*"/>
</patternset>
</dirset>
這是用patternset來定義DirSet的模式,這個模式還可以在外部引用。如:
- <dirset dir="{build.dir}">
- <patternset refid="non.test.classes"/>
- </dirset>
<dirset dir="{build.dir}">
<patternset refid="non.test.classes"/>
</dirset>
上面定義了一個名為non.test.classes的PatternSet,現(xiàn)在就可以引用他了。refid即reference ID.
3.FileSet即文件集合,他的內(nèi)部屬性與DirSet幾乎一樣,只是多了一個file和defaultexcludes。和dirset一樣,經(jīng)常
嵌入patternset來定義文件集合;但是也有另外一個很常用的類型,叫selector,它并不是一個真正的類型或元素,只是一種、一類類型的統(tǒng)
稱。如contains、date、depend、depth、different、filename、present、containsregexp、
size、type等。
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/3209946220096105521217
posted @
2009-07-10 05:05 C.B.K 閱讀(430) |
評論 (0) |
編輯 收藏
第一種方法:
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
-> ON <dbname>.*
-> TO <username>@<host name>
-> IDENTIFIED BY '<password>';
where <dbname> is the name of the database you are tyring to
connect to, <username> is the username of the user trying to
connect to the database, <host name> the name of the host (in
your case the XXX host) and <password> the password of the user.
第二種方法:
通過客戶端軟件設(shè)置用戶的主機(jī)以及權(quán)限,


文章來源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200952925050579
posted @
2009-06-29 14:51 C.B.K 閱讀(1565) |
評論 (0) |
編輯 收藏
一、什么是條件變量
與互斥鎖不同,條件變量是用來等待而不是用來上鎖的。條件變量用來自動阻塞一個線程,直到某特殊情況發(fā)生為止。通常條件變量和互斥鎖同時使用。
條件變量使我們可以睡眠等待某種條件出現(xiàn)。條件變量是利用線程間共享的全局變量進(jìn)行同步的一種機(jī)制,主要包括兩個動作:一個線程等待"條件變量的條件成立"而掛起;另一個線程使"條件成立"(給出條件成立信號)。
條
件的檢測是在互斥鎖的保護(hù)下進(jìn)行的。如果一個條件為假,一個線程自動阻塞,并釋放等待狀態(tài)改變的互斥鎖。如果另一個線程改變了條件,它發(fā)信號給關(guān)聯(lián)的條件
變量,喚醒一個或多個等待它的線程,重新獲得互斥鎖,重新評價條件。如果兩進(jìn)程共享可讀寫的內(nèi)存,條件變量可以被用來實現(xiàn)這兩進(jìn)程間的線程同步。
使用條件變量之前要先進(jìn)行初始化??梢栽趩蝹€語句中生成和初始化一個條件變量如:
pthread_cond_t my_condition=PTHREAD_COND_INITIALIZER;(用于進(jìn)程間線程的通信)。
也可以利用函數(shù)pthread_cond_init動態(tài)初始化。
二、條件變量函數(shù)
1.
名稱: |
pthread_cond_init |
目標(biāo): |
條件變量初始化 |
頭文件: |
#include < pthread.h> |
函數(shù)原形: |
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); |
參數(shù): |
cptr 條件變量
attr 條件變量屬性 |
返回值: |
成功返回0,出錯返回錯誤編號。 |
pthread_cond_init函數(shù)可以用來初始化一個條件變量。他使用變量attr所指定的屬性來初始化一個條件變量,如果參數(shù)attr為空,那么它將使用缺省的屬性來設(shè)置所指定的條件變量。
2.
名稱: |
pthread_cond_destroy |
目標(biāo): |
條件變量摧毀 |
頭文件: |
#include < pthread.h> |
函數(shù)原形: |
int pthread_cond_destroy(pthread_cond_t *cond); |
參數(shù): |
cptr 條件變量 |
返回值: |
成功返回0,出錯返回錯誤編號。 |
pthread_cond_destroy函數(shù)可以用來摧毀所指定的條件變量,同時將會釋放所給它分配的資源。調(diào)用該函數(shù)的進(jìn)程也并不要求等待在參數(shù)所指定的條件變量上。
3.
名稱: |
pthread_cond_wait/pthread_cond_timedwait |
目標(biāo): |
條件變量等待 |
頭文件: |
#include < pthread.h> |
函數(shù)原形: |
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t mytex,const struct timespec *abstime); |
參數(shù): |
cond 條件變量
mutex 互斥鎖 |
返回值: |
成功返回0,出錯返回錯誤編號。 |
第一個參數(shù)*cond是指向一個條件變量的指針。第二個參數(shù)*mutex則是對相關(guān)的互斥鎖的指針。函數(shù)pthread_cond_timedwait函數(shù)類型與函數(shù)pthread_cond_wait,區(qū)別在于,如果達(dá)到或是超過所引用的參數(shù)*abstime,它將結(jié)束并返回錯誤ETIME.pthread_cond_timedwait函數(shù)的參數(shù)*abstime指向一個timespec結(jié)構(gòu)。該結(jié)構(gòu)如下:
typedef struct timespec{
time_t tv_sec;
long tv_nsex;
}timespec_t;
3.
名稱: |
pthread_cond_signal/pthread_cond_broadcast |
目標(biāo): |
條件變量通知 |
頭文件: |
#include < pthread.h> |
函數(shù)原形: |
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond); |
參數(shù): |
cond 條件變量 |
返回值: |
成功返回0,出錯返回錯誤編號。 |
參數(shù)*cond是對類型為pthread_cond_t 的一個條件變量的指針。當(dāng)調(diào)用pthread_cond_signal時一個在相同條件變量上阻塞的線程將被解鎖。如果同時有多個線程阻塞,則由調(diào)度策略確定接收通知的線程。如果調(diào)用pthread_cond_broadcast,則將通知阻塞在這個條件變量上的所有線程。一旦被喚醒,線程仍然會要求互斥鎖。如果當(dāng)前沒有線程等待通知,則上面兩種調(diào)用實際上成為一個空操作。如果參數(shù)*cond指向非法地址,則返回值EINVAL。
下面是一個簡單的例子,我們可以從程序的運(yùn)行來了解條件變量的作用。
#include <pthread.h> #include <stdio.h> #include <stdlib.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥鎖*/ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化條件變量*/
void *thread1(void *); void *thread2(void *);
int i=1; int main(void) { pthread_t t_a; pthread_t t_b;
pthread_create(&t_a,NULL,thread2,(void *)NULL);/*創(chuàng)建進(jìn)程t_a*/ pthread_create(&t_b,NULL,thread1,(void *)NULL); /*創(chuàng)建進(jìn)程t_b*/ pthread_join(t_b, NULL);/*等待進(jìn)程t_b結(jié)束*/ pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); exit(0); }
void *thread1(void *junk) { for(i=1;i<=9;i++) { pthread_mutex_lock(&mutex);/*鎖住互斥量*/ if(i%3==0) pthread_cond_signal(&cond);/*條件改變,發(fā)送信號,通知t_b進(jìn)程*/ else printf("thead1:%d\n",i); pthread_mutex_unlock(&mutex);/*解鎖互斥量*/
sleep(1); }
}
void *thread2(void *junk) { while(i<9) { pthread_mutex_lock(&mutex);
if(i%3!=0) pthread_cond_wait(&cond,&mutex);/*等待*/ printf("thread2:%d\n",i); pthread_mutex_unlock(&mutex);
sleep(1); }
} |
程序創(chuàng)建了2個新線程使他們同步運(yùn)行,實現(xiàn)進(jìn)程t_b打印20以內(nèi)3的倍數(shù),t_a打印其他的數(shù),程序開始線程t_b不滿足條件等待,線程t_a運(yùn)行使a循環(huán)加1并打印。直到i為3的倍數(shù)時,線程t_a發(fā)送信號通知進(jìn)程t_b,這時t_b滿足條件,打印i值。
下面是運(yùn)行結(jié)果:
#cc –lpthread –o cond cond.c
#./cond
thread1:1
thread1:2
thread2:3
thread1:4
thread1:5
thread2:6
thread1:7
thread1:8
thread2:9
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/3209946220095235658763
posted @
2009-06-23 17:07 C.B.K 閱讀(293) |
評論 (0) |
編輯 收藏
工具:grub4dos0.4.2(想要的給我發(fā)信,我發(fā)給你,loveitdoit@163.com)
文件:fedora7.0映像文件,可在網(wǎng)上下載。
過程:
1.解壓縮grub4dos0.4.2,把里面的 grldr和menu.lst,文件復(fù)制到c盤根目錄下。
2.fedora7.0映像文件不必解壓,必須放在fat32的分區(qū)里。把里面的isolinux目錄下
的VMLINUZ、INITRD.IMG解壓到c盤根目錄下。
3.在c:\下找到menu.lst,用記事本打開并修改,刪除其他命令,添加以下命令!
title Linux System Install
kernel (hd0,0)/vmlinuz
initrd (hd0,0)/initrd.img
4.修改c:\boot.ini文件,在最后面添加c:\grldr="Start GRUB"并保存即可。
5.重起系統(tǒng),選擇Start GRUB,開始安裝。
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/3209946220095234437396
posted @
2009-06-23 16:05 C.B.K 閱讀(143) |
評論 (0) |
編輯 收藏
花了半天時間研究了下下MYSQL的備份實現(xiàn),發(fā)現(xiàn)其是在MY.CNF(MY.INI)配置文件中作的設(shè)置,直接設(shè)置服務(wù)器唯一性ID號加上其它的附加設(shè)
置,則可作為一臺MASTER,而在
SLAVE機(jī)上,也只需要在配置文件中設(shè)置一下連接MASTER所需的參數(shù)即可,如果在MASTER里也加上連到SLAVE機(jī)的參數(shù),則就是雙向備份
了~~不過,這些連接參數(shù)中用到的賬號需要注意權(quán)限的設(shè)置,否則會搞半天沒反就急死你迪。。。
我在WIN上和LINUX上各裝了MYSQL5,下面是它們的配置:
WIN(172.22.33.33)下的MASTER(由于我改了端口3327所以下面多加了個端口方面的特殊處理了)的配置(my.ini):(**一定要在mysqld配置段中配置,不象PHP,APACHE可以隨便找個方便的地方配的,注意哈??!)
[mysqld]
#master 設(shè)置
server-id=1
log-bin=c:/masterlog
binlog-do-db=db5
#實現(xiàn)雙機(jī)備份段,給MASTER同時加上SLAVE段,可選哈,如果不選,那就是WIN到LIN的主從備份
master-host=172.22.1.37
master-user=backup2
master-password=backup2
master-port=3306
master-connect-retry=60
replicate-do-db=db5
數(shù)據(jù)庫中加一個賬號:
GRANT FILE,REPLICATION SLAVE,REPLICATION CLIENT,SUPER ON *.*
TO [email=backup@]backup@'172.22.1.37'[/email] IDENTIFIED by 'backup';
這個權(quán)限表示,這個backup賬號只能由從備份機(jī)172.22.1.37訪問只能用來進(jìn)行備份操作
LINUX(172.22.1.37)下的SLAVE機(jī)的配置(把安裝目錄里找到的任意一個*.cnf拷到/etc/my.cnf下進(jìn)行修改):
server-id=2
#如果不需要雙向備份下面兩行可以不要
#否則還要加一個數(shù)據(jù)庫用戶賬號
/*
GRANT FILE,REPLICATION SLAVE,REPLICATION CLIENT,SUPER ON *.*
TO [email=backup2@]backup2@'172.22.33.33'[/email] IDENTIFIED by 'backup2';
*/
log-bin=./masterlog
binlog-do-db=db5
#---------------------------------------
master-host=172.22.33.33
master-user=backup
master-password=backup
master-port=3327
master-connect-retry=60
replicate-do-db=db5
由于只是大概的弄了一下,特別是在數(shù)據(jù)庫用戶方面沒有作仔細(xì)試驗:),可能會有所不太準(zhǔn)確的地方,還有就是,上面測試用到的數(shù)據(jù)庫一定要是已經(jīng)建立好并且
結(jié)構(gòu)相同的,兩臺機(jī)子都重啟后會進(jìn)行檢查,如果出現(xiàn)找不到或者檢查到結(jié)構(gòu)不同,會報錯,最好就是在創(chuàng)建空數(shù)據(jù)庫時或初始時安裝兩個一樣的數(shù)據(jù)庫后就建立好
關(guān)系,對于不同版本的MYSQL,官方說明也可以同步,但想一想,把MYSQL5 的數(shù)據(jù)備份到4中去丟失5的特性也沒什么意義吧。。
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200952335921779
posted @
2009-06-23 15:59 C.B.K 閱讀(220) |
評論 (0) |
編輯 收藏
【第一篇】
首先、確定你自己的英語水平。中國大學(xué)畢業(yè)生的通病是,書面閱讀還可以,口語不行,聽力很差,書寫湊合。但每個人具體情況又都不一樣,有人閱讀專業(yè)書一目
十行,但讀報紙很費(fèi)勁。有人聽新聞可以,聽別的不行。你必須首先了解自己,然后針對你的情況對癥下藥。這種評估工作最好找英語好的人幫你做,如果不方便,
只能自己評自己,就要盡量做到客觀。 其次、確定自己的發(fā)音水平。我有個朋友對我說他的發(fā)音沒問題,可實際上他說得很多詞我都聽不懂。你學(xué)的是英國音還
是美國音都無所謂,反正最終從你嘴里出來的肯定是中國音。最重要的是發(fā)音要合理。英語每一個單詞都有自己的念法,你不能憑空想象。比如,有人把
RESUME讀做RE-'SOOM,這樣,別人說RE-SIU-'MAY,你不知道是什么。你念RE-'SOOM,別人也聽不懂。再次、確定自己的英語學(xué)
習(xí)目標(biāo)。我這里僅把口語交流做為目標(biāo)。最后、開始學(xué)習(xí)。
1、口語學(xué)習(xí)的關(guān)鍵是要模仿人家的說話。這包括語音和語調(diào)兩部分。中國英語教學(xué)重視語調(diào)的很少,盡管很多時候語調(diào)可能比語音更重要。
2、買一臺錄音機(jī),找一合磁帶。根據(jù)你的水平,可以選擇新概念第二或第三冊,也可以到圖書館借一套有書和磁帶的小故事集。注意:一定要有書,故事篇幅不能太長,生詞量要小,過于簡單沒有關(guān)系。我傾向于使用故事,而不是對話或新聞聽力材料。
3、進(jìn)行跟讀訓(xùn)練。放磁帶,看著書,搞明白每一個單詞的意思,理解整個故事情節(jié)。然后,放一句,暫停,學(xué)著人家讀一句,然后,放下一句,暫停,再學(xué)一句,繼續(xù)。
4、跟讀過程中要注意的幾點:
(1)一定要盡力模仿發(fā)音和語調(diào),越象越好。
(2)開始時速度可以比較慢,要逐步使自己跟上人家的速度。
(3)中間可以回倒重放,但我傾向于讓大家完成一小段后再回去重來。
5、同步閱讀。當(dāng)你對文章發(fā)音、語調(diào)完全掌握之后,就要在放錄音的同時同步跟讀。爭取讓自己的聲音與他完全重合。注意語調(diào)和語音。如果中間有結(jié)巴的地方也不要緊,繼續(xù)讀下去,然后再回來重讀。
6、關(guān)掉錄音機(jī),朗誦課文。注意使用學(xué)到的語音語調(diào)。帶滾瓜爛熟之后,可以進(jìn)入下一篇課文。
這樣,一兩個月之后,當(dāng)你“精讀”過五到十篇約一千字篇幅的文章之后,你會發(fā)現(xiàn)你的英語發(fā)音和聽力有了明顯的進(jìn)步。再配合其他學(xué)習(xí),如與人聊天,看電視,聽廣播,等等,口語水平會得到顯著提高。
【第二篇】
英語作為一種工具,其實用性愈顯重要。傳統(tǒng)英語教育方法由于過于艱深化,以及盲目的應(yīng)試模式使大部分的英語學(xué)習(xí)者學(xué)了幾年甚至數(shù)十年,卻仍然處于聽不懂開不了口的尷尬境地。那么究竟如何才能在比較短的時間里快速提高口語水平,讓她真正為你所用呢?
西方最新流行一種外語學(xué)習(xí)理論,即口語提高的最好方式就是采用短期突破法。從下面的公式中,就可以看出,口語短期突破的方法是很有效的。
口語提高速度定律=說英語時間/說中文時間Speed of learning English=Speaking English/Speaking Chinese ( in a period of time)
比如,在給定的一天時間內(nèi)(16小時),學(xué)生A練習(xí)英語口語的時間為14小時,說中文的時間為2小時,兩者的比例為7:1;學(xué)生B練習(xí)口語的時間為2
小時英語,說中文的時間為14小時。比例為1:7。如此一來,學(xué)生A比學(xué)生B說英語的比例大49倍。
我們認(rèn)為:這一理論其實就是對語言學(xué)習(xí)規(guī)律一次很好的回歸,語言的核心是使用者能夠隨時隨地地使用它。你用的時間越長,你就越熟練,這里我們說的使用
就是“說”,用嘴巴表達(dá)出來,而不是用眼睛和腦子去看和死記。如果你能夠在一段時間內(nèi)的大部分時間里堅持持續(xù)使用英語而不是中文進(jìn)行表達(dá),把學(xué)習(xí)英語的任
務(wù)轉(zhuǎn)化成母語似的說話習(xí)慣,你就完全可以在很短的時間內(nèi)有效掌握一口流利的英語口語。
當(dāng)然現(xiàn)實情況卻是:很多人并沒有這樣的勇氣和能力去堅持使用一個完全不熟悉的語言進(jìn)行日常的交流!所以選用一套優(yōu)秀的教材和相應(yīng)的工具就顯得異常重要了,這種教材應(yīng)該具備以下特點才能幫助你克服困難:
?。?、能夠隨時隨地學(xué)習(xí),讓你很容易就接觸到英語;
2、能夠讓你脫離書本,完全浸在英語環(huán)境里;
3、內(nèi)容應(yīng)該精挑細(xì)選,具備典型性和代表性,幫助你在短時間內(nèi)掌握精華內(nèi)容,從而建立起長期學(xué)習(xí)的信心和基本能力。
同時你應(yīng)該注意培養(yǎng)自己的自信,學(xué)會勇敢犯錯誤,克服恐懼的心理障礙。其實這種心理障礙是成人自己加給自己的,為什么我們小時候?qū)W母語這么自然容易,就是因為那個時候不知道什么是丟臉。所以我們應(yīng)該象小時候那樣暫時忘卻丟臉,勇敢地去丟臉!
【第三篇】
想提高英語口語水平,首先要在語音上下功夫:)~
下面是些方法,你可以根據(jù)自己的學(xué)習(xí)方式掌握:)~
1.其次,要有大量的閱讀和聽力做基礎(chǔ)。在讀和聽的過程中,積累了詞匯,掌握了句型,熟悉了用英語表達(dá)思想的方式,最重要的是培養(yǎng)了語感。
2.同時,學(xué)英語口語也需要用多種辦法:如大聲朗讀英語對話和文章,朗讀各種句型的例句和口語中最常用的句子,背誦文章及演講,與會英語的人練口語,當(dāng)
然,最好與以英語為母語的人練口語。事實上,自言自語亦是練習(xí)口語的有效的方法之一。如果你把自己說的英語給錄制下來,聽聽自己的錄音,若有問題,再加以
改正,效果就會更好。
3.說英語還要有膽量。如果你能在說不太出口,或是說不好的情況下,大膽地說。說上一段時間后,突然有一天你會自如、清楚地表達(dá)自己的思想。有了大膽說的精神,你才能闖過口語的難關(guān)。
4.只會學(xué)英語,而不能盡快地去用,那就永遠(yuǎn)也學(xué)不好英語。在學(xué)英語的過程中,要始終尋找機(jī)會說英語。比如說,你周圍有幾個喜歡說英語的朋友,大家在一起
就要用英語來交談。這種交談有利于每個人的英語學(xué)習(xí),因為大家都有機(jī)會運(yùn)用自己已掌握的英語知識來交流思想,鞏固了已學(xué)的知識,并把知識轉(zhuǎn)化成技能,同
時,還能從別人那兒學(xué)到新的東西。要想學(xué)好英語口語就要多說。
5.能同以英語為母語的人說英語是最佳方法。在國內(nèi)學(xué)英語缺乏環(huán)境,看電影學(xué)英語口語是彌補(bǔ)環(huán)境不足的好方法。英語電影是一部英語國家的生活、文化、風(fēng)俗
等一切的百科全書,是最全的英語口語百科全書。大量地看英文電影就是你徹底攻克英語“聽”和“說”的法寶。英語電影把你帶入了一個新的世界中去。你在電影
中,學(xué)到了英語口語的語匯、短語、句子結(jié)構(gòu),以及表達(dá)各種內(nèi)容的說法。你要做的就是把自己想像成電影中的一個角色,在經(jīng)歷著自己的生活,又在經(jīng)歷著其他人
的生活??傊?,看一部電影比在美國生活一天還好,看電影也能學(xué)到地道的英語口語。
【第四篇】
當(dāng)代社會是個開放社會,信息社會,人們越來越重視交際,而我國改革開放的成功也日益提高了我國在世界上的地位,我們與世界各國交流的領(lǐng)域越來越廣了,沒有出眾的英語口語表達(dá)將會寸步難行。
而要提高英語口語表達(dá)能力,就要先了解英語口語表達(dá)的過程是怎樣發(fā)生的。大家知道,語言是思維的外殼。口語表達(dá)的過程,實際上是一個復(fù)雜的心理和生理過程,是思維借助詞語按一定句式迅速轉(zhuǎn)換為有聲言語的過程。因此,口語能力的強(qiáng)弱取決于:
1、思維能力的強(qiáng)弱,特別是與口語有關(guān)的思維的條理性、敏銳性與靈活性,這是關(guān)鍵。
2、準(zhǔn)確、迅速地組織言語(選詞、造句、組段、構(gòu)篇)能力的強(qiáng)弱,這是基礎(chǔ)。
3、運(yùn)用語言的能力的強(qiáng)弱,這是前提。
根據(jù)口語表達(dá)循序漸進(jìn)的一般規(guī)律,口語訓(xùn)練的重點應(yīng)是培養(yǎng)敏銳的思維和強(qiáng)烈的語感。具體包括:
1、語音。學(xué)會科學(xué)發(fā)聲方法,能用準(zhǔn)確、響亮、流暢的英語進(jìn)行口頭表達(dá)。
2、語調(diào)。能借助聲音高低升降、抑揚(yáng)頓挫的變化來表達(dá)復(fù)雜的感情,掌握停連和輕重、抑揚(yáng)和明暗、快慢和松緊等一般的朗讀技巧。
3、詞匯。能掌握比較豐富的口語詞匯。
4、語脈。說話能做到有條有理、語言流暢、上下貫通、一脈相承。
5、語境。說話注意目的、對象、場合,合乎規(guī)定情景的要求,講禮貌、有針對性。懂得口語修辭。在會話中有隨機(jī)應(yīng)變的能力。
此外,還要懂得口頭言語的輔助手段--表情、姿勢、動作等態(tài)勢言語的運(yùn)用。
由于書面語和口語是相互滲透、相互促進(jìn)的,為提高口語的表現(xiàn)力,可在說話訓(xùn)練之前先進(jìn)行一章朗讀、朗誦訓(xùn)練。聽和說是一個事物的兩個方面,吸收、表達(dá)
兩者不能偏廢,所以口語訓(xùn)練體系中也應(yīng)包括。通過以上訓(xùn)練,掌握一定的朗讀朗誦技巧,培養(yǎng)準(zhǔn)確、流利、有感情地朗讀朗誦一般作品的能力,特別注意培養(yǎng)強(qiáng)烈
的語感。
3、聽力訓(xùn)練
培養(yǎng)聽的注意力、理解力、記憶力和辨析力,提高聽知能力,養(yǎng)成良好的聽的習(xí)慣。
4、口語表達(dá)基本方式訓(xùn)練
進(jìn)行敘述、描述、評述、解說等口語表達(dá)基本方式的訓(xùn)練,培養(yǎng)內(nèi)部言語向外部言語迅速轉(zhuǎn)化的能力,結(jié)合進(jìn)行語調(diào)、語脈的訓(xùn)練。
5、會話型言語訓(xùn)練
言語形式有會話型和獨(dú)白型兩類。會話是指兩個以上的人圍繞一個或幾個話題一起說話的形式,如交談、座談、辯論、審訊等。會話時參加者是互為聽、講者
的,因此后面的發(fā)言常常受到前面發(fā)言的制約。另外,由于當(dāng)面交談,大量態(tài)勢語代替了言語表達(dá),會話者的言語結(jié)構(gòu)往往不嚴(yán)謹(jǐn)、不完善,省略句較多。
可進(jìn)行如下訓(xùn)練:通過交談和辯論兩種會話言語訓(xùn)練,了解它們的一般特點、注意事項,結(jié)合進(jìn)行應(yīng)變能力和禮貌用語的訓(xùn)練,從而在會話中有效地培養(yǎng)隨機(jī)應(yīng)變的能力。
6、獨(dú)白型言語訓(xùn)練
獨(dú)白是指一個人單獨(dú)發(fā)言而其他人都作為聽眾的言語表達(dá)形式,如:講故事、作報告、講課、演講、講解員的解說等。獨(dú)白言語一般不在進(jìn)行過程中跟聽眾問答
交流,因此要求在事先要周密地了解聽眾的要求并系統(tǒng)地組織好發(fā)言內(nèi)容和有關(guān)態(tài)勢語。獨(dú)白是一種高層次的言語形式。
可通過講故事和演講兩種獨(dú)白言語的訓(xùn)練,了解它們的一般特點、注意事項,結(jié)合進(jìn)行運(yùn)用態(tài)勢語的訓(xùn)練,這類訓(xùn)練很有利于培養(yǎng)思維的條理性和連貫性。
7、即興小品訓(xùn)練
即興小品要求表演者按照規(guī)定的題目和要求,在規(guī)定的時間內(nèi),充分發(fā)揮自己的想象,不用或少用道具,通過言語和動作的表演,展現(xiàn)社會生活中的某個瞬間或片斷,表達(dá)一個簡單的主題。
嚴(yán)格地說,小品應(yīng)該是話劇藝術(shù)表演訓(xùn)練的一種形式,但由于它具有綜合的特點,對訓(xùn)練思維的創(chuàng)造性、敏捷性、條理性、言語表達(dá)的準(zhǔn)確性、形象性、流暢
性,以及應(yīng)變力,乃至姿勢的綜合運(yùn)用等等,都有很大的好處,所以我們要想英語口語表達(dá)能力更上一個層次,這種形式的訓(xùn)練也要加以采用。
懂得了英語口語表達(dá)的規(guī)律,并不等于就有了一口流暢的英語表達(dá)口才,就好象讀了介紹游泳的書并不等于一定會游泳一樣,關(guān)鍵還是要在長期的時實踐中持之
以恒地艱苦磨練。這種訓(xùn)練不同于我們平時常聽常說的那種日常英語口語訓(xùn)練。日常的英語口語訓(xùn)練與之相比簡單得多,所用的詞匯量及話題所涉及的深度都是相當(dāng)
有限的。而真正高層次的英語口語交際所需達(dá)到的流暢性、條理性、敏銳性和靈活性并不是常練一些日常用語就能達(dá)到的,其中用到的詞匯量也因話題的深入和多樣
而大大增加了。
所以,要想真正地提高英語口語,說一口流利而又有水平的交際英語,得有對英語口語表達(dá)感興趣作為前提,懂得以上的規(guī)律,重視運(yùn)用以上的訓(xùn)練步驟,加上
長期的艱苦訓(xùn)練,才會有成效,才會達(dá)到目的。聽力訓(xùn)練,當(dāng)然,在訓(xùn)練過程中,聽和說是無法截然分開的。
因此,英語口語訓(xùn)練體系可按以下順序安排:
1、語音訓(xùn)練
在學(xué)習(xí)英語語音知識的基礎(chǔ)上加強(qiáng)語音訓(xùn)練,進(jìn)行方音辨正練習(xí)。通過學(xué)習(xí),打好英語語音知識,有一定的辨音能力,能用英語正確、清楚、響亮地表達(dá)。
2、朗讀朗誦訓(xùn)練
進(jìn)行呼吸、發(fā)聲與共鳴訓(xùn)練,吐字納音的訓(xùn)練,以及各種朗讀朗誦技巧的訓(xùn)練,學(xué)會常用文體的朗讀、朗誦,懂得在朗誦中恰當(dāng)使用態(tài)勢語
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/3209946220095109201252
posted @
2009-06-10 09:20 C.B.K 閱讀(94) |
評論 (0) |
編輯 收藏
[關(guān)鍵字]:java,design pattern,設(shè)計模式,《Java與模式》,Chain of Responsibility,責(zé)任鏈模式
[環(huán)境]:StarUML5.0 + JDK6
[作者]:Winty (wintys@gmail.com)
[正文]:

package pattern.chainofresponsibility;
/**
* 責(zé)任鏈模式:Chain of Responsibility
* @version 2009-5-9
* @author Winty(wintys@gmail.com)
*/
public class ChainOfResponsibilityTest{
public static void main(String[] args){
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
Handler handler3 = new ConcreteHandler3();
//設(shè)置責(zé)任鏈
handler3.setSuccessor(handler2);
handler2.setSuccessor(handler1);
//發(fā)送命令
handler3.handleRequest();
}
}
/**
*抽象處理者
*/
abstract class Handler{
protected Handler successor;
public Handler getSuccessor(){
return successor;
}
public void setSuccessor(Handler successor){
this.successor = successor;
}
public abstract void handleRequest();
}
/**
*具體處理者
*/
class ConcreteHandler1 extends Handler{
public void handleRequest(){
if(getSuccessor() != null){
System.out.print("Request passed:from class Concrete1");
System.out.println(" to class" + getSuccessor().getClass().getName());
getSuccessor().handleRequest();
}
else{
System.out.println("Request handled in ConcreteHandler1");
}
}
}
/**
*具體處理者
*/
class ConcreteHandler2 extends Handler{
public void handleRequest(){
if(getSuccessor() != null){
System.out.print("Request passed:from class Concrete2");
System.out.println(" to class " + getSuccessor().getClass().getName());
getSuccessor().handleRequest();
}
else{
System.out.println("Request handled in ConcreteHandler2");
}
}
}
/**
*具體處理者
*/
class ConcreteHandler3 extends Handler{
public void handleRequest(){
if(getSuccessor() != null){
System.out.print("Request passed:from class Concrete3");
System.out.println(" to class " + getSuccessor().getClass().getName());
getSuccessor().handleRequest();
}
else{
System.out.println("Request handled in ConcreteHandler3");
}
}
}
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/320994622009410264843
posted @
2009-05-10 14:07 C.B.K 閱讀(88) |
評論 (0) |
編輯 收藏
這么一個需求:同一臺服務(wù)器上有兩個應(yīng)用,如
http://hostA:8080/services和
http://hostA:8080/admin外部訪問時,需要從不同的域名訪問,如
http://services.host.com和
http://admin.host.com一開始給他們這么一個比較簡單的解決方案:
分別把services和admin兩個應(yīng)用,部署到不同的兩個端口上,如
services ->
http://hostA:8081/admin ->
http://hostA:8082/接著在防火墻配兩個公網(wǎng)IP,然后dns上把services.host.com和admin.host.com配置到這兩個IP上。
當(dāng)請求到達(dá)防火墻時,防火墻根據(jù)所訪問的ip轉(zhuǎn)發(fā)到hostA的對應(yīng)端口上。
前
方用的防火墻是我們公司的Audemon
100,和公司的Audemon系統(tǒng)組的交流后得知,目前的防火墻版本不支持同時配置兩個ip,要到六月底才能出版本支持。!@…%#%…%¥,暈倒,好
像這是很基本的功能來的吧,居然還不支持。沒辦法,此路不通。由于防火墻是不管域名的(因為域名資料是通過應(yīng)用層傳輸?shù)?,那更別指望防火墻根據(jù)域名轉(zhuǎn)發(fā)
了。
因此,我們只好提供了軟件級的解決方案,讓前方在Tomcat前加一個Apache 2.2,通過Apache的Virtual Host + AJP實現(xiàn)轉(zhuǎn)發(fā)。
Apache的部分配置如下:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName host1.com
ProxyPass / ajp://host1.com:8009/
ProxyPassReverse / ajp://host1.com:8009/
</VirtualHost>
<VirtualHost *:80>
ServerName host2.com
ProxyPass / ajp://host2.com:8019/
ProxyPassReverse / ajp://host2.com:8019/
</VirtualHost>
Tomcat也需要配置AJP Connector,如host1.com的配置
<Connector port=”8009″ enableLookups=”false” redirectPort=”8443″ protocol=”AJP/1.3″ />
這個方案相對于防火墻的硬件方案,性能上要差一些,但還是不錯的。
另
外還有一種方案是通過iptables的domain module來實現(xiàn),但這個domain
module好像是國內(nèi)的某個高手寫的,只更新到v0.02版本,并沒有提交到iptables的標(biāo)準(zhǔn)里。雖然可以用而且性能比Apache的方案要高一
些,但是風(fēng)險較大,而且配置麻煩(既要編譯內(nèi)核,又要配置iptables的rules),所以沒有用這種方式。
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/320994622009326115641438
posted @
2009-04-26 11:57 C.B.K 閱讀(4204) |
評論 (0) |
編輯 收藏
隨著訪問量的不斷提高,以及對響應(yīng)速度的要求,進(jìn)行負(fù)載均衡設(shè)置就顯得非常必要了。公司的系統(tǒng)在最初設(shè)計的時候就已經(jīng)考慮到了負(fù)載均衡的規(guī)劃,www靜態(tài)
服務(wù)器配置了兩臺,由于初期項目時間緊,并且訪問量并不高,所以當(dāng)時只用了一臺,另一臺在內(nèi)網(wǎng)中,只是進(jìn)行了同步,并為發(fā)揮出效用來。此次就是對負(fù)載均衡
的一個簡單測試。
先介紹一下apache mod_proxy_balancer的幾個配置規(guī)則(從網(wǎng)上找的):
將Apache作為LoadBalance前置機(jī)分別有三種不同的部署方式,分別是:
1 )輪詢均衡策略的配置
進(jìn)入Apache的conf目錄,打開httpd.conf文件,在文件的末尾加入:
ProxyPass / balancer://proxy/ #注意這里以"/"結(jié)尾
<Proxy balancer://proxy>
BalancerMember http://192.168.6.37:6888/
BalancerMember http://192.168.6.38:6888/
</Proxy>
我們來觀察上述的參數(shù)“ProxyPass / balancer://proxy/”,其中,“ProxyPass”是配置虛擬服務(wù)器的命令,“/”代表發(fā)送Web請求的URL前綴,如:http://myserver/或者h(yuǎn)ttp://myserver/aaa,這些URL都將符合上述過濾條件;“balancer://proxy/”表示要配置負(fù)載均衡,proxy代表負(fù)載均衡名;BalancerMember 及其后面的URL表示要配置的后臺服務(wù)器,其中URL為后臺服務(wù)器請求時的URL。以上面的配置為例,實現(xiàn)負(fù)載均衡的原理如下:
假設(shè)Apache接收到http://localhost/aaa請求,由于該請求滿足ProxyPass條件(其URL前綴為“/”),該請求會被分發(fā)到后臺某一個BalancerMember,譬如,該請求可能會轉(zhuǎn)發(fā)到 http://192.168.6.37:6888/aaa進(jìn)行處理。當(dāng)?shù)诙€滿足條件的URL請求過來時,該請求可能會被分發(fā)到另外一臺BalancerMember,譬如,可能會轉(zhuǎn)發(fā)到http://192.168.6.38:6888/。如此循環(huán)反復(fù),便實現(xiàn)了負(fù)載均衡的機(jī)制。
2) 按權(quán)重分配均衡策略的配置
ProxyPass / balancer://proxy/ #注意這里以"/"結(jié)尾
<Proxy balancer://proxy>
BalancerMember http://192.168.6.37:6888/ loadfactor=3
BalancerMember http://192.168.6.38:6888/ loadfactor=1
</Proxy>
參數(shù)”loadfactor”表示后臺服務(wù)器負(fù)載到由Apache發(fā)送請求的權(quán)值,該值默認(rèn)為1,可以將該值設(shè)置為1到100之間的任何值。以上面的配置
為例,介紹如何實現(xiàn)按權(quán)重分配的負(fù)載均衡,現(xiàn)假設(shè)Apache收到http://myserver/aaa
4次這樣的請求,該請求分別被負(fù)載到后臺服務(wù)器,則有3次連續(xù)的這樣請求被負(fù)載到BalancerMember為http://192.168.6.37:6888的服務(wù)器,有1次這樣的請求被負(fù)載BalancerMember為http://192.168.6.38:6888后臺服務(wù)器。實現(xiàn)了按照權(quán)重連續(xù)分配的均衡策略。
3) 權(quán)重請求響應(yīng)負(fù)載均衡策略的配置
ProxyPass / balancer://proxy/ lbmethod=bytraffic #注意這里以"/"結(jié)尾
<Proxy balancer://proxy>
BalancerMember http://192.168.6.37:6888/ loadfactor=3
BalancerMember http://192.168.6.38:6888/ loadfactor=1
</Proxy>
參數(shù)“l(fā)bmethod=bytraffic”表示后臺服務(wù)器負(fù)載請求和響應(yīng)的字節(jié)數(shù),處理字節(jié)數(shù)的多少是以權(quán)值的方式來表示的。
“l(fā)oadfactor”表示后臺服務(wù)器處理負(fù)載請求和響應(yīng)字節(jié)數(shù)的權(quán)值,該值默認(rèn)為1,可以將該值設(shè)置在1到100的任何值。根據(jù)以上配置是這么進(jìn)行均
衡負(fù)載的,假設(shè)Apache接收到http://myserver/aaa請求,將請求轉(zhuǎn)發(fā)給后臺服務(wù)器,如果BalancerMember為http://192.168.6.37:6888后臺服務(wù)器負(fù)載到這個請求,那么它處理請求和響應(yīng)的字節(jié)數(shù)是BalancerMember為http://192.168.6.38:6888 服務(wù)器的3倍(回想(2)均衡配置,(2)是以請求數(shù)作為權(quán)重負(fù)載均衡的,(3)是以流量為權(quán)重負(fù)載均衡的,這是最大的區(qū)別)。
看明白了沒有,根據(jù)不同的需要,可以按這三種方式進(jìn)行配置。我按照第三種配置的,感覺上這種對于負(fù)載的均衡更全面合理。我的配置很簡單,如下:
先配置均衡器:
<Proxy balancer://proxy>
BalancerMember ajp://127.0.0.1:8009/ loadfactor=1
BalancerMember http://192.168.10.6:8083/ loadfactor=1
</Proxy>
其中http://192.168.10.6:8083實際上是另外一個端口啟動的apache,為了測試,它就簡單的直接轉(zhuǎn)發(fā)所有請求到tomcat。
對于上次的VirtualHost進(jìn)行以下的修改即可:
<VirtualHost *:80>
ServerName www.test.com
DocumentRoot /www
DirectoryIndex index.html index.jsp
<Directory "/www">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
<Directory "/control">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
ProxyPass /nxt/images/ !
ProxyPass /nxt/js/ !
ProxyPass /nxt/css/ !
#ProxyPass / ajp://127.0.0.1:8009/
#ProxyPassReverse / ajp://127.0.0.1:8009/
ProxyPass / balancer://proxy/
ProxyPassReverse / balancer://proxy/
</VirtualHost>
注釋掉之前的ajp轉(zhuǎn)發(fā),而配置成通過balancer去處理。
通過觀察access log,的確有部分請求發(fā)送到了8083端口的apache上,而有部分是直接ajp轉(zhuǎn)發(fā)到tomcat上了。對于更多的負(fù)載均衡的參數(shù)檢測,待空了再做。
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200932611555639
posted @
2009-04-26 11:56 C.B.K 閱讀(151) |
評論 (0) |
編輯 收藏
一、集群和負(fù)載均衡的概念
(一)集群的概念
集群(Cluster)是由兩臺或多臺節(jié)點機(jī)(服務(wù)器)構(gòu)成的一種松散耦合的計算節(jié)點集合,為用
戶提供網(wǎng)絡(luò)服務(wù)或應(yīng)用程序(包括數(shù)據(jù)庫、Web服務(wù)和文件服務(wù)等)的單一客戶視圖,同時提供接近容錯機(jī)的故障恢復(fù)能力。集群系統(tǒng)一般通過兩臺或多臺節(jié)點服
務(wù)器系統(tǒng)通過相應(yīng)的硬件及軟件互連,每個群集節(jié)點都是運(yùn)行其自己進(jìn)程的獨(dú)立服務(wù)器。這些進(jìn)程可以彼此通信,對網(wǎng)絡(luò)客戶機(jī)來說就像是形成了一個單一系統(tǒng),協(xié)
同起來向用戶提供應(yīng)用程序、系統(tǒng)資源和數(shù)據(jù)。除了作為單一系統(tǒng)提供服務(wù),集群系統(tǒng)還具有恢復(fù)服務(wù)器級故障的能力。集群系統(tǒng)還可通過在集群中繼續(xù)增加服務(wù)器
的方式,從內(nèi)部增加服務(wù)器的處理能力,并通過系統(tǒng)級的冗余提供固有的可靠性和可用性。
(二)集群的分類
1、高性能計算科學(xué)集群:
以解決復(fù)雜的科學(xué)計算問題為目的的IA集群系統(tǒng)。是并行計算的基礎(chǔ),它可以不使用專門的由十至上萬個獨(dú)立處理器組成的并行超級計算機(jī),而是采用通過高速
連接來鏈接的一組1/2/4
CPU的IA服務(wù)器,并且在公共消息傳遞層上進(jìn)行通信以運(yùn)行并行應(yīng)用程序。這樣的計算集群,其處理能力與真正超級并行機(jī)相等,并且具有優(yōu)良的性價比。
2、負(fù)載均衡集群:
負(fù)載均衡集群為企業(yè)需求提供更實用的系統(tǒng)。該系統(tǒng)使各節(jié)點的負(fù)載流量可以在服務(wù)器集群中盡可能平均合理地分?jǐn)偺幚?。該?fù)載需要均衡計算的應(yīng)用程序處理端
口負(fù)載或網(wǎng)絡(luò)流量負(fù)載。這樣的系統(tǒng)非常適合于運(yùn)行同一組應(yīng)用程序的大量用戶。每個節(jié)點都可以處理一部分負(fù)載,并且可以在節(jié)點之間動態(tài)分配負(fù)載,以實現(xiàn)平
衡。對于網(wǎng)絡(luò)流量也如此。通常,網(wǎng)絡(luò)服務(wù)器應(yīng)用程序接受了大量入網(wǎng)流量,無法迅速處理,這就需要將流量發(fā)送給在其它節(jié)點。負(fù)載均衡算法還可以根據(jù)每個節(jié)點
不同的可用資源或網(wǎng)絡(luò)的特殊環(huán)境來進(jìn)行優(yōu)化。
3、高可用性集群:
為保證集群整體服務(wù)的高可用,考慮計算硬件和軟件的容錯性。如果高可用性群集中的某個節(jié)點發(fā)生了故障,那么將由另外的節(jié)點代替它。整個系統(tǒng)環(huán)境對于用戶是一致的。
實際應(yīng)用的集群系統(tǒng)中,這三種基本類型經(jīng)常會發(fā)生混合與交雜。
(三)典型集群
科學(xué)計算集群:
1、Beowulf
當(dāng)談到 Linux
集群時,許多人的第一反映是 Beowulf。那是最著名的 Linux科學(xué)軟件集群系統(tǒng)。實際上,它是一組適用于在 Linux
內(nèi)核上運(yùn)行的公共軟件包的通稱。其中包括流行的軟件消息傳遞 API,如“消息傳送接口”(MPI) 或“并行虛擬機(jī)”(PVM),對 Linux
內(nèi)核的修改,以允許結(jié)合幾個以太網(wǎng)接口、高性能網(wǎng)絡(luò)驅(qū)動器,對虛擬內(nèi)存管理器的更改,以及分布式進(jìn)程間通信 (DIPC)
服務(wù)。公共全局進(jìn)程標(biāo)識空間允許使用 DIPC 機(jī)制從任何節(jié)點訪問任何進(jìn)程。
2、MOSIX
Beowulf類似于給系統(tǒng)安裝的一個支持
集群的外掛軟件,提供了應(yīng)用級的集群能力。而MOSIX是徹底修改Linux的內(nèi)核,從系統(tǒng)級提供了集群能力,它對應(yīng)用而言是完全透明的,原有的應(yīng)用程
序,可以不經(jīng)改動,就能正常運(yùn)行在MOSIX系統(tǒng)之上。集群中的任何節(jié)點都可以自由地加入和移除,來接替其它節(jié)點的工作,或是擴(kuò)充系統(tǒng)。MOSIX
使用自適應(yīng)進(jìn)程負(fù)載均衡和內(nèi)存引導(dǎo)算法使整體性能最大化。應(yīng)用程序進(jìn)程可以在節(jié)點之間實現(xiàn)遷移,以利用最好的資源,這類似于對稱多處理器系統(tǒng)可以在各個處
理器之間切換應(yīng)用程序。由于MOSIX通過修改內(nèi)核來實現(xiàn)集群功能,所以存在兼容性問題,部分系統(tǒng)級應(yīng)用程序?qū)o法正常運(yùn)行。
負(fù)載均衡/高可用性集群
3、LVS(Linux Virtual Server)
這是一個由國人主持的項目。
它是一個負(fù)載均衡/高可用性集群,主要針對大業(yè)務(wù)量的網(wǎng)絡(luò)應(yīng)用(如新聞服務(wù)、網(wǎng)上銀行、電子商務(wù)等)。
LVS
是建立在一個主控服務(wù)器(通常為雙機(jī))(director)及若干真實服務(wù)器(real-server)所組成的集群之上。real-server負(fù)責(zé)實
際提供服務(wù),主控服務(wù)器根據(jù)指定的調(diào)度算法對real-server進(jìn)行控制。而集群的結(jié)構(gòu)對于用戶來說是透明的,客戶端只與單個的IP(集群系統(tǒng)的虛擬
IP)進(jìn)行通信,也就是說從客戶端的視角來看,這里只存在單個服務(wù)器。
N54537Real-server可以提供眾多服務(wù),如ftp,
http, dns, telnet, nntp, smtp
等。主控服務(wù)器負(fù)責(zé)對Real-Server進(jìn)行控制??蛻舳嗽谙騆VS發(fā)出服務(wù)請求時,Director會通過特定的調(diào)度算法來指定由某個Real-
Server來應(yīng)答請求,而客戶端只與Load Balancer的IP(即虛擬IP,VIP)進(jìn)行通信。
其他集群:
現(xiàn)在集群系統(tǒng)可謂五花八門,絕大部分的OS開發(fā)商,服務(wù)器開發(fā)商都提供了系統(tǒng)級的
集群產(chǎn)品,最典型的是各類雙機(jī)系統(tǒng),還有各類科研院校提供的集群系統(tǒng)。以及各類軟件開發(fā)商提供的應(yīng)用級別的集群系統(tǒng),如數(shù)據(jù)庫集
群,Application Server 集群,Web Server集群,郵件集群等等。
(四)負(fù)載均衡
1、概念
由于目前現(xiàn)有網(wǎng)絡(luò)的各個核心部分隨著業(yè)務(wù)量的提高,訪問量和數(shù)據(jù)流量的快速增長,其處理能力和計算強(qiáng)度也相應(yīng)地增大,使得單一的服務(wù)器設(shè)備根本無法承擔(dān)。
在此情況下,如果扔掉現(xiàn)有設(shè)備去做大量的硬件升級,這樣將造成現(xiàn)有資源的浪費(fèi),而且如果再面臨下一次業(yè)務(wù)量的提升時,這又將導(dǎo)致再一次硬件升級的高額成本
投入,甚至性能再卓越的設(shè)備也不能滿足當(dāng)前業(yè)務(wù)量增長的需求。
針對此情況而衍生出來的一種廉價有效透明的方法以擴(kuò)展現(xiàn)有網(wǎng)絡(luò)設(shè)備和服務(wù)器的帶寬、增加吞吐量、加強(qiáng)網(wǎng)絡(luò)數(shù)據(jù)處理能力、提高網(wǎng)絡(luò)的靈活性和可用性的技術(shù)就是負(fù)載均衡(Load Balance)。
2、特點和分類
負(fù)載均衡(Server Load Balance)一般用于提高服務(wù)器的整體處理能力,并提高可靠性,可用性,可維護(hù)性,最終目的是加快服務(wù)器的響應(yīng)速度,從而提高用戶的體驗度。
負(fù)載均衡從結(jié)構(gòu)上分為本地負(fù)載均衡(Local Server Load Balance)和地域負(fù)載均衡(Global Server Load
Balance)(全局負(fù)載均衡),一是指對本地的服務(wù)器群做負(fù)載均衡,另一是指對分別放置在不同的地理位置、有不同的網(wǎng)絡(luò)及服務(wù)器群之間作負(fù)載均衡。
地域負(fù)載均衡有以下的特點:
(1)解決網(wǎng)絡(luò)擁塞問題,服務(wù)就近提供,實現(xiàn)地理位置無關(guān)性
(2)對用戶提供更好的訪問質(zhì)量
(3)提高服務(wù)器響應(yīng)速度
(4)提高服務(wù)器及其他資源的利用效率
(5)避免了數(shù)據(jù)中心單點失效
3、負(fù)載均衡技術(shù)主要應(yīng)用
(1)DNS負(fù)載均衡
最早的負(fù)載均衡技術(shù)是通過DNS來實現(xiàn)的,在DNS中為多個地址配置同一個名字,因而查詢這個名字的客戶機(jī)將得到其中一個地址,從而使得不同的客戶訪問不
同的服務(wù)器,達(dá)到負(fù)載均衡的目的。DNS負(fù)載均衡是一種簡單而有效的方法,但是它不能區(qū)分服務(wù)器的差異,也不能反映服務(wù)器的當(dāng)前運(yùn)行狀態(tài)。
(2)代理服務(wù)器負(fù)載均衡 使用代理服務(wù)器,可以將請求轉(zhuǎn)發(fā)給內(nèi)部的服務(wù)器,使用這種加速模式顯然可以提升靜態(tài)網(wǎng)頁的訪問速度。然而,也可以考慮這樣一種技術(shù),使用代理服務(wù)器將請求均勻轉(zhuǎn)發(fā)給多臺服務(wù)器,從而達(dá)到負(fù)載均衡的目的。
(3)地址轉(zhuǎn)換網(wǎng)關(guān)負(fù)載均衡 支持負(fù)載均衡的地址轉(zhuǎn)換網(wǎng)關(guān),可以將一個外部IP地址映射為多個內(nèi)部IP地址,對每次TCP連接請求動態(tài)使用其中一個內(nèi)部地址,達(dá)到負(fù)載均衡的目的。
(4)協(xié)議內(nèi)部支持負(fù)載均衡 除了這三種負(fù)載均衡方式之外,有的協(xié)議內(nèi)部支持與負(fù)載均衡相關(guān)的功能,例如HTTP協(xié)議中的重定向能力等,HTTP運(yùn)行于TCP連接的最高層。
(5)NAT
負(fù)載均衡 NAT(Network Address Translation
網(wǎng)絡(luò)地址轉(zhuǎn)換)簡單地說就是將一個IP地址轉(zhuǎn)換為另一個IP地址,一般用于未經(jīng)注冊的內(nèi)部地址與合法的、已獲注冊的Internet
IP地址間進(jìn)行轉(zhuǎn)換。適用于解決Internet IP地址緊張、不想讓網(wǎng)絡(luò)外部知道內(nèi)部網(wǎng)絡(luò)結(jié)構(gòu)等的場合下。
(6)反向代理負(fù)載均
衡
普通代理方式是代理內(nèi)部網(wǎng)絡(luò)用戶訪問internet上服務(wù)器的連接請求,客戶端必須指定代理服務(wù)器,并將本來要直接發(fā)送到internet上服務(wù)器的連
接請求發(fā)送給代理服務(wù)器處理。反向代理(Reverse
Proxy)方式是指以代理服務(wù)器來接受internet上的連接請求,然后將請求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器,并將從服務(wù)器上得到的結(jié)果返回給
internet上請求連接的客戶端,此時代理服務(wù)器對外就表現(xiàn)為一個服務(wù)器。反向代理負(fù)載均衡技術(shù)是把將來自internet上的連接請求以反向代理的
方式動態(tài)地轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的多臺服務(wù)器進(jìn)行處理,從而達(dá)到負(fù)載均衡的目的。
(7)混合型負(fù)載均衡
在有些大型網(wǎng)絡(luò),由于多個服務(wù)器群內(nèi)硬件設(shè)備、各自的規(guī)模、提供的服務(wù)等的差異,我們可以考慮給每個服務(wù)器群采用最合適的負(fù)載均衡方式,然后又在這多個服
務(wù)器群間再一次負(fù)載均衡或群集起來以一個整體向外界提供服務(wù)(即把這多個服務(wù)器群當(dāng)做一個新的服務(wù)器群),從而達(dá)到最佳的性能。我們將這種方式稱之為混合
型負(fù)載均衡。此種方式有時也用于單臺均衡設(shè)備的性能不能滿足大量連接請求的情況下。
二、搭建集群和實現(xiàn)負(fù)載平衡
(一)前期準(zhǔn)備
我的系統(tǒng)用的是windowsXP專業(yè)版,我要做的是,用一個apache和多個(這里以兩個作為示例)tomcat,通過jk方式,構(gòu)造一個集群。以下是要首先準(zhǔn)備的東西:
1、jdk,我用的版本是jdk1.5.0_06,下載地址是http://192.18.108.216/ECom/EComTicketServlet/BEGIND597A309654D73D910E051D73D539D5F/-2147483648/2438196255/1/852050/851882/2438196255/2ts+/westCoastFSEND/jdk-1.5.0_13-oth-JPR/jdk-1.5.0_13-oth-JPR:3/jdk-1_5_0_13-windows-i586-p.exe
2、apache,我用的版本是2.2.4,下載地址是http://apache.justdn.org/httpd/binaries/win32/apache_2.2.4-win32-x86-openssl-0.9.8d.msi
3、tomcat,我用的版本是5.5的解壓版本,這里要注意:不能用安裝的版本,因為一臺機(jī)器上裝兩個一樣的tomcat,是會出錯誤的。下載地址是http://apache.mirror.phpchina.com/tomcat/tomcat-5/v5.5.25/bin/apache-tomcat-5.5.25.zip
4、jk,這個jk的版本,本來有兩個的,但是版本2已經(jīng)被廢棄掉了,目前可用的jk版本是1.2.25。每個apache的版本,都會有一個特定的jk與之對應(yīng),所以這里要用的jk也必須是為apache-2.2.4開發(fā)的那個才行。它的下載地址是http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/win32/jk-1.2.25/mod_jk-apache-2.2.4.so
有了這四樣?xùn)|西,我們就可以開始做集群了。
(二)安裝
1、相信需要看這篇文章的人,JDK的安裝一定不會陌生,這里不在贅述。只是需要提醒一下:環(huán)境變量別忘記配置了。
2、安裝apache也沒有什么難度,就是在安裝過程中要配置域名、網(wǎng)址和管理員郵箱之類的信息,這
個信息完全可以按照提示,然后修改下填入即可,之后想修改的話直接到配置文件中改就行了。除了這個地方,還要保證機(jī)器上的80端口沒有被其他程序占用。至
于安裝路徑,完全取決于個人愛好。其他的默認(rèn)就行了。安裝成功后,系統(tǒng)右下角的托盤區(qū)會有個圖標(biāo),我們可以通過這個啟動apache,如果那個小紅點變成
綠色,說明服務(wù)已經(jīng)正常啟動了(如果服務(wù)沒有啟動起來,說明安裝過程中的配置有錯誤,建議卸載后重裝)。如果按照默認(rèn),端口是80的話,那打開瀏覽器,輸
入:http://localhost/ ,應(yīng)該可以看到 " It works “的字樣。這樣就可以進(jìn)入下一步了。
3、解壓縮tomcat,記得要做兩份。這里不妨將兩個tomcat命名為:tomcat-
5.5.25_1和tomcat-5.5.25_2,其實這兩個文件夾中的東西是完全一樣的。但是我為了在同一臺機(jī)器上做集群,那就要保證兩個
tomcat運(yùn)行起來不會在端口上起沖突。進(jìn)入tomcat-5.5.25_1/conf目錄,用文本編輯器打開并修改server.xml,將該
tomcat的默認(rèn)8080端口改為8088(其實沒必要改,我改這個是因為我機(jī)器上還有其他tomcat占用著8080端口)。然后進(jìn)入tomcat-
5.5.25_2/conf目錄,同樣將8080修改掉,至于改成多少沒多大關(guān)系,只要不占用其他程序的端口,應(yīng)該不會出什么問題。這樣,tomcat就
算安裝好了。
4、jk這東西是一個連接模塊,不用安裝,直接將mod_jk-apache-2.2.4.so這個文件拷貝到apache安裝目錄下的modules文件夾下面就行了。
這樣,安裝完成,下面開始配置。
(三)配置
這個地方才是搭建集群的關(guān)鍵所在,我也會盡我的可能寫的詳細(xì)點。
1、配置tomcat
為防止沖突,進(jìn)入第二個tomcat主目錄,然后進(jìn)入conf目錄,打開server.xml修改配
置。主要是修改端口,我這里把所有的端口信息,都在原有基礎(chǔ)上加1000,即原端口是8009,我改為9009。當(dāng)然,你不必和我一樣,只要保證不沖突就
OK!這些配置在apache的配置中可能會用到。
2、配置apache
(1)進(jìn)入apache的主目錄,然后進(jìn)入conf文件夾,用文本編輯器打開httpd.conf,在該文件末尾加上如下幾行:
### 加載 mod_jk 模塊
LoadModule jk_module modules/mod_jk-apache-2.2.4.so
### 配置 mod_jk
JkWorkersFile conf/workers.properties #加載集群中的workers
JkMountFile conf/uriworkermap.properties #加載workers的請求處理分配文件
JkLogFile logs/mod_jk.log #指定jk的日志輸出文件
JkLogLevel warn #指定日志級別
(2)不要改變目錄,新建一個文件:workers.properties,該文件用來配置web容器的信息。該文件的內(nèi)容如下:
# worker列表
worker.list=controller, status
#第一個server的配置,server名為s1
#ajp13 端口號,在tomcat下server.xml配置,默認(rèn)8009
worker.s1.port=8009
#tomcat的主機(jī)地址,如不為本機(jī),請?zhí)顚慽p地址
worker.s1.host=localhost
worker.s1.type=ajp13
#server的加權(quán)比重,值越高,分得的請求越多
worker.s1.lbfactor=1
#第二個server的配置,server名為s2
worker.s2.port=9009
worker.s2.host=localhost
worker.s2.type=ajp13
worker.s2.lbfactor=1
#server名為controller,用于負(fù)載均衡
worker.controller.type=lb
worker.retries=3 #重試次數(shù)
#指定分擔(dān)請求的server列表,用逗號分隔
worker.controller.balanced_workers=s1,s2
#設(shè)置用于負(fù)載均衡的server的session可否共享 有不少文章說設(shè)置為1是可以的,但是我是設(shè)置為0才可以的
worker.controller.sticky_session=0
#worker.controller.sticky_session_force=1
worker.status.type=status
(3)不要改變目錄,新建一個文件:uriworkermap.properties,文件內(nèi)容如下:
/*=controller #所有請求都由controller這個server處理
/jkstatus=status #所有包含jkstatus請求的都由status這個server處理
!/*.gif=controller #所有以.gif結(jié)尾的請求都不由controller這個server處理,以下幾個都是一樣的意思
!/*.jpg=controller
!/*.png=controller
!/*.css=controller
!/*.js=controller
!/*.htm=controller
!/*.html=controller
這里的"!”類似于java中的"!”,是“非”的意思。
這樣,apache一塊就配置好了。
3、再修改tomcat配置:這里兩個tomcat都要配置。
仍然是打開第一步中的那個server.xml文件,找到<Engine
name="Catalina"
defaultHost="localhost">這一行,在里面加上一句:jvmRoute="s1",即把該句改為:<Engine
name="Catalina" defaultHost="localhost"
jvmRoute="s1">。這里的s1就是第二步中配置的用于負(fù)載均衡的server的名稱。如果該tomcat的端口是第二步中s1用的端
口,那這里就寫s1,第二個tomcat就應(yīng)該是s2了。
這樣,配置就完成了。
(四)運(yùn)行
進(jìn)入兩個tomcat的bin目錄,執(zhí)行兩個tomcat的startup.bat啟動這兩個
tomcat,然后將apache重新啟動后,運(yùn)行起來看看效果吧。如果不出意外,兩個tomcat的窗口應(yīng)該是你一次我一次的打印日志信息了,而且此時
session也是共享了的。
到這里,集群搭建好了,負(fù)載均衡也實現(xiàn)了。
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200932611544216
posted @
2009-04-26 11:54 C.B.K 閱讀(196) |
評論 (0) |
編輯 收藏
附錄B SQL*PLUS
Sql*plus 中使用綁定變量:
sql> variable x number;
sql> exec :x := 7788;
sql> SELECT empno,ename from scott.emp where empno=:x;
SQL*PLUS 是Oracle提供的一個工具程序,它不僅可以用于測試,運(yùn)行SQL語句和PL/SQL塊,而且還可以用于管理Oracle數(shù)據(jù)庫,
1.啟動sql*plus
為了使用sql*plus,必須首先要啟動sql*plus。Oracle不僅提供了命令行和圖形界面的sql*plus,而且還可以在web瀏覽器中
運(yùn)行.
(1)在命令運(yùn)行sql*plus
在命令行運(yùn)行sql*plus是使用sqlplus命令來完成的,該命令適用于任何操作系統(tǒng)平臺,
語法如下:
sqlplus [username]/[password][@server]
如上所示:username用于指定數(shù)據(jù)庫用戶名,password用于指定用戶口令,server則用于指定主機(jī)字符串(網(wǎng)絡(luò)服務(wù)名).
當(dāng)連接到本地數(shù)據(jù)時,不需要提供網(wǎng)絡(luò)服務(wù)名,如果要連接到遠(yuǎn)程數(shù)據(jù)庫,則必須要使用網(wǎng)絡(luò)服務(wù)名.
(2)在windows環(huán)境中運(yùn)行sql*plus
如果在windows環(huán)境中安裝了oralce數(shù)據(jù)庫產(chǎn)品,那么可以在窗口環(huán)境中運(yùn)行sql*plus
具體方法: "開始->程序->oracle-oradb10g_home1->application development->sql*plus"
2.連接命令
(1)conn[ect]
該命令用于連接到數(shù)據(jù)庫。注意,使用該命令建立新會話時,會自動斷開先前會話,示例如下:
sql>conn scott/yhai1981@demo
(2)disc[onnect]
該命令用于斷開已經(jīng)存在的數(shù)據(jù)庫連接。注:該命令只是斷開連接會話,而不會退出sql*plus,示例如下:
sql>disc
(3)passw[ord]
該命令用于修改用戶的口令。注,任何用戶都可以使用該命令修改其自身口令,但如果要修改其他用戶的口令時,
則必須以DBA身份(sys和system)登錄,在sql*plus中,當(dāng)修改用戶口令時,可以使用該命令取代sql命令alter user,
示例如下:
sql>passw
更改scott的口令
舊口令:******
新口令:******
重新鍵入新口令:******
口令已更改
sql>
(4)exit
該命令用于退出 sql*plus,另外你也可以使用quit命令退出sql*plus.使用該命令不僅會斷開連接,而且也會退出sql*plus
注:默認(rèn)情況下,當(dāng)執(zhí)行該命令時會自動提交事務(wù)。
3,編輯命令
(1)l[ist]
該命令用于列出sql緩沖區(qū)的內(nèi)容,使用該命令可以列出sql緩沖某行,某幾行或所有行的內(nèi)容。在顯示結(jié)果中,數(shù)據(jù)字為具體
的行號,而"*"則表示當(dāng)前行。
示例一:列出sql緩沖區(qū)所有內(nèi)容
sql>l
示例二:列出sql緩沖區(qū)首行內(nèi)容:
sql>l1
(2)a[ppend]
該命令用于在sql緩沖區(qū)的當(dāng)前行尾部添加內(nèi)容。注:該命令將內(nèi)容追加到標(biāo)記為"*"的行的尾部,示例如下:
sql>l
1 select empno,ename,sal,hiredate,comm,deptno
2 from emp
3* where deptno=10
sql>a and job='CLERK'
sql>l
SQL> list
1 select empno,ename,sal,hiredate,comm,deptno
2 from emp
3* where deptno=10 and job='CLERK'
(3)c[hange]
該命令用于修改sql緩沖區(qū)的內(nèi)容。如果在編寫sql語句時寫錯了某個詞,那么使用該命令可以進(jìn)行修改,
sql>select ename from temp where deptno=10;
SQL> c /temp/emp
1* select ename from emp where deptno=10
(4)del
該命令用于刪除sql緩沖區(qū)中內(nèi)容,使用它可以刪除某行,某幾行或所有行,在默認(rèn)情況下,當(dāng)直接執(zhí)行
del時,只刪除當(dāng)前行的內(nèi)容,示例如下:
SQL> l
1 select ename
2 from emp
3* where deptno=20
sql>del
SQL> l
1 select ename
2* from emp
如果一次要刪除多行,則指定起始行號和終止行號,例如"del 3 5"
(5)i[nput]
該命令用于在sql緩沖區(qū)的當(dāng)前行后新增加一行。示例如下:
SQL> l
1 select ename
2* from emp
sql>i where deptno=30
如果要在首行前增加內(nèi)容,則使用"0文本"
sql>0 create table temp as
SQL> l
1 create table temp as
2 select ename
3 from emp
4* where deptno=30
(6) n
該數(shù)值用于定位sql緩沖區(qū)的當(dāng)前行,示例如下:
(7)edi[t]
該命令用于編輯sql緩沖區(qū)的內(nèi)容。當(dāng)運(yùn)行該命令時,在windows平臺中會自動啟動"記事本",以編輯sql緩沖區(qū)
(8)run和/
run的/命令都可以用于運(yùn)行sql緩沖區(qū)中的sql語句。注:當(dāng)使用run命令時,還會列出sql緩沖區(qū)內(nèi)容,eg:
SQL> run
1* select ename from emp where deptno=20
4.文件操縱命令
(1)save
該命令用于將當(dāng)前sql緩沖區(qū)的內(nèi)容保存到sql腳本中。當(dāng)執(zhí)行該命令時,默認(rèn)選項為create,即建立新文件。
eg:
SQL> save c:\a.sql create
已創(chuàng)建 file c:\a.sql
當(dāng)執(zhí)行命令之后,就會建立新腳本文件a.sql,并將sql緩沖區(qū)內(nèi)容存放到該文件中。如果sql已經(jīng)存在,使用
replace選項可以替撚已存在的sql腳本,如果要給已存在的sql腳本追加內(nèi)容,可以使用append選項。
(2)get
該命令與save命令作用恰好相反,用于將sql腳本中的所有內(nèi)容裝載到sql緩沖區(qū)中。
eg:
SQL> get c:\a.sql
1* select ename from emp where deptno=20
(3)start和@
start和@命令用于運(yùn)行sql腳本文件。注:當(dāng)運(yùn)行sql腳本文件時,應(yīng)該指定文件路徑.eg:
SQL> @c:\a.sql
ENAME
----------
SMITH
JONES
SCOTT
ADAMS
FORD
(4)@@
該命令與@命令類似,也可以運(yùn)行腳本文件,但主要作用是在腳本文件中嵌套調(diào)用其它的腳本文件。當(dāng)使用該命令
嵌套腳本文件時,可在調(diào)用文件所在目錄下查找相應(yīng)文件名。
(5)ed[it]
該命令不僅可用于編輯sql緩沖區(qū)內(nèi)容,也可以用于編輯sql腳本文件。當(dāng)運(yùn)行該命令時,會啟動默認(rèn)的系統(tǒng)編輯
器來編輯sql腳本。運(yùn)行方法為:
sql>edit c:/a.sql
(6)spool
該命令用于將sql*plus屏幕內(nèi)容存放到文本文件中。執(zhí)行該命令時,應(yīng)首先建立假脫機(jī)文件,并將隨后sql*plus
屏幕的所有內(nèi)容全部存放到該文件中,最后使用spool off命令關(guān)閉假脫機(jī)文件。eg:
sql>spool c:\a.sql
5.格式命令
sql*plus不僅可以用于執(zhí)行sql語句、pl/sql塊,而且還可以根據(jù)select結(jié)果生成報表。使用sql*plus的格式命令
可以控制報表的顯示格式,例如使用column命令可以控制列的顯示格式,使用ttitle命令可以指定頁標(biāo)題;使用
btitle命令可以指定頁腳注。
(1)col[umn]
該命令用于控制列的顯示格式。column命令包含有四個選項,其中clear選項用于清除已定義列的顯示格式:
heading選項用于指定列的顯示標(biāo)題;justify選項用于指定列標(biāo)題的對齊格式(left,center,right);format選項用于
指定列的顯示格式,其中格式模型包含以下一些元素。
An:設(shè)置char,varchar2類型列的顯示寬度;
9: 在number類型列上禁止顯示前導(dǎo)0;
0: 在number類型列上強(qiáng)制顯示前導(dǎo)0;
$: 在number類型列前顯示美元符號;
L: 在number類型列前顯示本地貨幣符號;
.: 指定number類型列的小數(shù)點位置;
,: 指定number類型列的千分隔符;
eg1:使用column設(shè)置列顯示格式
sql>col ename heading 'name' format a10
sql>col sal heading 'sal' format L99999.99
sql>select ename,sal,hiredate from emp
sql>where empno=7788;
name sal HIREDATE
---------- ------------------- -------------------
SCOTT ¥3000.00 04/19/1987 00:00:00
sql>col ename clear
sql>col sal clear
sql>select ename,sal,hiredate from emp
sql>where empno=7788;
(2)title
該命令用于指定頁標(biāo)題,頁標(biāo)題會自動顯示在頁的中央。如果頁標(biāo)題由多個詞組成,則用單引號引住。如果要將頁
標(biāo)題分布在多行顯示,則用"|"分開不同單詞。如果不希望顯示頁標(biāo)題,則使用"ttitle off"命令,禁止顯示,eg:
SQL> set linesize 40
SQL> ttitle 'employee report'
SQL> select ename,sal,hiredate from emp where empno=7788;
星期二 5月 20 第 1
employee report
ENAME SAL
---------- ----------
HIREDATE
-------------------
SCOTT 3000
04/19/1987 00:00:00
(3)btitle
該命令用于指定頁腳注,頁腳注會自動顯示在頁的中央。如果頁腳注由多個詞組成,則用單引號引注。如果要將頁腳注
分布在多行顯示,則用"|"分開不同單詞。如果不希望顯示頁腳注,則使用"btitle off"命令,禁止顯示。eg:
SQL> btitle 'page end'
SQL> select ename,sal,hiredate from emp where empno=7788
ENAME SAL
---------- ----------
HIREDATE
-------------------
SCOTT 3000
04/19/1987 00:00:00
page end
(4)break
該命令用于禁止顯示重復(fù)行,并將顯示結(jié)果分隔為幾個部分,以表現(xiàn)更友好的顯示結(jié)果,通常應(yīng)該在order by 的排序列上
使用該命令。eg:
SQL> set pagesize 40
SQL> break on deptno skip 1
SQL> select deptno,ename,sal from emp order by deptno
2 ;
DEPTNO ENAME SAL
---------- ---------- ----------
10 CLARK 2450
KING 5000
MILLER 1300
20 JONES 2975
FORD 3000
ADAMS 1100
SMITH 800
SCOTT 3000
30 WARD 1250
TURNER 1500
ALLEN 1600
JAMES 950
BLAKE 2850
MARTIN 1250
6.交互式命令
如果經(jīng)常要執(zhí)行某些sql語句和sql*plus命令,可以將這些語句和命令存放到sql腳本中。通過使用sql腳本,
一方面可以降低命令輸入量,另一方面可以避免用戶的輸入錯誤。為了使得sql腳本可以根據(jù)不同輸入獲得
不同結(jié)果,需要在sql腳本中包含交互式命令。通過使用交互式命令,可以在sql*plus中定義變量,并且在運(yùn)行
sql腳本時可以為這些變量動態(tài)輸入數(shù)據(jù)。下面介紹sql*plus的交互命令,以及引用變量所使用的標(biāo)號。
(1)&
引用替代變量(substitution variable)時,必須要帶有該標(biāo)號。如果替代變量已經(jīng)定義,則會直接使用其數(shù)據(jù),
如果替代變量沒有定義,則會臨時定義替代變量(該替代變量只在當(dāng)前語句中起作用),并需要為其輸入數(shù)據(jù)。
注:如果替代變量為數(shù)字列則提供數(shù)據(jù),則可以直接引用;如果替代變量為字符類型列或日期類型列提供數(shù)據(jù),
則必須要用單引號引注。eg:
SQL> select ename,sal from emp where deptno=&no and job='&job';
輸入 no 的值: 20
輸入 job 的值: CLERK
原值 1: select ename,sal from emp where deptno=&no and job='&job'
新值 1: select ename,sal from emp where deptno=20 and job='CLERK'
(2)&&
該標(biāo)號類似于單個&標(biāo)號。但需要注意,&標(biāo)號所定義的替代變量只在當(dāng)前語句中起作用;而&&標(biāo)號所定義的變量
會在當(dāng)前sql*plus環(huán)境中一直生效。eg:
SQL> select ename,sal from emp where deptno=&&no and job='&&job' --定義了no變量
輸入 no 的值: 20
輸入 job 的值: CLERK
原值 1: select ename,sal from emp where deptno=&&no and job='&&job'
新值 1: select ename,sal from emp where deptno=20 and job='CLERK'
SQL> select ename,sal from emp where deptno=&no;
原值 1: select ename,sal from emp where deptno=&no --直接引用no變量
新值 1: select ename,sal from emp where deptno=20
ENAME SAL
---------- ----------
SMITH 800
JONES 2975
SCOTT 3000
ADAMS 1100
FORD 3000
如例所示,當(dāng)?shù)谝淮我胣o變量時,使用&&標(biāo)號需要為其輸入數(shù)據(jù);當(dāng)?shù)诙我胣o變量時,
使用&標(biāo)號直接引用其原有值,而不需要輸入數(shù)據(jù)。
(3)define
該命令用于定義類型為char的替代變量,而且該命令的定義的替代變量只在當(dāng)前sql*plus環(huán)境中起作用。
當(dāng)使用該命令定義變量時,如果變量值包含空格或區(qū)分大小寫,則用引號引注。另外,使用"define變量名"可以檢查變量
是否已經(jīng)定義。eg:
sql>set verify off
sql>define title=CLERK
sql>select ename,sal from where job='&title';
(4)accept
該命令可以用于定義char,number和date類型的替代變量。與define命令相比,accept命令更加靈活。當(dāng)使用該命令定義替代
變量時,還可以指定變量輸入提示、變量輸入格式、隱藏輸入內(nèi)容。
eg1:指定變量輸入提示
SQL> accept title prompt '請輸入崗位:'
請輸入崗位:CLERK
SQL> select ename,sal from emp where job='&title';
原值 1: select ename,sal from emp where job='&title'
新值 1: select ename,sal from emp where job='CLERK'
ENAME SAL
---------- ----------
SMITH 800
ADAMS 1100
JAMES 950
MILLER 1300
eg2:隱藏用戶輸入
sql>accept pwd hide
(5)undefine
該命令用于清除替代變量的定義。eg:
sql>undefine pwd
SQL> disc
從 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options 斷開
SQL> conn scott/&pwd
輸入 pwd 的值: yhai1981
已連接
(6)prompt的pause
prompt命令用于輸出提示信息,而pause命令則用于暫停腳本執(zhí)行。在sql腳本中結(jié)合使用這兩條命令,可以控制sql腳本
的暫停的執(zhí)行。假定在a.sql腳本中包含以下命令:
prompt '按<Return>鍵繼續(xù)'
pause
當(dāng)運(yùn)行該sql腳本時,會暫停執(zhí)行,eg:
sql>@c:\a.sql
'按<Return>鍵繼續(xù)'
(7)variable
該命令用于在sql*plus中定義綁定變量。當(dāng)在sql語句或pl/sql塊中引用綁定變量時,必須要在綁定變量前加冒號(:);
當(dāng)直接給綁定變量賦值時,需要使用execute命令(類似于調(diào)用存儲過程).示例如下:
sql>var no number
sql>exec :no:=7788
sql>select ename from emp where empno=:no;
ename
------------------
scott
(8)print
該命令用于輸出綁定變量結(jié)果,eg:
SQL> print no
NO
----------
7788
7.顯示和設(shè)置環(huán)境變量
使用sql*plus的環(huán)境變量可以控制其運(yùn)行環(huán)境,例如設(shè)置行顯示寬度,設(shè)置每頁顯示的行數(shù)、
設(shè)置自動提交標(biāo)記、設(shè)置自動跟蹤等等。使用show命令可以顯示當(dāng)前sql*plus的環(huán)境變量設(shè)置
:使用set命令可以修改當(dāng)前sql*plus的環(huán)境變量設(shè)置。下面介紹常用的sql*plus環(huán)境變量。
(1)顯示所有環(huán)境變量
為了顯示sql*plus的所有環(huán)境變量,必須要使用show all命令。示例如下:
SQL> show all
appinfo 為 OFF 并且已設(shè)置為 "SQL*Plus"
arraysize 15
autocommit OFF
autoprint OFF
autorecovery OFF
autotrace OFF
blockterminator "." (hex 2e)
btitle OFF 為下一條 SELECT 語句的前幾個字符
cmdsep OFF
colsep " "
compatibility version NATIVE
concat "." (hex 2e)
copycommit 0
COPYTYPECHECK 為 ON
define "&" (hex 26)
describe DEPTH 1 LINENUM OFF INDENT ON
echo OFF
editfile "afiedt.buf"
embedded OFF
escape OFF
用于 6 或更多行的 FEEDBACK ON
flagger OFF
flush ON
heading ON
headsep "|" (hex 7c)
instance "local"
linesize 80
lno 4
loboffset 1
logsource ""
long 80
longchunksize 80
markup HTML OFF HEAD "<style type='text/css'> body {font:10pt
Arial,Helvetica,sans-serif; color:black; background:White;} p
{font:10pt Arial,Helvetica,sans-serif; color:black; background:White;}
table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black;
background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;}
th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699;
background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt
Arial,Helvetica,Geneva,sans-serif; color:#336699;
background-color:White; border-bottom:1px solid #cccc99;
margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2
{font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699;
background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt
Arial,Helvetica,sans-serif; color:#663300; background:#ffffff;
margin-top:0pt; margin-bottom:0pt;
vertical-align:top;}</style><title>SQL*Plus
Report</title>" BODY "" TABLE "border='1' width='90%'
align='center' summary='Script output'" SPOOL OFF ENTMAP ON PREFORMAT
OFF
newpage 1
null ""
numformat ""
numwidth 10
pagesize 14
PAUSE 為 OFF
pno 1
recsep WRAP
recsepchar " " (hex 20)
release 1002000100
repfooter OFF 為 NULL
repheader OFF 為 NULL
serveroutput OFF
shiftinout INVISIBLE
showmode OFF
spool ON
sqlblanklines OFF
sqlcase MIXED
sqlcode 0
sqlcontinue "> "
sqlnumber ON
sqlpluscompatibility 10.2.0
sqlprefix "#" (hex 23)
sqlprompt "SQL> "
sqlterminator ";" (hex 3b)
suffix "sql"
tab ON
termout ON
timing OFF
trimout ON
trimspool OFF
ttitle OFF 為下一條 SELECT 語句的前幾個字符
underline "-" (hex 2d)
USER 為 "SCOTT"
verify ON
wrap : 將換至下一行
SQL> spool off
(2)arraysize
該環(huán)境變量用于指定數(shù)組提取尺寸,其默認(rèn)值為15.該值越大,網(wǎng)絡(luò)開銷將會越低,但占用內(nèi)存會增加。假定使用默認(rèn)值,
如果查詢返回行數(shù)為50行,則需要通過網(wǎng)絡(luò)傳送4將數(shù)據(jù);如果設(shè)置為25,則網(wǎng)絡(luò)傳送次數(shù)只有兩次。eg:
SQL> show arraysize
arraysize 15
SQL> set arraysize 25
(3)autocommit
該環(huán)境變量用于設(shè)置是否自動提交dml語句,其默認(rèn)值為off(表示禁止自動提交)。當(dāng)設(shè)置為ON時,每次執(zhí)行DML
語句都會自動提交。eg:
SQL> show autocommit
autocommit OFF
SQL> set autocommit on
SQL> show autocommit
autocommit IMMEDIATE
(4)colsep
該環(huán)境變量用于設(shè)置列之間的分隔符,默認(rèn)分隔符為空格。如果要使用其它分隔符,則使用set命令進(jìn)行設(shè)置。eg:
sql>set colsep |
SQL> select ename,sal from emp where empno=7788
ENAME | SAL
----------|----------
SCOTT | 3000
(5)feedback
該環(huán)境變量用于指定顯示反饋行數(shù)信息的最低行數(shù),其默認(rèn)值為6。如果要禁止顯示行數(shù)反饋信息,則將feedback
設(shè)置為off。假設(shè)只要有查詢結(jié)果就返回行數(shù),那么可以將該環(huán)境變量設(shè)置為1.eg:
sql>set feedback 1
sql>select ename,sal from emp where empno=7788;
ENAME | SAL
----------|----------
SCOTT | 3000
已選擇 1 行。
(6)heading
該環(huán)境變量用于設(shè)置是否顯示標(biāo)題,其默認(rèn)值為on。如果不顯示列標(biāo)題,則設(shè)置為off。eg:
sql>set heading off
sql>select ename,sal from emp where empno=7788
SCOTT | 3000
(7)linesize
該環(huán)境變量用于設(shè)置行寬度,默認(rèn)值為80。在默認(rèn)情況下,如果數(shù)據(jù)長度超過80個字符,那么在sql*plus中會折
行顯示數(shù)據(jù)結(jié)果。要在一行中顯示全部數(shù)據(jù),應(yīng)該設(shè)置更大的值。eg:
(8)pagesize
該環(huán)境變量用于設(shè)置每頁所顯示的行數(shù),默認(rèn)值為14
set pagesize 0; //輸出每頁行數(shù),缺省為24,為了避免分頁,可設(shè)定為0。
(9)long
該環(huán)境變量用于設(shè)置long和lob類型列的顯示長度。默認(rèn)值為80,也就是說當(dāng)查詢long或lob列時,只會顯示該列的前80個字符,
應(yīng)該設(shè)置更大的值。eg:
sql>show long
long 80
sql>set long 300
(10)serveroutput
該環(huán)境變量用于控制服務(wù)器輸出,其默認(rèn)值為off,表示禁止服務(wù)器輸出。在默認(rèn)情況下,當(dāng)調(diào)用dbms_output包時,
不會在sql*plus屏幕上顯示輸出結(jié)果。在調(diào)用dbms_output包時,為了在屏幕上輸出結(jié)果,必須要將serveroutput設(shè)置
為on。eg:
sql>set serveroutput on
sql>exec dbms_output.put_line('hello')
(11)termout
該環(huán)境變量用于控制sql腳本的輸出,其默認(rèn)值為ON。當(dāng)使用默認(rèn)值時,如果sql腳本有輸出結(jié)果,則會在屏幕上輸出
顯示結(jié)果,如果設(shè)置為OFF,則不會在屏幕上輸出sql腳本。eg:
SQL> set termout off
SQL> @c:\a
(12)time
該環(huán)境變量用于設(shè)置在sql提示符前是否顯示系統(tǒng)時間,默認(rèn)值為off,表示禁止顯示系統(tǒng)時間。如果設(shè)置為on,
則在sql提示符前會顯示系統(tǒng)時間.eg:
SQL> set time on
12:09:59 SQL>
(13)timing
該環(huán)境變量用于設(shè)置是否要顯示sql語句執(zhí)行時間,默認(rèn)值為off,表示不會顯示sql語句執(zhí)行時間。如果設(shè)置為
ON,則會顯示sql語句執(zhí)行時間。eg:
sql>set timing on
SQL> select count(*) from emp;
COUNT(*)
----------
14
已選擇 1 行。
已用時間: 00: 00: 00.03
(14)trimspool
set trimout on; //去除標(biāo)準(zhǔn)輸出每行的拖尾空格,缺省為off
set trimspool on; //去除重定向(spool)輸出每行的拖尾空格,缺省為off
如果trimspool設(shè)置為on,將移除spool文件中的尾部空格 ,trimout同trimspool功能相似,只不過對象是控制臺。
If trimspool is set to on, it will remove trailing blanks in spooled files.
See also trimout which does the same thing to the output to the console (terminal).
eg:
set trimspool off
spool c:\temp\trimspool.txt
declare
v_name varchar2(30);
begin
SELECT table_name into v_name
FROM all_tables
WHERE rownum =1;
dbms_output.put_line(v_name);
end;
/
set trimspool on
declare
v_name varchar2(30);
begin
SELECT table_name into v_name
FROM all_tables
WHERE rownum =1;
dbms_output.put_line(v_name);
end;
/
spool off
-- from ITPUB
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200932325331787
posted @
2009-04-23 14:54 C.B.K 閱讀(1404) |
評論 (0) |
編輯 收藏
如果機(jī)房馬上要關(guān)門了,或者你急著要和MM約會,請直接跳到第六個自然段。
我們這里說的KMP不是拿來放電影的(雖然我很喜歡這個軟件),而是一種算法。KMP算法是拿來處理字符串匹配的。換句話說,給你兩個字符串,你需要回
答,B串是否是A串的子串(A串是否包含B串)。比如,字符串A="I'm
matrix67",字符串B="matrix",我們就說B是A的子串。你可以委婉地問你的MM:“假如你要向你喜歡的人表白的話,我的名字是你的告白
語中的子串嗎?”
解決這類問題,通常我們的方法是枚舉從A串的什么位置起開始與B匹配,然后驗證是否匹配。假如A串長度為n,B串長度為m,那么這種方法的復(fù)雜度是O
(mn)的。雖然很多時候復(fù)雜度達(dá)不到mn(驗證時只看頭一兩個字母就發(fā)現(xiàn)不匹配了),但我們有許多“最壞情況”,比如,A=
"aaaaaaaaaaaaaaaaaaaaaaaaaab",B="aaaaaaaab"。我們將介紹的是一種最壞情況下O(n)的算法(這里假設(shè)
m<=n),即傳說中的KMP算法。
之所以叫做KMP,是因為這個算法是由Knuth、Morris、Pratt三個提出來的,取了這三個人的名字的頭一個字母。這時,或許你突然明白了
AVL
樹為什么叫AVL,或者Bellman-Ford為什么中間是一杠不是一個點。有時一個東西有七八個人研究過,那怎么命名呢?通常這個東西干脆就不用人名
字命名了,免得發(fā)生爭議,比如“3x+1問題”。扯遠(yuǎn)了。
個人認(rèn)為KMP是最沒有必要講的東西,因為這個東西網(wǎng)上能找到很多資料。但網(wǎng)上的講法基本上都涉及到“移動(shift)”、“Next函數(shù)”等概念,這
非常容易產(chǎn)生誤解(至少一年半前我看這些資料學(xué)習(xí)KMP時就沒搞清楚)。在這里,我換一種方法來解釋KMP算法。
假如,A="abababaababacb",B="ababacb",我們來看看KMP是怎么工作的。我們用兩個指針i和j分別表示,A[i-j+
1..i]與B[1..j]完全相等。也就是說,i是不斷增加的,隨著i的增加j相應(yīng)地變化,且j滿足以A[i]結(jié)尾的長度為j的字符串正好匹配B串的前
j個字符(j當(dāng)然越大越好),現(xiàn)在需要檢驗A[i+1]和B[j+1]的關(guān)系。當(dāng)A[i+1]=B[j+1]時,i和j各加一;什么時候j=m了,我們就
說B是A的子串(B串已經(jīng)整完了),并且可以根據(jù)這時的i值算出匹配的位置。當(dāng)A[i+1]<>B[j+1],KMP的策略是調(diào)整j的位置
(減小j值)使得A[i-j+1..i]與B[1..j]保持匹配且新的B[j+1]恰好與A[i+1]匹配(從而使得i和j能繼續(xù)增加)。我們看一看當(dāng)
i=j=5時的情況。
i = 1 2 3 4 5 6 7 8 9 ……
A = a b a b a b a a b a b …
B = a b a b a c b
j = 1 2 3 4 5 6 7
此時,A[6]<>B[6]。這表明,此時j不能等于5了,我們要把j改成比它小的值j'。j'可能是多少呢?仔細(xì)想一下,我們發(fā)現(xiàn),j'必
須要使得B[1..j]中的頭j'個字母和末j'個字母完全相等(這樣j變成了j'后才能繼續(xù)保持i和j的性質(zhì))。這個j'當(dāng)然要越大越好。在這里,B
[1..5]="ababa",頭3個字母和末3個字母都是"aba"。而當(dāng)新的j為3時,A[6]恰好和B[4]相等。于是,i變成了6,而j則變成了
4:
i = 1 2 3 4 5 6 7 8 9 ……
A = a b a b a b a a b a b …
B = a b a b a c b
j = 1 2 3 4 5 6 7
從上面的這個例子,我們可以看到,新的j可以取多少與i無關(guān),只與B串有關(guān)。我們完全可以預(yù)處理出這樣一個數(shù)組P[j],表示當(dāng)匹配到B數(shù)組的第j個字母
而第j+1個字母不能匹配了時,新的j最大是多少。P[j]應(yīng)該是所有滿足B[1..P[j]]=B[j-P[j]+1..j]的最大值。
再后來,A[7]=B[5],i和j又各增加1。這時,又出現(xiàn)了A[i+1]<>B[j+1]的情況:
i = 1 2 3 4 5 6 7 8 9 ……
A = a b a b a b a a b a b …
B = a b a b a c b
j = 1 2 3 4 5 6 7
由于P[5]=3,因此新的j=3:
i = 1 2 3 4 5 6 7 8 9 ……
A = a b a b a b a a b a b …
B = a b a b a c b
j = 1 2 3 4 5 6 7
這時,新的j=3仍然不能滿足A[i+1]=B[j+1],此時我們再次減小j值,將j再次更新為P[3]:
i = 1 2 3 4 5 6 7 8 9 ……
A = a b a b a b a a b a b …
B = a b a b a c b
j = 1 2 3 4 5 6 7
現(xiàn)在,i還是7,j已經(jīng)變成1了。而此時A[8]居然仍然不等于B[j+1]。這樣,j必須減小到P[1],即0:
i = 1 2 3 4 5 6 7 8 9 ……
A = a b a b a b a a b a b …
B = a b a b a c b
j = 0 1 2 3 4 5 6 7
終于,A[8]=B[1],i變?yōu)?,j為1。事實上,有可能j到了0仍然不能滿足A[i+1]=B[j+1](比如A[8]="d"時)。因此,準(zhǔn)確的說法是,當(dāng)j=0了時,我們增加i值但忽略j直到出現(xiàn)A[i]=B[1]為止。
這個過程的代碼很短(真的很短),我們在這里給出:
程序代碼
j:=0;
for i:=1 to n do
begin
while (j>0) and (B[j+1]<>A[i]) do j:=P[j];
if B[j+1]=A[i] then j:=j+1;
if j=m then
begin
writeln('Pattern occurs with shift ',i-m);
j:=P[j];
end;
end;
最后的j:=P[j]是為了讓程序繼續(xù)做下去,因為我們有可能找到多處匹配。
這個程序或許比想像中的要簡單,因為對于i值的不斷增加,代碼用的是for循環(huán)。因此,這個代碼可以這樣形象地理解:掃描字符串A,并更新可以匹配到B的什么位置。
現(xiàn)在,我們還遺留了兩個重要的問題:一,為什么這個程序是線性的;二,如何快速預(yù)處理P數(shù)組。
為什么這個程序是O(n)的?其實,主要的爭議在于,while循環(huán)使得執(zhí)行次數(shù)出現(xiàn)了不確定因素。我們將用到時間復(fù)雜度的攤還分析中的主要策略,簡單地
說就是通過觀察某一個變量或函數(shù)值的變化來對零散的、雜亂的、不規(guī)則的執(zhí)行次數(shù)進(jìn)行累計。KMP的時間復(fù)雜度分析可謂攤還分析的典型。我們從上述程序的j
值入手。每一次執(zhí)行while循環(huán)都會使j減?。ǖ荒軠p成負(fù)的),而另外的改變j值的地方只有第五行。每次執(zhí)行了這一行,j都只能加1;因此,整個過程
中j最多加了n個1。于是,j最多只有n次減小的機(jī)會(j值減小的次數(shù)當(dāng)然不能超過n,因為j永遠(yuǎn)是非負(fù)整數(shù))。這告訴我們,while循環(huán)總共最多執(zhí)行
了n次。按照攤還分析的說法,平攤到每次for循環(huán)中后,一次for循環(huán)的復(fù)雜度為O(1)。整個過程顯然是O(n)的。這樣的分析對于后面P數(shù)組預(yù)處理
的過程同樣有效,同樣可以得到預(yù)處理過程的復(fù)雜度為O(m)。
預(yù)處理不需要按照P的定義寫成O(m^2)甚至O(m^3)的。我們可以通過P[1],P[2],...,P[j-1]的值來獲得P[j]的值。對于剛才
的B="ababacb",假如我們已經(jīng)求出了P[1],P[2],P[3]和P[4],看看我們應(yīng)該怎么求出P[5]和P[6]。P[4]=2,那么P
[5]顯然等于P[4]+1,因為由P[4]可以知道,B[1,2]已經(jīng)和B[3,4]相等了,現(xiàn)在又有B[3]=B[5],所以P[5]可以由P[4]
后面加一個字符得到。P[6]也等于P[5]+1嗎?顯然不是,因為B[ P[5]+1
]<>B[6]。那么,我們要考慮“退一步”了。我們考慮P[6]是否有可能由P[5]的情況所包含的子串得到,即是否P[6]=P[
P[5] ]+1。這里想不通的話可以仔細(xì)看一下:
1 2 3 4 5 6 7
B = a b a b a c b
P = 0 0 1 2 3 ?
P[5]=3是因為B[1..3]和B[3..5]都是"aba";而P[3]=1則告訴我們,B[1]和B[5]都是"a"。既然P[6]不能由P
[5]得到,或許可以由P[3]得到(如果B[2]恰好和B[6]相等的話,P[6]就等于P[3]+1了)。顯然,P[6]也不能通過P[3]得到,因
為B[2]<>B[6]。事實上,這樣一直推到P[1]也不行,最后,我們得到,P[6]=0。
怎么這個預(yù)處理過程跟前面的KMP主程序這么像呢?其實,KMP的預(yù)處理本身就是一個B串“自我匹配”的過程。它的代碼和上面的代碼神似:
程序代碼
P[1]:=0;
j:=0;
for i:=2 to m do
begin
while (j>0) and (B[j+1]<>B[i]) do j:=P[j];
if B[j+1]=B[i] then j:=j+1;
P[i]:=j;
end;
最后補(bǔ)充一點:由于KMP算法只預(yù)處理B串,因此這種算法很適合這樣的問題:給定一個B串和一群不同的A串,問B是哪些A串的子串。
串匹配是一個很有研究價值的問題。事實上,我們還有后綴樹,自動機(jī)等很多方法,這些算法都巧妙地運(yùn)用了預(yù)處理,從而可以在線性的時間里解決字符串的匹配。我們以后來說。
Matrix67原創(chuàng)
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200931645748543
posted @
2009-04-16 16:58 C.B.K 閱讀(79) |
評論 (0) |
編輯 收藏
(1)給金額添加逗號
import java.text.*;
NumberFormat formater = new DecimalFormat("###,###.##");
formater.format(12342351432534.24565);
(2)日期格式換
Date now = new Date();
SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
formater.format(now());
SimpleDateFormat
模式字母(所有其他字符 'A'
到 'Z'
和 'a'
到
'z'
都被保留):
模式字母通常是重復(fù)的,其數(shù)量確定其精確表示:
- Text: 對于格式化來說,如果模式字母的數(shù)量大于或等于
4,則使用完全形式;否則,在可用的情況下使用短形式或縮寫形式。對于分析來說,兩種形式都是可接受的,與模式字母的數(shù)量無關(guān)。
- Number: 對于格式化來說,模式字母的數(shù)量是最小的數(shù)位,如果數(shù)位不夠,則用
0 填充以達(dá)到此數(shù)量。對于分析來說,模式字母的數(shù)量被忽略,除非必須分開兩個相鄰字段。
- Year: 對于格式化來說,如果模式字母的數(shù)量為 2,則年份截取為 2
位數(shù),否則將年份解釋為 number。 SimpleDateFormat
示例
以下示例顯示了如何在美國語言環(huán)境中解釋日期和時間模式。給定的日期和時間為美國太平洋時區(qū)的本地時間 2001-07-04 12:08:56。
日期和時間模式
| 結(jié)果
|
"yyyy.MM.dd G 'at' HH:mm:ss z"
| 2001.07.04 AD at 12:08:56 PDT
|
"EEE, MMM d, ''yy"
| Wed, Jul 4, '01
|
"h:mm a"
| 12:08 PM
|
"hh 'o''clock' a, zzzz"
| 12 o'clock PM, Pacific Daylight Time
|
"K:mm a, z"
| 0:08 PM, PDT
|
"yyyyy.MMMMM.dd GGG hh:mm aaa"
| 02001.July.04 AD 12:08 PM
|
"EEE, d MMM yyyy HH:mm:ss Z"
| Wed, 4 Jul 2001 12:08:56 -0700
|
"yyMMddHHmmssZ"
| 010704120856-0700
|
"yyyy-MM-dd'T'HH:mm:ss.SSSZ"
| 2001-07-04T12:08:56.235-0700 |
文章來源:
http://blog.163.com/ccbobo_cat/blog/static/32099462200931621628957
posted @
2009-04-16 14:16 C.B.K 閱讀(83) |
評論 (0) |
編輯 收藏