我在網路上看了諸多評論「高鐵訂票系統」重複訂位相關問題的文章與討論串,大部分的 IT 人,謾罵聲不斷,認為該檢討承包系統開發的廠商;也有一小部份人提出自己的看法與建議的解決方案。這非常好,系統的不穩定性造成民眾的不便,本來就該有人監督,廠商也應該虛心接受眾多人所給予的建議。個人並不打算批判,以擔任軟體架構顧問的角度來看此事件時,先找出根本的問題是什麼,然後再提出具體的解決方案。我打算分兩篇文章論述,一篇為觀念篇;另一為實作篇。觀念部分,希望能就系統的結構性來探討;實作部分則會提出整個系統分析設計的過程與實作碼的產出,同時也打算模擬數千至數萬人同時訂票的情境與意外的處理,應該是盡量會接近原廠商所使用的平台(J2EE Solution)。當然,個人更是歡迎,若有機會,原廠商可以找我們過去聊聊,我們絕對很樂意效勞,也願意更進一步說明我們所診斷出來的問題,並且提供開出的處方為何。
一般看待高鐵訂票系統之所以出問題,原因有二:
- 經營者的看法與實際使用有落差:
持這種觀點的人,主要是著眼在經營者提出利用「飛機訂票系統」的觀念來實做高鐵的訂位,實際上並不恰當,飛機的訂位主要是預定「航班」,而實際的劃位則必須在各自的機場櫃臺進行Check-in,這與高鐵的座位預售,明顯有相當大的差距。 - 實做平台的考量上,未考慮到分散式交易:
這種看法大多是資訊專業人員的看法,也就是說,由於未考慮到各售票單位(包括櫃臺以及售票機)對於某一個已訂位的位置的交易,造成在同一時間內,多個售票單位可以販售同一個位置的現象,這主要是屬於「Transaction Lock」的問題。
事實上,這兩個問題都是存在的,然而,這卻不是造成高鐵訂票系統出問題的「主要原因」! 無論是持哪種看法,其實都是「見樹不見林」,忽略了整體軟體設計最重要的核心 – 「軟體結構」的問題。
先從第一個觀點說起:
使用者需求本來就是會不斷地變動,然而,身為軟體設計人員,在開始進行系統分析設計時,本來就應該要想到「使用者需求」是「暫時」的,然而,重點應該是在於軟體結構本身,能不能夠充分地配合使用者需求的變動而有所彈性;因此,把系統出問題怪罪到使用者需求的變動,是軟體設計人員的「墮落」!
從上述的例子來說,使用者雖然在一開始就提出了不正確的需求,但是,當管理者在上線前一、兩個月就發現了這個「重複訂位」的問題,軟體設計人員卻沒有辦法在這段期間內修復這個問題,這很明顯地,並非是單純的「需求變動」而已,勢必是整體的軟體結構發生了大問題,造成了「地基不穩」,以致於「挖東牆補西牆」,永遠沒有辦法確實解決這個問題。
再從第二個觀點來看:
Transaction 的問題,其實是資訊系統管理面「最基本」的問題,套用前述的觀點,怎麼有可能在一、兩個月前發現這個問題,卻拖了一、兩個月都沒有辦法解決,這也很明顯地,勢必是在結構上出了嚴重的問題,以致於根本沒有辦法對症下藥。
那麼,軟體結構究竟是出了什麼問題呢? 以下,我們就上述兩個現象分別來說明:
第一個現象主要是軟體的整體結構不夠穩定,而且缺乏彈性,因此,當使用者的「企業規則」(Business Rule)有所變動時,系統沒有辦法快速因應。
這很明顯地,是設計人員在設計系統時,並沒有針對企業的應用系統結構進行良好的分析,致使在捕捉系統的「本質性物件(Essential Object)」時,出了大問題。本質性物件沒有辦法捕捉好,自然而然對於整體系統的未來彈性,就很容易出嚴重的問題。什麼叫「本質性物件」呢? 其實就是無論企業的作業流程(Process Flow)或是企業的使用者需求(User Requirement)如何變動,但是其基本的結構都不會輕易改變的那些重要概念(Essential Concept),就是所謂的本質性物件。
我們以高鐵訂票系統為例,其本質性物件其實非常單純,我們以 UML 標準的 類別圖(ClassDiagram)來表達:
從這張圖中,其實就可以看出個端倪:
左下角的兩個物件:Seat 與 班次,主要是由高鐵人員自行維護的相關基本資料,然而,所有的重點應該在於「訂票交易」與「訂票Demand」這兩個物件上。
從訂票交易來說,其只要能夠提供起站及下車站給「訂票Demand」的物件,不管究竟是像飛機的依班次決定是否有空位;或是像現在高鐵實際營運的依特定座位決定是否有空位,其實,該訂票Demand物件只要回答「可不可以訂位」就可以了!
至於其實做的相關細節,應該都被隱藏在「Specific 班次」以及「SpecificSeat」兩個子型態(SubType)的物件中。
這樣設計的結構最大的好處是:
當我們發現未來高鐵的軟硬體設施真的如同飛機一樣,可以讓乘客先行訂位,之後才在各自搭乘的櫃臺進行「Check-in」以確認其真實的位置,此時,我們只要再重新「Plug-in」「Specific 班次」的物件到高鐵的訂票系統中就可以了!
至於第二個問題,則是整體 IT 結構規劃的問題。也就是說,由於沒有對整體的系統結構作一個有效的區分,而導致 系統面 與實際 問題領域(ProblemDomain) 面糾纏不清,大幅增加了整體應用系統的複雜度與管理成本。這個部分的問題,其實可以用 "Boundary-Control-Entity" 的 分析層次的設計框架 來予以解決。關於實作的相關設計議題,我們留待實作篇再來討論。
訂閱 RSS (by FeedBurner)
訂閱 RSS (by Wordpress)


