以色列宣布成功防御对国防公司的网络攻击
Aspect使用了OC的消息转发流程,有一定的性能消耗。本文作者使用C++设计语言,并使用libffi进行核心trampoline函数的设计,实现了一个iOS AOP框架——Lokie。相比于业内熟知的Aspects,性能上有了明显的提升。本文将分享Lokie的具体实现思路。 前言 不自觉的想起自己从业的这十几年,如白驹过隙。现在谈到上还熟悉的的语言以ASM/C/C++/OC/JS/Lua/Ruby/Shell等为主,其他的基本上都是用时拈来过时忘,语言这种东西变化是在太快了, 不过大体换汤不换药,我感觉近几年来所有的语言隐隐都有一种大统一的走势,一旦有个特性不错,你会在不同的语言中都找到这种技术的影子。所以我对使用哪种语言并不是很执着,不过C/C++是信仰罢了 : ) Lokie 工作中大部分用OC和Ruby、Shell之类的东西,前段时间一直想找一款合适的iOS下能用的AOP框架。iOS业内比较被熟知的应该就是Aspect了。但是Aspect性能比较差,Aspect的trampoline函数借助了OC语言的消息转发流程,函数调用使用了NSInvocation,我们知道,这两样都是性能大户。有一份测试数据,基本上NSInvocation的调用效率是普通消息发送效率的100倍左右。事实上,Aspect只能适用于每秒中调用次数不超过1000次的场景。当然还有一些其他的库,虽然性能有所提升,但不支持多线程场景,一旦加锁,性能又有明显的损耗。 找来找去也没有什么趁手的库,于是想了想,自己写一个吧。于是Lokie便诞生了。 Lokie的设计基本原则只有两条,第一高效,第二线程安全。为了满足高效这一设计原则,Lokie一方面采用了高效的C++设计语言,标准使用C++14。C++14因引入了一些非常棒的特性比如MOV语义,完美转发,右值引用,多线程支持等使得与C++98相比,性能有了显著的提升。另一方面我们抛弃了对OC消息转发和NSInvocation的依赖,使用libffi进行核心trampoline函数的设计,从而直接从设计上就砍倒性能大户。此外,对于线程锁的实现也使用了轻量的CAS无锁同步的技术,对于线程同步开销也降低了不少。 通过一些真机的性能数据来看,以iPhone 7P为例, Aspect百万次调用消耗为6s左右,而相同场景Lokie开销仅有0.35s左右, 从测试数据上来看,性能提升还是非常显著的。 我是个急性子,看书的时候也是喜欢先看代码。所以我先帖lokie的开源地址: https://github.com/alibaba/Lokie 喜欢翻代码的同学可以先去看看。
Lokie的头文件非常简单, 如下所示只有两个方法和一个LokieHookPolicy的枚举。 这样通过自定义 filter 的方式我们解决了扩展性的问题,注意我们使用了Activate注解,这样 dubbo 就会把注释的Filter 作为 dubbo 原生的 Filter 自动加载,而不需要显示的配置 provider 或者 consumer 的 filter,也就避免了对代码的侵入性。
这里的业务逻辑执行前后的扩展也是通过责任链的模式来执行一个个的的 slot, 我们先定义好时间戳校验,签名校验,Session转id等 slot, 然后在 xml 中指定这些 slot 的执行顺序 另外注意高亮的 dubboSlot 阶段,在 dubbo 2.7 之前 dubbo 底层返回 Future(会一直占用一个线程轮询结果),对异步编程不友好,2.7 之后返回了 CompleteFuture,与 webflux 的异步编程模型完美结合(发起调用嵌入式网关后立马返回,等调用完成后才执行,是真正的异步)。 嵌入式网关设计 首先我们要明白为啥会有嵌入式网关的需求,主要有三个原因
那么嵌入式网关如何实现呢,业务服务是以 dubbo 服务的形式存在的,而在 dubbo 中有一个 Filter 机制,是专门为服务提供方和服务消费方调用过程进行拦截设计的,每次远程方法执行,该拦截都会被执行。这样就为开发者提供了非常方便的扩展性,所以嵌入式网关的主要设计思路就是自定义 dubbo 的 filter,然后在此 filter 中执行相关的扩展逻辑即可,伪代码如下: (编辑:唐山站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |