一、目前现状:
第三方商品,目前主要是三个,美团、京东和饿了吗,美团采用两个小时进行一次全量同步,京东目前采用一天增量同步一次数据(京东数据缓存到本地,每次去与京东商品库存价格进行对比,只同步变化的数据,达到增量同步的效果),在开店较多的情况下商品同步速度就会变慢,无法满足需求
二、新版发送中心(流程图)
1、发送中心收到商品变更请求时,去对应的第三方进行商品变更
2、若变更成功则结束,若变更失败,则进行三次尝试,三次之后依旧失败,则将失败数据记录进数据库,并记录失败原因
3、定时扫描失败记录表,向上游发送消息,请求再次同步(以此来达到保证百分百成功),或者提供页面,人为进行商品重试,同时定期清理失败记录表
具体同步流程提炼为一个抽象类,美团、京东、饿了么去重载实现具体的业务,整体同步框架固定不变(开始同步数据到同步数据结束)
service:
接口:SyncService(作用:同步商品)
方法:Object sync(Object obj,ThirdTypeEnum thirdType,String appKey,String interface,int count,boolean retry);obj 同步参数,thirdType 第三方类型 appKey 第三方账号 interface 具体接口 count 重试次数,retry是否进行异步尝试
方法:Object get(Object obj,ThirdTypeEnum thirdType,String appKey,String interface,int count);obj 同步参数,thirdType 第三方类型 appKey 第三方账号 interface 具体接口 count 重试次数
抽象service AbstractSyncService(主要负责从开始同步数据到结束的整个流程) 实现SyncService接口
新增抽象方法:
JSONObject getToken(String appKey);
String getSign(String interface,JSONObject common,Object obj);
String buildUrl(String interface,String methodType,String sign,JSONObject common,Object obj);
实现方法sync(Object obj,ThirdTypeEnum thirdType,String appKey,String interface,int count,boolean retry);
1、如果count<max(默认三次)则执行下列步骤,超过max结束
2、验证参数(obj/thirdType/appKey/interface),若参数为空则返回
3、根据appKey调用getToken获取token和公共参数
4、根据接口和上一步获取的信息和待更新的参数一起获取加密签名
5、根据interface methodType common obj)获取构建请求url
6、调用thirdparty进行消息发送
7、若成功则删除之前同类型的请求失败信息并结束返回数据,如不成功判断count++,若count++<max则进行重新同步,若count++>max则进行失败记录并记录失败原因
实现方法get(Object obj,ThirdTypeEnum thirdType,String appKey,String interface,int count);
1、如果count<max(默认三次)则执行下列步骤,超过max结束
2、验证参数(obj/thirdType/appKey/interface),若参数为空则返回
3、根据appKey调用getToken获取token和公共参数
4、根据接口和上一步获取的信息和待更新的参数一起获取加密签名
5、根据interface methodType common obj)获取构建请求url
6、调用thirdparty进行消息发送
7、若成功则返回数据,如不成功判断count++,若count++<max则进行重新获取
具体第三方SyncServiceImpl:
MeituanSyncServiceImpl 继承自AbstractSyncService 并实现三个抽象方法
1、getToken(String appKey);
根据appKey去数据库获取appSecret(数据库以key/value方式进行存储,一个key对应一条数据),最终把list转化为JSONObject common字典(美团只有appId和appSecret),并添加timestamp参数为当前时间戳秒数
2、getSign(String interface,JSONObject common,Object obj);
①、把common对象和obj对象转化为一个字典
②、把字典按照key升序(排除掉appSecret)按照key=value链接中间用&符拼接
③、把url详细地址+"?"+2得到的字符串+appSecret的值进行拼接
④、对3得到的字符串进行md5加密得到最终的sign
3、buildUrl(String interface,String methodType,String sign,JSONObject common,Object obj) 方法实现
①、若是get请求则把common参数和obj参数(排除掉appSecret)以?方式拼接在url后面并追加&sign为2中得到的签名
②、若是post请求,则把common参数(排除掉appSecret)和sign以?方式拼接在url后面,obj参数以body方式进行发送
JdSyncServiceImpl继承自AbstractSyncService 并实现三个抽象方法
1、getToken(String appKey);
根据appKey去数据库获取appSecret等信息(数据库以key/value方式进行存储,一个key对应一条数据),最终把list转化为JSONObject common字典(京东包含信息token/appKey/appSecret/format/v等参数),并添加timestamp参数(提前一分钟避免因为响应时间造成问题,API要求6分钟之内即可)并转化为字符串形式(yyyy-MM-dd HH:mm:ss)
2、getSign(String interface,JSONObject common,Object obj);
①、把common对象转化为一个字典,并把obj转化为json传以jd_param_json为key存储进json
②、把字典按照key升序(排除掉appSecret)按照keyvalue链接中间用空字符拼接得到str
③、把appSecret+str+appSecret拼接之后进行md5加密并转化为大写得到最终的签名
3、buildUrl(String interface,String methodType,String sign,JSONObject common,Object obj) 方法实现
①、则把common参数(排除掉appSecret)和sign参数转化为字典,并加入obj(obj 转化为json,以jd_param_json为key)以body形式进行发送
ElemeSyncServiceImpl继承自AbstractSyncService 并实现三个抽象方法
1、getToken(String appKey);
失败记录Service(记录同步失败的操作记录,便于后期进行异步重试)(添加、删除、查询)(商品ID、操作类型(添加、修改,同步库存等等),第三方店家/appKey/时间/是否重试)
异常logService 把同步失败的原因进行记录,便于后期进行维护(添加 查询)(失败记录ID、第三方类型、操作、异常code、异常msg、异常原因)
token管理(添加新的token (新账号) 修改(定时同步token策略),查询 查询token用于数据同步)
三、发送中心(第一期要对接的接口)
对外暴露sc接口:
美团service (关于美团的操作)
京东Service (关于京东的一系列操作)
饿了么Service (关于饿了么的一些列操作)
token管理(添加token 上游新加业态/token更新接口)
异常记录接口(查询)
异常日志接口(查询)
具体实现方案:
1、提供n个service(一个第三方一个service),分别对接特定的第三方,底层抽象一个统一的发送模型(三次重试,错误记录,接口限制),对应的第三方去实现具体的方法逻辑(具体的token获取、参数加密、url拼接)
2、对外暴露一个service,把所有的第三方采用统一入口,对外暴露统一的数据入口,把对应的参数转化作为规则存储进数据库(出参也是一样),数据库存储对应的方法指向的第三方请求的接口
备注:
第一种方案逻辑较清晰,出问题时可以进行快速定位,并且各个第三方之间相互不会受影响
第二种方案:所有接口采用统一入参模型,接入相对简单,并且有需求变更时不需要重新项目可以进行无缝对接,但是开发难度较高,参数转化模型要进行缜密测试,并且由于不通第三方加密规则和传参方式不同,要进行统一开发,需要实现先定义好较丰富的规则逻辑,以满足不同第三方的需求变化