个人开源-智能交通系统

       匆匆忙忙15天的编码工作,终于完成了系统的初稿,虽然还有很多功能没有实现,很多细节有待完善但是项目的架构和核心流程是确定下来了。在此期间又找到了很多基础上的不足,打算加足马力继续充电。都说知道的越多,不知道的就会越少。但是编程方面来看,却是学的越多发现自己不知道的东西也越多。

 

      这个系统之所以被开发其目的是:为缓解现如今拥堵城市交通寻找一个可行的方案。借助计算机超强的计算能力,通过改变交通信号灯、道路位置等单一变量,观察一定规模的车辆在驶入实验区到驶出实验区所用时间的差异。从而得出更加优秀的道路布局方案,应用到现实中去。如此高大上的目的任重而道远,非一朝一夕所能成之。不防还是先看看从这几天的编码中学到了什么吧。

 

      真不敢保证在不涉及代码的前提下把整个项目1W多行代码讲明白,之后会再更博,写一下那些经典的架构或者编码思路。至于算坐标就不说了,也不建议看,因为很乱,自己数学不行,事先想的与真实不符只能修修补补,修3次以后,对于自己还好。对于其他人来说看代码绝对变成了一场灾难。况且这种东西一个人一个思路,除非专业人员,感觉没有必要研究它。

 

      整体架构

 

     its服务器启动之后就会加载自身各个组件,并计算各组件的坐标或者长度。即使Tomcat web服务器和浏览器不开,its服务器照样可以运行,丝毫不受影响。浏览器的作用有两点,一:显示系统当前的运行情况。二:作为典型B/S架构的成员,提供系统管理界面。当浏览器开启时,会使用HTML5的WebSocket协议向web服务器发送一条加载区域坐标的指令,然后web服务器将指令解析到一个指令队列中(指令队列是防止指令可能不止一条,web服务器处理指令时,可能这条指令并没有发完,导致冲突)当指令全部解析到指令队列中后,再逐条执行。这是web服务器会使用Socket向its服务器发送命令。its解析命令并返回需要的json字符串。web服务器再将结果返回到浏览器,浏览器通过一个JQuery插件来解析json字符串,渲染成动画。其他加载路,车道,灯,车都跟加载区域信息一样,只不过有些组件需要一直变动,它们要写在一个定时器中隔一段时间向web服务器发一次命令。

 

     its服务器架构

 

 

      架构整体采用Tomcat的生命周期架构。每一个继承StandardBase的组件都有init,start,stop,destroy等状态,而且LifecycleSupport类提供了监听器的支持,监听没有一个组件状态的改变。可以为每个组件的每一个状态注册监听器,这一思想超强的增加了系统的可扩展性。

 

      这一架构图的另一个亮点是车行驶规则的定义ChangeLaneRule,JudgeLightRule,ChangeRoadRule,CarRunRule分别代表着前面有车判断是否可以换道行驶,判断信号灯的状态,是否可以换路如果可以就换路行驶,车最基本的行驶。他们被包装在Pipeline中。是的,它就是tomcat中的Pipeline而上面提到的rule其实就是tomcat中的valve。车在刚开始上路是会被设置一个和这条路一样的长度,每次计算伴随着长度的减少,也就给人一种车在行驶的感觉。当这段长度减到0是就该换路了。车行驶是调用了StandardCar中的run方法,实际上调用的是StandardCarRun,StandardCarRun中又有Pipeline,Pipeline再调用一系列行驶规则,这样就顺理成章的出现了车行驶的现象。

      

自定义AOP



 

两个接口两个类实现了一个再简单不过的AOP,用来为mybatis管理事务。不仅可以有前后通知,还可以处理异常。虽然完全跟sping没有可比性,但是多少也彰显了面向切面编程,核心代码与非核心代码分离的思想。暂时还没来得及看sping源码,之后有机会还要继续优化。这个小Demo中暂时还能看出两点可以完善一下,一是切入点使用正则直接写死到了代码中,其实完全可以写到配置文件中。再者就是ServiceImpl中强制引入了session,还可以在mapper上加个注解,在FilterChain链中检测注解然后注入mapper的代理实例,既然这些代码只有自己在用,这样的话不涉及反射性能还会高点所以就没去加注解。 虽然重复造轮子对别人来说没有意义,但是可以加深自己对经典轮子的印象,可以使自己更好的使用那些轮子甚至自己为现有的轮子换胎,打气这都是有可能的。

 

Mongodb统计行车数据

 

      之前写过两篇博客,一篇是mongodb的安装与基本操作,一篇是最新的JavaAPI代码调用mongodb。两篇博客再加上这次在智能交通系统中的使用。很难不让人认识到写一个demo或者做一个简单的测试与真正在项目中使用是有很大区别的。更何况这也不算项目。之前做测试,只要出结果就好,从来没有考虑过其他。但是真正运用到项目中来又是另一番景象。看到开启链接和关闭链接的语句就放在那。总感觉很不舒服。到底如何管理链接资源才能不让数据库出现安全问题又能保证最大的执行效率。还有就是mongodb作为内存数据库,肯定比其他事务性数据库更容易受到外界的影响,如何才能将风险系数降到最低。不得不承认自己在这方面还是一片空白。甚至连最基本的查询API语句的组织都组织不好。随着数据的膨胀与需求的增加NoSQL数据库和动态类型语言肯定是一个趋势。好吧,又为自己挖了一个大大的坑。以后还得多多努力啊。

 

Connector

 

      使用Tomcat5之前Connector的思路在Processor中设置一个available boolean标志,初始为false,Processor在初始化时会调用自己的await方法然后遇到!available全部遇到wait挂起线程。直到Connector获取链接请求从阻塞状态转换为非阻塞状态时,从Processor池中获取一个然后调用Processor的asign方法并将Socket传给Processor,asign中notifyall唤醒所有挂起线程。之前的await继续执行,处理Connector传入的Socket。然后再将自己放回Processor池,并重新修改available标志。等待下一次Connector的调用。第一次见到这个思路时就被它打动了,真的很漂亮。这次本打算使用Tomcat7中的Coyoto作为自己系统的连接器。但是追了半小时源码之后虽然有个大致的思路可是一些Concurrent包中的类成了拦路虎,很多都不知道是什么作用,或者就是了解一点网上介绍的只言片语,这完全是不够的。Concurrent包及里边涉及到的同步算法,数据结构又是一个大坑。

 

WebService和MBean

 

      这个项目暂时使用SOAP1.1版本实现了一个WebService的运用。之前也测试过CXF框架,但是里边涉及到的Jar包实在是太可怕了。最终还是决定使用小清新版本的,不引入WebService的jar包。但是这样也丧失了SOAP1.2调用接口的能力。WebService一般都是作为不同语言之间或者不同公司之间相互通信的工具实现的,在这个小东西上使用这的难免有点大材小用了。有兴趣可以把它的代码摘出来,作为一个WebService的小Demo来看待。从传输性能来讲Socket > RMI > WebService 。但是使用的方便程度与范围广度又基本呈负相关。所以技术选型要谨慎,确定好需求是前提。感觉WebService最好还是传双方定义好的XML文件或者json,这个小Demo并没有这么做,导致以后分页会很麻烦。MBean之前想加上的,计划的是使用MBean来修改组件的参数,但是现在连基本的Mapper都还没写,但是现在又发现有那么多的基础东西要学,还要准备不久之后找工作面试,暂时就不加了吧

 

细节

 

      在写Socket通信传输数据时使用了ByteArrayInputStream和ByteArrayOutputStream有一个错误排了很长时间,这两个对象还都是被Buffered包装类装饰的。明明已经close了流为什么还是不能刷出数据。最后手哆嗦了一下,点进了ByteArrayInputStream的close方法的源码,乖乖居然是空的。之后就老老实实刷新和关闭他们的Buffered类了。这种错误发现还好,,找不到说不定什么时候会给你致命一击。还能想起一点就是加锁问题,有没有必要加,要不要加,怎么加都是要考虑的。首先要通篇考虑这片区域会不会出现多线程同时操作的情况。如果出现,那么想一下有没有必要加锁,在代表信号状态的字段上我选择了使用volatile关键字,而没有加锁。只要保证资源被使用时能重新从堆内存中读取,资源被修改后能够立刻被刷到内存中就好,期间多少出现的一点状态不一致相较于性能考虑还是可以容忍的。但是有些地方不加锁就会出现多线程操作异常,比如车在车道上的添加,遍历,删除几个操作就不能同时发生,如果在遍历时你增加或者删除了元素,一定会发生异常的。那么这时候就要加锁了。怎么加?暂时的理解是加最小范围的锁。能在方法内加不在方法上加。最好不要使用this锁。Java中处处皆对象,连锁也是对象。一把this锁所到了这个方法上,你操作这个对象的其他的同步方法统统需要进入等待队列等待所被释放然后各线程抢占。现在感觉这样是很不理智的,现在也只是稍微接触了一点皮毛。同步问题绝对没有那么简单,以后还要好好研究留心观察。也许现在认为很对的概念以后会感觉很荒唐。

总结

     博客通篇写下来,又看了一些代码,突破万行代码大关的窃喜所剩无几。又一个豆腐渣工程诞生了。里边除借鉴了一些Tomcat源码的设计思路外,剩下的也就没有任何作料了。先抛开故障恢复,集群减压(其实这个程序一开始是打算写成分布式的,还留了一张表做接口,现在也不好意思说了),分模块加载,系统快照等高级功能不谈,单看灵活性,易操作性,各组件的高内聚低耦合程度。就让本作者潸然泪下。最后送自己一句话:好好补补基础吧!

源码下载地址:https://github.com/smallbug-vip/its

目录介绍:

area:its服务器源码

center:Web服务器源码

bin:打包好的可运行文件与war包

sql:mysql数据脚本

mongodb数据库记录数据默认是关闭的Constant 里面有一个ISNOTEINFO 参数可以配置如果为0就关闭,其他数字为开启。所以如果资源有限没必要配置mongodb数据库。

部署:

bin文件夹中的center.war考到web服务器下。双击a.bat即可运行its服务器,全部运行文件都在area-0.0.1-SNAPSHOT.jar里面,记得修改里面的MySQL数据库配置

注:运行jar包是在jdk1.8环境下使用maven插件打包的,center.war需要支持webSocket协议的服务器。道路参数不要该太大否则超出浏览器支持的最大的Canvers宽度就会无法显示Chrome是15000多一点,具体忘了。建议使用Chrome浏览器。

 

 车辆行驶效果图:



 

 

开三个客户端测试连接器,远远没有达到负载上限:


 

 

测试Processor池是否可以扩充:

 


 

数据统计界面:



 
 本学期计划:



 

猜你喜欢

转载自smallbug-vip.iteye.com/blog/2279915
今日推荐