易用性

易用性听起来更像是一个评判产品的标准。没错,我们在开发这样一个技术框架的时候,也要有产品意识。框架是否易集成、易插拔、跟业务代码是否松耦合、提供的接口是否够灵活等等,都是我们应该花心思去思考和设计的。有的时候,文档写得好坏甚至都有可能决定一个框架是否受欢迎。

性能

对于需要集成到业务系统的框架来说,我们不希望框架本身的代码执行效率,对业务系统有太多性能上的影响。对于性能计数器这个框架来说,一方面,我们希望它是低延迟的,也就是说,统计代码不影响或很少影响接口本身的响应时间;另一方面,我们希望框架本身对内存的消耗不能太大。

扩展性

这里说的扩展性跟之前讲到的代码的扩展性有点类似,都是指在不修改或尽量少修改代码的情况下添加新的功能。但是这两者也有区别。之前讲到的扩展是从框架代码开发者的角度来说的。这里所说的扩展是从框架使用者的角度来说的,特指使用者可以在不修改框架源码,甚至不拿到框架源码的情况下,为框架扩展新的功能。这就有点类似给框架开发插件。关于这一点,我举一个例子来解释一下。feign 是一个 HTTP 客户端框架,我们可以在不修改框架源码的情况下,用如下方式来扩展我们自己的编解码方式、日志、拦截器等。

  1. Feign feign = Feign.builder()
  2. .logger(new CustomizedLogger())
  3. .encoder(new FormEncoder(new JacksonEncoder()))
  4. .decoder(new JacksonDecoder())
  5. .errorDecoder(new ResponseErrorDecoder())
  6. .requestInterceptor(new RequestHeadersInterceptor()).build();
  7. public class RequestHeadersInterceptor implements RequestInterceptor {
  8. @Override
  9. public void apply(RequestTemplate template) {
  10. template.header("appId", "...");
  11. template.header("version", "...");
  12. template.header("timestamp", "...");
  13. template.header("token", "...");
  14. template.header("idempotent-token", "...");
  15. template.header("sequence-id", "...");
  16. }
  17. public class CustomizedLogger extends feign.Logger {
  18. //...
  19. }
  20. public class ResponseErrorDecoder implements ErrorDecoder {
  21. @Override
  22. public Exception decode(String methodKey, Response response) {
  23. //...
  24. }
  25. }

容错性

容错性这一点也非常重要。对于性能计数器框架来说,不能因为框架本身的异常导致接口请求出错。所以,我们要对框架可能存在的各种异常情况都考虑全面,对外暴露的接口抛出的所有运行时、非运行时异常都进行捕获处理。

通用性

为了提高框架的复用性,能够灵活应用到各种场景中。框架在设计的时候,要尽可能通用。我们要多去思考一下,除了接口统计这样一个需求,还可以适用到其他哪些场景中,比如是否还可以处理其他事件的统计信息,比如 SQL 请求时间的统计信息、业务统计信息(比如支付成功率)等。

安全性

稳定性&可用性

监控预警

是否有完备的监控机制,预警机制。

编译部署

怎么做编译,怎么做部署

架构

架构是否合理,在整个业务大图里,需要放到哪个位置上去。

参考

几个设计原则:

  1. 兼容性:新旧版接口兼容,客户端历史版本兼容,开放服务的新旧接入业务兼容;
  2. 扩展性:系统具备扩展能力和负载水平伸缩能力;
  3. 高性能:服务具备高吞吐低时延;
  4. 高可用:系统具备几级容灾等级,核心服务容灾等级4
  5. 高可靠:有良好的RTO(恢复时间目标)和RPO(恢复点目标)表现,节点重启、宕机变更数据不丢;代理支持热切换和热重启;节点异常快速剔除能力
  6. 边界划分清晰:系统边界清晰,低耦合