rpc服务设计
包的划分
-
xxx-api : api给调用方使用
-
xxx-core:业务实现 【具体可以再分吧】
-
xxx-job: 任务
-
xxx-web :部署 maven profile环境【没有统一的配置中心】
接口设计原则:
异常区分
-
rpc框架异常
-
系统异常
-
业务异常
接口设计
-
业务成功
-
是否重试 【rpc框架配置】
-
异常处理
基于dubbo的问题
A服务--> B服务
-
中间网络异常:访问超时
-
B服务宕机:访问超时
-
B服务rpc框架异常:抛出rpc框架异常
-
B服务系统异常:内部异常或者业务异常
dubbo服务为例,默认重试2次,如果有多个提供值默认随机选另外一个,重试之内在调不通调用b服务跑出RpcException,如果配置上mock降级,返回null,看业务
dubbo服务化最佳实战
-
分包: api,core,web; 建议将服务接口,服务模型,服务异常等均放在API包中
-
粒度:服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,
服务分为:原子服务(订单的crud等),核心(业务)服务,只做查询的查询服务等,接口 入参 出参 要明确 拒绝:Map query(Map)
-
版本:每个接口都应该有版本号
-
兼容性: 服务接口增加方法,或服务模型增加字段,可向后兼容(删除方法或删除字段,将不兼容,枚举类型新增字段也不兼容,需通过变更版本号升级)
-
异常:处理RpcException框架异常,其他的不建议跑出异常,建议定义 code和msg描述问题,查找问题的时候在b服务的机器上面查询,异常带来反序列化等性能问题,
RpcException问题看业务A---->B--->C,业务场景是否可以降级等
- 服务的配置尽量在服务提供者方面配置完善,考虑该服务相关问题
接口方法的是否重试,并发量,超时时间,是否mock, 复杂均衡策略,失效转移策略,综合接口是查询,幂等等考虑
-
分布式服务中,所有的服务都可能不可靠,对一个服务内的 调用确保一个服务 的相关业务
-
服务级别:细粒度服务提供数据操作,不涉及业务的基础服务,以及业务聚合服务,避免分布式事务
分布式rpc调用分析
电商常用的 优惠券,订单服务, 支付服务
- 流程:
三个独立的服务,单独的db库;先来考虑下单的服务调用
-
下单之前用户必然要先选择优惠券,所以下单之前要调用扣减优惠券走rpc调用(失败到此结果提示扣减优惠券失败),调用成功走用户下单流程
-
如果下单失败,必然要回滚扣掉的优惠券,怎么操作?走rpc添加优惠券,如果此时优惠券服务超时了就添加不成功了
这里可以利用,消息队列的特性(保证消息至少成功消费一次),发一条添加刚才扣掉的优惠券消息
- 如果下单成功,就去支付,而此时支付成功但是返回结果的时候失败了?如何处理?一般此时的订单就在支付中的状态
支付失败,提示支付失败即可
- 分布式rpc调用三种状态: 失败,成功, 超时(可能成功可能失败需要特别思考)
分布式调用
非实时、非强一致性
- 走mq消息实现方式:同时做好防止重复消费,幂等性等
实时,强一致性
- 参考蘑菇街创建订单流程
-
将分布式事务,分解成多个本地事务,然后结合mq回滚
-
先创建一个状态为:不可见的订单,锁定优惠券(失败)发送废单消息
-
锁定优惠券成功,扣减库存(失败),也发送 废单消息
-
扣减库存成功修改订单为可见状态
-
只要是 废单消息 消息(回库存,回劵劵等)
网友评论