使用ZeroMQ彻底重构OpenVPN的设想以及一些新想法

在一个迟到的雨夜,我怀着无比激动的心情写了不到20行代码…但是这不到20行代码却是一个新发现,它彻底解决了OpenVPN的三个重大问题,是的,彻底解决。ZeroMQ的到来我接触ZeroMQ这玩意确实有点晚,那是上一个下雨的周日,我自己宅在家里看罗马史,畅想着这个辉煌的帝国,伟大的制度。 ZeroMQ彻底颠覆了以往的socket编程模型。它使得底层的BSD socket对程序员不再可见,程序员只需要处理自己业务即可,即收到某个消息,将其做一些处理,然后要么回复一个消息,要么转发,而根本不必管它从哪里来,要到哪里去,具体的路径是怎样的。 总的来讲,ZeroMQ正如其文档作者所说,它旨在修复这个世界。ZeroMQ通过代码来组网,彻底将程序员从底层的BSD socket及以下的网络细节中解放出来,程序员可以通过消息组建一个新的网络,可以满足任意点到任意点的消息可达性。从ZeroMQ提供的API可以看出,它几乎完全抛弃了“网络相关”的一切机制,再也找不到sockaddr结构体,当然你也再也不可能获取什么IP地址了,实际上在ZeroMQ看来,根本就没有IP地址,也没有传输层,以太网的概念,程序员可以完全不懂这些。这就好比即便是顶级网络工程师也可以不懂物理层编码规范以及PHY规范一样。这是一个真实的抽象! 当然,由于ZeroMQ作为一个通信库而不是一个标准,它目前还要构建于既有的TCP等协议之上 ,然而,你可以看到,能体现TCP的API将TCP协议,IP地址,端口等概念退化成了一个字符串标号,比如在ZeroMQ中,"inproc://step2","tcp://localhost:5671"等是并列的,前者仅仅是在说,底层的通信协议是进程内部的通信协议,后者是使用TCP,如果不看zmq_bind,zmq_connect调用,比如它们被封装了起来,你是无法区分两个zmq_socket的,不管是通过IPC,还是管道,还是TCP,ZeroMQ唯一要保证的事就是,消息的可达性。至于底层的BSD socket是在跟谁进行着连接,至于IPC具体过程,ZeroMQ是不管的。 在云计算,物联网时代,分工细化继续进行着,必须把程序员从网络的困境中解放出来!这一直都是一个愿景,早在10年前,我还在上大学,那个时候就不断有人推出一系列的中间件,声称“屏蔽了底层细节,让程序员只关注业务逻辑”,可是效果都不大好,几乎都是将程序员从网络的复杂性引到了中间件本身的复杂性,这个趋势在云时代是可悲的。直到有了ZeroMQ类似的东西,它足够简单,实现了针对程序员的真正减负。 ZeroMQ,作为一个MQ,它真的和别的MQ一样吗?完全不一样!它甚至是一个库而不是一个系统,它是让程序员用的,它和系统管理员关系不大。它不需要你搭建什么系统,不需要你去做任何配置,不需要特殊的服务器,它只是一个库,在Debian上可以轻松地被./configure & make & make install,然后就可以基于它的API编程了,它的API可以被man到,只需要man -k zmq就知道大多数的API了,最后gcc test.c -o test -lzmq,然后运行它即可。对于使用TCP的zmq而言,通过抓包,你会发现它在TCP之上它封装了很多新的协议,是的,ZeroMQ拥有自己的一套协议。 我相对认真地考虑了一下ZeroMQ对OpenVPN而言意味着什么。OpenVPN可以说是个代理,然而它又和一般的应用层代理截然不同,即,它的连接不由应用层协议决定,事实上,在OpenVPN隧道里填充的是一个以太帧或者IP数据报文,除非隧道自己想断开,否则在无故障的情况下,连接是长期存在的。在编程模型上,OpenVPN实则一个转发器,不考虑加密/解密时,它其实就是从一个BSD socket接收一段数据,然后解封装后将其送入TUN网卡字符设备,或者反过来,从TUN网卡字符设备接收一段数据,将其封装后送入BSD socket。使用ZeroMQ的各种模式组合,这个是很容易完成的。似乎可以直接套用ZeroMQ的多线程模型,事实上真的可以。 不得不提到的几个美中不足,倒不是说ZeroMQ多么的不好,毕竟我还没有精通它,无权过问和指责ZeroMQ的过多细节,这是一点自己的想法。不过应该事先说明的是,ZeroMQ压根不是设计出来让人满足特殊需求的,针对于它所擅长的领域,它已经做得很不错了。ZeroMQ美中不足1.ZeroMQ无法在底层使用UDP进行传输层这个似乎是因为UDP难以追踪并映射客户端导致的,但是要想做到这点似乎不难,使用内核的conntrack类似的机制只是其中一法,最好的办法还是在协议层面解决。对于UDP的ZeroMQ,在ZeroMQ的数据传输协议中增加一个字段用来做TCP五元组类似的事情,当然这需要维护一张map,你也许觉得查找这张map的开销有多大,但是往往而言,在做到一个低效率的版本之前,不要考虑优化。 不过,从ZeroMQ的设计初衷来看,它需要消息本身的可靠传输,兼顾有边界的短消息,高并发,这也许解释了为什么ZeroMQ使用TCP而不是UDP。也许,ZeroMQ本身的协议就是基于考虑传输协议的,如果使用了UDP,它也还是要自己做Reliable层的。然而我要说的是,为何不能更进一步呢?我记得当初UDP从TCP/IP中剥离出来的过程走的就是类似的一条路,毕竟,如果将功能有限的ZeroMQ发展成一个全面的通信库,就该考虑众口难调的各种传输需求,而这,确实需要重新审视和设计ZeroMQ的协议了。2.ZeroMQ不支持文件描述符和问题1一样,ZeroMQ并不支持通过文件描述符机制之间进行的传输。如果把ZeroMQ定位成一个I/O库而不是通信库,可能一开始就应该支持文件描述符了,要知道,对于操作系统接口而言,一个socket和一个TUN文件描述符没有任何区别,大家都可以被poll/select。既然旨在让ZeroMQ成为一个代码联网的库,那何不将所有通信机制都支持掉呢?数据可以来自socket,也可以来自文件,数据可以发往socket,可以发往同一进程的不同线程,当然也可以发往TUN网卡。如果这样,OpenVPN的改造简直不用写什么代码了。3.Zero不支持IP地址变更ZeroMQ作为REQ方时支持坚持不懈地重连探测,直到REP方启动或者断开后又恢复。但是一旦REQ连接成功,其IP地址变化了,它无法将这个变化告诉REP方,这等于说还是没有完全屏蔽底层网络的变化。如果REQ可以将这个变化信息作为协议的一部分通告REP方,那么REP方将可以及时更新map消息,保证期间消息的传递继续进行。好像有头大象在吸水。然后再去了芦笛岩,

使用ZeroMQ彻底重构OpenVPN的设想以及一些新想法

相关文章:

你感兴趣的文章:

标签云: