自定义头部 -->
Dubbo的接口设计&编写规范
Published on 2020-03-22 11:39 in 分类: MicroServer , Dubbo with AllenAlan

Dubbo的接口设计&编写规范

Dubbo的接口设计&编写规范

action->facade->biz->dao

好的Dubbo服务接口设计,并非只是纯粹的接口服务化

接口类型

同步&异步

  • 简单的数据查询接口:action -> facade -> dao(例根据Id查询记录)
  • 带业务逻辑的数据查询接口:action -> facade -> biz -> dao(复杂的查询,带业务逻辑)
  • 简单的数据写入接口:action -> facade -> dao(简单数据插入)
  • 带业务逻辑的数据写入接口:action -> facade ->biz -> dao(有业务逻辑的数据处理)

设计原则

  • 服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将地面临分布式事务问题

  • Dubbo暂未提供分布式事务支持,同时可以减少系统间的网络交互

  • 服务接口建议以业务场景为单位划分,并对相近的业务做抽象,防止接口数量爆增(爆炸)。

  • 不建议使用过于抽象的通用接口,如Map query(Map),这样的接口没有明确语义,会给后期维护带来不便

  • 给每个接口默认分配一个版本, 方便升级维护

接口兼容性

  • 服务接口增加方法,或服务模型增加字段,可向后兼容

  • 删除方法或删除字段,将不兼容,枚举类型新增字段也不兼容,需要通过变更版本号升级

异常处理

  • 建议使用异常汇报错误,而不是返回错误码,异常信息能携带更多的信息,以及语义更友好。

  • 如果担心性能问题,可以通过override掉异常类的finlllnStackTrace()方法为空方法,使其不拷贝栈信息。

  • 查询方法不建议抛出checked异常, 或者说让Consumer尽量减少接受异常的种类

  • Provider上尽量多配置Consumer端的属性, 让Provider实现者一开始就思考Provider服务特点、服务质量的问题


简单聊下

Specification 模式解决接口爆炸问题

public interface UserMainProvider {
    UserMainDTO findByUserId(Long userId);
    UserMainDTO findByUsername(String username);
    List<UserMainDTO> listByUsername(Long username);
    List<UserMainDTO> listByNickname(Long nickname);
}

先不要纠结我有没有写注释, 像这样的接口书写方式,后期业务复杂的话肯定会出现接口爆炸的情况

我们可以这样修改:

public interface UserMainProvider {

    UserMainDTO findByUsername(UserMainSpec spec);
    List<UserMainDTO> listByUsername(UserMainSpec spec);
    PageInfo<UserMainDTO> page(UserMainPageSpec spec);

}

如果你了解领域驱动设计,会发现这里借鉴了其中 Specification 模式的思想。不清楚自行google吧

单参数易于管理

我们可以定义个抽象父类,方便做一些统一的做一些东西, 例如公用参数, 切面对象等等

@Data
public abstract class RpcSpecification<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    /** 追溯ID */
    private String traceId;
    /** 操作类型*/
    private OperationTypeEnum operationType;
    /** client IP */
    private String clientIP;
    /** client name */
    private String clientName;
}

接口异常设计

如果是dubbo 这种裸体rpc的话我还是建议通过抛异常的形式处理, 当然很多人在REST风格的影响下,也会封装一个对象, 这太麻烦, 每次都要解析对象处理各种code的场景,

我们可以这样做:

  • Provider 尽量处理异常
  • 定义一个全局异常放在公用包中.
  • Consumer 也不要傻傻的一个一个处理了, 建议用@ExceptionHandler 统一处理全局异常.

可参考<Dubbo的异常处理>这篇文章

好了就这些, 欢迎关注, 转发, 评论, 点赞~

posted @   AllenAlan  阅读(3682)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
点击右上角即可分享
微信分享提示