小Demo带来大项目

今天心情不错,公司终于签下了一个综合业务监控系统的大单。到底有多大我也不知道,反正连软件带硬件不算小。按照销售的说法,拿下这个项目一个重要的因素就是要提供一个吸引眼球的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对象,适合做上图中的“层”的概念。先如下封装并设置属性:

 1 package  demo;
 2
 3 import  java.awt.Color;
 4 import  twaver.Group;
 5 import  twaver.TWaverConst;
 6
 7 public   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,用不同颜色,试试效果:

1 createLayer(Color.orange,  50 0 10 " 7.png " " <html><center>软件<br>业务层</center></html> " );
2 createLayer(Color.green.darker(), 180 200 15 " 8.png " " <html><center>技术<br>应用层</center></html> " );
3 createLayer(Color.magenta.darker(), 280 350 5 " 5.png " " <html><center>技术<br>软件层</center></html> " );
4 createLayer(Color.cyan.darker(), 400 570 7 " 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源代码中学习到的):

 1 package  demo;
 2
 3 import  java.awt.Point;
 4 import  java.awt.geom.GeneralPath;
 5 import  twaver.network.TNetwork;
 6 import  twaver.network.ui.LinkUI;
 7
 8 public   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有透明属性。于是试了一下,效果不还错:

1 this .putGroupOpaque( false );

层的透明与覆盖

下一步,关键了:要增加层与层之间资源的“依赖关系”。例如一个Oracle跑在一台主机上,而Oracle中的一个关键表空间需要重点监控,它决 定了上层一个视频点播业务是否能够正常。为了体现这个依赖关系,在跨层的节点中间建立link。这个link和层内部link显示上应当有所区别:

 1 package  demo;
 2
 3 import  java.awt.Color;
 4 import  twaver.Link;
 5 import  twaver.Node;
 6 import  twaver.TWaverConst;
 7 import  twaver.base.OrthogonalLinkDirectionType;
 8
 9 public   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!也不难,调试了几个小时,用一个递归法总算搞定了。代码如下:

 1 package  demo;
 2
 3 import  java.util.Collection;
 4 import  java.util.Iterator;
 5 import  twaver.AlarmSeverity;
 6 import  twaver.Element;
 7 import  twaver.Node;
 8
 9 public   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 html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值