一切都在變
blog也搬遷了:http://blog.sina.com.cn/liuwendao
來武漢快三年了,留在北京的最后一件物件-電吉它,也被我拿到武漢來了
我們這么混,能成功嗎?
立帖為證
posted @ 2007-09-16 23:21 fisher 閱讀(1464) | 評論 (0) | 編輯 收藏
隨筆 - 59, 文章 - 4, 評論 - 184, 引用 - 7
|
一切都在變blog也搬遷了:http://blog.sina.com.cn/liuwendao posted @ 2007-09-16 23:21 fisher 閱讀(1464) | 評論 (0) | 編輯 收藏 [調(diào)查]國內(nèi)有多少人使用MINA?最近看到越來越多的人使用mina,甚至在線下也碰到合作公司的庫中使用MINA,出于好奇,嘗試一下用自己的blog做一下調(diào)查,訪問本blog的兄弟,如果您使用MINA作為自己的通訊基礎(chǔ)件,請留言介紹一下自己 posted @ 2006-12-27 13:00 fisher 閱讀(4517) | 評論 (20) | 編輯 收藏 隨想
軟件開發(fā)的世界里充滿了不理解,客戶不理解軟件是怎樣開發(fā)的、經(jīng)理不理解開發(fā)人員、開發(fā)人員不理解指揮者。
問題在于軟件開發(fā)驚人的困難,造成很少有開發(fā)人員能夠說出軟件自始至終是怎樣開發(fā)的,并能夠?qū)@個(gè)過程中會(huì)遇到的不同選擇所隱含的結(jié)果表現(xiàn)出適度的理解。 在軟件開發(fā)人員還很年輕的時(shí)候(十幾歲或二十出頭),他們通常集中精力學(xué)習(xí)和使用技術(shù),稱自己為perl程序員、Linux專家、EJB開發(fā)人員、.NET開發(fā)人員等。對他們來說技術(shù)是最重要的事情。因?yàn)榧夹g(shù)在不斷的變化,年輕的程序員傾向于大致學(xué)習(xí)一個(gè)技術(shù),在一到兩個(gè)項(xiàng)目中使用,然后重新開始學(xué)習(xí)新技術(shù)或者是學(xué)習(xí)以前使用過的技術(shù)的最新發(fā)展。這里的問題是,他們一遍又一遍的重復(fù)的學(xué)習(xí)的不過是同樣的低層次基本技能的不同風(fēng)味。 幸運(yùn)的是,很多開發(fā)人員在經(jīng)過了幾輪技術(shù)學(xué)習(xí)之后逐漸意識到:一旦用COBOL、Java、C#等語言為事務(wù)控制編寫過代碼,就會(huì)開始認(rèn)識到基本的、本質(zhì)的東西是不變的。不同環(huán)境下的數(shù)據(jù)庫訪問、用戶界面設(shè)計(jì)等領(lǐng)域也是同樣的情況。不久以后,開發(fā)人員逐漸認(rèn)識到無論具體的技術(shù)怎樣,很多基礎(chǔ)性的東西是保持不變的,這些基礎(chǔ)性的東西有的在學(xué)校里講過,有的沒有。 posted @ 2006-07-24 11:31 fisher 閱讀(2251) | 評論 (6) | 編輯 收藏 今天學(xué)會(huì)一個(gè)新名詞 - Troll來自pythoncn的maillist,呵呵,挺有意思
另一方面,在郵件列表這種有管理員的公共空間,可以向管理員提出封禁trolls的 提案。
+-------------------+ .:\:\:/:/:. | PLEASE DO NOT | :.:\:\:/:/:.: | FEED THE TROLLS | :=.' - - '.=: | | '=(\ 9 9 /)=' | Thank you, | ( (_) ) | Management | /`-vvv-'\ +-------------------+ / \ | | @@@ / /|,,,,,|\ \ | | @@@ /_// /^\ \\_\ @x@@x@ | | |/ WW( ( ) )WW \||||/ | | \| __\,,\ /,,/__ \||/ | | | jgs (______Y______) /\/\/\/\/\/\/\/\//\/\\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
posted @ 2006-06-13 10:27 fisher 閱讀(13592) | 評論 (9) | 編輯 收藏 程序員的進(jìn)化——從學(xué)生到首席執(zhí)行官(轉(zhuǎn))/*------------------------------------------- ? 程序員的進(jìn)化——從學(xué)生到首席執(zhí)行官 翻譯 2002 王詠剛 http://www.contextfree.net/ 轉(zhuǎn)譯自 Omri's Computer Humor Page http://www.cs.bgu.ac.il/~omri/Humor/ -------------------------------------------*/ -------------------------------------------------------------------------------- 中學(xué)階段 ? ? ? 10 PRINT "HELLO WORLD" ? ? ? 20 END -------------------------------------------------------------------------------- 大學(xué)一年級 ? ? ? program Hello(input, output) ? ? ? ? begin ? ? ? ? writeln('Hello World') ? ? ? ? end. -------------------------------------------------------------------------------- 大學(xué)高年級 ? ? ? (defun hello ? ? ? ? (cons 'Hello (list 'World)))) -------------------------------------------------------------------------------- 初級程序員 ? ? ? #include <stdio.h> ? ? ? void main(void) ? ? ? { ? ? ? ? char *message[] = {"Hello ", "World"}; ? ? ? ? int i; ? ? ? ? for(i = 0; i < 2; ++i) ? ? ? ? printf("%s", message ); ? ? ? ? printf("\n"); ? ? ? } -------------------------------------------------------------------------------- 編程老鳥 ? ? ? #include <iostream.h> ? ? ? #include <string.h> ? ? ? class string ? ? ? { ? ? ? private: ? ? ? ? int size; ? ? ? ? char *ptr; ? ? ? public: ? ? ? ? string() : size(0), ptr(new char('\0')) {} ? ? ? ? string(const string &s) : size(s.size) ? ? ? ? { ? ? ? ? ptr = new char[size + 1]; ? ? ? ? strcpy(ptr, s.ptr); ? ? ? ? } ? ? ? ? ~string() ? ? ? ? { ? ? ? ? delete [] ptr; ? ? ? ? } ? ? ? ? friend ostream &operator <<(ostream &, const string &); ? ? ? ? string &operator=(const char *); ? ? ? }; ? ? ? ostream &operator<<(ostream &stream, const string &s) ? ? ? { ? ? ? ? return(stream << s.ptr); ? ? ? } ? ? ? string &string::operator=(const char *chrs) ? ? ? { ? ? ? ? if (this != &chrs) ? ? ? ? { ? ? ? ? delete [] ptr; ? ? ? ? size = strlen(chrs); ? ? ? ? ptr = new char[size + 1]; ? ? ? ? strcpy(ptr, chrs); ? ? ? ? } ? ? ? ? return(*this); ? ? ? } ? ? ? int main() ? ? ? { ? ? ? ? string str; ? ? ? ? str = "Hello World"; ? ? ? ? cout << str << end ? ? ? ? return(0); ? ? ? } -------------------------------------------------------------------------------- 編程高手 ? ? ? [ ? ? ? uuid(2573F8F4-CFEE-101A-9A9F-00AA00342820) ? ? ? ] ? ? ? library LHello ? ? ? { ? ? ? ? // bring in the master library ? ? ? ? importlib("actimp.tlb"); ? ? ? ? importlib("actexp.tlb"); ? ? ? ? // bring in my interfaces ? ? ? ? #include "pshlo.idl" ? ? ? ? [ ? ? ? ? uuid(2573F8F5-CFEE-101A-9A9F-00AA00342820) ? ? ? ? ] ? ? ? ? cotype THello ? ? ? { ? ? ? interface IHello; ? ? ? interface IPersistFile; ? ? ? }; ? ? ? }; ? ? ? [ ? ? ? exe, ? ? ? uuid(2573F890-CFEE-101A-9A9F-00AA00342820) ? ? ? ] ? ? ? module CHelloLib ? ? ? { ? ? ? ? // some code related header files ? ? ? ? importheader(<windows.h>); ? ? ? ? importheader(<ole2.h>); ? ? ? ? importheader(<except.hxx>); ? ? ? ? importheader("pshlo.h"); ? ? ? ? importheader("shlo.hxx"); ? ? ? ? importheader("mycls.hxx"); ? ? ? ? // needed typelibs ? ? ? ? importlib("actimp.tlb"); ? ? ? ? importlib("actexp.tlb"); ? ? ? ? importlib("thlo.tlb"); ? ? ? ? [ ? ? ? ? uuid(2573F891-CFEE-101A-9A9F-00AA00342820), ? ? ? ? aggregatable ? ? ? ? ] ? ? ? ? coclass CHello ? ? ? { ? ? ? cotype THello; ? ? ? }; ? ? ? }; ? ? ? #include "ipfix.hxx" ? ? ? extern HANDLE hEvent; ? ? ? class CHello : public CHelloBase ? ? ? { ? ? ? public: ? ? ? ? IPFIX(CLSID_CHello); ? ? ? ? CHello(IUnknown *pUnk); ? ? ? ? ~CHello(); ? ? ? ? HRESULT __stdcall PrintSz(LPWSTR pwszString); ? ? ? private: ? ? ? ? static int cObjRef; ? ? ? }; ? ? ? #include <windows.h> ? ? ? #include <ole2.h> ? ? ? #include <stdio.h> ? ? ? #include <stdlib.h> ? ? ? #include "thlo.h" ? ? ? #include "pshlo.h" ? ? ? #include "shlo.hxx" ? ? ? #include "mycls.hxx" ? ? ? int CHello::cObjRef = 0; ? ? ? CHello::CHello(IUnknown *pUnk) : CHelloBase(pUnk) ? ? ? { ? ? ? ? cObjRef++; ? ? ? ? return; ? ? ? } ? ? ? HRESULT __stdcall CHello::PrintSz(LPWSTR pwszString) ? ? ? { ? ? ? ? printf("%ws\n", pwszString); ? ? ? ? return(ResultFromScode(S_OK)); ? ? ? } ? ? ? CHello::~CHello(void) ? ? ? { ? ? ? // when the object count goes to zero, stop the server ? ? ? cObjRef--; ? ? ? if( cObjRef == 0 ) ? ? ? ? PulseEvent(hEvent); ? ? ? return; ? ? ? } ? ? ? #include <windows.h> ? ? ? #include <ole2.h> ? ? ? #include "pshlo.h" ? ? ? #include "shlo.hxx" ? ? ? #include "mycls.hxx" ? ? ? HANDLE hEvent; ? ? ? int _cdecl main( ? ? ? int argc, ? ? ? char * argv[] ? ? ? ) { ? ? ? ULONG ulRef; ? ? ? DWORD dwRegistration; ? ? ? CHelloCF *pCF = new CHelloCF(); ? ? ? hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); ? ? ? // Initialize the OLE libraries ? ? ? CoInitializeEx(NULL, COINIT_MULTITHREADED); ? ? ? CoRegisterClassObject(CLSID_CHello, pCF, CLSCTX_LOCAL_SERVER, ? ? ? ? REGCLS_MULTIPLEUSE, &dwRegistration); ? ? ? // wait on an event to stop ? ? ? WaitForSingleObject(hEvent, INFINITE); ? ? ? // revoke and release the class object ? ? ? CoRevokeClassObject(dwRegistration); ? ? ? ulRef = pCF->Release(); ? ? ? // Tell OLE we are going away. ? ? ? CoUninitialize(); ? ? ? return(0); ? ? ? } ? ? ? extern CLSID CLSID_CHello; ? ? ? extern UUID LIBID_CHelloLib; ? ? ? CLSID CLSID_CHello = { /* 2573F891-CFEE-101A-9A9F-00AA00342820 */ ? ? ? ? 0x2573F891, ? ? ? ? 0xCFEE, ? ? ? ? 0x101A, ? ? ? ? { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 } ? ? ? }; ? ? ? UUID LIBID_CHelloLib = { /* 2573F890-CFEE-101A-9A9F-00AA00342820 */ ? ? ? ? 0x2573F890, ? ? ? ? 0xCFEE, ? ? ? ? 0x101A, ? ? ? ? { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 } ? ? ? }; ? ? ? #include <windows.h> ? ? ? #include <ole2.h> ? ? ? #include <stdlib.h> ? ? ? #include <string.h> ? ? ? #include <stdio.h> ? ? ? #include "pshlo.h" ? ? ? #include "shlo.hxx" ? ? ? #include "clsid.h" ? ? ? int _cdecl main( ? ? ? int argc, ? ? ? char * argv[] ? ? ? ) { ? ? ? HRESULT hRslt; ? ? ? IHello ? ? *pHello; ? ? ? ULONG ulCnt; ? ? ? IMoniker * pmk; ? ? ? WCHAR wcsT[_MAX_PATH]; ? ? ? WCHAR wcsPath[2 * _MAX_PATH]; ? ? ? // get object path ? ? ? wcsPath[0] = '\0'; ? ? ? wcsT[0] = '\0'; ? ? ? if( argc > 1) { ? ? ? ? mbstowcs(wcsPath, argv[1], strlen(argv[1]) + 1); ? ? ? ? wcsupr(wcsPath); ? ? ? ? } ? ? ? else { ? ? ? ? fprintf(stderr, "Object path must be specified\n"); ? ? ? ? return(1); ? ? ? ? } ? ? ? // get print string ? ? ? if(argc > 2) ? ? ? ? mbstowcs(wcsT, argv[2], strlen(argv[2]) + 1); ? ? ? else ? ? ? ? wcscpy(wcsT, L"Hello World"); ? ? ? printf("Linking to object %ws\n", wcsPath); ? ? ? printf("Text String %ws\n", wcsT); ? ? ? // Initialize the OLE libraries ? ? ? hRslt = CoInitializeEx(NULL, COINIT_MULTITHREADED); ? ? ? if(SUCCEEDED(hRslt)) { ? ? ? ? hRslt = CreateFileMoniker(wcsPath, &pmk); ? ? ? ? if(SUCCEEDED(hRslt)) ? ? ? hRslt = BindMoniker(pmk, 0, IID_IHello, (void **)&pHello); ? ? ? ? if(SUCCEEDED(hRslt)) { ? ? ? // print a string out ? ? ? pHello->PrintSz(wcsT); ? ? ? Sleep(2000); ? ? ? ulCnt = pHello->Release(); ? ? ? } ? ? ? ? else ? ? ? printf("Failure to connect, status: %lx", hRslt); ? ? ? ? // Tell OLE we are going away. ? ? ? ? CoUninitialize(); ? ? ? ? } ? ? ? return(0); ? ? ? } -------------------------------------------------------------------------------- 黑客初階 ? ? ? #!/usr/local/bin/perl ? ? ? $msg="Hello, world.\n"; ? ? ? if ($#ARGV >= 0) { ? ? ? ? while(defined($arg=shift(@ARGV))) { ? ? ? ? $outfilename = $arg; ? ? ? ? open(FILE, ">" . $outfilename) || die "Can't write $arg: $!\n"; ? ? ? ? print (FILE $msg); ? ? ? ? close(FILE) || die "Can't close $arg: $!\n"; ? ? ? ? } ? ? ? } else { ? ? ? ? print ($msg); ? ? ? } ? ? ? 1; -------------------------------------------------------------------------------- 黑客有成 ? ? ? #include <stdio.h> ? ? ? #define S "Hello, World\n" ? ? ? main(){exit(printf(S) == strlen(S) ? 0 : 1);} -------------------------------------------------------------------------------- 黑客高手 ? ? ? % cc -o a.out ~/src/misc/hw/hw.c ? ? ? % a.out -------------------------------------------------------------------------------- 黑客大蝦 ? ? ? % cat ? ? ? Hello, world. ? ? ? ^D -------------------------------------------------------------------------------- 初級經(jīng)理 ? ? ? 10 PRINT "HELLO WORLD" ? ? ? 20 END -------------------------------------------------------------------------------- 中級經(jīng)理 ? ? ? mail -s "Hello, world." bob@b12 ? ? ? Bob, could you please write me a program that prints "Hello, world."? ? ? ? I need it by tomorrow. ? ? ? ^D -------------------------------------------------------------------------------- 高級經(jīng)理 ? ? ? % zmail jim ? ? ? I need a "Hello, world." program by this afternoon. -------------------------------------------------------------------------------- 首席執(zhí)行官 ? ? ? % letter ? ? ? letter: Command not found. ? ? ? To: ^X ^F ^C ? ? ? % help mail ? ? ? help: Command not found. ? ? ? % damn! ? ? ? !: Event unrecognized ? ? ? % logout -------------------------------------------------------------------------------- posted @ 2006-05-18 17:14 fisher 閱讀(1059) | 評論 (0) | 編輯 收藏 Hello World的196種寫法
還記得孔乙己說:茴香豆的‘茴’字有四種寫法嗎?現(xiàn)在我們的知識份子已經(jīng)進(jìn)步了,看看Hello World的196種寫法:)
http://man.lupaworld.com/content/develop/hello/HelloWorld.shtml posted @ 2006-05-18 16:58 fisher 閱讀(874) | 評論 (0) | 編輯 收藏 趴在窗戶上看長江
下午寫完設(shè)計(jì),趴在武漢辦公室的窗戶上看風(fēng)景,天氣好的時(shí)候,左面長江右邊東湖都可以看到,其實(shí)想想在武漢出差也挺不錯(cuò)的,呵呵
posted @ 2006-05-17 18:03 fisher 閱讀(590) | 評論 (0) | 編輯 收藏 關(guān)于人.....
彼得·德魯克在他的《卓有成效的管理者?》當(dāng)中,闡述了知識工作者管理的秘訣,那就是知識工作者的工作效率來自于對其工作的有效性以及他的工作是否有所成就。這本1966年出版的管理學(xué)書籍經(jīng)過近50年的時(shí)間,反而越發(fā)顯得適應(yīng)潮流。
而卓有成效的知識工作管理者現(xiàn)在顯得比過去任何時(shí)候都要短缺,也比現(xiàn)時(shí)任何人才都要短缺。在現(xiàn)時(shí)這個(gè)信息爆炸,案例豐富的年代,戰(zhàn)略眼光與部署格局對于一個(gè)企業(yè)人才不再如此重要,對于企業(yè)戰(zhàn)略,任何有管理常識、了解企業(yè)實(shí)情的人大都可以分析得很到位,關(guān)鍵是要找到合適的人去實(shí)施。知道什么樣的人合適,以及找到這個(gè)合適的人,成為企業(yè)家最需要做的事情。而成為那個(gè)合適的人,則成為草根階層走入舞臺中央的必備能力。 附一篇來自經(jīng)濟(jì)觀察報(bào)劉軍的《笨蛋,最重要的是人!》 --------------------------------- ????? 2005年10月8日管理大師彼得·德魯克曾經(jīng)講過一個(gè)他和《時(shí)代》《財(cái)富》等雜志的出版人亨利·魯斯交往的故事。魯斯有個(gè)很好的新雜志方案——試圖創(chuàng)辦“從美國人思考角度出發(fā)”的高格調(diào)文化雜志,他去向德魯克求教。德魯克分析了一番說,“這份企劃案很棒,不過晚了50年。”接著,他對魯斯說出了最重要的話:“此外,《時(shí)代》的人也無法勝任。我猜,你想鼓勵(lì)一些外面的作家來為這本雜志執(zhí)筆,并以一般大眾為讀者群。但是你的專長卻是叫自己手下人搞定,因此大有不同。”? ????? 魯斯回答說,“我來向你請教,正因?yàn)槲也孪肽銜?huì)這么說。”他因而放棄了這個(gè)計(jì)劃,因?yàn)樗钪说闹匾浴=?jīng)過十多年的西方管理教育和知識傳播,中國企業(yè)管理者已經(jīng)熟知戰(zhàn)略的理性分析,與重視人比起來更重視事,另外先建立制度、而不是依靠人的觀念也被廣泛接受。不過,我卻逐漸感覺到,在這些問題上我們可能有點(diǎn)矯枉過正,對于知識型工作、對于管理,或許人更重要,是應(yīng)該優(yōu)先考慮的。? ????? 9月底,索尼新任CEO、美國人霍華德·斯特林格(Howard?Stringer)宣布索尼的戰(zhàn)略調(diào)整計(jì)劃:全球裁員一萬人,縮減工廠數(shù)目,出售1200億日元的不動(dòng)產(chǎn)與股票等非核心資產(chǎn),對消費(fèi)電子業(yè)務(wù)進(jìn)行架構(gòu)調(diào)整、將權(quán)力集中到這一業(yè)務(wù)的最高主管手中。在過去五年中,索尼逐漸失去消費(fèi)電子霸主地位,業(yè)績很不理想,這背后的根本原因正是這些戰(zhàn)略調(diào)整所觸及的問題。對于這一點(diǎn),大概稍微有點(diǎn)管理常識的人都知道,我想索尼前CEO出井伸之自然了然于心,他之下的索尼高管也清楚。不過,大概只有霍華德·斯特林格、索尼歷史上第一個(gè)外國人CEO、這個(gè)日本文化的局外人才能推行上述改革。? ???? 戰(zhàn)略,有管理常識、了解企業(yè)實(shí)情的人大都可以分析得很到位,但真正去做,就需要“合適的人”。我一直相信,選擇霍華德·斯特林格作為繼任者,是出井伸之的最重要的決策,體現(xiàn)這個(gè)亞洲最優(yōu)秀的商業(yè)領(lǐng)袖的領(lǐng)導(dǎo)才能。卡洛斯·戈恩已經(jīng)因成功在日產(chǎn)汽車(Nissan)實(shí)現(xiàn)大逆轉(zhuǎn)而成為全球最知名的管理者之一,他當(dāng)初所做的關(guān)閉工廠與裁員、破除日本式企業(yè)聯(lián)盟等措施,都是眾所周知的弊端,但惟有他這個(gè)合適的人才能推動(dòng)變革。斯特林格和戈恩都是在這種情境下最合適的人,只是恰巧他們都是外國人。? ????? Google、微軟和李開復(fù)之間的紛爭一直沒有停息的跡象。在這個(gè)過程中李開復(fù)把自己再次塑造成了最優(yōu)秀的技術(shù)專家形象,但如果相信這一點(diǎn),我們就錯(cuò)誤理解了Google的智慧。如果要一流的中文搜索研發(fā)人才,Google的最佳人選絕對不是李開復(fù),而可能是李彥宏。如果它的戰(zhàn)略訴求點(diǎn)是這個(gè),它可以百度買下,從而得到李彥宏。但是,Google在中國,需要的哪里是什么技術(shù)專家、研發(fā)中心?現(xiàn)在Google中國戰(zhàn)略要的合適的人是據(jù)稱是“技術(shù)專家”的李開復(fù),但他在公眾心目中的號召力和政府公關(guān)能力才是Google所看重的。? ????? 我們也可以循同樣的視角來看待雅虎和阿里巴巴之間的聯(lián)姻。這一次是把雅虎中國的業(yè)務(wù)交道馬云手中去讓他照料,因?yàn)閷τ谡l了解中國市場和能夠幫助雅虎發(fā)現(xiàn)中國市場潛力這個(gè)問題,馬云是最佳答案。雅虎在中國的最近兩次戰(zhàn)略行動(dòng)目標(biāo)都首先是為了“人”。上一次是雅虎在中國收購3721,反而讓其老板周鴻一擔(dān)任中國區(qū)總裁,從而讓雅虎中國從跨國公司在華分支機(jī)構(gòu)這樣的角色變成勇猛的中國本土企業(yè)。但在經(jīng)歷一段發(fā)展時(shí)期之后,雅虎中國就需要更合適的人。我們可以認(rèn)為,這是雅虎、阿里巴巴聯(lián)姻的主要原因之一。? ????? 先建立制度、體系,而不是“因人設(shè)事”這樣的觀點(diǎn)被廣泛接受,可是,我們忘記了這個(gè)觀念背后的工業(yè)化背景:所有人的都被當(dāng)成了可替換的零件,所以制度體系最重要。但是,對于知識型工作來說,特別是非重復(fù)的創(chuàng)造性工作,每個(gè)人的工作方式、結(jié)果都截然不同。? ????? 我們所設(shè)計(jì)的制度體系,在當(dāng)前的人員安排下也似乎運(yùn)轉(zhuǎn)正常。但是,由于這些人是無法替換的,人走了,看似精妙的體系也就出現(xiàn)出現(xiàn)問題了。這個(gè)時(shí)候,是去做不可能完成的任務(wù):尋找適合制度體系的一摸一樣的人?還是更改體系?或者看得更遠(yuǎn)點(diǎn),在現(xiàn)在的情境下,我們根本就不該把制度體系的重要性神話到這種程度?針對知識型工作的討論,和上文對最高管理者的討論并非沒有聯(lián)系,因?yàn)樵谖铱磥恚芾砉ぷ魇亲钪匾摹⒆罹邉?chuàng)造性的知識工作。? ????? 吉姆·柯林斯在《從優(yōu)秀到卓越》說卓越公司是“先人后事”:這些公司的主管不是先確定目的地(先有方向、愿景、戰(zhàn)略),然后才把人們引向那里;他們首先讓合適的人上車(不合適的人自然請下車),然后才決定去向何處。他所說的雖是方向、遠(yuǎn)景,但大體上和制度是同一類型的事物。我們都應(yīng)該了解,合適的人更重要,那些看似嚴(yán)密的戰(zhàn)略分析和完善的制度體系有時(shí)候會(huì)變成令人難以忍受的障礙,因?yàn)樗鼈兒汀昂线m的人”可能是完全矛盾的,這些人通常都難以放到一個(gè)既定的模子中去。? posted @ 2006-04-25 23:19 fisher 閱讀(1049) | 評論 (0) | 編輯 收藏 webwork2.2.2的dtd解析問題(感謝飛云小俠)
今天將webwork2.2.1更換成webwork2.2.2,出現(xiàn)了一個(gè)奇怪的異常,每次啟動(dòng)后,都會(huì)報(bào)出:
org.xml.sax.SAXParseException:?Element?type?"global-exception-mappings"?must?be?declared. 如果將xwork.xml中的global-exception-mappings注釋掉便好com.opensymphony.xwork.config.ConfigurationException:?Caught?exception?while?loading?file?xwork.xml ????with?nested?exception? org.xml.sax.SAXParseException:?Element?type?"global-exception-mappings"?must?be?declared. 頭疼了幾個(gè)小時(shí)解決不了,不得不求助飛云小俠 飛云小俠一出手果然不同,馬上定位了問題所在 就是這句: <!DOCTYPE?xwork?PUBLIC?"-//OpenSymphony?Group//XWork?1.1.1//EN"?"http://www.opensymphony.com/xwork/xwork-1.1.1.dtd"> 原來雖然幾次升級webwork.jar,但是xwork.xml的DTD解析還是用的原來的DTD,頂多就是改了DTD的地址,也就是將這句 ![]() ![]() ![]() ![]() 而實(shí)際上解析DTD是靠的前面那句 <!DOCTYPE?xwork?PUBLIC?"-//OpenSymphony?Group//XWork?1.1.1//EN"? 原來一直是![]() ![]() ![]() ![]() 多謝飛云小俠的幫助^_^ posted @ 2006-04-21 15:07 fisher 閱讀(1274) | 評論 (0) | 編輯 收藏 重讀溫博格自工作以來,我就養(yǎng)成了睡前讀書的習(xí)慣,這一年在武漢,實(shí)在買不到一些好書,每次回北京總要帶很多書過來,最近再次面臨回京購書的局面,在回京之前總不能閑著,于是從去年看過的書中亂翻,以第一感覺來決定自己最想重讀那本書,結(jié)果選中了溫博格的《成為技術(shù)領(lǐng)導(dǎo)者-解決問題的有機(jī)方法》 而溫博格的寫作方式,如同Ken在英文版序中所說,會(huì)引起大量的思考,對溫博格的文字的思考,思考對溫博格文字的思考,以及對自身思考的思考....通過溫博格的書,讓我體會(huì)到的事是,讀書,有時(shí)候是為了實(shí)用,而的有時(shí)候,則純粹是為了過癮。 下面的內(nèi)容,來自于本書第三章摘錄 各種各樣的想法是解決問題的核心,沒有想法就不可能找到解決方案,但想法太多又會(huì)雜亂無章,領(lǐng)導(dǎo)者需要對想法的交流進(jìn)行有效的管理。以下是領(lǐng)導(dǎo)者常用的12種典型的管理想法交流的方法以及點(diǎn)評。 posted @ 2006-03-18 06:44 fisher 閱讀(1344) | 評論 (1) | 編輯 收藏 歡迎加入“osgi觀察者”googlegroup
去年年底,osgi R4發(fā)布,eclipse建立equinox項(xiàng)目,標(biāo)志著以osgi為核心的組件管理模型正式進(jìn)入使用階段,鑒于今年年初jsr291的推出,osgi正式走向java世界的前端,遂建立osgi觀察者group,希望能同所有關(guān)心和喜愛osgi的國內(nèi)技術(shù)人員共同進(jìn)步。
加入osgi觀察者:
posted @ 2006-03-06 13:37 fisher 閱讀(1022) | 評論 (1) | 編輯 收藏 善待自己每一天
最近的忙碌加上精神壓力,讓我患上了胃病,每天吃完飯都會(huì)難受好一陣子,給自己學(xué)醫(yī)的兒時(shí)好友打電話,被勸之:“人生苦短,要學(xué)會(huì)善待自己每一天”。遂發(fā)此文為戒。
附一篇BJUG中Tin發(fā)的文章《白天紐約黑夜巴黎》 ------------------------------- 白天紐約黑夜巴黎 ------------------------------- 【王文華/文】 我在趕些什么?我耗盡青春用盡全力,拼命追求身外之物 紐約和巴黎,代表了我人生的兩個(gè)面向。紐約是白天,巴黎是黑夜 三十五歲之前,我認(rèn)定紐約是世上最棒的城市。我在加州念研究所 所以在紐約時(shí),我把握每分每秒去體會(huì)。白天,我在金融機(jī)構(gòu)做事 這種想法并不是到紐約才有的。其實(shí)從小開始,臺灣人就過著紐約生 在這種弱肉強(qiáng)食的生活方式,為了保持領(lǐng)先,每個(gè)人都在趕時(shí)間 臺灣,是不是也變成這樣? 每一件事,都變成工作。上班當(dāng)然是工作,下班后的應(yīng)酬也是工作 我曾熱烈擁抱這種生活,并著迷于這種因?yàn)闊境晒Χ俺龅慕箲] 這套想法,在我三十五歲以后,慢慢改變。 第一件動(dòng)搖我想法的,是父親的過世。我父親一生奉公守法 不止在病床,也在職場。當(dāng)我在企業(yè)越爬越高,才發(fā)現(xiàn)「資本主義 慢慢的,我體會(huì)到:世上有一種比「善有善報(bào)、惡有惡報(bào)」更高 我能在哪里找到那種公平和樂趣呢?我想過西藏、不丹、非洲 住紐約時(shí),法國是嘲諷的對象。身為經(jīng)濟(jì)、科技、和軍事強(qiáng)權(quán)的美國 搬回臺灣后,普羅旺斯、托斯卡尼突然流行。我看了弗朗西斯 是啊!我在趕些什么?我耗盡青春用盡全力,拚命追求身外之物 當(dāng)我重新學(xué)習(xí)法國,我發(fā)現(xiàn)法國和美國代表兩種截然不同的生活方式 不論是政府或個(gè)人,法國人都把精神投注在食、衣、住、行等 講到吃,法國有三百種起司、光是波爾多就有五十七個(gè)酒的產(chǎn)區(qū) You Can Eat」。 吃很重要,但也要會(huì)挑時(shí)間,朋友介紹我去試一家法國餐廳 聰明的主廚懂法律。法國法律規(guī)定一周工作最多三十五小時(shí) 當(dāng)然,法國這么深厚的文化,不可能只從吃喝玩樂而來。美國人讀書 一直跟著美國走的臺灣人,會(huì)心動(dòng)嗎? 我心動(dòng)了。十一月我到巴黎,一位法國朋友來接待我。臨走前我問他 「我要去銀行。」 「然后呢?」我問。 「我不懂你的意思......」 對我來說,「去銀行」是吃完午飯后跑去辦的小事。對法國人來說 這樣的生活,對美國或臺灣人來說,實(shí)在是太頹廢了。的確也是 我從巴黎回來,臺北并沒有改變。關(guān)了兩周的手機(jī)再度響起 「Projects」?多么紐約的字眼。 我真想說:「好好生活,不就是人生最大的project? 所以我說:「我還是會(huì)早起,白天努力寫作。但到了晚上 世界少了我,其實(shí)無所謂。但我少了我,還剩什么? 他笑一笑:「你這是用紐約來過白天,用巴黎來過黑夜。」 唉,他講得真好!這應(yīng)該是一個(gè)完美的妥協(xié)吧。也許有一天 「明天星期一,你要干嘛?」他問。 「我要去銀行。」 「然后呢?」 我張大眼睛,停頓了一下。 「然后呢?」他追問。 「然后我會(huì)摩拳擦掌,認(rèn)真地寫一篇文章。」 我們是不是也應(yīng)該學(xué)一學(xué)法國人呢?提高些生活質(zhì)量,注意身體。 posted @ 2006-02-28 11:04 fisher 閱讀(1018) | 評論 (4) | 編輯 收藏 MINA vs. QuickServer
很久沒更新blog了,實(shí)在太忙,今天看到有朋友在我去年的blog《MINA is a good framwork 》中回復(fù)提到比較一下MNA和QuickServer,遂寫一篇小文:
First for all, QuickServer is licensed as LGPL, and MINA as ASL 從我個(gè)人角度而言,去年看過QuickServer的源碼,我在項(xiàng)目中采用的每一個(gè)框架或類庫都會(huì)做綜合評價(jià),通常不會(huì)是一個(gè)原因?qū)е挛也捎没驔]有采用某個(gè)庫或框架,具體最后沒有采用QuickServer的原因忘記了,但是當(dāng)時(shí)給我的總體感覺是,QuickServer雖然很方便,但不會(huì)讓我在架構(gòu)上得到新的好處。而它最大的優(yōu)點(diǎn)則是,支持JDK1.3(如果沒記錯(cuò)的話),另外就是License的問題 下面看一看來自TrusinLee的評論: Thank for the information about another network application framework. I found a few differences: * QuickServer supports blocking mode. (MINA supports only non-blocking mode, but you can make your operation block at your will.) * QuickServer provides GUI-based admin. (MINA doesn't have one yet, but will have full JMX support soon, which is a standard.) * QuickServer uses java.util.logging. (MINA uses SLF4J, which is a safe replacement of commons-logging.) * QuickServer uses its own XML settings. (MINA provides Spring framework integration instead.) * QuickServer can specify maximum number of clients allowed. (MINA can do this using a filter, but not implemented by default. Of course, this will be implemented as an overload prevention filter.) * QuickServer team has one crew. (MINA has three crews.) * QuickServer project started in 2003. (MINA started in 2005.) * QuickServer has a difference event handler interface from MINA. (You'll have to compare it by yourself. IMHO, MINA has one simple enough handler which covers all QuickServer provides.) * QuickServer doesn't support UDP at all. (MINA does) * QuickServer doesn't support client-side API at all. (MINA does) * QuickServer integrated authentication and text protocol in its core. (MINA didn't and they are considered as a cross-cutting concern that a filter should take care of. IMHO, MINA is more extensible here.) 至于對MINA更詳細(xì)的介紹,可以看看我去年翻譯的MINA的Tutorial MinaTutorialInChinese posted @ 2006-02-24 21:58 fisher 閱讀(6235) | 評論 (18) | 編輯 收藏 一個(gè)SWT Application如何轉(zhuǎn)職成為RCP Appliactioin昨天david問到如何將舊的swt應(yīng)用轉(zhuǎn)成一個(gè)RCP應(yīng)用,昨晚胃疼難忍,于是草草說了一下,就早早上床休息了,早上起來又想起這件事情,遂在這里說一下思路 一個(gè)舊的SWT應(yīng)用,應(yīng)該都是有一個(gè)main函數(shù)里初始化一些UI組件,然后run一個(gè)事件循環(huán) 在RCP中,由于是基于Eclipse的插件體系,也就是說,使用我前面那篇文章發(fā)布的RCP Application,是可以直接發(fā)布成Eclipse插件的 我們只要將原swt的main函數(shù)中初始化的ui組件,放入到這幾個(gè)Advisor中進(jìn)行初始化 將下拉菜單項(xiàng)的ui組件的初始化工作放入到ApplicationActionBarAdvisor的如下方法: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
----------------------------------- 最后,基于Eclipse3.1的product方式的RCP程序?qū)@得同Eclipse相同的插件體系支持 posted @ 2006-01-17 11:02 fisher 閱讀(1749) | 評論 (0) | 編輯 收藏 使用Eclipse3.1的新特性方便的發(fā)布你的RCP Product
摘要: Eclipse3.1剛剛release的時(shí)候,它的RCP發(fā)布功能就很吸引我,當(dāng)時(shí)正好有個(gè)小東西要做,就用了這個(gè)功能發(fā)布了一個(gè)小程序,似乎很多人推薦用NSIS,但是我覺得Eclipse的這個(gè)功能似乎更方便,幾乎不用擔(dān)心任何部署的問題。
閱讀全文 posted @ 2006-01-16 23:16 fisher 閱讀(3719) | 評論 (4) | 編輯 收藏 N久沒有更新了-大雜燴-blogjava年終看點(diǎn)Blog有一個(gè)多月沒有更新了,今年8個(gè)月的忙碌生活,以及最后兩個(gè)月的突擊使我徹底失去了熱情,無論是工作還是寫blog,目前只想每天休息休息,看看書。 posted @ 2006-01-11 00:36 fisher 閱讀(731) | 評論 (4) | 編輯 收藏 【ESB專題】之六 - System Management及其相關(guān)模式開發(fā)一個(gè)基于消息的解決方案是不容易的事情,在生產(chǎn)中操作這樣一個(gè)產(chǎn)品同樣也是一個(gè)挑戰(zhàn):一個(gè)基于消息的集成解決方案一天可以產(chǎn)生、路由和轉(zhuǎn)換成千上萬的消息。我們不得不處理異常、效率瓶頸或改變合作系統(tǒng)。而為了使事情變得更加有挑戰(zhàn)性,組件經(jīng)常被分布在不同的平臺和機(jī)器上,甚至位于不同的地理位置。 System Management包含以下幾種模式 l Control Bus l Detour l Wire Tap l Message History l Message Store l Smart Proxy l Test Message l Channel Purger 除了與生據(jù)來的復(fù)雜性、分布式集成的規(guī)模以及個(gè)性化的應(yīng)用之外,低耦合的架構(gòu)使得測試和debug變得更加困難。Martin Fowler將這個(gè)癥狀稱為“架構(gòu)師的夢想,開發(fā)者的夢魘”。低耦合的架構(gòu)原則以及間接的依賴于外部系統(tǒng)提供了靈活性。然而,測試一個(gè)消息生產(chǎn)者不了解消息消費(fèi)者的系統(tǒng)可能會(huì)是一個(gè)挑戰(zhàn)。另外異步的和時(shí)間相關(guān)的消息使得事情變的更加復(fù)雜。舉例來說,消息方案可能被設(shè)計(jì)沒有被成消息生產(chǎn)者者必須從接受者那里得到一個(gè)回應(yīng)。同樣的消息基礎(chǔ)設(shè)施通常保證傳輸消息,但不能保證傳輸時(shí)間。這是的開發(fā)基于消息傳送結(jié)果的測試用例變得困難。 當(dāng)監(jiān)控一個(gè)消息解決方案,我們可以在兩個(gè)抽象層面上跟蹤消息流。一個(gè)典型的系統(tǒng)管理方案監(jiān)控多少消息被發(fā)送或者它多長時(shí)間得到一個(gè)被處理的消息。這些監(jiān)控方案不檢查消息數(shù)據(jù),除了可能會(huì)檢查消息頭中的幾個(gè)字段(比如消息標(biāo)識或者消息歷史)。與之相對的,BAM(business activity monitoring)方案聚焦于包含在消息中的有效數(shù)據(jù),舉例來說,發(fā)生在過去一小時(shí)的所有訂單的金額。System Management中的很多模式都足夠通用并可以用在以上兩個(gè)目的中(監(jiān)控消息頭或者消息內(nèi)容)。然而,由于BAM本身就是一個(gè)新領(lǐng)域,并且需要從數(shù)據(jù)倉庫中獲得很多數(shù)據(jù)(有些我們根本就沒有涉及到),我們決定在系統(tǒng)管理的內(nèi)容中討論這些模式。 系統(tǒng)管理模式被設(shè)計(jì)用于為保持一個(gè)基于消息的復(fù)雜系統(tǒng)的運(yùn)轉(zhuǎn)所提出的需求并提供工具。System Management的模式涉及三個(gè)種類:監(jiān)控和控制,觀察和分析消息流量,測試和調(diào)試。 監(jiān)控和控制 一個(gè)Control Bus提供一個(gè)單獨(dú)的控制點(diǎn)來對一個(gè)分布式方案進(jìn)行監(jiān)控和管理。它將多個(gè)組件連接到一個(gè)中心管理控制臺,這里可以顯示每個(gè)組件的狀態(tài)并且監(jiān)控通過每個(gè)組件的消息流量。控制臺同時(shí)也可以用于發(fā)送控制命令給組件,比如,轉(zhuǎn)變消息流。 我們可能想要在路由消息時(shí)添加附加的步驟,比如驗(yàn)證或者日志。由于這些步驟可能使效率降低,所以我們可以通過Control Bus來控制他們開關(guān)。一個(gè)Detour為我們提供這種能力。 觀察和分析消息流量 有時(shí)我們想要在不影響主要消息流的情況下觀察消息的內(nèi)容。一個(gè)Wire Tap允許我們接入到消息流中。 當(dāng)我們調(diào)試一個(gè)基于消息的系統(tǒng),知道一個(gè)特定的消息在哪使很有幫助的。Message History保留一個(gè)消息訪問過的所有組件的日志,而不需要增加組件間的依賴。 然而Message History依賴于單獨(dú)的消息,一個(gè)中心的Message Store可以提供一個(gè)穿越系統(tǒng)的每個(gè)消息的完整記錄。結(jié)合Message History,Message Store可以分析所有消息穿過系統(tǒng)的可能路徑。 Wire Tap, Message History, 和Message Store幫助我們分析異步的消息流。為了跟蹤發(fā)送到請求-應(yīng)答service的消息,我們需要在消息流中插入一個(gè)Smart Proxy。 測試和調(diào)試 在部署前測試一個(gè)消息系統(tǒng)是一個(gè)非常好的注意。但是測試不應(yīng)該停止在部署前。你應(yīng)該有能力驗(yàn)證正在運(yùn)行的消息系統(tǒng)運(yùn)行持續(xù)的運(yùn)行正常。你可以周期性的發(fā)送一個(gè)Test Message到系統(tǒng)中并驗(yàn)證結(jié)果。 當(dāng)一個(gè)組件失敗或者運(yùn)行不正常,它可以簡單的終止,并放棄一個(gè)channel中的剩余消息。在測試期間這是很有用的。一個(gè)Channel Purger可以為我們做這些。 posted @ 2005-11-23 20:20 fisher 閱讀(1654) | 評論 (7) | 編輯 收藏 【過勞死】27個(gè)危險(xiǎn)信號,在你身上發(fā)生幾個(gè)了? (zt)
最近身體不太好,轉(zhuǎn)貼一則文章,提醒自己多多休息和鍛煉。
------------------------ 只要踏入在我們IT這個(gè)行業(yè), 過不了幾年身體就是亞健康狀態(tài),過渡的話就可能會(huì)“過勞死”,要想防止“過勞死”,就必須了解身體為我們發(fā)出的“過勞死”信號。 研究者認(rèn)為:在這27項(xiàng)癥狀和因素中占有7項(xiàng)以上,即是有過度疲勞危險(xiǎn)者,占10項(xiàng)以上就可能在任何時(shí)候發(fā)生“過勞死”。同時(shí),在第1項(xiàng)到第9項(xiàng)中占兩項(xiàng)以上或者在第10項(xiàng)到18項(xiàng)中占3項(xiàng)以上者也要特別注意,這27項(xiàng)癥狀和因素分別是: 哥們, 上面27條在你身上出現(xiàn)幾條癥狀了? 怕怕吧? 轉(zhuǎn)自: 電子商務(wù)論壇 http://bbs.eczn.com/ 上面下劃線的是我有的問題,你都有哪些? posted @ 2005-11-23 13:38 fisher 閱讀(709) | 評論 (0) | 編輯 收藏 WTP1.0已經(jīng)到達(dá)M9
經(jīng)過這半年的使用,WTP在我們組內(nèi)已經(jīng)從只用于開發(fā)Web Service的工具變成web開發(fā)的首選插件
雖然只是0.7版,但WTP的設(shè)計(jì)確實(shí)很好,目前WTP1.0已經(jīng)release到了M9,還有20幾天就到達(dá)release date了,熱烈期待中.... posted @ 2005-11-23 13:29 fisher 閱讀(635) | 評論 (0) | 編輯 收藏 【ESB專題】之五 - Message Endpoint及其相關(guān)模式
l Messaging Gateway l Messaging Mapper l Transactional Client l Polling Consumer l Event-Driven Consumer l Competing Consumers l Message Dispatcher l Selective Consumer l Durable Subscriber l Idempotent Receiver l Service Activator 發(fā)送和接收模式 有些endpoint模式既可以使用在發(fā)送方也可以使用在接受方。它們描述一個(gè)應(yīng)用連接一個(gè)消息系統(tǒng)的一般情況。 包裝消息代碼 - 一個(gè)應(yīng)用不應(yīng)該意識到正在使用消息同另外一個(gè)應(yīng)用程序通訊,大多數(shù)應(yīng)用代碼應(yīng)該在不知道message的情況下被編寫。在應(yīng)用集成的地方,應(yīng)該有一個(gè)薄薄的一層代碼來執(zhí)行應(yīng)用的集成部分。當(dāng)集成是由消息實(shí)現(xiàn)的,這層將應(yīng)用連接到消息系統(tǒng)的代碼稱為一個(gè)Message Gateway 數(shù)據(jù)轉(zhuǎn)換 - 當(dāng)發(fā)送者和接受者使用不同的數(shù)據(jù)格式,或者不同的消息格式(支持不同的發(fā)送和接收者),在這種情況下,使用一個(gè)Message Mapper來在應(yīng)用格式和消息格式之間轉(zhuǎn)換數(shù)據(jù)。 外部控制的事務(wù) - 消息系統(tǒng)在內(nèi)部和外部使用事務(wù),默認(rèn)的,每個(gè)發(fā)送和接收方法在他們自己的事務(wù)中運(yùn)行。Message生產(chǎn)者和消費(fèi)者應(yīng)可選的使用一個(gè)Transactional Client來控制事務(wù),當(dāng)你需要將幾個(gè)消息一起發(fā)送伙通過其他事務(wù)服務(wù)整理消息時(shí)是很有用的。 消息消費(fèi)者模式 其他endpoint模式只適用于消息消費(fèi)者,發(fā)送消息是簡單的。棘手的問題是決定一個(gè)消息應(yīng)該何時(shí)發(fā)送,它應(yīng)包含什么,以及怎樣將它送到接受者 - 這是為什么我們有很多消息結(jié)構(gòu)模式 - 但是一旦消息被構(gòu)建,發(fā)送它是很容易的。另一方面,接收消息 - 很麻煩。因此許多endpoint模式是關(guān)于接收消息的。 接收消息的一個(gè)最重要的主題就是流量控制:一個(gè)應(yīng)用控制,或者調(diào)節(jié)它消費(fèi)消息的速度。一個(gè)潛在的問題是任何server都面臨著大量的客戶端請求會(huì)使其超載。通過遠(yuǎn)程過程調(diào)用(RPI),server幾乎受到客戶端調(diào)用的支配。同樣的,通過消息,server不能控制客戶端發(fā)送請求的速度 - 但是server可是控制它處理這些請求的速度。應(yīng)用不必像消息系統(tǒng)傳送消息那么快的接收并處理消息;使用一個(gè)Message Channel可以使它在一個(gè)可接收的速率上處理消息。然而,當(dāng)消息積累太多,而server還有資源可以處理的更快,它可以使用同步message消費(fèi)者來加快速度。所以使用這些消息消費(fèi)者模式可以讓你的應(yīng)用將速度控制在它可以承受的范圍。 許多消息消費(fèi)者模式都是成對出現(xiàn)的,你可以任選一個(gè)使用。 同步或異步接受者 - 可以使用輪詢消費(fèi)者或一個(gè)事件驅(qū)動(dòng)消費(fèi)者。輪詢提供最好的流量控制,因?yàn)槿绻?/SPAN>server忙,則它不再繼續(xù)輪詢消息,所以message將阻塞在隊(duì)列。事件驅(qū)動(dòng)的消費(fèi)者傾向于消息到達(dá)便觸發(fā)處理,所以有可能會(huì)使server超載,但是每個(gè)消費(fèi)者每次只處理一個(gè)消息,所以限制消費(fèi)者的數(shù)量可以有效的控制消費(fèi)速度。 消息分派 vs 消息獲取 - 另外一個(gè)二選一的模式是一堆消費(fèi)者如何處理一堆消息。如果每個(gè)消費(fèi)者獲得一個(gè)消息,他們可以并行的處理消息。最簡單的方法是Competing Consumers,也就是一個(gè)點(diǎn)對點(diǎn)的channel有多個(gè)消費(fèi)者。每個(gè)都可能獲得任何消息;消息系統(tǒng)的實(shí)現(xiàn)決定那個(gè)消費(fèi)者獲得消息。如果你想控制消息到消費(fèi)者的匹配過程,使用Message Dispatcher。這時(shí)只有一個(gè)消費(fèi)者接收消息,但是將委派消息到一個(gè)執(zhí)行者去處理。一個(gè)應(yīng)用程序可以通過限制消費(fèi)者或執(zhí)行者的數(shù)量來控制流量。當(dāng)然,分派者Message Dispatcher也可以實(shí)現(xiàn)一個(gè)流量控制行為。 接收所有消息或者過濾 - 默認(rèn)的,任何到達(dá)一個(gè)Message Channel的消息對于監(jiān)聽著這個(gè)channel的Message Endpoint都是可用的。然而有些消費(fèi)者并不打算處理channel上的任何消息,而是希望只處理其中幾種。這樣一個(gè)識別的消費(fèi)者可以使用一個(gè)Selective Consumer來描述它將接收什么類型的消息。然后消息系統(tǒng)將只將匹配的消息對該接受者描述為可用。 當(dāng)斷開連接的時(shí)候訂閱消息 - Publish-Subscribe Channels帶來的問題是,如果一個(gè)消費(fèi)者感興趣一個(gè)channel,但是現(xiàn)在網(wǎng)絡(luò)是斷開的怎么辦?是不是一個(gè)未連接的應(yīng)用將錯(cuò)過發(fā)布的消息,即使它已經(jīng)訂閱過該消息?默認(rèn)的,是的,訂閱只對連接的訂閱者有效,為了使應(yīng)用不會(huì)因?yàn)檫B接而錯(cuò)過訂閱的消息,要使用Durable Subscriber。 等冪 - 有時(shí)一個(gè)消息可能被傳輸不只一次,可能因?yàn)橄⑾到y(tǒng)不確定該消息是否已經(jīng)被成功的傳遞過,或者可能因?yàn)?/SPAN>Message Channel的QoS被設(shè)置較低來提高效率。另一面的,消息接受者認(rèn)為每個(gè)消息只會(huì)被傳輸一次,并且當(dāng)它們重復(fù)處理相同的消息,它們會(huì)出錯(cuò)。一個(gè)Idempotent Receiver可以優(yōu)雅的處理重復(fù)的消息,并且阻止它們引起接收者應(yīng)用的發(fā)生錯(cuò)誤。 同步或異步服務(wù) - 另外一個(gè)選擇是一個(gè)應(yīng)用應(yīng)該暴露它的service為同步(RPI)還是異步的(Messaging)。不同的客戶端可能喜歡不同的方式;不同的環(huán)境可能需要不同的方式。既然很難選擇,就一起使用。一個(gè)Service Activator連接一個(gè)Message Channel到一個(gè)應(yīng)用的同步服務(wù)以便當(dāng)一個(gè)消息被接收,service就被調(diào)用。同步客戶端可以簡單的直接調(diào)用service;異步客戶端可以通過發(fā)送消息調(diào)用service。 Message Endpoint的相關(guān)主題 Message Endpoint的另外一個(gè)重要主題是很難同其他模式共同應(yīng)用Transactional Client。Event-Driven Consumer通常不能適當(dāng)?shù)脑谕獠靠刂剖聞?wù),Message Dispatcher也必須小心的設(shè)計(jì)這個(gè)問題,Competing Consumers的事務(wù)也是個(gè)重大問題。最安全的使用Transactional Client是使用一個(gè)單獨(dú)的Polling Consumer,但是這不會(huì)是一個(gè)令人滿意的解決方案。 這里特別要提到應(yīng)該會(huì)保證成功的JMS風(fēng)格的MDB,EJB的一種。一個(gè)MDB是一個(gè)消息消費(fèi)者,它即使一個(gè)Event-Driven Consumer又是一個(gè)支持J2EE分布式事務(wù)的Transactional Client,并且它可以作為Competing Consumers動(dòng)態(tài)的池化,甚至作為一個(gè)Publish-Subscribe Channel。這是在一個(gè)自由的應(yīng)用中實(shí)現(xiàn)這些是一個(gè)困難且乏味的組合,但是這個(gè)功能作為一個(gè)EJB容器的內(nèi)建的功能被提供。(MDB框架如何實(shí)現(xiàn)的?本質(zhì)上,容器通過一個(gè)動(dòng)態(tài)改變大小的可重用的執(zhí)行者的線程池來實(shí)現(xiàn)了一個(gè)Message Dispatcher,在那里每個(gè)執(zhí)行者自己使用自己的session和事務(wù)來消費(fèi)消息。) 最后,緊記一個(gè)單獨(dú)的Message Endpoint可以很好結(jié)合幾個(gè)不同的模式。一組Competing Consumers可以被作為Polling Consumers實(shí)現(xiàn),同時(shí)也可以是一個(gè)Selective Consumers并且可以作為一個(gè)Service Activator調(diào)用一個(gè)應(yīng)用的service。 一個(gè)Message Dispatcher可以是一個(gè)Event-Driven Consumer和一個(gè)使用Messaging Mapper的一個(gè)Durable Subscriber。無論一個(gè)endpoint實(shí)現(xiàn)什么模式,它總是一個(gè)Messaging Gateway。所以,不要考慮使用哪種模式 - 而要考慮如何結(jié)合他們。這是使用模式解決問題的魅力所在。 要實(shí)現(xiàn)一個(gè)Message Endpoint有很多選擇。Message Endpoint模式用于解釋這些選擇是什么以及如何最好的使用它們。 posted @ 2005-11-22 21:40 fisher 閱讀(2091) | 評論 (2) | 編輯 收藏 【ESB專題】之四 - Message Transformation及其相關(guān)模式通常,通過消息系統(tǒng)集成的應(yīng)用很少有同樣的消息格式。比如說,一個(gè)帳務(wù)系統(tǒng)同一個(gè)CRM系統(tǒng)對客戶對象是有著不同的概念的。基于這個(gè),一個(gè)系統(tǒng)可能將消息存儲在關(guān)系表中,另一個(gè)可能存儲在文件中。集成已存在的系統(tǒng)通常意味著我們沒有修改系統(tǒng)以便使他們更好的一起工作的自由。然而,集成方案不得不協(xié)調(diào)和解決各種系統(tǒng)之間的不同。Message Translator模式提供了一個(gè)通用的解決方案。這里解釋幾種特定的Message Translator。 Message Transformation包含以下幾種模式: l Envelope Wrapper l Content Enricher l Content Filter l Claim Check l Normalizer l Canonical Data Model 大多數(shù)消息系統(tǒng)放置特定的需求在消息頭的格式和內(nèi)容中。我們包裝有效數(shù)據(jù)到一個(gè)Envelope Wrapper中以適應(yīng)消息基礎(chǔ)設(shè)施的需求。如果消息需要穿過不同的消息基礎(chǔ)設(shè)施,可以結(jié)合多個(gè)Envelope Wrapper。 如果原始系統(tǒng)不能提供目標(biāo)系統(tǒng)需要的數(shù)據(jù)域,可以使用一個(gè)Content Enricher。它可以查找缺少的信息并從已有數(shù)據(jù)中計(jì)算出它。Content Filter正好相反,它從消息中刪除不需要的數(shù)據(jù)。Claim Check也從消息中刪除數(shù)據(jù),但是它將存儲他們以便以后取回。Normalizer將多個(gè)不同格式的消息翻譯成統(tǒng)一格式。 消除依賴 消息轉(zhuǎn)換在集成中是一個(gè)很深的話題。Message Channels和Message Routers可以通過消除應(yīng)用必須知道另外一個(gè)應(yīng)用的位置的需求從而解除應(yīng)用間的基本依賴。 一個(gè)應(yīng)用可以發(fā)送一個(gè)消息到Message Channel而不必?fù)?dān)心誰來取出消息。然而消息格式增加了另外一種依賴。如果一個(gè)應(yīng)用不得不將消息格式化成另外一個(gè)應(yīng)用的數(shù)據(jù)格式,通過Message Channel解耦的說法就像一個(gè)幻想。接收系統(tǒng)的任何改變或切換到另外一個(gè)接收系統(tǒng)都需要對發(fā)送應(yīng)用進(jìn)行改變。Message Translators可以幫助除去這種依賴。 元數(shù)據(jù)管理 將消息從一個(gè)消息格式轉(zhuǎn)換到另一個(gè)格式需要操作元數(shù)據(jù) - 描述數(shù)據(jù)格式的數(shù)據(jù)。 元數(shù)據(jù)在兩個(gè)并行系統(tǒng)之間的集成中扮演著非常重要的角色。一個(gè)處理實(shí)際的消息數(shù)據(jù),另外一個(gè)處理元數(shù)據(jù)。許多用于處理消息數(shù)據(jù)的模式也同樣可以管理元數(shù)據(jù)。比如說,Channel Adapter不僅可以從一個(gè)系統(tǒng)中移進(jìn)和移出消息,還可以從一個(gè)外部應(yīng)用中獲取元數(shù)據(jù),并將其加載到一個(gè)元數(shù)據(jù)倉庫中。使用這個(gè)倉庫,集成開發(fā)者可以定義應(yīng)用元數(shù)據(jù)與Canonical Data Model.之間的轉(zhuǎn)換。 元數(shù)據(jù)集成
消息系統(tǒng)外的數(shù)據(jù)轉(zhuǎn)換 這些轉(zhuǎn)換模式組成的很多原則可以被應(yīng)用于非消息集成。比如說,File Transfer可以執(zhí)行系統(tǒng)間的轉(zhuǎn)換工作。類似的,Remote Procedure Invocation必須使請求使用要調(diào)用的service的格式,即使應(yīng)用本身的格式可能不同。典型的,需要調(diào)用程序來執(zhí)行轉(zhuǎn)換。一些最成熟的轉(zhuǎn)換引擎組成了ETL工具,比如Informatica或者DataMirror。這些工具一般都一次轉(zhuǎn)換大量的數(shù)據(jù),而不是轉(zhuǎn)換單個(gè)消息。 Message System應(yīng)專注于幾種基本的Message Translator模式。而不應(yīng)該關(guān)心實(shí)體間結(jié)構(gòu)轉(zhuǎn)換的細(xì)節(jié)(不同的數(shù)據(jù)模型之間的轉(zhuǎn)換,比如ER模型不支持多對多關(guān)系而其他的支持這種)。關(guān)于這個(gè)主題最老也使最相關(guān)的書是Kent的《Data and Reality》。 posted @ 2005-11-21 21:40 fisher 閱讀(1615) | 評論 (1) | 編輯 收藏 【ESB專題】之三 - Message Construction及其相關(guān)模式在前面的關(guān)鍵組件中我們提到了Messages。當(dāng)兩個(gè)應(yīng)用想要交換數(shù)據(jù),他們將數(shù)據(jù)包裝在一個(gè)message中。但是一個(gè)Message Channel不能傳輸原始數(shù)據(jù),它只能傳輸包含在一個(gè)message中的數(shù)據(jù)(即傳輸特定格式的數(shù)據(jù))。 Message在消息系統(tǒng)中處于信息載體的位置,而在ESB中,還消息識別、序列以及生存周期等職責(zé)。 Message的結(jié)構(gòu)涉及以下幾個(gè)模式: l Command Message l Document Message l Event Message l Request-Reply l Return Address l Correlation Identifier l Message Sequence l Message Expiration l Format Indicator 創(chuàng)建和發(fā)送一個(gè)Message產(chǎn)生以下幾個(gè)問題: 消息意圖 - Message最終是為了運(yùn)送一些數(shù)據(jù),但是發(fā)送者可能有其他目的,比如它希望接受者使用消息做些事情。它可以發(fā)送一個(gè)Command Message,指定它希望調(diào)用的接受者上的函數(shù)或方法。發(fā)送者告訴接受者運(yùn)行那些代碼。發(fā)送者可以發(fā)送一個(gè)Document Message來傳送它的數(shù)據(jù)結(jié)構(gòu)到接受者。發(fā)送者發(fā)送數(shù)據(jù)到接受者,但是不指定接受者應(yīng)該做什么。 或者它可以發(fā)送一個(gè)Event Message,通知接受者發(fā)送者那里有一個(gè)改變。發(fā)送者不應(yīng)告訴接受者應(yīng)該怎樣適應(yīng)這個(gè)改變,而只應(yīng)提供通知。 返回一個(gè)應(yīng)答 - 當(dāng)一個(gè)應(yīng)用發(fā)送一個(gè)消息,它通常期望得到一個(gè)回應(yīng)來確定消息被處理并提供一個(gè)結(jié)果。這是一個(gè)Request-Reply場景。Request通常是一個(gè)Command Message,而應(yīng)答是一個(gè)包含返回值或異常的Document Message。請求者應(yīng)該在請求中指定一個(gè)Return Address來告訴應(yīng)答者使用哪個(gè)通道來傳回應(yīng)答。請求者可能在一個(gè)處理過程中發(fā)送多個(gè)請求,所以應(yīng)答應(yīng)該包含一個(gè)Correlation Identifier來指出這個(gè)應(yīng)答對應(yīng)哪個(gè)請求。 有兩個(gè)Request-Reply場景需要注意;它們都包含了一個(gè)Command Message請求和一個(gè)對應(yīng)的Document Message應(yīng)答。在第一個(gè)場景中,Message RPC,請求不但要調(diào)用應(yīng)答者的函數(shù),而且期望一個(gè)返回值。這是RPC。另一個(gè)場景中,Message Query,請求者執(zhí)行一個(gè)查詢;應(yīng)答者執(zhí)行查詢并在應(yīng)答中返回結(jié)果。這是遠(yuǎn)程查詢。 大量的數(shù)據(jù) - 有時(shí)應(yīng)用想要傳送大量的數(shù)據(jù)結(jié)構(gòu),放入一個(gè)單獨(dú)的message里面不是很合適。在這種情況下,將他們分解成可管理的消息塊并將他們作為Message Sequence發(fā)送。這些消息必須按順序發(fā)送,以便接受者能夠充足原始數(shù)據(jù)結(jié)構(gòu)。 慢速消息 - 消息系統(tǒng)的一個(gè)問題是發(fā)送者通常不知道接受者要多久才能接受到消息。然而,消息的內(nèi)容可能是時(shí)間敏感的,所以如果消息在某一時(shí)間內(nèi)沒有被接受,它將被忽略并取消。在這種情況下,sender應(yīng)該使用Message Expiration來指定一個(gè)到期時(shí)間。如果消息系統(tǒng)在規(guī)定時(shí)間內(nèi)無法傳輸一個(gè)消息,應(yīng)該將它取消并刪除到Dead Letter Channel中。同樣的一個(gè)receiver接受到一個(gè)超出該時(shí)間點(diǎn)的消息,也要取消該消息。 總之,只選擇使用消息是不夠的。使一個(gè)消息工作的其他決定性因素來自于消息所要完成的任務(wù)。 posted @ 2005-11-19 20:31 fisher 閱讀(1416) | 評論 (6) | 編輯 收藏 【ESB專題】之二 - Message Channel及其相關(guān)模式在前面一個(gè)專題中,我們列出了一個(gè)ESB系統(tǒng)所需要關(guān)心的所有方面的關(guān)鍵組件,這里介紹其中的Message Channels所關(guān)注的問題及相關(guān)的模式。 Message Channel主題之下包含以下模式,分別用于解決channel中不同方面的問題: l Point-to-Point Channel l Publish-Subscribe Channel l Datatype Channel l Invalid Message Channel l Dead Letter Channel l Guaranteed Delivery l Channel Adapter l Messaging Bridge l Message Bus 當(dāng)兩個(gè)應(yīng)用需要交換數(shù)據(jù),它們通過連接兩端的channel來發(fā)送數(shù)據(jù)。發(fā)送的應(yīng)用可能不知道哪個(gè)應(yīng)用將接受數(shù)據(jù)。然而,通過選擇特定的channel來發(fā)送,發(fā)送者知道接受者將是守候在channel另一端等待數(shù)據(jù)的應(yīng)用之一。通過這種方式,生產(chǎn)數(shù)據(jù)的應(yīng)用有了一個(gè)同數(shù)據(jù)消費(fèi)者通訊的途徑。 Message Channels面對的各個(gè)主要問題: 如果一個(gè)應(yīng)用要傳輸或接受數(shù)據(jù),它一定會(huì)用到一個(gè)channel。問題是你的應(yīng)用要知道要使用什么樣的channel,以及用它來做什么。 固定的channel集合 - Channel中討論的一個(gè)主題是,一個(gè)應(yīng)用可用的Message Channel集合一般是固定的。設(shè)計(jì)一個(gè)應(yīng)用時(shí),一個(gè)開發(fā)者必須知道將某種類型的數(shù)據(jù)放到哪里可以同其他應(yīng)用共享該數(shù)據(jù),以及從什么地方可以找到其他應(yīng)用的特定數(shù)據(jù)。這些通訊路徑不會(huì)在運(yùn)行期動(dòng)態(tài)的創(chuàng)建和發(fā)現(xiàn);它們需要在設(shè)計(jì)期間就確定下來,以便應(yīng)用知道它的數(shù)據(jù)從哪里來以及數(shù)據(jù)將去哪里。( 雖然大多數(shù)channel必須被靜態(tài)定義使正確的,但是也有例外,有些情況下動(dòng)態(tài)channel是很好用的。一個(gè)例外就是Request-Reply模式中的reply channel。請求者可以創(chuàng)建或者獲得一個(gè)應(yīng)答者不知道的新的channel,并在請求消息中指定該channel為Return Address,應(yīng)答者就可以使用它。另外一個(gè)例外是支持集成channels的消息系統(tǒng)實(shí)現(xiàn)。一個(gè)接受者可以訂閱一個(gè)集成體系的根channel,然后發(fā)送者可以發(fā)布消息到一個(gè)子channel,而接受者不需要知道子channel,仍然會(huì)收到消息。這些都是不常見的情況,channel通常仍然是在部署之前被定義,并且應(yīng)用被設(shè)計(jì)連接到一個(gè)已知的channel集合 )。 決定channel的集合 - 一個(gè)相關(guān)的主題是,誰決定那些Message Channel是可用的 - message系統(tǒng)還是應(yīng)用程序?換句話說,是由消息系統(tǒng)確定一些channel,然后要求應(yīng)用程序使用它們?還是應(yīng)用決定它們需要什么channel,然后要求消息系統(tǒng)提供它們?這個(gè)問題沒有一個(gè)簡單的答案,設(shè)計(jì)必須的channel集合是迭代的。首先,應(yīng)用要決定消息系統(tǒng)提供哪些channel。然后應(yīng)用將圍繞這些channel設(shè)計(jì)它們的通訊,但是如果這樣是不可行的,它們將需要添加額外的channel。當(dāng)一些應(yīng)用已經(jīng)使用了一個(gè)確定的channel集合,當(dāng)加入新的應(yīng)用,它們將使用已存在的channel。當(dāng)為應(yīng)用添加新的功能,它們需要新的channel。 單向channel - 另外一個(gè)經(jīng)常引起混淆的是一個(gè)Message channel是單向的還是雙向的。技術(shù)上來說,兩者都不是,一個(gè)channel更像是一個(gè)桶,一個(gè)應(yīng)用放入數(shù)據(jù),另外一個(gè)應(yīng)用從中取出數(shù)據(jù)。但是由于數(shù)據(jù)是放在消息中從一個(gè)應(yīng)用傳到另一個(gè),這使得channel具有方向性,使它變成單向的。如果一個(gè)channel是雙向的,應(yīng)用將從中發(fā)送和接受數(shù)據(jù),雖然技術(shù)上是可行的,但是會(huì)有小小的問題,應(yīng)用將有可能持續(xù)的取出自己放進(jìn)去的希望發(fā)送給其他應(yīng)用的消息。所以,為了實(shí)踐性的目的,channel是單向的。作為結(jié)論,兩個(gè)應(yīng)用如果有雙向通訊,它們需要兩個(gè)channel,每個(gè)方向一個(gè)。 如何使用Message channels: 現(xiàn)在我們來討論以下如何使用channel。 一對一或者一對多 - 當(dāng)你的應(yīng)用共享一些數(shù)據(jù),你希望只將它共享給一個(gè)應(yīng)用還是對它感興趣的所有應(yīng)用?要傳送數(shù)據(jù)到一個(gè)單獨(dú)的應(yīng)用,使用Point-to-Point Channel。這并不意味著發(fā)送到這個(gè)channel的每個(gè)數(shù)據(jù)都發(fā)送給同樣的接受者,因?yàn)橐粋€(gè)channel可能有多個(gè)接受者。它意味著,實(shí)際上,保證每個(gè)數(shù)據(jù)都被同一個(gè)應(yīng)用接收。如果你想讓所有接收應(yīng)用都能接收數(shù)據(jù),使用Publish-Subscribe Channel。當(dāng)你通過這種方式發(fā)送數(shù)據(jù),channel將高效的復(fù)制數(shù)據(jù)到每一個(gè)接收者。 什么類型的數(shù)據(jù) - 任何內(nèi)存中的數(shù)據(jù)都有一個(gè)類型。另一方面,所有數(shù)據(jù)都是一些bytes集合。消息系統(tǒng)工作同這類似,消息內(nèi)容必須符合某些類型以便接受者了解數(shù)據(jù)的結(jié)構(gòu)。Datatype Channel認(rèn)為在一個(gè)channel中的數(shù)據(jù)必須擁有同樣的類型。這也是為什么消息系統(tǒng)需要很多channel的主要原因(每個(gè)channel一種格式)。如果數(shù)據(jù)可以是任意的格式,那么消息系統(tǒng)在兩個(gè)應(yīng)用之間只需要兩條channel。 無效的和過期的消息 - 消息系統(tǒng)可以確定消息被正確的傳輸,但是它不能保證接受者知道如何處理它。接收者對數(shù)據(jù)格式和意義存在期望。當(dāng)它接收到一個(gè)不符合期望的消息,它什么也不能做。它們能作的,就是將這個(gè)陌生的消息放入到一個(gè)特別設(shè)計(jì)的Invalid Message Channel并希望某些監(jiān)控這個(gè)channel的工具能夠取出這個(gè)消息,并指出該如何處置它們。許多消息系統(tǒng)有一個(gè)類似的內(nèi)建特征,一個(gè)Dead Letter Channel,用來存放成功送出但卻無法成功投遞的消息。另外,一個(gè)系統(tǒng)管理工具應(yīng)該監(jiān)視Dead Letter Channel并且決定如何處置這些無法投遞的消息。 故障檢測 - 如果一個(gè)消息系統(tǒng)發(fā)生故障或停機(jī)維護(hù),它的消息會(huì)怎樣?當(dāng)它重啟并重新運(yùn)行,它的消息能否還在它的channel中?默認(rèn)的:不會(huì);channel將消息存儲在內(nèi)存中。然而,Guaranteed Delivery將channel持久化以便將它們的消息存儲到硬盤上。這會(huì)影響效率,但會(huì)使消息更加可靠,即使消息系統(tǒng)是不可靠的。 非消息客戶端 - 如果一個(gè)應(yīng)用不能連接到一個(gè)消息系統(tǒng)但是仍然想要參與消息怎么辦?通常它只能自認(rèn)倒霉了,但是如果消息系統(tǒng)可以通過某種方式連接到應(yīng)用系統(tǒng) - 通過它的用戶界面,它的service API,它的數(shù)據(jù)庫,或者一個(gè)TCP/IP或HTTP這樣的網(wǎng)絡(luò)連接 - 那么消息系統(tǒng)可以使用一個(gè)Channel Adapter。這允許你連接到一個(gè)或多個(gè)連接到應(yīng)用的channel而不必改變應(yīng)用或者可能也不需要一個(gè)同應(yīng)用運(yùn)行在同一個(gè)機(jī)器上的消息客戶端。有時(shí)‘非消息客戶端’真的是一個(gè)消息客戶端,但是只有連接的是其他消息系統(tǒng)的時(shí)候。 通訊中樞 - 隨著越來越多的企業(yè)應(yīng)用系統(tǒng)連接到消息系統(tǒng)以便通過消息暴露他們的功能,消息系統(tǒng)變成了企業(yè)中一站式功能的集散地。一個(gè)應(yīng)用只需簡單的知道用哪個(gè)channel來請求功能,以及從哪個(gè)監(jiān)聽結(jié)果。消息系統(tǒng)本質(zhì)上變成一個(gè)消息總線,一個(gè)提供所有企業(yè)應(yīng)用甚至變化中的應(yīng)用和功能的中樞。你可以更快速的集成。 如你所見,使用消息構(gòu)建應(yīng)用不僅僅是將他們連接到消息系統(tǒng)并發(fā)送消息。消息必須使用Message Channel來發(fā)送。Channel必須被設(shè)計(jì)為某個(gè)目的服務(wù),比如基于被共享的數(shù)據(jù)類型,共享數(shù)據(jù)的應(yīng)用類型,和接收數(shù)據(jù)的應(yīng)用。 posted @ 2005-11-17 22:56 fisher 閱讀(1296) | 評論 (1) | 編輯 收藏 【ESB專題】-面向消息的EAI的關(guān)鍵組件企業(yè)集成有很多種模式,隨著技術(shù)的發(fā)展,實(shí)時(shí)的、面向消息的企業(yè)集成越來越成為主流,面向消息的企業(yè)集成的穩(wěn)定性和兼容性要求其基礎(chǔ)件,也就是message系統(tǒng)必須提供足夠強(qiáng)壯和可擴(kuò)展的設(shè)計(jì),下面幾種是作為面向消息的企業(yè)集成的基礎(chǔ)件所必須提供的幾個(gè)關(guān)鍵性組件。 消息集成使得message系統(tǒng)負(fù)責(zé)轉(zhuǎn)換兩個(gè)應(yīng)用之間的數(shù)據(jù)格式,從而使得應(yīng)用可以專注于他們需要共享什么數(shù)據(jù)而不是如何共享它們。
Channels — Messaging應(yīng)用通過一個(gè)Message Channel傳送數(shù)據(jù),一個(gè)sender到receiver的虛擬管道。一個(gè)新安裝的消息系統(tǒng)默認(rèn)不包含任何channel;你必須知道你的應(yīng)用需要怎樣通訊,然后才能建立channel來完成它。 Messages — Message是在channel上傳輸?shù)牟豢煞指畹陌R虼耍瑸榱藗鬏敂?shù)據(jù),應(yīng)用必須將數(shù)據(jù)打包成一個(gè)或多個(gè)packets,將每個(gè)packet包裝成一個(gè)message,然后將其傳輸?shù)揭粋€(gè)channel。同樣的,一個(gè)receiver應(yīng)用在接受到message后必須從message中提取出數(shù)據(jù)才能使用。Message系統(tǒng)應(yīng)該能重復(fù)的傳輸message,直到它成功為止。 Pipes and Filters — 最簡單的情況下,message系統(tǒng)將一個(gè)消息直接從sender計(jì)算機(jī)傳送到receiver計(jì)算機(jī)。然而,通常在消息從sender中發(fā)出后,receiver接受到之前,有一些動(dòng)作需要對message執(zhí)行。舉例來說,message也許需要驗(yàn)證或者轉(zhuǎn)換。Pipes and Filters架構(gòu)使用channel將多個(gè)處理步驟連接起來。 Routing — 在一個(gè)大型的、擁有許多不同的應(yīng)用和channel連接的企業(yè)應(yīng)用中,一個(gè)message可能需要穿過多個(gè)channel才能到達(dá)最終目的地。Message的路由如此復(fù)雜以至于最初的發(fā)送者無法知道那些channel能將message傳送給最終的receiver。因此,最初的發(fā)送者將message發(fā)送給一個(gè)Message Router,一個(gè)以Pipes and Filters架構(gòu)中的filter形式存在的應(yīng)用組件。Router將決定如何將message發(fā)送到最終receiver或者至少是下一個(gè)Router。 Transformation — 不同的應(yīng)用的數(shù)據(jù)格式可能不同。為了調(diào)節(jié)sender和receiver之間的數(shù)據(jù)格式不同的問題,message必須經(jīng)過一個(gè)中介的filter,一個(gè)Message Translator,它將message從一個(gè)格式轉(zhuǎn)換成另外一個(gè)格式,或轉(zhuǎn)換成一個(gè)公共的格式。 Endpoints — 大多數(shù)的應(yīng)用程序沒有內(nèi)建的能力來同一個(gè)message系統(tǒng)交互。因此他們必須包含一個(gè)中間層,它知道應(yīng)用系統(tǒng)如何工作,也知道message系統(tǒng)如何工作,并橋接兩個(gè)系統(tǒng)。這個(gè)系統(tǒng)是一組并列的Message Endpoints,它能夠使得應(yīng)用發(fā)送和接受message。 System manager - 作為一個(gè)大型的消息集成系統(tǒng),其面向消息的、異步、低耦合的本質(zhì)使得系統(tǒng)更加難以調(diào)試,運(yùn)行期的狀態(tài)也難以跟蹤,所以,我們必須有強(qiáng)有力的手段進(jìn)行系統(tǒng)的運(yùn)行期管理和監(jiān)控,同時(shí)最好能夠在運(yùn)行進(jìn)行動(dòng)態(tài)更新,以保障系統(tǒng)的強(qiáng)壯性。 posted @ 2005-11-16 20:56 fisher 閱讀(2335) | 評論 (6) | 編輯 收藏 |
|||||||||