失效链接处理 |
2021阿里技术人的百宝黑皮书 PDF 下载
本站整理下载:
相关截图:
![]()
主要内容:
谈谈Java接口Result设计
这篇文章酝酿了很久,一直想写,却一直觉得似乎要讲的东西有点杂,又不是很容易讲清楚,又怕争议的地方很
多,就一拖再拖。但是,每次看到不少遇到跟这个设计相关导致的问题,又忍不住跟人讨论,但又很难一次说清
楚,于是总后悔没有及早把自己的观点写成文章。不管怎样,观点还是要表达的,无论对错。
作者:书牧
出品:淘系技术 故障的推手——“Result"
先说结论:接口方法,尤其是对外HSF(开源版本即dubbo) api,接口异常建议不要使用Result,而应该使用异
常。阿里内部的java编码,已经习惯性对外API一股脑儿使用“Result”设计——这是导致许多故障的重要原因!
// 用户查询的HSF服务API,使用了Result做为返回结果
public interface UserService {
Result<User> getUserById(Long userId);
}
// 一段客户端应用facade的调用示例。读写缓存逻辑部分省略,仅做示意
public User testGetUser(Long userId) {
String userKey = "userId-" + userId;
// 先查缓存,如果命中则返回缓存中的user
// cacheManager.get(123, userKey);
// ...
try{
Result<User> result = userService.getUserById(userId);
if (result.isSuccess()) {
cacheManager.put(123, userKey, result.getData());
一个简化的例子
后端篇
技术人的百宝黑皮书2021版
淘系技术出品
01 年度精选技术栈内容
后端篇/技术经典总结
1234123456789
10
11
2
上面的代码很简单,客户端应用对User查询服务做了个缓存。有些同学可能一眼就看出来,这里隐藏的bug:第10
行的“result.isSuccess()”为false的实际含义是什么?是服务端系统异常吗?还是用户不存在?光看API是很难
确定的。不得不去找服务提供方或文档确认其逻辑,根据错误码进行区分。如果是服务端系统异常,那么第15行将
导致线上bug,因为后续1小时对该用户的请求都认为用户不存在了。
严谨点的写法
如果要写正确逻辑,那么代码可能会变成这样:
技术人的百宝黑皮书2021版
淘系技术出品
01 年度精选技术栈内容
后端篇/技术经典总结
18
return result.getData();
}
// 否则缓存空对象,代表用户不存在
cacheManager.put(123, userKey, NullCacheObject.getInstance(), 3600);
return null;
} catch (Exception e) {
// TODO log
throw new DemoException("getUserById error. userId=" + userId, e);
}
}
public User testGetUser(Long userId) {
String userKey = "userId-" + userId;
// 先查缓存,如果命中则返回缓存中的user
// cacheManager.get(123, userKey);
// ...
try{
Result<User> result = userService.getUserById(userId);
if (result.isSuccess()) {
cacheManager.put(123, userKey, result.getData());
return result.getData();
}
if ("USER_NOT_FOUND".equals(result.getCode())) {
// 否则缓存空对象,代表用户不存在
cacheManager.put(123, userKey, NullCacheObject.getInstance(), 3600);
} else {
// 可能是SYSTEM_ERROR、DB_ERROR等一些系统性的异常,TODO log
throw new DemoException("getUserById error. userId=" + userId + ", result=" + result);
|