右上图展示了要转换代码需要填写的信息,左上图展示了整个接口调用所需要的步骤,依次总共需要8步。
架构组这套方案是有缺陷的:
1.步骤繁琐,耗时,沟通成本高。
2.无法解析泛型,需另开发一个不含有泛型的接口,比如XXXforPHP。
3.一个接口涉及多个服务调用,本地调试时无法同时调试线上和沙箱服务。
右上图展示了代码转化工具的使用方法,左上图展示了实现接口调用的整个步骤,共需7步。
从架构组方案迭代到安居客方案,沟通成本相对减少,但是也是有其缺陷的:
1.步骤还是相对比较复杂,比较耗时。
2.遇到泛型需要去询问服务方是何种泛型,不能自动解析。
3.一个接口涉及多个服务调用,本地调试时无法同时调试线上和沙箱服务。
4.转换代码是一种离线模式,同时不能下载多个服务。
现在存在的问题有以下几点:
1.步骤太多,既耗时开发效率也低。
2.代码转换完以后需要自己将代码拷贝到项目中的指定目录(有很多同学因为目录拷贝错误导致接口调不通)。
3.泛型不能自动解析。
4.本地接口涉及多个服务时,不能同时调试线上和沙箱服务。
从现有方案可以看出,现在PHP调用Java接口步骤是很繁琐的,开发效率偏低。 而且还有两个问题: 泛型无法解析、不便本地调试。 所以要进行重构来解决这些问题。 重构要围绕下面三个方向进行:
具体实现流程如下。
第一步:实现代码工程化管理。
从PHPbase拿到解析坐标后的数据,也就是那个JSON数据,反解析获取到三个包含contract、entity、enum的数组。
下面三个图展示了三个数组的部分具体内容:
第一个图是截取的contract数组中的部分信息。key是一个完整的包名,value就是这个类中的所有函数信息。我们看下第一个方法,key是由方法名字+hash值+params字符串组成。value就是入参的类型信息,可以看到有string,有object。类型是object 的就有这个对象对应的class信息。params是入参,带有return的就是出参信息。
第二个图是截取的entity数组中的部分信息。我们看到key是一个完整的包名,value是实体的字段信息。比如第一个字段排序是第一个,不是泛型,类型是list,子元素类型是object,elem_class就是这个object的包名信息。key为998对应的value就是Java中注解SCFSerializer.name的值
第三个图是截取的enum数组中的部分信息。key是完整包名,value就是各个常量的值。
数组信息分析完,看下具体解析过程。contract数组解析流程图如下所示:
拿到contract数组循环遍历,对于类文件的目录我们用的是包名+固定路径“Libs/wscfcore/package”,为了防止和项目中已有的代码相区别,我们将代码放到了libs/wscfcore/package下。命名空间也是包名信息+刚才那个固定路径,大家可以看下右上方这个图。对于类文件的依赖,也是包括两部分,一个是固定的依赖 “use libswscfcoreclient”,这个是因为类中的构造方法用到了scf client的实例化。依赖的另一部分就是参数中用到的引用。生成方法的时候要考虑两个问题,一个是重名问题,一个是序列化问题。
当方法重名的时候我们用0,1来进行区分,比如getInfo0,getInfo1。这里面有一个坑,就是要考虑下每次生成这个方法时的顺序问题,因为方法重名里面的参数个数是不一样的,所以名字绝对不能变换顺序。我们为了防止发生顺序变更问题,在Java代码生成的时候用到了一个hash值。就是将方法名、入参、出参做了一个hash值,这个肯定是唯一的,通过这个来保证顺序不变。
生成方法的时候还要考虑第二个问题那就是序列化的问题,我们看下右上方这个图,对于第四个参数的类型是非基础类型,所以这个类型序列化时对应的typeID也就是hash值就从这个类的包名来获取,通过在这建立全局数组,在后边生成typeID的时候获取这个参数的包名信息。$params这个参数里面包含了lookup,methodName,以及入参信息。
entity数组解析流程图如下所示:
生成实体的过程中也要生成目录,命名空间,依赖。这些同contract的分析是一样的,就不赘述了。实体的构造方法我们看右上图可以看出是对静态变量TSPEC赋值的过程。这个变量是一个数组,里面包含了各个字段的信息,名字var,顺序orderID,是不是泛型isGeneric,以及类型type。对于复杂类型list也要生成它的子元素的类型。这个类型信息在从服务器拿到二进制流数据进行反序列化的时候要用到,类型必须和其相同才能正确的解析出来。如果这个实体类有继承,那么也要生成这个类的继承类。
enum数组解析如下图所示:
Enum的解析就简单些了。要生成目录,命名空间,const信息。const信息遍历enum数组即可。到这Java代码到PHP代码的转化就完成了,并生成在了指定位置。我们再也不用手动拷贝代码了。避免了因为拷贝代码路径出错导致的接口调不通问题。
第二步:解决泛型解析问题。
Java同学是知道泛型对应的具体是何种类型,就是他们开发的实体中的某一个,不过PHP同学是不知道的。但是这个泛型序列化以后的typeID值也就是hashcode值我们可以拿到,那么我们将所有实体做一个hash计算,然后我们反推是不是就可以知道泛型是哪个实体了呢?
所以优化build.php文件,收集服务的实体和枚举信息,进行hash计算。我们现在有scfv1、scfv3两种协议,不同协议对应的typeID是不同的,所以针对这两种协议进行hash计算。对于scfv1协议,若实体中有scheme字段(998),那么对scheme字段进行。若没有,则对类名进行hash计算。而对于scfv3协议是对整个包名进行计算。有了这个hash文件就可以解析泛型了。
第三步:解决本地无法同时调试线上和沙箱服务的问题。增加沙箱配置文件,方便开发者进行调试。文件如下图所示:
服务名字和沙箱IP要准确对应上。底层获取服务信息时,判断有此文件,拿到服务的信息就可以直接走沙箱服务了。对于不存在于此文件的服务是走线上的。如果将代码放到沙箱环境,灰度的申请就可以用这个文件代替了,省去了申请的操作。
第四步:将步骤由8步减少为3步。
下面这个图是IHouseService类的内容,可以看到实例化此类要传入服务名serviceName,查找类lookup,分别对应上图中的hmc、HouseService
从集团方案迭代到租房方案,调用步骤由原来的八步减少到了现在的三步。
租房方案的实现代码的目录结构展示如下所示:
wscfcore这个目录是包括了所有scf相关的文件。Hashdata这个目录里面放的是hash文件。package.lock里面存储了所有项目中目前已经下载的服务坐标信息,存的是字符串。package目录里面存的是所有下载的代码。Build文件是整个代码的核心,根据坐标拉取Java代码然后再转化为PHP代码放在指定位置。service.xml文件是存放我们要下载的服务的pom坐标,采用xml格式方便大家直接将坐标信息复制粘贴即可。wscfcore目录会放到composer中供大家下载使用。
PHP同学用这套代码,调用某个服务的接口时,实现了PHP同学调Java接口就像Java同学调Java接口是一样的,是一种无痕式的调用。
分享标题:一种支持泛型解析的PHPScf无痕化技术方案
网页路径:http://www.csdahua.cn/qtweb/news39/518089.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网