基于Redis构建10万+终端级的高性能部标JT808协议的Gps网关服务器
在开发一个大规模的部标GPS监控平台的时候,就算我们花费再多的时间设计和规划,我们也并不能准确的预测出自己未来的车载终端接入量有多大,而且一开始就为了我们宏伟的设计蓝图,投入大规模的服务器硬件设备和网络带宽,这会带来极高的成本投入,也会在早期造成大马拉小车,空耗+复杂度过高。所以大多数的平台一定是从一两台服务器搭建运营环境, 随着车载终端量级越来越大,并发越来越高,业务模式也越来越复杂,我们需要将程序解构,从一个模块拆出多个模块,从单机运行变成多台服务器分布式部署,从单进程变成多服务模式。所以我们设计的时候,就必须要构建这种可扩展的由1变成N的架构,必须要有一个可扩展的高可用的基于部标jt808协议的服务器。
我们这里所说的10万+终端接入,首先是10万+在线的,另外并不是简单的接入,如果做一个基于Netty的网关,只负责协议解析并将数据通过消息队列转发出去, 这样的网关,随便一个程序员熟练使用Netty框架都可以轻松做到, 因为一个进程的Netty本身支持几万个连接时没有任何问题的, 而加上一个 Rocket MQ 或者样Kafka, 这样的网关只是一堆开源框架堆砌起来的Toy, 它的性能测试报告既没有意义也是没有任何技术含量的, 我们不需要实验室的数据, 我们能够给实际要购买的客户,实际演示真实客户的GPS平台.
什么很多人使用Netty和Kafka, 程序一样容易出问题呢, 因为我们后续肯定还要保证实时数据推送、海量数据入库和查询、报警电子围栏分析和复杂的业务逻辑计算都能稳定的运行,这不仅需要扎实的编程能力,也需要长期运营的磨合,往往需要很多次的版本迭代。在这种场景下,通过长期经验, 我们觉得单台服务器或者单进程的一个808网关服务器是很难支撑到的。我们需要保证的是从前到后一系列的稳定运行指标:
1) 接入:10万+终端接入不出现排队和无法接入现象,由于一般的基于JT808协议的终端设备,都是基于TCP长连接通信,UDP的很少,10万+长连接的维持对服务器的压力可想而知非常大。一般的服务器带宽不够的时候,或者由于服务器处理速度慢,造成连接无法及时归还连接池,造成服务器接入的时候,就卡壳。我们一般采用Netty来做为JT808服务器的NIO Socket服务器框架,而Netty在开发的时候就要求在Handler中,获取的连接数据的时候,必须不能做耗时的操作。这就要求我们必须要异步处理。
2) 实时性 : 虽然终端接入了,但是后续的逻辑处理模块如果处理速度过慢,即使是异步的,也会造成数据在内存中排队等候处理的情况,这样当数据传递到web用户面前的时候,就是滞后的,不满足用户对实时性的要求。如报警弹窗,位置显示等都是对实时性有要求的功能。
3) 数据入库:并发的连接,必然会造成对数据库并发请求加大,要求及时入库的GPS数据也是海量的,一分钟将有几十万级别的GPS数据等待入库,而且根据jt808协议,一条0×0200指令的定位数据包,经过服务器解析和逻辑计算后,又衍生出报警记录,油量温度记录,里程统计记录等等,数据量也非常的大。虽然并发是提高入库效率的手段,但是并发过高,超过数据库服务器承载的能力,又会造成数据库服务器卡壳,进而造成连锁反应,web用户经常会看到页面打开过慢,数据显示不出来,其实不是web服务器的问题,是数据库的压力太大,难以及时响应。所以一个能承受10万+终端的部标808服务器,并不简单的是要求代码写的好性能高,前期数据库的设计和规划能力和实际的承载能力也必须要跟得上,这就是一条流水线,那个环节掉链子,都是多米诺效应的崩溃。
4) 查询, 有长期运营经验的程序员都知道, 90%以上的服务器问题,都是由于数据库压力大, 造成整个程序卡壳, 进而造成程序队列堵塞, 内存增长来不及释放进而崩溃, 所以成熟的程序员, 总是非常注意数据库优化的问题, 以及程序中对于数据库的冲击的处理有着丰富的手段, 没有实战经验的程序员, 即使在优秀的代码基础上做二次开发, 也会非常容易造成性能问题, 因为他们没有技术积累, 又缺乏耐心阅读代码, 总是第一时间去想做局部的修改, 完成任务放在最前面, 而把阅读消化代码, 整体提高自己技术水平放在后面.
5) 实际的业务场景处理, 压力是比较难模拟的, 这也是很多人做了压力测试, 上线后,也一样出现各种各样的性能问题, 这就需要我们本着务实的精神, 在实际的运营过程中, 做后续的优化. 而不是纸上谈兵, 在实验室里面写出来, 做下压力测试报告, 就昭告天下了.
在实际的运营中,单台的阿里云服务器并不贵,带宽的运营成本要高于服务器的成本,所以我们在设计架构的时候,必须要保证部标808服务器是可以像刀片一样是可以插拔的,通过分散压力,来保证系统的稳定运行。当某一个服务器模块停用或者上线,是不需要整个平台调整或者改造开发的,web平台是无感的。
所以我们不能让Web平台直接面对808服务器,而是在808服务和Web平台之间,增加一个Redis缓存服务器,808服务器的实时GPS数据直接push到Redis缓存中,web平台获取实时数据的时候,不是通过RPC调用808服务器的实时服务,而是通过Redis的API,直接从Redis缓存中获取。利用Redis的Pipeline模式,可以批量获取所需的实时数据。
需要JT 808协议 服务器端源码不含web平台(java和C#两版本可选其一)+808模拟测试终端工具 +压力测试工具 的请联系我购买1200元(2379423771@qq.com), 参见文章:基于Java Netty框架构建高性能的Jt808协议的GPS服务器
在Web平台给终端下发指令的时候,如何知道终端是在那一台服务器上,这个是通过在Redis中缓存一个Sim卡号和部标808服务器Id的映射关系表,当终端接入的某台服务器的时候,808服务器会自动在Redis上更新映射表,这样web平台下发指令的时候,就知道通过那个部标808服务器下发指令。
由于Redis有消息队列的功能,对于报警推送等实时性要求高的场合,当部标808服务器解析报警后,可以直接推送给Redis队列,然后web平台通过订阅消息队列,获取报警消息,然后再经由Websocket推送给前端平台。可以看出整个报警的推送路径发生了重大改变,不再是从数据库读取出来,而是通过典型的分布式内存,不断的推送。不单提高了报警响应的速度,更重要的是,大部分的GPS平台,报警误报频繁,频繁的插入数据库,对数据库压力非常的大。
(20385)