<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    TWaver - 專注UI技術

    http://twaver.servasoft.com/
    posts - 171, comments - 191, trackbacks - 0, articles - 2
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    小Demo帶來大項目

    Posted on 2010-09-14 18:41 TWaver 閱讀(5987) 評論(2)  編輯  收藏

    今天心情不錯,公司終于簽下了一個綜合業務監控系統的大單。到底有多大我也不知道,反正連軟件帶硬件不算小。按照銷售的說法,拿下這個項目一個重要的因素就是要提供一個吸引眼球的demo,而我們做的不錯!今天和大家分享一下喜悅和經驗!

    這個項目是一個省級電信運營商的綜合業務監控系統。公司跟了好長時間了。由于是一個綜合的業務監控系統,涉及的管理資源非常多,又要提供大屏幕顯示,所以對系統的呈現效果要求非常高(“政績工程”么)。前前后后提了很多“無禮”要求,陸續提過的有3D電子地圖、3D機房監控、場景仿真、全動畫、Google Earth、全Flash等等….弄的我們暈頭轉向、焦頭爛額。其實很多時候,用戶自己也不知道想要什么,反正對廠商的要求就是一個字:“炫”,兩個字“好看”,三個字:“一定好好看!”(不對,好像是四個字哦)。

    言歸正傳,項目跟蹤過程中,商務始終告訴我們研發一定要做好一件事:如何做好呈現,尤其是綜合的業務監控和呈現,這是獲得項目的關鍵,一定要“出彩”。這個“綜合呈現”說起來容易,做起來難。作為省級的電信運營商,內部的各種軟硬件系統無數,要監控從上到下、從軟到硬,真是煩不勝煩:

    • 基礎設施層:主要是網絡上的硬件設備,包括交換機、路由器、防火墻、各種主機設備服務器等等;
    • 軟件層:這一層主要是主機上面運行的操作系統和各類業務軟件系統,例如操作系統(Windows、AIX/HP-UX/LINUX/SOLARIS)、各種中間件(WebLogic、JBoss、IIS、WebSphere等)、數據庫(Oracle、Sybase、MySQL)等;
    • 應用層:這一層是指運行在軟件層內部的一些細粒度資源,包括一些關鍵的軟件進程、數據庫表空間、業務連接、消息隊列等等。這一層數量繁雜、數量眾多。不過這些資源的狀態直接會影響其上層支撐的業務。
    • 業務層:業務層是最頂層,由以上底層資源所共同支撐起來的面向用戶的各種業務。對業務最容易理解的描述就是電信提供給客戶的具體“服務”。例如視頻業務、短信業務、WAP業務、專網業務等等。這些業務才是用戶最終關心的東西,因為這些業務才是客戶的核心資產,是拿來賣錢的最終產品。一旦出問題,將直接影響money!

    此外,還有一大堆機房環境監控的要求,什么配電柜供電、開關狀態、UPS、蓄電池、空調、適度溫度漏水消防通風門禁視頻………一大堆。所以,要對業務進行監控,就必須對業務所支撐的各個底層資源進行監控。另外,還要能夠對這些資源的關系進行連接和定義,一旦發生故障和問題,能夠從上到下迅速定位故障起源,在最短時間內發現問題、解決問題。如何呈現這些依賴關系,并對故障和告警進行縱向定位,是軟件呈現的一個核心問題,也是用戶最關心的一個問題。

    用戶要求我們先制作一個demo程序,看我們將如何呈現“綜合監控”的效果。在充分了解了用戶需求之后,經過討論,我們想做一個完全圖形化的分層、跨層的綜合監控界面。界面要美觀,有動畫效果,能夠清晰的顯示資源依賴關系和告警傳播定位。

    需要監控和管理的資源
    接下來要寫代碼了。肯定先用我熟悉的TWaver試試。研究了一下,TWaver中有一個平行四邊形的Group對象,適合做上圖中的“層”的概念。先如下封裝并設置屬性:

     1package demo;
     2
     3import java.awt.Color;
     4import twaver.Group;
     5import twaver.TWaverConst;
     6
     7public class LayerGroup extends Group {
     8
     9    public LayerGroup() {
    10        init();
    11    }

    12
    13    public LayerGroup(Object id) {
    14        super(id);
    15        init();
    16    }

    17
    18    private void init() {
    19        this.setGroupType(TWaverConst.GROUP_TYPE_PARALLELOGRAM);
    20        this.putGroupAngle(45);
    21
    22        this.putGroup3D(true);
    23        this.putGroupDeep(10);
    24        this.putGroupOutline(false);
    25        this.putGroupFillColor(Color.green.darker());
    26        this.putGroupGradient(true);
    27        this.putGroupGradientFactory(TWaverConst.GRADIENT_LINE_E);
    28        this.putGroupHandlerVisible(false);
    29        this.putGroupDoubleClickEnabled(false);
    30        this.putBorderColor(Color.white);
    31        this.putBorderInsets(3);
    32        this.putBorderAntialias(true);
    33        this.putBorderStroke(TWaverConst.STROKE_SOLID_4);
    34        this.putBorderVisible(false);
    35        this.putLabelHighlightable(false);
    36
    37        this.setEnableAlarmPropagationFromChildren(false);
    38    }

    39}

    40

    通過這個簡單的封裝,再往Group里頭放幾個節點和連線,顯示效果如下:

    用Group制作的“層”效果

    怎么樣,有點意思吧?開頭不錯,繼續改進!再依次排列4個Group,用不同顏色,試試效果:

    1createLayer(Color.orange, 50010"7.png""<html><center>軟件<br>業務層</center></html>");
    2createLayer(Color.green.darker(),18020015"8.png""<html><center>技術<br>應用層</center></html>");
    3createLayer(Color.magenta.darker(),2803505"5.png""<html><center>技術<br>軟件層</center></html>");
    4createLayer(Color.cyan.darker(),4005707"1.png""<html><center>基礎<br>設施層</center></html>");
    5

    以上代碼封裝了創建一個層的函數,給定顏色、坐標位置、內部節點數量、圖標、文字等等。上面代碼中的HTML風格字符串是為了在TWaver中(好像Swing中也是這樣的)顯示換行的標簽。每一個層作為容器包含了很多不同類型的資源。顯示效果如下圖:

    四層拓撲圖顯示效果

    注意其中的連線有下垂的彎曲效果。這是我以前在做項目封裝過的一個TWaver技巧:通過重寫twaver的Link的UI類,重新指定path走向實現的。其實也很簡單,首先獲得link的from點和to點,取值中間點,再把y縱向增加20,把這個點作為quadTo的控制點畫曲線即可。對TWaver熟悉的朋友可以看一下這段代碼(其實這個效果也是從TWaver Java的demo源代碼中學習到的):

     1package demo;
     2
     3import java.awt.Point;
     4import java.awt.geom.GeneralPath;
     5import twaver.network.TNetwork;
     6import twaver.network.ui.LinkUI;
     7
     8public class InnerLinkUI extends LinkUI {
     9
    10    public InnerLinkUI(TNetwork network, InnerLink link) {
    11        super(network, link);
    12    }

    13
    14    @Override
    15    public GeneralPath getPath() {
    16        GeneralPath customPath = new GeneralPath();
    17        Point p1 = this.getFromPoint();
    18        Point p2 = this.getToPoint();
    19        customPath.moveTo(p1.x, p1.y);
    20        int offset = 20;
    21        customPath.quadTo((p1.x + p2.x) / 2, (p1.y + p2.y) / 2 + offset, p2.x, p2.y);
    22        return customPath;
    23    }

    24}

    25

    用這種link做出的拓撲圖比較生動美觀。多加幾個節點連線就能看出來了:

    四層復雜拓撲圖顯示效果

    不過發現平行四邊形Group一個問題:當兩個Layer疊加后,下面的節點會被完全覆蓋,看不見了。用戶說:能不能也能看見?(暈,蓋住了也要看見。誰讓人家是甲方呢?)于是詢問TWaver的人,一個哥們說Group有透明屬性。于是試了一下,效果不還錯:

    1this.putGroupOpaque(false);

    層的透明與覆蓋

    下一步,關鍵了:要增加層與層之間資源的“依賴關系”。例如一個Oracle跑在一臺主機上,而Oracle中的一個關鍵表空間需要重點監控,它決定了上層一個視頻點播業務是否能夠正常。為了體現這個依賴關系,在跨層的節點中間建立link。這個link和層內部link顯示上應當有所區別:

     1package demo;
     2
     3import java.awt.Color;
     4import twaver.Link;
     5import twaver.Node;
     6import twaver.TWaverConst;
     7import twaver.base.OrthogonalLinkDirectionType;
     8
     9public class LayerLink extends Link {
    10    public LayerLink(Node from, Node to) {
    11        super(from, to);
    12        init();
    13    }

    14
    15    public LayerLink(Object id, Node from, Node to) {
    16        super(id, from, to);
    17        init();
    18    }

    19
    20    private void init() {
    21        this.putLink3D(true);
    22        this.putLinkWidth(4);
    23        this.putLinkOutlineWidth(0);
    24        this.putLinkColor(Color.lightGray);
    25        this.putLinkAntialias(false);
    26        this.setLinkType(TWaverConst.LINK_TYPE_ORTHOGONAL);
    27    }

    28}

    29

    顯示出來后,效果并不理想,有點亂。主要是沒有“跨層”的立體感。

    跨層連線效果

    圖中跨層的link沒有呈現出“穿透層”的感覺,多了以后反而破壞了整個拓撲圖的立體感和生動感,需要再改進。最好能夠顯示“穿層而過”的效果。需求變態么?不弄點猛藥還想拿單子么,程序員就是要與各種“不可能”說“不”嘛!經過反復研究和實驗,終于做出了一個更好的效果,如下圖:

    連線的跨層穿透效果

    注意觀察其中穿層效果,不知大家是否喜歡?

    連線的透明穿透

    怎么做到的呢?其實也簡單,一點就破,我就不點破了吧,賣個關子先。大家可以先猜猜看,源代碼里頭也能看到答案。接下來,可以增加一些跨層連線了!看看下圖效果:

    跨層連線的綜合效果圖

    效果還不錯吧?銷售看過后非常滿意,連說有新意。不過還有最后一個很頭大的問題:需要顯示告警及其傳播路線,也就是告警發生后,要從底層一直沿著依賴關系傳播到上層。于是開始研究TWaver的AlarmPropagator告警傳播器。通過研究發現,其實告警傳播也不復雜,主要原理是當告警發生后,它會根據AlarmPropagator的“指示”和定義的規則,沿著一個特定的“路徑”進行告警傳播。被傳播過的地方,會顯示一個有告警顏色的外框,標志其告警狀態。

    但是問題是,TWaver的告警傳播器是按照“父子關系”進行傳播的。也就是默認情況下,告警總是從孩子傳給父親,一直到沒有parent為止。按照這個規則,這個demo中一個節點發生告警后,會傳播給平行四邊形這個層對象,這顯然是沒有意義的,不符合我的要求。我們需要告警沿著層的“依賴關系”進行跨層傳播。于是重寫AlarmPropagator!也不難,調試了幾個小時,用一個遞歸法總算搞定了。代碼如下:

     1package demo;
     2
     3import java.util.Collection;
     4import java.util.Iterator;
     5import twaver.AlarmSeverity;
     6import twaver.Element;
     7import twaver.Node;
     8
     9public class DemoPropagator {
    10
    11    public void propagate(Element element) {
    12        AlarmSeverity severity = element.getAlarmState().getHighestNativeAlarmSeverity();
    13        if (element instanceof Node) {
    14            Node node = (Node) element;
    15
    16            Collection links = node.getAllLinks();
    17            if (links != null && !links.isEmpty()) {
    18                Iterator it = links.iterator();
    19                while (it.hasNext()) {
    20                    Object o = it.next();
    21                    if (o instanceof LayerLink) {
    22                        LayerLink link = (LayerLink) o;
    23                        if (link.getAlarmState().isEmpty()) {
    24                            link.getAlarmState().addAcknowledgedAlarm(severity);
    25
    26                            Node anotherNode = link.getFrom();
    27
    28                            if (anotherNode.getAlarmState().isEmpty()) {
    29                                anotherNode.getAlarmState().addAcknowledgedAlarm(severity);
    30                                if (anotherNode != node) {
    31                                    propagate(anotherNode);//這里遞歸!
    32                     }

    33                            }

    34                        }

    35                    }

    36                }

    37            }

    38        }

    39    }

    40}

    41

    這里代碼的邏輯主要是判斷是不是跨層link,如果是就沿著它進行傳播。噢吼!上面代碼好像泄露了上面“穿透Layer”的秘密了,呵呵。最后,再來一個“告警模擬器”來模擬隨機、隨時發生告警,也就是用一個單獨的線程在里面sleep然后生成Alarm并發送到拓撲圖的節點上。直接上代碼:

     1package demo;
     2
     3import java.util.Iterator;
     4import javax.swing.SwingUtilities;
     5import twaver.AlarmSeverity;
     6import twaver.Element;
     7import twaver.TDataBox;
     8import twaver.TWaverUtil;
     9
    10public class AlarmMocker extends Thread {
    11
    12    private TDataBox box = null;
    13    private DemoPropagator propagator = new DemoPropagator();
    14
    15    public AlarmMocker(TDataBox box) {
    16        this.box = box;
    17    }

    18
    19    @Override
    20    public void run() {
    21        while (true{
    22            try {
    23                Thread.sleep(1 * 1000);
    24            }
     catch (InterruptedException ex) {
    25                ex.printStackTrace();
    26            }

    27
    28            SwingUtilities.invokeLater(new Runnable() {
    29
    30                public void run() {
    31
    32                    if (TWaverUtil.getRandomInt(5== 1{
    33                        //clear all alarm and propagation.
    34                        Iterator it = box.iterator();
    35                        while (it.hasNext()) {
    36                            Element e = (Element) it.next();
    37                            e.getAlarmState().clear();
    38                        }

    39                    }

    40
    41                    Element element = box.getElementByID("4." + TWaverUtil.getRandomInt(10));
    42                    if (element != null{
    43                        element.getAlarmState().addNewAlarm(AlarmSeverity.getRandomSeverity());
    44                        propagator.propagate(element);
    45                    }

    46                }

    47            }
    );
    48        }

    49    }

    50}

    告警模擬器把最底層的里面的節點隨機產生告警,再隨機的清除,模擬現實網絡的監控狀態。然后運行demo,觀察其告警傳播的路線是否符合預期,也就是沿著層進行傳播。

    注意一個細節:由于上面告警模擬器在一個單獨的Thread線程中運行,在產生告警并更改界面時候,需要用SwingUtilities.invokeLater進行代碼封裝調用,保證它在Swing線程中執行,避免屏幕和界面“花”或不可預知的顯示結果。唉,誰讓Swing是單線程而且是線程不安全呢?這是個古老話題,就不羅嗦了。

    廢話不多說,直接上最終效果圖:

    demo最終運行界面

    雙擊層動畫旋轉并放大

    看到告警跨層傳播的效果了嗎?最后,根據客戶的要求,又增加了一些動畫效果:雙擊平行四邊形后,平行四邊形會動畫變成矩形、動畫飛到屏幕中間,然后動畫放大內部拓撲圖,供用戶查看細節;再次雙擊,平行四邊形快速旋轉縮小并回到原來位置。demo程序交付并演示后,獲得客戶高度評價。用我們商務人員的話來說就是:“我們的demo最出彩!”作為程序員,自己做的東西能為公司創造價值和利潤就是最大的肯定和成就感!

    由于demo摻雜了不少公司的代碼,我花了一點時間整理一下,弄出了一個干凈的demo代碼,請見附件,請感興趣的朋友請直接下載,歡迎留言討論。 解壓demo.zip后,中有兩個jar包和run.bat,雙擊run.bat就可以運行demo。我是用JDK6編譯的,請各位確保首先安裝了JAVA 6環境。如有任何運行問題請留言。

    demo所限內容僅供技術交流和參考,請慎作商業用途。

    補充:

    看到留言中很多朋友都說“第一次看到用程序做demo”,也把我弄“驚詫”了。因為自己從業這些年基本上都是用程序做demo,已經習以為常,甚至成為理所當然了。看到很多朋友說“用PPT和美工圖片”做DEMO,確實感覺自己有點out了。在電信、電力這些行業里面,項目都比較大、復雜,沒有一定的商務和技術實力以及經驗是很難獲得項目機會的。PPT作為產品介紹和各種交流肯定是沒問題的;但如果說要做大項目的“系統演示”那可是夠“空對空”的。可以想象一下:如果我們是局方、甲方或客戶,要花幾百萬做一個項目,給各個廠商一個月的時間來準備一個技術交流和產品演示,我們是愿意把項目交給用精美PPT演示的廠商,還是愿意給效果同樣漂亮但用實實在的程序或DEMO來演示的廠商呢?誰家更有實力?誰家更重視項目?誰家更有技術和人才?誰家更有想法?誰家更有經驗?這個問題幾乎不用回答。

    一個有實力的軟件公司,打大單不拿點真家伙,光靠美工弄幾個花里胡哨的圖片或者PPT就能拿下項目,那絕對是太不可思議了。我接觸的這些公司哪個不是靠多年的行業積累和系統經驗,哪次面對這樣的大戰役不是要抽出一兩個技術好手來加班加點的做些真家伙(半真也行,老系統扣出一部分模塊和代碼,就算在此基礎上修修改改去運行也可)去演示?甚至有的時候去演示的幾乎就是可以上線的系統,或在另外一個老的類似項目緊急改進出來的半成品系統。如果沒有這些項目和技術經驗做沉淀和積累,一旦中標,很多時候系統上線只給3個月的時間,完全從頭來個瀑布式的從需求分析、從頭開發?做夢吧。現在行業競爭越來越慘烈,客戶要求越來越高越復雜,技術變化快,你不能做到又快又好的提供系統和解決方案,只能靠邊站了。

    這是一個大的監控系統,涉及很多子系統和其他業務系統。這里僅僅是一個簡潔的高層次全網監控界面,是很小一部分,是一個小UI而已。但是這個UI會被投射到一個2*4的大型液晶屏幕墻上,讓全屋子的人抬頭就能看到全網的鏈接情況、告警情況;讓公司領導經常過來看到;讓兄弟省市領導經常參觀到。所以,它的作用不可小視(提高形象的作用不也是作用么)。這也是為什么客戶這么重視的原因。另外麻雀雖小,五臟俱全;以管窺豹也可以時見一斑。我們搞技術的就是應當多思考多創新多學習多交流、踏踏實實在細節上下功夫,也許才能更好的體現我們的價值。

    如果demo所體現出來的UI呈現思路和設計想法或者代碼中的技巧能夠給大家帶來一點點啟發,本人就感到非常非常滿足了!

    謝謝各位!

    附:帶窗口的Demo運行圖


    評論

    # re: 小Demo帶來大項目[未登錄]  回復  更多評論   

    2010-09-14 18:48 by 菜鳥
    真佩服你們的技術和耐心。

    # re: 小Demo帶來大項目  回復  更多評論   

    2014-12-08 13:49 by dtya
    膜拜一下。。。

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 久久久久国色AV免费看图片| 女人被男人桶得好爽免费视频| 亚洲AV无码国产精品色午友在线 | 亚洲精品无码一区二区| 久久亚洲国产精品五月天婷| 国产精品免费大片| 亚洲人成自拍网站在线观看| 亚洲熟女少妇一区二区| 成年美女黄网站18禁免费| 久久不见久久见免费影院www日本| 亚洲国产视频网站| 中文字幕精品亚洲无线码二区| 91频在线观看免费大全| 久久久久国色AV免费观看| 亚洲中文字幕久久精品无码A| 亚洲av无码国产精品色午夜字幕| 午夜毛片不卡免费观看视频| 无码精品一区二区三区免费视频 | 久久精品免费一区二区喷潮| 日本免费高清视频| 国产午夜精品理论片免费观看| 最新亚洲人成无码网站| 亚洲制服在线观看| 亚洲高清无在码在线无弹窗| 亚洲精品白浆高清久久久久久| 国产一区二区免费在线| 岛国片在线免费观看| 免费h片在线观看网址最新| 97人妻精品全国免费视频| 国产精品偷伦视频免费观看了 | 99无码人妻一区二区三区免费| 国产羞羞的视频在线观看免费| 久久国产福利免费| 黄桃AV无码免费一区二区三区 | 99re免费视频| 国产一卡二卡四卡免费| 18禁无遮挡无码国产免费网站 | 亚洲国产综合精品中文第一区| 日韩亚洲AV无码一区二区不卡| 亚洲一区二区三区四区在线观看| 亚洲日本乱码在线观看|