我在網路上看了諸多評論「高鐵訂票系統」重複訂位相關問題的文章與討論串,大部分的 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” 的 分析層次的設計框架 來予以解決。關於實作的相關設計議題,我們留待實作篇再來討論。
40 條留言
Kenming Wang
Hi Oldbass:
我並不打算批判專案管理與整合測試等議題,我的本意是希望軟體人員能重視根本性的結構設計問題。
很可惜,我這一篇文章發表以來,雖然得到不少迴響,到竟然連一個人都沒有對圖中的類別設計圖來討論。
PiPPen
我相當期待後續要模擬數千至數萬人同時訂票的情境! 但如果以實作來想是否應該會對J2EE伺服器端採用叢集的方式(JBoss Clustering)整合中間層多台MQ Server來進行? 模擬方式是否會以上述架構進行測試?
p.s 我日前才上完HSDC的UML課程,那時上課有提到你們也有使用JBoss! ^_^
Oldball
在我看來
第一個問題要怪罪軟體的人士不合理的, 若是從開始討論軟體規格時都沒有提到可能會要直接賣票而不是只有預定的座位. 那麼從軟體規劃到實作的人不可能加入一個不會實現的功能在那裡. 時間就是金錢專案已經很趕了, 誰還敢加入一些有的沒有的. 這只能夠怪決策者決策錯誤. 軟體的人只是揹黑鍋. 其實要改可以, 就要退到一開始的設計階段, 我想沒人可以承擔這的後果.
第二個問題那真的是軟體的錯了, 最簡的的交易原則都沒有把握. 系統規劃的人真該打.
Kenming Wang
Hello stevenchen:
實做面的技術是必然要達成的,不過呢,仍如文中所述,要能把最根本的結構面給顧好。
後面您所提的論述,算是業界的常態了,個人並不打算再提文去抱怨這類的事情的,作自己認為該走的方向,走下去,心態調適開心就好了。
stevenchen
從高鐵的售票系統與台彩的售票系統來看,都可以看出一個端倪:
就是對這種在短時間內會有大量資料要處理的系統搞不定
這在實作的技術面上的確有其難度與訣竅,不是光從系統分析就有辦法可以解決的,不過良好軟體架構是最基本的,但關鍵在其實作面,不過在大家在技術層次上大加撻伐的同時,是否有考慮過一件事情:
如果你就是這些技術人員,在一個需要3個月時間才能完成的計劃裏,遇到一個完全不了解軟體開發的主管,不顧底下技術人員的反應,定出3天就能完成計劃的偉大夢想,讓除了這些技術人員之外的所有人都做著這樣的春秋大夢….
如果你是這些技術人員,3天後你是要交出你用URL分析出的各種圖表呢?還是一個漏洞百出但還可以撐一下下場面的程式呢?
我想如果你用這樣的角度來看事情的話,這些結果就一點都不難理解了.
我只能說國內的軟體業充斥著太多這樣的現象:
1.外行領導內行
2.短視近利,只想快速獲得蠅頭小利,或者先開出天方夜譚的條件,先搶到這個專案再說,從不想真正花時間好好深入去研究,培養人才,反正船到橋頭自然直,問題遇到了再說
對於主管來說
明天程式就要交了
什麼URL?!
我看應該是U aRe Late!!!!
同人的生活派對
「漫談高鐵訂票系統的結構分析—觀念篇」之我見
對克明兄的漫談高鐵訂票系統的結構分析—觀念篇〉,有網友回應:
根據我的經驗,高鐵訂票系統的這些問題根本是不應該發生的。稍有一點 Database System Management 經驗的都會知道 Transaction Loc…
Kenming Wang
Hi 昆蟲:
其實如我文中所述, Transaction Lock 是個問題,但不是主要的問題,個人是認為,軟體的結構設計,出了根本性的問題。
昆蟲
根據我的經驗,高鐵訂票系統的這些問題根本是不應該發生的。稍有一點 Database System Management 經驗的都會知道 Transaction Locking 及 Loading 的 issues. 不只鐵路系統用到,任何 Business Transaction 都要考慮到的。 比起Wall Street 的交易,這個只是幼稚園的難度。
我比較好奇的是高鐵公司如何外包、選擇廠商、合約內容、有無求償。在商業上走的是正常的路,還是後面開小門靠關係。
技術一點都不是問題,問題在經營者的是否光明正大。如此而已!