根據我的經驗,高鐵訂票系統的這些問題根本是不應該發生的。稍有一點 Database System Management 經驗的都會知道 Transaction Locking 及 Loading 的 issues. 不只鐵路系統用到,任何 Business Transaction 都要考慮到的。 比起Wall Street 的交易,這個只是幼稚園的難度。
我比較好奇的是高鐵公司如何外包、選擇廠商、合約內容、有無求償。在商業上走的是正常的路,還是後面開小門靠關係。
技術一點都不是問題,問題在經營者的是否光明正大。如此而已!
Hi 昆蟲:
其實如我文中所述, Transaction Lock 是個問題,但不是主要的問題,個人是認為,軟體的結構設計,出了根本性的問題。
「漫談高鐵訂票系統的結構分析—觀念篇」之我見
對克明兄的漫談高鐵訂票系統的結構分析—觀念篇〉,有網友回應:
根據我的經驗,高鐵訂票系統的這些問題根本是不應該發生的。稍有一點 Database System Management 經驗的都會知道 Transaction Loc…
從高鐵的售票系統與台彩的售票系統來看,都可以看出一個端倪:
就是對這種在短時間內會有大量資料要處理的系統搞不定
這在實作的技術面上的確有其難度與訣竅,不是光從系統分析就有辦法可以解決的,不過良好軟體架構是最基本的,但關鍵在其實作面,不過在大家在技術層次上大加撻伐的同時,是否有考慮過一件事情:
如果你就是這些技術人員,在一個需要3個月時間才能完成的計劃裏,遇到一個完全不了解軟體開發的主管,不顧底下技術人員的反應,定出3天就能完成計劃的偉大夢想,讓除了這些技術人員之外的所有人都做著這樣的春秋大夢….
如果你是這些技術人員,3天後你是要交出你用URL分析出的各種圖表呢?還是一個漏洞百出但還可以撐一下下場面的程式呢?
我想如果你用這樣的角度來看事情的話,這些結果就一點都不難理解了.
我只能說國內的軟體業充斥著太多這樣的現象:
1.外行領導內行
2.短視近利,只想快速獲得蠅頭小利,或者先開出天方夜譚的條件,先搶到這個專案再說,從不想真正花時間好好深入去研究,培養人才,反正船到橋頭自然直,問題遇到了再說
對於主管來說
明天程式就要交了
什麼URL?!
我看應該是U aRe Late!!!!
Hello stevenchen:
實做面的技術是必然要達成的,不過呢,仍如文中所述,要能把最根本的結構面給顧好。
後面您所提的論述,算是業界的常態了,個人並不打算再提文去抱怨這類的事情的,作自己認為該走的方向,走下去,心態調適開心就好了。
在我看來
第一個問題要怪罪軟體的人士不合理的, 若是從開始討論軟體規格時都沒有提到可能會要直接賣票而不是只有預定的座位. 那麼從軟體規劃到實作的人不可能加入一個不會實現的功能在那裡. 時間就是金錢專案已經很趕了, 誰還敢加入一些有的沒有的. 這只能夠怪決策者決策錯誤. 軟體的人只是揹黑鍋. 其實要改可以, 就要退到一開始的設計階段, 我想沒人可以承擔這的後果.
第二個問題那真的是軟體的錯了, 最簡的的交易原則都沒有把握. 系統規劃的人真該打.
我相當期待後續要模擬數千至數萬人同時訂票的情境! 但如果以實作來想是否應該會對J2EE伺服器端採用叢集的方式(JBoss Clustering)整合中間層多台MQ Server來進行? 模擬方式是否會以上述架構進行測試?
p.s 我日前才上完HSDC的UML課程,那時上課有提到你們也有使用JBoss! ^_^
Hi Oldbass:
我並不打算批判專案管理與整合測試等議題,我的本意是希望軟體人員能重視根本性的結構設計問題。
很可惜,我這一篇文章發表以來,雖然得到不少迴響,到竟然連一個人都沒有對圖中的類別設計圖來討論。
Hi PiPPen:
是否採用 Cluster & MQ,在測試的實作,其實沒那麼必要,那算是效能上測試的範疇。而現在最為重要的,反而是驗證結構與交易處理機制的測試。
不要一次把所有的議題全給考量進來,那反而會失焦,而沒有真正凸顯出重點來。
We are the first place of
JavaBase OpenSource SOA-ERP/CRM
in SourceFroge……………..
用UML畫出Client主動更新車次座次表
哪是想要提款機想主動更新銀行主機帳戶金額
會死得很慘
不是 Data Lock Only
Where is AP Server – SOA each Server for each Day and each thread for each train….
Make right thing better than
Make thing right
我看了一下 UML 圖,老實說,英文有句話 The Devil is in the Detail. 要用一個簡單的 UML 去找出高鐵軟體問題是不可能的。(何況他們的 UML 可能會完全不同於你的圖)
高鐵不是六個月完成的,但是發現訂票軟體的問題像是「一覺醒來,什麼都不對了。」
硬體做得那麼好,訂票軟體做得那麼爛,不是很奇怪嗎?
Hi 昆蟲先生:
我這一張 UML 結構圖是表達的 "單純",但本身並不簡單喔。光是這個: 班次 – Specific班次, 其深意您倒是可以思考解讀看看,看看是否能用實際的 instance(個體) 來解釋。
還有,當然也不是用那麼四個類別就可以解決訂票的結構問題,該系統可能會需要有上百個類別。但問題是,若最核心的部分都有問題的話,其它的還用談嗎?
我到很希望,只要就這四個類別,來確認高鐵是否也有類似於此的結構?(我的推測應該是沒有)。至於其它的衍生類別,說真的,要長出來百來個不是什麼難事的。
Do right thing better than
Do thing right
機械製圖無法指導汽車工程的方向
UML製圖無法指導軟件工程的方向
昆蟲 你想太多了….
錄音師無法取代歌手
好好畫圖
容易溝通
不然 Rose 早幹掉 BEA / SAP / Oracle
我覺得自從這次高鐵的售票系統出包之後,網路上就有不少IT的業者就軟體的觀點提出它們的見解,不過我覺得大家好像都沒有真正切中問題的核心:
系統為什麼當掉?
很多人想到database Transaction Lock 與 loading 的 issues? 對,多數人都只看到這一層,Transaction Lock 的確是會讓系統看起來好像是當掉,但事實上一開始只是不會動,最後因為積了一大堆的Transaction程式才有可能當掉,問題是Transaction Lock解決了之後系統就不會當了嗎?是嗎?
database loading 太重時,系統看起來反應慢到好像當掉,最後真的有可能會因為這樣的原因真的當掉,那怎麼辦?
換更快的機器?
調database的參數?
如果這樣loading還是太大!? 那怎麼辦?
Adempiere提到:
Where is AP Server – SOA each Server for each Day and each thread for each train….
那負責除夕那天下班後的那班自強號,某個server的某個thread一定會很忙吧? 會不會忙到反應也像是當掉一樣的慢呢?
不過至少算是看到另一層面的解法了…
那班自強號,某個server的某個thread一定會很忙吧
No,
Each Train total seats is fix, why can get more work…
No.Busy
Sir..
Use SOA Please Don’t Lock data
Because each train belong one SOA thread,
Only this thread can update this table,
Why need Lock table,
You know data-lock is heavy duty for a database…….
祝你年年賺大錢
精細的流程展現
無法解決錯誤的架構
錯誤的高速公路交流道規劃
無法用施工品質來解決錯誤的規劃
十哩路程才ㄧ出口/入口(Highway Exit/Entrance)
因為不是到處有
出口/入口車潮ㄧ定長又長
假如到處有出口
簡易下坡出口何需大S
錯誤的高速公路交流道規劃
無法用施工品質來解決錯誤的規劃
SOA 不是 WebService + XML + UML
是
車次座位起訖張數登錄 WebService Function
等待SOA 主動分配
取得分配 WebService Function
等待收現/刷卡/轉帳 Client Work-Station
收款確認登錄 WebService Function
SOA 主動將分配中轉到收款確認
==>Each Train total seats is fix, why can ==>get more work…
==>No.Busy
1.忙不忙"最主要"不是決定在request(在此是座位)的多寡或者固定,而是"會不會同時發生"!!
這就是即時系統與一般非即時系統的差別!!!!
一節車箱大概有30幾個位置吧?那一輛火車10個車箱,就有3百多個位置可以賣,那如果全省有三百多個人"同時"來搶買這班火車的的座位,一個thead同時service 300多個request,忙不忙?
所以平常系統不是都好好的,只是"每逢佳節必當機",不是嗎?
============================================
這個才是真正考驗系統架構與程式實作技巧之決勝點!!!
============================================
2.這樣的做法,thread"可能"的忙碌程度會隨著一輛火車所加掛的車箱數增加而提高,會有這樣的問題.
3.同樣的一個thread就代表一台火車,thread的數目會隨著火車的數目增加,在擴充性是個可能的隱憂.
==>Use SOA Please Don’t Lock data
==>Because each train belong one SOA thread,
==>Only this thread can update this table,
==>Why need Lock table,
==>You know data-lock is heavy duty for a ==>database…….
1.這樣的做法只是把lock的動作從database拿出來,拿到thread這個地方來控制同步的動作,這是對的,因為需要同步的系統總是要有一個地方在控制同步的動作,而這個動作交給database是最不明智的選擇,只是交給SOA的thread是否是明智的選擇,這我就不知道了,因為我沒有"操過"SOA的thread….
同步的這個動作,交給database與交給SOA thread來控制,對我來說,其實都一樣
==>反正就不是我在控制的,換句話說,它們的performance也不是我所能左右的,而那這樣重要的東西交給別人…
會不會太冒險了一點….
Dear Stevenchen :
You are a really good partner for SYSTEM revolution…
Welcome Skype AdempiereTaiwan
有你真好
We have many site’s WebService accept Regist and Insert Request table…
Each train’s SOA check Request allocate seats table.
Then client call WebService again check allocated seats…
==>有你真好
這是謬讚了…
==>We have many site’s WebService accept ==>Regist and Insert Request table…
==>Each train’s SOA check Request allocate ==>seats table.
==>Then client call WebService again check ==>allocated seats…
web service 是個非同步的做法,用這樣的做法來處理這種"有點"需要即時的東西(其實這種系統離真正即時還差遠了),基本上會有兩個地方會有performance的issue,如果client所call的web service是藉由網頁的話,那提供這個web service的提供者應該就是web server,web server的performance就是第一道難關要過,系統一忙,response time越久,client端就越不耐煩,越不耐煩就一直按reload再次發出request,這樣web server肯定是更忙,最後造成的是一個惡性循環,直到web server掛掉為止…
或許你可以改善web server的硬體與參數的微調,但終究效果有限,這只是隔靴搔癢而已,總之web server的performance不是你能左右的,除非這個web server是你寫的,不過這就更不可能了…
所以說實在,以我的觀點,web service並不太適合做這樣的事情,這就有點像要用腳踏車上高速公路,實在是太冒險了…
We call web-service is from Clinet-Side
can be a c++GUI/ javaGUI /dotNetGUI / Point of Sale / Browser
這樣web server肯定是更忙,
最後造成的是一個惡性循環,
直到web server掛掉為止…
You are Right..
或許你可以改善web server的硬體與參數的微調,
但終究效果有限,這只是隔靴搔癢而已,
總之web server的performance不是你能左右的,
除非這個web server是你寫的,
不過這就更不可能了…
Yes, we do.
(Not me only, web server is our product,base on JBOSS with IBM’s American RD after our world-wide team work we revolution and extend for SOA)
I know you must a SMART Profesor.
Hello stevenchen and Adempiere:
我在 HSDc 的論壇,也放了同樣一篇的文章,兩位的意見,可以至:
http://www.hsdc.com.tw/modules/newbb/viewtopic.php?topic_id=260&forum=10
讓更多的網友們參與討論。
To Adempiere:
可以思考看看,高鐵是否是 OLTP 性質的系統? 若是,那麼它適合 "loose" or "tight" coupling 的連結方式? 再來看, "web service" 是屬於 "loose" or "tight" 的性質呢?
To stevenchen:
這是屬於系統層級底層的細部設計思考議題,在細部設計的議題,是需要考量到所使用的平台特性與如何 "善用" 其特性;而個人這篇文章,是偏向於高階設計的議題,也就是結構性的設計可量。
兩個層次的設計,在實做的議題中,必須要能互補,才能達成彈性應變、穩定、效能等諸多需求。
==>We call web-service is from Clinet-Side
==>can be a c++GUI/ javaGUI /dotNetGUI / ==>Point of Sale / Browser
這就應該有救了…
==>Yes, we do.
==>(Not me only, web server is our ==>product,base on JBOSS with IBM’s American ==>RD after our world-wide team work we ==>revolution and extend for SOA)
既然這是你們的產品,那就更有救了
就看你們的功力了….
==>I know you must a SMART Profesor
錯!! 我是一個退休多時的工友了….
==>To stevenchen:
==>這是屬於系統層級底層的細部設計思考議題…
說實在,我不認為這是屬於"系統層級底層"的議題,這主要是server端的軟體架構與程式實作相關的議題
==>才能達成彈性應變、穩定、效能等諸多需求。
以實作的觀點來看,這是何等沉重的用語,而且是一個比一個沉重,真的是"說時簡單作時難"阿…
不過真的是不錯,有人能提出這樣的議題,就待您的大作詳解了,期待中….
Hi stevenchen:
>說實在,我不認為這是屬於"系統層級底層"的議題,這主要是server端的軟體架構與程式實作相關的議題
yes, 你說的沒有錯,這是 server 端的軟體結構與實做相關的議題。不過,這與我所說 "系統層級底層" 的實做與設計議題,好像沒有衝突喔。
後述你所提的,當然更是在實做最為嚴肅與實在的現實問題了,個人可從來沒有輕忽與會給簡單帶過的。
但是,需求、軟體結構(請注意,是源自 domain concept)、實做這三環,是缺一不可,我這一篇文章,旨在凸顯軟體結構的重要性,這點我在諸多 IT 人員的論述中,都不容易看得到。
非常歡迎 stevenchen 有機會參與我們所舉辦的研討會時見面討論,畢竟,片段式的文章太容易引起誤解了。
不知實作篇何時出爐?
在觀念篇中有提到,原文如下:
==>"實作部分則會提出整個系統分析設計的過程與實作碼的產出,同時也打算模擬數千至數萬人同時訂票的情境與意外的處理"
所以實作篇中應該會有這些內容:
1.整個系統分析設計的過程
2.實作碼的產出
3.打算模擬數千至數萬人同時訂票的情境
4.意外的處理
不知道我這樣有沒有斷章取義,至少我是照原文copy的…
相當令人期待的內容,引領期盼中…
Hi stevenchen:
我並不知道你真正的想法是什麼。我在文中提出會有具體的實做產出,不過,那並不是為了別人,是我們認為該做的,如是而已,所以,是否有哪些內容,那並可不一定要照你所列出的期望。
我會以為,stevenchen 你個人有自己的想法,有自己關心的實做議題,那相當好。我更會建議其實 stevenchen 可以提出自己的見解與解決方案,那會是好事。
我並不喜歡筆戰,也不喜歡就各自的觀點去捍衛與辯論,從文字對談當中,太容易引起誤會與不必要的不愉快了。
不過,若是 stevenchen 你真的有高度興趣於此話題,不妨可以約在研討會結束後,可以相互交換一些看法與觀念,這我個人是相當歡迎,因為,直接從面對面的對談當中,比較容易可以知道對方的假設點與觀點,也比較不致容易引起誤解。
==>我並不喜歡筆戰,也不喜歡就各自的觀點去捍衛與辯論,從文字對談當中,太容易引起誤會與不必要的不愉快了。
呵呵
討論到最後何時開始變成筆戰了!?…
每個人都有自己不同的觀點
這些觀點大家不一定一樣
所以才要提出來大家交換意見
這是大家就事論事討論,
只要是
===================
"言之有理","言之有物"
===================
自然就不用去捍衛與辯論什麼
如果提出的觀點是要用捍衛與辯論來維護的話
那可能就是這個觀點很難讓人認同吧…
至於我列的那四點,是從您的文章中節錄下來的,不是"我"的期望,我是沒有什麼期望啦,所以您的實作自然就不是照著"我"的期望去做的,所以不要想太多,您能暢所欲言就好了
這
就是我真正的想法
我們喜歡溫文儒雅的爭辯
我們會說對你的用心有高度的讚賞
我們會說對你的天賦有高度的景仰
我們會說對你的方向有參考的價值
我們會說對你的細節有不同的方法
機械工程師需要機械製圖師來展現機械工程的方向
軟件工程師需要UML製圖師來展現軟件工程的方向
向 RationalRose 致敬
向 UML製圖師 致敬
以前系統是 Client端的ㄧ個session
去新增與更新 ㄧ至多個Table
SOA 是 Client端的ㄧ個session
只登錄他的 Request 在 專屬的前台伺服器上
後台主動服務主機會依序服務每一個前台伺服器
需注意的是
每一個物件(Table)的Update(更新)
僅屬於一個主機的一個Thread
========================
請參照提款機的方法
更新台新銀行的存款餘額
請問可以由中華銀行的提款機
專屬的前台伺服器系統來做嗎 ?
Hi stevenchen and Adempiere:
沒想到我也不自覺地捲入兩位的爭論中,這可非我所願。
stevenchen 可能不覺得這是筆戰,若是言之有理,也不需要捍衛自己的觀點。說起來有道理。不過,我也說過,文字很容易引起片段式的誤解,還有,我很清楚討論的主題早已失焦了,這點 stevenchen 可能也是不以為然。
我其實也不是認同 Adempiere 所提的 SOA,不是不能使用 SOA,但會是 Web-Service 與 實體系統虛與實的互補,但是這以幾百個字來說明並不好解釋。而至於拿 SOA 與 Thread 來比較,這我覺得很奇怪,兩者完全是不同的層級,不同的觀點,實在無法相提並論的。
我曾經邀請 stevenchen 面對面的討論,不過沒有得到任何回應,我也希望 Adempiere 可以一起與會,大家可以就自己的想法、建議與解決方案彼此交換心得,我會覺得這會是更正面有助益的事,否則落於文字的辯論,實在很抱歉,我個人是比較覺得意義不會太大。
至於兩位的討論,我真的希望能轉移至:
http://www.hsdc.com.tw/modules/newbb/viewtopic.php?topic_id=260&forum=10
讓更多的網友們參與討論。
To Adempiere:
如果您還有興趣繼續討論的話,找個其它專業的討論區,或者貴公司有沒有什麼討論的平台,post出來,我們再來討論,比較不受打擾