以下列出的是 HttpClient 提供的主要的功能,要知道更多詳細(xì)的功能可以參見 HttpClient 的主頁。
下面將逐一介紹怎樣使用這些功能。首先,我們必須安裝好 HttpClient。
下面是個我寫的程序:
package com.newpalm.unicomfetch.threads;
import java.util.Vector;
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.cookie.CookieSpec;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.tags.TableColumn;
import org.htmlparser.tags.TableRow;
import org.htmlparser.tags.TableTag;
import org.htmlparser.visitors.ObjectFindingVisitor;
/**
* 用來演示登錄表單的示例
* @author Liudong
*/
public class FormLoginDemo {
public static void main(String[] args) throws Exception{
Parser parser = null;
ObjectFindingVisitor visitor = null;
HttpClient client = new HttpClient();
//模擬登錄頁面
PostMethod post = new PostMethod("<a href="http://211.90.119.58:9999/SPLogin.aspx"><span style="color: #78ba00;">http://211.90.119.58:9999/SPLogin.aspx</span></a>");
NameValuePair name = new NameValuePair("txtHandsetNumber", "123456");
NameValuePair pass = new NameValuePair("txtPassword", "123456");
NameValuePair __VIEWSTATE = new NameValuePair("__VIEWSTATE", "dDwtMTUxMzkxNTQ0Mzt0PDtsPGk8MT47PjtsPHQ8O2w8aTwxPjs+O2w8dDxwPGw8VGV4dDs+O2w8XDxtYXJxdWVlIERpcmVjdGlvbj0idXAiIGJlaGF2aW9yPSJzY3JvbGwiICBoZWlnaHQ9JzE1MCcgc2Nyb2xsZGVsYXk9MzAwIG9ubW91c2VvdmVyPSd0aGlzLnN0b3AoKScgb25tb3VzZW91dD0ndGhpcy5zdGFydCgpJ1w+XDxpbWcgc3JjPSJpbWFnZS9kZWZhdWx0X2NhbGxfaWNvbi5naWYiIHdpZHRoPSI0IiBoZWlnaHQ9IjciXD4mbmJzcFw7Jm5ic3BcO1w8YSBocmVmID0iIyIgb25jbGljaz0ib3BlbldpbmRvdygnL0J1bGxldGluLmFzcHg/QnVsbGV0aW5JZD0yMycpIlw+c3DkuJrliqHmjqXlhaXms6jmhI/kuovpoblcPC9hXD4KXDxiclw+XDxiclw+XDwvbWFycXVlZVw+Oz4+Ozs+Oz4+Oz4+O2w8YnRuTG9naW47Pj4pKEgdIvj1JmRdgJaS7sGzD39jZg==");
NameValuePair btnLoginx = new NameValuePair("btnLogin.x", "0");
NameValuePair btnLoginy = new NameValuePair("btnLogin.y", "5");
post.setRequestBody(new NameValuePair[]{name,pass,__VIEWSTATE,btnLoginx,btnLoginy});
int status = client.executeMethod(post);
post.releaseConnection();
//查看cookie信息
CookieSpec cookiespec = CookiePolicy.getDefaultSpec();
Cookie[] cookies = client.getState().getCookies();
if (cookies.length == 0) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.length; i++) {
System.out.println(cookies[i].toString());
}
}
//訪問所需的頁面
GetMethod get = new GetMethod("<a href="http://211.90.119.58:9999/PhoneSearch/PhoneSearch.aspx"><span style="color: #78ba00;">http://211.90.119.58:9999/PhoneSearch/PhoneSearch.aspx</span></a>");
client.executeMethod(get);
visitor = new ObjectFindingVisitor(TableTag.class);
parser = new Parser();
parser.setInputHTML(get.getResponseBodyAsString());
parser.setEncoding("GBK");
parser.visitAllNodesWith(visitor);
//取得要解析的頁面數(shù)
Node[] tables = visitor.getTags();
TableTag tableTag = (TableTag) tables[tables.length-1];
TableRow[] rows = tableTag.getRows();
TableRow row = rows[0];
TableColumn[] col = row.getColumns();
int pageNumber = Integer.parseInt(col[0].getChildrenHTML().substring(25, 29));
get.releaseConnection();
for(int i=1;i<pageNumber;i++){
PostMethod pt = new PostMethod("<a href="http://211.90.119.58:9999/PhoneSearch/PhoneSearch.aspx"><span style="color: #78ba00;">http://211.90.119.58:9999/PhoneSearch/PhoneSearch.aspx</span></a>");
NameValuePair txtPage = new NameValuePair("txtPage",Integer.toString(i));
__VIEWSTATE = new NameValuePair("__VIEWSTATE", "")
NameValuePair __EVENTTARGET = new NameValuePair("__EVENTTARGET", "");
NameValuePair __EVENTARGUMENT = new NameValuePair("__EVENTARGUMENT", "");
NameValuePair TBMDN = new NameValuePair("TBMDN", "");
NameValuePair TBServiceType = new NameValuePair("TBServiceType", "");
NameValuePair TBStartTime = new NameValuePair("TBStartTime", "");
NameValuePair TBEndTime = new NameValuePair("TBEndTime", "");
NameValuePair btnGotox = new NameValuePair("btnGoto.x", "26");
NameValuePair btnGotoy = new NameValuePair("btnGoto.y", "13");
pt.setRequestBody(new NameValuePair[]{__EVENTTARGET,__EVENTARGUMENT,__VIEWSTATE,TBMDN,TBServiceType,TBStartTime,TBEndTime,txtPage,btnGotox,btnGotoy});
int a = client.executeMethod(pt);
parser.setInputHTML(pt.getResponseBodyAsString());
parser.setEncoding("GBK");
parser.visitAllNodesWith(visitor);
tables = visitor.getTags();
tableTag = (TableTag) tables[tables.length-3];
rows = tableTag.getRows();
row = rows[1];
col = row.getColumns();
System.out.println(col[4].getChildrenHTML().toString());
get.releaseConnection();
}
}
}
下面介紹在使用HttpClient過程中常見的一些問題。
某目標(biāo)頁的編碼可能出現(xiàn)在兩個地方,第一個地方是服務(wù)器返回的http頭中,另外一個地方是得到的html/xml頁面中。
根據(jù)RFC2616中對自動轉(zhuǎn)向的定義,主要有兩種:301和302。301表示永久的移走(Moved Permanently),當(dāng)返回的是301,則表示請求的資源已經(jīng)被移到一個固定的新地方,任何向該地址發(fā)起請求都會被轉(zhuǎn)到新的地址上。302表示暫時(shí) 的轉(zhuǎn)向,比如在服務(wù)器端的servlet程序調(diào)用了sendRedirect方法,則在客戶端就會得到一個302的代碼,這時(shí)服務(wù)器返回的頭信息中 location的值就是sendRedirect轉(zhuǎn)向的目標(biāo)地址。
HttpClient支持自動轉(zhuǎn)向處理,但是象POST和PUT方式這種要求接受后繼服務(wù)的請求方式,暫時(shí)不支持自動轉(zhuǎn)向,因此如果碰到POST方 式提交后返回的是301或者302的話需要自己處理。就像剛才在POSTMethod中舉的例子:如果想進(jìn)入登錄BBS后的頁面,必須重新發(fā)起登錄的請 求,請求的地址可以在頭字段location中得到。不過需要注意的是,有時(shí)候location返回的可能是相對路徑,因此需要對location返回的 值做一些處理才可以發(fā)起向新地址的請求。
另外除了在頭中包含的信息可能使頁面發(fā)生重定向外,在頁面中也有可能會發(fā)生頁面的重定向。引起頁面自動轉(zhuǎn)發(fā)的標(biāo)簽是:<meta http-equiv=”refresh” content=”5; url=http://www.ibm.com/us”>。如果你想在程序中也處理這種情況的話得自己分析頁面來實(shí)現(xiàn)轉(zhuǎn)向。需要注意的是,在上面那 個標(biāo)簽中url的值也可以是一個相對地址,如果是這樣的話,需要對它做一些處理后才可以轉(zhuǎn)發(fā)。
HttpClient提供了對SSL的支持,在使用SSL之前必須安裝JSSE。在Sun提供的1.4以后的版本中,JSSE已經(jīng)集成到JDK中, 如果你使用的是JDK1.4以前的版本則必須安裝JSSE。JSSE不同的廠家有不同的實(shí)現(xiàn)。下面介紹怎么使用HttpClient來打開Https連 接。這里有兩種方法可以打開https連接,第一種就是得到服務(wù)器頒發(fā)的證書,然后導(dǎo)入到本地的keystore中;另外一種辦法就是通過擴(kuò)展 HttpClient的類來實(shí)現(xiàn)自動接受證書。
方法1,取得證書,并導(dǎo)入本地的keystore:
2. 單擊”View Certificate”,在彈出的對話框中選擇”Details”,然后再單擊”Copy to File”,根據(jù)提供的向?qū)纱L問網(wǎng)頁的證書文件
3. 向?qū)У谝徊剑瑲g迎界面,直接單擊”Next”,
4. 向?qū)У诙剑x擇導(dǎo)出的文件格式,默認(rèn),單擊”Next”,
5. 向?qū)У谌剑斎雽?dǎo)出的文件名,輸入后,單擊”Next”,
6. 向?qū)У谒牟剑瑔螕?#8221;Finish”,完成向?qū)?br />
7. 最后彈出一個對話框,顯示導(dǎo)出成功
|
其中參數(shù)alias后跟的值是當(dāng)前證書在keystore中的唯一標(biāo)識符,但是大小寫不區(qū)分;參數(shù)file后跟的是剛才通過IE導(dǎo)出的證書所在的路徑和文件名;如果你想刪除剛才導(dǎo)入到keystore的證書,可以用命令:
|
|
運(yùn)行該程序可能出現(xiàn)的問題:
1. 拋出異常java.net.SocketException: Algorithm SSL not available。出現(xiàn)這個異常可能是因?yàn)闆]有加JSSEProvider,如果用的是IBM的JSSE Provider,在程序中加入這樣的一行:
|
或者也可以打開<java-home>"lib"security"java.security,在行
|
后面加入security.provider.3=com.ibm.jsse.IBMJSSEProvider
2. 拋出異常java.net.SocketException: SSL implementation not available。出現(xiàn)這個異常可能是你沒有把ibmjsse.jar拷貝到<java-home>"lib"ext"目錄下。
3. 拋出異常javax.net.ssl.SSLHandshakeException: unknown certificate。出現(xiàn)這個異常表明你的JSSE應(yīng)該已經(jīng)安裝正確,但是可能因?yàn)槟銢]有把證書導(dǎo)入到當(dāng)前運(yùn)行JRE的keystore中,請按照前 面介紹的步驟來導(dǎo)入你的證書。
方法2,擴(kuò)展HttpClient類實(shí)現(xiàn)自動接受證書
因?yàn)檫@種方法自動接收所有證書,因此存在一定的安全問題,所以在使用這種方法前請仔細(xì)考慮您的系統(tǒng)的安全需求。具體的步驟如下:
|
|
HttpClient中使用代理服務(wù)器非常簡單,調(diào)用HttpClient中setProxy方法就可以,方法的第一個參數(shù)是代理服務(wù)器地址,第二個參數(shù)是端口號。另外HttpClient也支持SOCKS代理。
Dec 2nd 2010 | from PRINT EDITION
TOWARDS the end of 2003 and early in 2004 China’s most senior leaders put aside the routine of governing 1.3 billion people to spend a couple of afternoons studying the rise of great powers. You can imagine history’s grim inventory of war and destruction being laid out before them as they examined how, from the 15th century, empires and upstarts had often fought for supremacy. And you can imagine them moving on to the real subject of their inquiry: whether China will be able to take its place at the top without anyone resorting to arms.
In many ways China has made efforts to try to reassure an anxious world. It has repeatedly promised that it means only peace. It has spent freely on aid and investment, settled border disputes with its neighbours and rolled up its sleeves in UN peacekeeping forces and international organisations. When North Korea shelled a South Korean island last month China did at least try to create a framework to rein in its neighbour.
But reasonable China sometimes gives way to aggressive China. In March, when the North sank a South Korean warship, killing 46 sailors, China failed to issue any condemnation. A few months later it fell out with Japan over some Chinese fishermen, arrested for ramming Japanese coastguard vessels around some disputed islands—and then it locked up some Japanese businessmen and withheld exports of rare earths vital for Japanese industry. And it has forcefully reasserted its claim to the Spratly and Paracel Islands and to sovereignty over virtually the entire South China Sea.
As the Chinese leaders’ history lesson will have told them, the relationship that determines whether the world is at peace or at war is that between pairs of great powers. Sometimes, as with Britain and America, it goes well. Sometimes, as between Britain and Germany, it does not.
So far, things have gone remarkably well between America and China. While China has devoted itself to economic growth, American security has focused on Islamic terrorism and war in Iraq and Afghanistan. But the two mistrust each other. China sees America as a waning power that will eventually seek to block its own rise. And America worries about how Chinese nationalism, fuelled by rediscovered economic and military might, will express itself (see our special report).
The Peloponnesian pessimists
Pessimists believe China and America are condemned to be rivals. The countries’ visions of the good society are very different. And, as China’s power grows, so will its determination to get its way and to do things in the world. America, by contrast, will inevitably balk at surrendering its pre-eminence.
They are probably right about Chinese ambitions. Yet China need not be an enemy. Unlike the Soviet Union, it is no longer in the business of exporting its ideology. Unlike the 19th-century European powers, it is not looking to amass new colonies. And China and America have a lot in common. Both benefit from globalisation and from open markets where they buy raw materials and sell their exports. Both want a broadly stable world in which nuclear weapons do not spread and rogue states, like Iran and North Korea, have little scope to cause mayhem. Both would lose incalculably from war.
The best way to turn China into an opponent is to treat it as one. The danger is that spats and rows will sour relations between China and America, just as the friendship between Germany and Britain crumbled in the decades before the first world war. It is already happening in defence. Feeling threatened by American naval power, China has been modernising its missiles, submarines, radar, cyber-warfare and anti-satellite weapons. Now America feels on its mettle. Recent Pentagon assessments of China’s military strength warn of the threat to Taiwan and American bases and to aircraft-carriers near the Chinese coast. The US Navy has begun to deploy more forces in the Pacific. Feeling threatened anew, China may respond. Even if neither America nor China intended harm—if they wanted only to ensure their own security—each could nevertheless see the other as a growing threat.
Some would say the solution is for America to turn its back on military rivalry. But a weaker America would lead to chronic insecurity in East Asia and thus threaten the peaceful conduct of trade and commerce on which America’s prosperity depends. America therefore needs to be strong enough to guarantee the seas and protect Taiwan from Chinese attack.
How to take down the Great Wall
History shows that superpowers can coexist peacefully when the rising power believes it can rise unhindered and the incumbent power believes that the way it runs the world is not fundamentally threatened. So a military build-up needs to be accompanied by a build-up of trust.
There are lots of ways to build trust in Asia. One would be to help ensure that disputes and misunderstandings do not get out of hand. China should thus be more open about its military doctrine—about its nuclear posture, its aircraft-carriers and missile programme. Likewise, America and China need rules for disputes including North Korea (see article), Taiwan, space and cyber-warfare. And Asia as a whole needs agreements to help prevent every collision at sea from becoming a trial of strength.
America and China should try to work multilaterally. Instead of today’s confusion of competing venues, Asia needs a single regional security forum, such as the East Asia Summit, where it can do business. Asian countries could also collaborate more in confidence-boosting non-traditional security, such as health, environmental protection, anti-piracy and counter-terrorism, where threats by their nature cross borders.
If America wants to bind China into the rules-based liberal order it promotes, it needs to stick to the rules itself. Every time America breaks them—by, for instance, protectionism—it feeds China’s suspicions and undermines the very order it seeks.
China and America have one advantage over history’s great-power pairings: they saw the 20th century go disastrously wrong. It is up to them to ensure that the 21st is different.
譯者注:WordPress是最受歡迎的博客發(fā)布平臺之一,具有免費(fèi),高度可定制、容易安裝和使用等特色。由于Wordpress是如此流行和受歡迎,你可以找到大量的Wordpress開發(fā)以及管理等方面的資源,豐富的用戶指南讓你能夠快速的上手使用。參考資料:30個頂級Wordpress培訓(xùn)視頻指南與教程
有很多天才設(shè)計(jì)師選擇發(fā)表免費(fèi)的wordpress主題。大多數(shù)時(shí)候,對于他們來說唯一的一點(diǎn)小要求就是保留他們的設(shè)計(jì)元素,并鏈接到他們的網(wǎng)站(非常合理的要求)。
在本文中,我們整理了50個優(yōu)秀的、高質(zhì)量的、免費(fèi)的Wordpress主題給大家。這些主題包含了制作精細(xì)且華麗的主題,也有簡潔清爽的主題,你可以找到適合你的設(shè)計(jì)品位的wordpress主題。
說明: 請務(wù)必檢查主題的許可協(xié)議,不要違反使用限制(如果有的話),并且保留設(shè)計(jì)師的設(shè)計(jì)屬性[footer中的設(shè)計(jì)信息],即使設(shè)計(jì)師沒有要求你這么做。[互聯(lián)網(wǎng)營銷博客注:設(shè) 計(jì)一個漂亮的wordpress theme,需要花費(fèi)設(shè)計(jì)師很多的時(shí)間和精力,如果你喜歡這些免費(fèi)的wordpress主題,請尊重設(shè)計(jì)師的勞動成果。]
譯者注:在本文中介紹的wordpress主題均為英文模板,對于使用英文寫博客的朋友來說,這里還有我收集的3個英文寫作軟件可以參考,都有免費(fèi)試用版本可供下載:1、Whitesmoke - 最適合ESL使用的英文寫作和語法糾錯軟件,支持mac os。2、Stylewriter - 最適合公司,組織,作家使用的plain english寫作軟件。3、Ginger Software - 英文拼寫和語法檢查軟件,和whitesmoke差不多,但更為專業(yè)的英文寫作工具。
為了向你展示這些 CSS Hack 是否正常運(yùn)作,我新建六個 P 標(biāo)簽,并給每一個 P 標(biāo)簽一個特有的 id。這將向你展示 CSS Hack 的運(yùn)作情況。
<p id="opera">我來自 Opera 7.2 - 9.5</p>
<p id="safari">我是神奇的 Safari</p>
<p id="firefox">我來自 Firefox</p>
<p id="firefox12">我是你爺爺 Firefox 1 - 2 </p>
<p id="ie7">我是囧 IE 7</p>
<p id="ie6">我是腦瘸 IE 6</p>
然后我讓這些 P 標(biāo)簽?zāi)J(rèn)都不顯示
<style type="text/css"> body p{display: none;} </style>
使用 IE CSS 條件注釋區(qū)分 IE 瀏覽器
最簡單的區(qū)分 IE 瀏覽器的方法自然是使用他們的條件注釋。 微軟創(chuàng)建了一個強(qiáng)大的語法來讓我們?nèi)?shí)現(xiàn)這個功能。我不想再詳細(xì)地介紹 IE 條件注釋了,我想你在搜索引擎能搜索到上萬個搜索條目,我這里只要這兩個:
<!--[if IE 7]>
<style type="text/css">
</style> <![endif]-->
<!--[if IE 6]>
<style type="text/css"> </style>
<![endif]-->
使用 CSS 解析器 Hacks 區(qū)分 IE
雖說 IE 條件注釋十分簡單好用,但是如果你想把全部的 CSS 放到一個文件里的 話,那么你不得不使用別的方法。注意這里的 IE 7 Hack將只對 IE7 有效,因?yàn)?nbsp;IE6 根本不知道 > 選擇符。同時(shí)你也得注意 > 選擇符對于其他瀏覽器同樣是無效的。
html > body #ie7 {*display: block;}
body #ie6 {_display: block;}
CSS Hack 區(qū)分 Firefox
第一個使用了 body:empty 來區(qū)分 Firefox 1 和 2 。第二個 hack使用了全部 Firefox 瀏覽器的專有擴(kuò)展 -moz。 -moz 只對 Firefox有效,使用這個 Hack 大可不必?fù)?dān)心其他瀏覽器的影響。
body:empty #firefox12 {display: block;}
@-moz-document url-prefix() {#firefox { display: block; }}
CSS Hack 區(qū)分 Safari
Safari 的 CSS hack 與 Firefox 的 hack 看起來很像,使用的是 Safari瀏覽器的專有擴(kuò)展 -webkit 且只對 Safari 瀏覽器有效。
@media screen and (-webkit-min-device-pixel-ratio:0) {#safari { display: block; }}
CSS Hack 區(qū)分 Opera
@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) {head~body #opera { display: block; }}
然后,全部合在一起便是
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>CSS Browser Hacks - 52css.com</title>
<style type="text/css">
body p {
display: none;
}
html:first-child #opera {
display: block;
}
html > body #ie7 {
*display: block;
}
body #ie6 {
_display: block;
}
body:empty #firefox12 {
display: block;
}
@-moz-document url-prefix() {
#firefox {
display: block;
}
}
@media screen and (-webkit-min-device-pixel-ratio:0) {
#safari {
display: block;
}
}
@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) {
head~body #opera {
display: block;
}
}
</style>
</head>
<body>
<p id="opera">我來自 Opera 7.2 - 9.5</p>
<p id="safari">我是神奇的 Safari</p>
<p id="firefox">我來自 Firefox</p>
<p id="firefox12">我是你爺爺 Firefox 1 - 2 </p>
<p id="ie7">我是囧 IE 7</p>
<p id="ie6">我是腦瘸 IE 6</p>
</body>
</html>
CSS Hack 雖好且方便兼容各瀏覽器,但是通不過 W3C 驗(yàn)證,所以還得自己權(quán)衡是否有必要去使用。
"一切都在流動,沒有什么是持久的。一切都在融化,沒有什么是固定不變的" - 赫拉克利特(Heracleitus)
大約在2003年中的時(shí)候,SOA的概念逐漸進(jìn)入人們的視野,一時(shí)間眾人樂此不疲的發(fā)表各自對SOA的見解。SOA已經(jīng)成 為IT業(yè),尤其是軟件開發(fā)及系統(tǒng)集成領(lǐng)域從業(yè)者的熱門話題。很多的權(quán)威機(jī)構(gòu)也紛紛預(yù)測SOA的美妙前景,例如,Gartner 預(yù)言,到了 2008 年,至少 60% 的企業(yè)將使用 SOA 作為其IT架構(gòu)。拋開喧囂躁動以及隨聲附和,對于軟件開發(fā)者而言,經(jīng)過了一年多的概念灌輸,伴隨著不斷增長的困惑,更多的人希望能靜下心來看一看:究竟怎 樣的系統(tǒng)架構(gòu)是符合SOA設(shè)計(jì)的,而又有哪些技術(shù)可以用來實(shí)現(xiàn)SOA呢?特別是企業(yè)服務(wù)總線(Enterprise Service Bus, ESB), 看起來更是SOA中一個玄虛的概念,本系列文章將通過實(shí)際的案例分析來詳細(xì)講解在SOA系統(tǒng)中是怎樣實(shí)施ESB的。
本系列文章將直接面向廣大的軟件開發(fā)人員, 首先以直觀的方式介紹什么是ESB, 然后引入一個實(shí)際案例,以此為基礎(chǔ),詳細(xì)介紹怎樣一步一步實(shí)現(xiàn)ESB。現(xiàn)在我們談?wù)揝OA和ESB的時(shí)候都不再是空中樓閣,IBM作為SOA的倡導(dǎo)者,已 經(jīng)提供了很好的產(chǎn)品來實(shí)現(xiàn)我們的設(shè)想。我們會在本系列中的第二、第三部分中分別介紹基于WebSphere 6 和IBM EAI產(chǎn)品的兩種實(shí)現(xiàn)方式, 然后在第四部分中介紹在復(fù)雜的企業(yè)應(yīng)用場景中總線(Bus)怎樣互聯(lián), 怎樣擴(kuò)展。希望通過本系列文章,能讓廣大讀者朋友快速掌握ESB的實(shí)際開發(fā)技巧。
關(guān)于SOA的概念,你可以找到很多的文章從不同的角度來描述它,不同的軟件提供商也有不同的定義方式。BEA有流體計(jì)算, 微軟有Indigo 和SOA-building, SAP有ESA。 每個人都可以從不同的視角來理解SOA,從程序員的角度,SOA是一種全新的開發(fā)技術(shù),新的組件模型,比如說Web Service;從架構(gòu)設(shè)計(jì)師的角度,SOA就是一種新的設(shè)計(jì)模式,方法學(xué);從業(yè)務(wù)分析人員的角度,SOA就是基于標(biāo)準(zhǔn)的業(yè)務(wù)應(yīng)用服務(wù)。從概念的角 度,IBM對SOA的定義是最為全面的,既SOA是一種構(gòu)造分布式系統(tǒng)的方法,它將業(yè)務(wù)應(yīng)用功能以服務(wù)的形式提供給最終用戶應(yīng)用或其他服務(wù)。SOA包括如 下要素:
本文針對的讀者是軟件開發(fā)人員,站在開發(fā)人員的角度,往往希望軟件開發(fā)能夠滿足對于開發(fā)效率、可靠性、易維護(hù)性、易管理等多方面的更高要求。讓我們通過回顧軟件開發(fā)的演化過程來看一看SOA出現(xiàn)的必然性:
我們注意到,SOA同樣也強(qiáng)調(diào)重用(Reuse), 但是相對于傳統(tǒng)的代碼重用,對象重用,和部件重用,SOA的重用粒度更粗。SOA的重用在于業(yè)務(wù)級的應(yīng)用,即服務(wù)的重用,這與軟件的發(fā)展規(guī)律是相一致的。 在軟件發(fā)展的過程中,軟件重用的對象越來越接近我們的現(xiàn)實(shí)生活。通過部件的重用,軟件的開發(fā)更具效率,并且開始試圖用組件表達(dá)業(yè)務(wù)模式。但是,IT人員仍 很難對業(yè)務(wù)人員解釋清楚IT結(jié)構(gòu)怎樣映射到業(yè)務(wù)模型上。然而,IT架構(gòu)與業(yè)務(wù)模型的彌合是不可避免的方向。現(xiàn)代企業(yè)的業(yè)務(wù)環(huán)境所面臨的最大挑戰(zhàn)就是變化, 規(guī)則在變,需求在變,而對變化做出最快的反應(yīng),盡快地適應(yīng)變化,成為企業(yè)占得先機(jī),成功運(yùn)作的關(guān)鍵。很多企業(yè)的業(yè)務(wù)環(huán)境依賴于他們的IT架構(gòu),因此,IT 部門往往直接承載了業(yè)務(wù)變化帶來的壓力。每一個具體的業(yè)務(wù)變化,都直接反應(yīng)到對現(xiàn)有的IT平臺的要求:要么企業(yè)IT架構(gòu)本身對變化自適應(yīng),要么IT架構(gòu)能 夠在短時(shí)間內(nèi)根據(jù)新的業(yè)務(wù)規(guī)則做出調(diào)整。這就是SOA架構(gòu)提出的根本原因,我們需要一種更加貼近業(yè)務(wù)的IT架構(gòu),能夠直接描繪業(yè)務(wù),對那些不懂IT技術(shù)的 業(yè)務(wù)領(lǐng)域?qū)<襾碚f,業(yè)務(wù)服務(wù)卻是他們最熟悉的,也就是說是SOA把軟件重用的對象從IT人員上升到了業(yè)務(wù)人員。因此,我們可以說SOA與其它的模式相比, 最大的進(jìn)步在于它與業(yè)務(wù)的關(guān)聯(lián)性,"服務(wù)"對應(yīng)到實(shí)際業(yè)務(wù)。IT通過"服務(wù)"與業(yè)務(wù)發(fā)生了密切的關(guān)系,業(yè)務(wù)人員和IT人員都可以專注于業(yè)務(wù)邏輯的實(shí)現(xiàn),而 共同的語言就是"服務(wù)"。
但不是什么場合都適用SOA。通常來講,SOA適用于較為復(fù)雜的IT架構(gòu),經(jīng)常需要與外部復(fù)雜的IT環(huán)境交互,并且需要快 速地應(yīng)對頻繁發(fā)生的業(yè)務(wù)變化。就像你不可能在控制洗衣機(jī)的芯片上使用EJB開發(fā)一樣,如果你的IT環(huán)境規(guī)模很小,足以靈活地應(yīng)對變化,不需要與其他的異構(gòu) IT環(huán)境頻繁交互,那么SOA帶來的好處就不足以抵消它給你帶來的系統(tǒng)復(fù)雜性。但是,即令如此,你也并沒有被完全排除在SOA的大趨勢之外。SOA是如此 地倍受矚目,我們可以預(yù)見到它的迅猛發(fā)展,因此即使你的內(nèi)部IT架構(gòu)本身并不是基于SOA的,你也還有機(jī)會參與到未來的SOA架構(gòu)中去。例如,將你的某個 業(yè)務(wù)以服務(wù)的形式發(fā)布到某個外部SOA平臺上供別人使用,作為第三方SOA平臺的一個服務(wù)提供者(Service Provider)存在。
在選擇SOA的實(shí)施方案時(shí),要記住,軟件的具體實(shí)現(xiàn)技術(shù)諸如Web 服務(wù)與SOA是兩回事,SOA是一個概念,方法學(xué), 或者用一個更時(shí)髦的詞:一種模型。而Web 服務(wù)呢?它是一種具體的實(shí)現(xiàn)技術(shù),就像EJB一樣。SOA ≠ Web服務(wù)。不過公平地講,Web 服務(wù)倒確實(shí)是目前最適合實(shí)現(xiàn)SOA的技術(shù)之一,用Web 服務(wù)來封裝業(yè)務(wù)服務(wù)是個不錯的選擇。因?yàn)閃eb服務(wù)是標(biāo)準(zhǔn)的,WS-I協(xié)議保證了來自不同廠商的Web服務(wù)即使運(yùn)行在不同的平臺上,底層的實(shí)現(xiàn)機(jī)理不同也 可以順利交互,這是以前的任何一種技術(shù)如CORBA,EJB,或DCOM都不能做到的。而且,Web服務(wù)的定義與實(shí)現(xiàn)是分開描述的,即松散耦合,因此,可 以很方便地替換服務(wù)的內(nèi)在實(shí)現(xiàn)而不會對現(xiàn)有的系統(tǒng)造成任何沖擊,這也極大地促進(jìn)了IT架構(gòu)的靈活性。
對于SOA更進(jìn)一步的了解,可以參考IBM developerWorks上其他SOA相關(guān)的文章(請參見參考資料),我們的系列文章將主要討論ESB,因此不再此過多地論述SOA了。為了使我們下面的論述更順暢,請先牢記典型的SOA架構(gòu)有哪些基本的要求:
讓我們暫時(shí)回到網(wǎng)絡(luò)技術(shù)不普及的時(shí)代,你怎樣在兩臺機(jī)器之間傳遞文件?我還記得為了給實(shí)驗(yàn)室的每臺機(jī)器安裝Borland C++的環(huán)境,猜猜我動用了什么:一根"串口線"。不過,我仍然覺得慶幸,好在每臺機(jī)器都運(yùn)行同樣的操作系統(tǒng)- DOS(很少有人還記得DOS中有Interlnk這樣一個命令吧), 用來通過串口線在兩臺機(jī)器間傳遞流文件。否則我將不得不用軟盤來拷貝所有的安裝文件。我那個時(shí)候的夢想就是,哪一天有這么一個叫做"網(wǎng)絡(luò)"的東西能夠把實(shí) 驗(yàn)室里面所有機(jī)器都連接起來,而不用我在各機(jī)器之間跑來跑去。
讓我們回歸主題,你現(xiàn)在已經(jīng)基本明白了什么是SOA。假定你已經(jīng)按照SOA的思想提煉出了各種業(yè)務(wù)服務(wù),公布出來,同樣, 你發(fā)現(xiàn)其他很多人也做了同樣的事情。大家都很振奮,開始踴躍的嘗試,我調(diào)用你的一個服務(wù),你調(diào)我的一個服務(wù)。啊哈!大家都SOA了。且慢,那么這個SOA 給你們帶來了什么好處呢?Ok,現(xiàn)在我可以在J2EE環(huán)境里調(diào)用.Net的組件了,但是原來沒有SOA的時(shí)候也可以做到的呀。只要兩個節(jié)點(diǎn)之間互相認(rèn)可對 方的方式,即使不存在公開/統(tǒng)一的服務(wù)界面也可以實(shí)現(xiàn)點(diǎn)到點(diǎn)的互聯(lián)。因此我們不得不承認(rèn),如果我們只有服務(wù),而服務(wù)的請求者和服務(wù)的提供者之間仍然需要這 種顯式的點(diǎn)到點(diǎn)的調(diào)用,那么這就不是一個典型的SOA架構(gòu)。請看圖二,服務(wù)的參與雙方都必須建立1對1 的聯(lián)系。這樣一個結(jié)構(gòu)與我十幾年前的那種互聯(lián)的方式何其相似!但是,還記得我們上面提到的SOA三個基本要素嗎?顯然第三點(diǎn)沒有做到。
因此,在SOA中,我們還需要這樣一個中間層,能夠幫助實(shí)現(xiàn)在SOA架構(gòu)中不同服務(wù)之間的智能化管理。最容易想到的是這樣 一個HUB-Spoke結(jié)構(gòu),在SOA架構(gòu)中的各服務(wù)之間設(shè)置一個類似于Hub的中間件,由它充當(dāng)整個SOA架構(gòu)的中央管理器的作用。請看圖三,現(xiàn)在服務(wù) 的請求者和提供者之間有了一個智能的中轉(zhuǎn)站, 服務(wù)的請求者不再需要了解服務(wù)提供者的細(xì)節(jié)。不錯!看上去是一個好的SOA結(jié)構(gòu)。事實(shí)上,傳統(tǒng)的EAI就是通過這樣一種方式來試圖解決企業(yè)內(nèi)部的應(yīng)用整合 問題。
EAI的目標(biāo)是支持對現(xiàn)有IT系統(tǒng)的重新利用,通過EAI技術(shù)能夠?qū)⒉煌能浖拖到y(tǒng)串聯(lián)起來,延長這些應(yīng)用系統(tǒng)的生命周 期。傳統(tǒng)的EAI,往往使用如CORBA和COM等的消息中間件進(jìn)行分布式,跨平臺的程序交互,修改企業(yè)資源規(guī)劃以達(dá)到新的目標(biāo),使用中間件、XML等方 法來進(jìn)行數(shù)據(jù)分配。因此,實(shí)際上傳統(tǒng)的EAI是部件級的重用。很不幸的是,基于部件的架構(gòu)沒有統(tǒng)一的標(biāo)準(zhǔn),因此,各個廠商都有各自不同的EAI解決方案, 你會看到各種各樣的中間件平臺。如果EAI碰到了異構(gòu)的IT環(huán)境,就必須分別考慮怎樣在各個不同的中間件之間周旋,來實(shí)現(xiàn)合理的互聯(lián)方式,你不得不考慮各 種復(fù)雜的可能性。因此,你所見過的大多數(shù)傳統(tǒng)EAI解決方案都比較笨重。
再回顧一下我們上面介紹過的SOA的應(yīng)用場景:復(fù)雜的企業(yè)級架構(gòu)。如果我們選擇Hub的模式來構(gòu)建SOA基礎(chǔ)架構(gòu),從純粹 邏輯的角度,可能會出現(xiàn)哪些問題呢?首先,整個SOA架構(gòu)的性能,如果每個服務(wù)的請求都經(jīng)過中央Hub的中轉(zhuǎn),那么Hub的負(fù)擔(dān)會很重,速度會隨著參與者 的增多而愈來愈慢;其次,這樣的系統(tǒng)會很脆弱,一旦Hub出錯,整個SOA架構(gòu)都會癱瘓;最后,這樣的架構(gòu)會破壞SOA的開放性原則,參與者運(yùn)行在一個相 對封閉的環(huán)境中,擴(kuò)展起來十分麻煩。因此,這也不是理想的SOA架構(gòu)。
好了,現(xiàn)在該ESB登場了,請看我們的正解:
它與前面的Hub結(jié)構(gòu)有什么不同呢?首先,它比單一Hub的形式更開放,總線結(jié)構(gòu)有無限擴(kuò)展的可能;其次,真正體現(xiàn)了 SOA的理念, 一切皆為服務(wù),服務(wù)在總線(BUS)中處于平等的地位。即使我們需要一些Hub,那么它們也是以某種服務(wù)的形式部署在總線上,相比上面的結(jié)構(gòu)要靈活的多。 這就是ESB,我們需要給它一個明確的定義:ESB是一種在松散耦合的服務(wù)和應(yīng)用之間標(biāo)準(zhǔn)的集成方式。它可以作用于:
很不幸,上面的定義看上去很拗口,我們暫且用一句較通俗的話來描述它:ESB就是在SOA架構(gòu)中實(shí)現(xiàn)服務(wù)間智能化集成與管 理的中介。而它與SOA的關(guān)系要相對好理解一些:ESB是邏輯上與SOA 所遵循的基本原則保持一致的服務(wù)集成基礎(chǔ)架構(gòu),它提供了服務(wù)管理的方法和在分布式異構(gòu)環(huán)境中進(jìn)行服務(wù)交互的功能。可以這樣說,ESB是特定環(huán)境下(SOA 架構(gòu)中)實(shí)施EAI的方式: 首先,在ESB系統(tǒng)中,被集成的對象被明確定義為服務(wù),而不是傳統(tǒng)EAI中各種各樣的中間件平臺,這樣就極大簡化了在集成異構(gòu)性上的考慮,因?yàn)椴还苡性鯓? 的應(yīng)用底層實(shí)現(xiàn),只要是SOA架構(gòu)中的服務(wù),它就一定是基于標(biāo)準(zhǔn)的。
其次,ESB明確強(qiáng)調(diào)消息(Message)處理在集成過程中的作用,這里的消息指的是應(yīng)用環(huán)境中被集成對象之間的溝通。 以往傳統(tǒng)的EAI實(shí)施中碰到的最大的問題就是被集成者都有自己的方言,即各自的消息格式。作為基礎(chǔ)架構(gòu)的EAI系統(tǒng),必須能夠?qū)ο到y(tǒng)范疇內(nèi)的任何一種消息 進(jìn)行解析。傳統(tǒng)的EAI系統(tǒng)中的消息處理大多是被動的,消息的處理需要各自中間件的私有方式支持,例如API的方式。因此盡管消息處理本身很重要,但消息 的直接處理不會是傳統(tǒng)EAI系統(tǒng)的核心。ESB系統(tǒng)由于集成對象統(tǒng)一到服務(wù),消息在應(yīng)用服務(wù)之間傳遞時(shí)格式是標(biāo)準(zhǔn)的,直接面向消息的處理方式成為可能。如 果ESB能夠在底層支持現(xiàn)有的各種通訊協(xié)議,那么對消息的處理就完全不考慮底層的傳輸細(xì)節(jié),而直接通過消息的標(biāo)準(zhǔn)格式定義來進(jìn)行。這樣,在ESB中,對消 息的處理就會成為ESB的核心,因?yàn)橥ㄟ^消息處理來集成服務(wù)是最簡單可行的方式。這也是ESB中總線(Bus)功能的體現(xiàn)。其實(shí),總線的概念并不新鮮,傳 統(tǒng)的EAI系統(tǒng)中,也曾經(jīng)提出過信息總線的概念,通過某種中間件平臺,如CORBA來連接企業(yè)信息孤島,但是,ESB的概念不僅僅是提供消息交互的通道, 更重要的是提供服務(wù)的智能化集成基礎(chǔ)架構(gòu)。
最后,事件驅(qū)動成為ESB的重要特征。通常服務(wù)之間傳遞的消息有兩種形式,一種是調(diào)用(Call), 即請求/回應(yīng)方式,這是常見的同步模式。還有一種我們稱之為單路消息(One-way),它的目的往往是觸發(fā)異步的事件, 發(fā)送者不需要馬上得到回復(fù)。考慮到有些應(yīng)用服務(wù)是長時(shí)間運(yùn)行的,因此,這種異步服務(wù)之間的消息交互也是ESB必須支持的。除此之外,ESB的很多功能都可 以利用這種機(jī)制來實(shí)現(xiàn),例如,SOA中服務(wù)的性能監(jiān)控等基礎(chǔ)架構(gòu)功能,需要通過ESB來提供數(shù)據(jù),當(dāng)服務(wù)的請求通過ESB中轉(zhuǎn)的時(shí)候,ESB很容易通過事 件驅(qū)動機(jī)制向SOA的基礎(chǔ)架構(gòu)服務(wù)傳遞信息。
首先,我們來看一看ESB有哪些基本的功能。既然ESB會以中介的身份出現(xiàn),它就必須有兩方面的考慮,首先它必須了解被它 中介的兩個端點(diǎn):1)服務(wù)的請求者以及請求者對服務(wù)的要求,2)服務(wù)的提供者和它所提供服務(wù)的描述;其次,它必須具有某種機(jī)制能夠完成中介的任務(wù)。我們把 這兩類考慮歸納為ESB的兩個基本功能:面向服務(wù)的原數(shù)據(jù)(MetaData)管理功能 和中介(Mediation)功能。 作為SOA的重要構(gòu)成部分,ESB承擔(dān)的重任還包括怎樣將企業(yè)架構(gòu)中已存在的業(yè)務(wù)服務(wù)連接到總線上來,我們稱之為適配器(Adapter)功能。盡管服務(wù) 本身已經(jīng)用公開的接口來描述,但具體的實(shí)現(xiàn)還是運(yùn)行在不同的環(huán)境中,因此,ESB還應(yīng)該提供對服務(wù)底層協(xié)議的支持,譬如應(yīng)用協(xié)議J2ee,.Net, 通訊協(xié)議如Http,JMS等等。除此之外,還需要對具體應(yīng)用中涉及到的服務(wù)加以管理,如性能,可靠性,安全性等等。
ESB 提供了最基本的功能來保障SOA系統(tǒng)的運(yùn)行,這些功能應(yīng)該包含下列內(nèi)容:
很多時(shí)候,很難界定哪些功能是應(yīng)該由SOA的基礎(chǔ)架構(gòu)(infrastructure)提供的,而哪些應(yīng)該放在ESB的范 疇內(nèi)來解決。筆者認(rèn)為,放大或突出ESB在SOA架構(gòu)中的地位并不很恰當(dāng)。比較合理的解釋是:ESB應(yīng)該構(gòu)筑在完善的SOA架構(gòu)上,做它應(yīng)該做的事-服務(wù) 集成。至于怎樣集成,應(yīng)該根據(jù)你的上下文環(huán)境,考慮有哪些SOA的基礎(chǔ)設(shè)施可供你使用,然后再基于SOA的基礎(chǔ)架構(gòu)來實(shí)現(xiàn)你的ESB設(shè)計(jì)。
在更高的層次,ESB還提供諸如服務(wù)代理,協(xié)議轉(zhuǎn)換等等功能,我們稱之為ESB的應(yīng)用模式(ESB usage pattern)。作為SOA架構(gòu)的服務(wù)集成功能提供者,我們可以總結(jié)出的一些比較常用的應(yīng)用模式,例如:
1)協(xié)議轉(zhuǎn)換模型,用于當(dāng)服務(wù)的請求者與服務(wù)提供者基于不同協(xié)議時(shí)的消息轉(zhuǎn)換情形
2)消息廣播模式,用于事件驅(qū)動多個動作或者消息廣播的情形
3)服務(wù)匹配模式,用于需要動態(tài)選擇服務(wù)提供者的情形,例如可以根據(jù)消息的內(nèi)容,或負(fù)載情況,或服務(wù)級別約定(SLA),來為服務(wù)請求者選擇合適的服務(wù)。
這里我們只列舉了3個典型的模式,而這樣的例子實(shí)在太多了,發(fā)揮你的創(chuàng)造性,你還會想出來更多的,這也是ESB的魅力所 在。但是,在ESB的設(shè)計(jì)上,注意不能喧賓奪主,ESB的功能在于幫助服務(wù)的集成,而不是參與業(yè)務(wù)邏輯。業(yè)務(wù)邏輯應(yīng)該封裝在業(yè)務(wù)服務(wù)中,或通過業(yè)務(wù)編排服 務(wù)(Process Service)來組織。
關(guān)于ESB,目前還沒有被一致接受的標(biāo)準(zhǔn)。我們可以通過選擇成熟的EAI 中間件來實(shí)現(xiàn)服務(wù)的集成與互操作性。這樣做的好處是你的開發(fā)過程會很順暢,因?yàn)樗呀?jīng)足夠穩(wěn)定且有豐富的工具支持。通常這樣的EAI產(chǎn)品在目前階段都還不 是基于開放的標(biāo)準(zhǔn),例如IBM的WebSphere MQ5.3,作為IBM EAI實(shí)現(xiàn)ESB的消息平臺,就不是開放的標(biāo)準(zhǔn)。如果一定要選擇開放標(biāo)準(zhǔn)的ESB實(shí)現(xiàn)方式,Web 服務(wù)加上WS-* 協(xié)議幾乎是我們唯一的選擇,但畢竟SOA、ESB仍處于起步的階段,一方面我們還沒有很成熟的產(chǎn)品支持所有的WS-*協(xié)議,另一方面這些WS-* 協(xié)議本身還處在頻繁變化的階段。因此當(dāng)你選擇ESB實(shí)施方案的時(shí)候,最好考慮平衡ESB實(shí)施、開發(fā)的工作量。
這里你可能會有疑問,既然SOA架構(gòu)追求開放性,為什么我們要容忍用私有的ESB產(chǎn)品如IBM WBI/MQ來構(gòu)建SOA架構(gòu)的集成環(huán)境?這是一個好問題。SOA始終是我們追求的大目標(biāo),開放是必然的趨勢,這是毋庸置疑的。但是,請注意ESB的定 義,至少到目前為止,還沒有明確的要求它的實(shí)現(xiàn)一定是開放的,每一個軟件供應(yīng)商對它都可能有不同的理解和實(shí)現(xiàn)的策略。我們不用懷疑ESB將來的開放之路, 但至少在目前階段,我們不能坐下來等待它的到來。 其實(shí),ESB充當(dāng)?shù)氖荢OA中的中介角色,因此,即使將來ESB變化了,對服務(wù)的請求者和服務(wù)的提供者都不會造成很大的沖擊,因?yàn)樗緛砭褪菍τ脩敉该? 的。舉個例子,J2EE,它的標(biāo)準(zhǔn)一直在變化中,但是大家通常都能接受它的變化,社會總是要進(jìn)步的,IT也一樣。你不可能因?yàn)镴2EE 兩年以后要出1.6就不再使用現(xiàn)在的1.4了。
IBM目前可以用于ESB實(shí)施的產(chǎn)品也可以分為兩大陣營:
現(xiàn)有的EAI解決方案,可能涉及如下的IBM軟件產(chǎn)品:
WAS6 中提供了嶄新的消息服務(wù)平臺WPM(WebSphere platform messaging),并基于這一平臺提供了ESB的一個具體實(shí)現(xiàn)- SIBus(Service Integration Bus) 它可以支持同步和異步的消息通信。總線(Bus)通過互聯(lián)的消息引擎管理消息源。同時(shí)支持基于Web服務(wù)和JMS,MQ格式的消息交互。你可以從WAS6 身上看到IBM戰(zhàn)略的變化,SIBus只是IBM加大對于SOA支持的一步,你還會很快看到更多的變化,例如獨(dú)立的ESB產(chǎn)品,ESB的開發(fā)工具等等。但 是,你完全不必?fù)?dān)心,這些變化都會保持兼容性,現(xiàn)在SOA的投入,無論是以哪一種方式,都會在IBM的SOA整體考慮之中。
上述的兩種方案并不是對立的,你可以選擇基于成熟產(chǎn)品實(shí)現(xiàn)ESB,也可以嘗試一下IBM的最新技術(shù)。這兩種方案甚至可以互聯(lián),見圖八。我們將在系列的第四部分講解這一較為復(fù)雜的場景。
在本系列文章接下來的三部分中,我們將繼續(xù)詳細(xì)描述ESB的具體實(shí)現(xiàn)步驟。
本文向您介紹了SOA以及ESB 的基本知識,確定了一些 ESB 實(shí)現(xiàn)中最常見的基本功能,論述了ESB產(chǎn)生的必要性,以及ESB在SOA中的地位。
李珉,IBM SOA Design Center 高級工程師,技術(shù)經(jīng)理,曾領(lǐng)導(dǎo)WAS6 SIBus的測試工作,對ESB的技術(shù)發(fā)展一直有所關(guān)注。
1996年,Gartner最早提出SOA。2002年12月,Gartner提出SOA是"現(xiàn)代應(yīng)用開發(fā)領(lǐng)域最重要的課題",SOA并不是一個新事 物,IT組織已經(jīng)成功建立并實(shí)施SOA應(yīng)用軟件很多年了,BEA、IBM、等廠商看到了它的價(jià)值,紛紛跟進(jìn)。SOA的目標(biāo)在于讓IT變得更有彈性,以更快 地響應(yīng)業(yè)務(wù)單位的需求,實(shí)現(xiàn)實(shí)時(shí)企業(yè)(Real-Time Enterprise,這是Gartner為SOA描述的愿景目標(biāo))。而BEA的CIO Rhonda早在2001年6月就提出要將BEA的IT基礎(chǔ)架構(gòu)轉(zhuǎn)變?yōu)镾OA,并且從對整個企業(yè)架構(gòu)的控制能力、提升開發(fā)效率、加快開發(fā)速度、降低在客戶 化和人員技能的投入等方面取得了不錯的成績。
SOA是在計(jì)算環(huán)境下設(shè)計(jì)、開發(fā)、應(yīng)用、管理分散的邏輯(服務(wù))單元的一種規(guī)范。這個定義決定了SOA的廣泛性。SOA要求開發(fā)者從服務(wù)集成的 角度來設(shè)計(jì)應(yīng)用軟件,即使這么做的利益不會馬上顯現(xiàn)。SOA要求開發(fā)者超越應(yīng)用軟件來思考,并考慮復(fù)用現(xiàn)有的服務(wù),或者檢查如何讓服務(wù)被重復(fù)利用。SOA 鼓勵使用可替代的技術(shù)和方法(例如消息機(jī)制),通過把服務(wù)聯(lián)系在一起而非編寫新代碼來構(gòu)架應(yīng)用。經(jīng)過適當(dāng)構(gòu)架后,這種消息機(jī)制的應(yīng)用允許公司僅通過調(diào)整原 有服務(wù)模式而非被迫進(jìn)行大規(guī)模新的應(yīng)用代碼的開發(fā),使得在商業(yè)環(huán)境許可的時(shí)間內(nèi)對變化的市場條件做出快速的響應(yīng)。
SOA也不僅僅是一種開發(fā)的方法論--它還包含管理。例如,應(yīng)用SOA后,管理者可以方便的管理這些搭建在服務(wù)平臺上的企業(yè)應(yīng)用,而不 是管理單一的應(yīng)用模塊。其原理是,通過分析服務(wù)之間的相互調(diào)用,SOA使得公司管理人員方便的拿到什么時(shí)候、什么原因、哪些商業(yè)邏輯被執(zhí)行的數(shù)據(jù)信息,這 樣就幫助了企業(yè)管理人員或應(yīng)用架構(gòu)師迭代地優(yōu)化他們的企業(yè)業(yè)務(wù)流程、應(yīng)用系統(tǒng)。
SOA的一個中心思想就是使得企業(yè)應(yīng)用擺脫面向技術(shù)的解決方案的束縛,輕松應(yīng)對企業(yè)商業(yè)服務(wù)變化、發(fā)展的需要。企業(yè)環(huán)境中單個應(yīng)用程序 是無法包容業(yè)務(wù)用戶的(各種)需求的,即使是一個大型的ERP解決方案,仍然不能滿足這個需求在不斷膨脹、變化的缺口,對市場快速做出反應(yīng),商業(yè)用戶只能 通過不斷開發(fā)新應(yīng)用、擴(kuò)展現(xiàn)有應(yīng)用程序來艱難的支撐其現(xiàn)有的業(yè)務(wù)需求。通過將注意力放在服務(wù)上,應(yīng)用程序能夠集中起來提供更加豐富、目的性更強(qiáng)的商業(yè)流 程。其結(jié)果就是,基于SOA的企業(yè)應(yīng)用系統(tǒng)通常會更加真實(shí)地反映出與業(yè)務(wù)模型的結(jié)合。服務(wù)是從業(yè)務(wù)流程的角度來看待技術(shù)的--這是從上向下看的。這種角度 同一般的從可用技術(shù)所驅(qū)動的商業(yè)視角是相反的。服務(wù)的優(yōu)勢很清楚:它們會同業(yè)務(wù)流程結(jié)合在一起,因此能夠更加精確地表示業(yè)務(wù)模型、更好地支持業(yè)務(wù)流程。相 反我們可以看到以應(yīng)用程序?yàn)橹行牡钠髽I(yè)應(yīng)用模型迫使業(yè)務(wù)用戶將其能力局限為應(yīng)用程序的能力。
企業(yè)流程(enterprise process)是流經(jīng)企業(yè)框架的空氣,它賦予業(yè)務(wù)模型里的組件以生命,并更加清晰地定義了它們之間的關(guān)系。流程定義了同業(yè)務(wù)模型進(jìn)行交互操作的專門方 法。例如,會計(jì)可能是企業(yè)服務(wù)系統(tǒng)的一個組件--但是將發(fā)票寄給客戶卻是一個業(yè)務(wù)流程。服務(wù)被定義用來支持業(yè)務(wù)流程,因而貫穿整個流程始終的是:各種服務(wù) 組件在流程和邏輯實(shí)現(xiàn)過程中的裝配操作。理解業(yè)務(wù)流程是定制服務(wù)的關(guān)鍵所在。
二、SOA 的描述所適用的原則
圖 1說明了這些原則。注意,雖然 Web 服務(wù)技術(shù)非常符合這些原則,但它并不是唯一符合這些原則的技術(shù)。
為了實(shí)現(xiàn) SOA,應(yīng)用程序和基礎(chǔ)架構(gòu)都必須支持 SOA 原則。啟用 SOA 應(yīng)用程序涉及到創(chuàng)建服務(wù)接口,服務(wù)接口可以直接也可以間接地通過使用適配器用于現(xiàn)有的或新的功能。從最基本的級別來看,啟用該基礎(chǔ)架構(gòu)涉及到規(guī)劃功能來將服務(wù)請求路由和傳遞給正確的服務(wù)提供者。然而,基礎(chǔ)架構(gòu)支持在不影響服務(wù)的客戶端的情況下由另一個服務(wù)實(shí)現(xiàn)替代原有的服務(wù)實(shí)現(xiàn)也是至關(guān)重要的。這不僅需要根據(jù) SOA 原則指定服務(wù)接口,而且需要基礎(chǔ)架構(gòu)允許客戶端代碼以獨(dú)立于所涉及的服務(wù)位置和通信協(xié)議的方式來調(diào)用服務(wù)。
三、ESB是什么?
根據(jù)維基百科的ESB定義,ESB有如下特性:
對于其中一些廠商(IBM、微軟)來說,ESB是將一系列能力聯(lián)結(jié)在一起的一種模式,而其他廠商認(rèn)為ESB是一種產(chǎn)品。在2005年,微軟Identity Platform的產(chǎn)品經(jīng)理Rich Turner寫道:
ESB[產(chǎn)品]是一根聰明的管子,用來連接各個愚笨的節(jié)點(diǎn)。[……]Web Service的途徑讓節(jié)點(diǎn)本身也變得聰明,減少了對底下聰明管道的需要,并確保了跨越任何平臺與設(shè)備的開放的通訊。