本文主要从我们为什么需要CR?CR面临哪些挑战?CR的最佳实践几个方面分析,希望可以给读者一些参考。
文章来源:https://www.toymoban.com/news/detail-608824.html
为什么需要CR?
代码质量
技术交流
卓越工程
CR面临哪些挑战?
挑战1:CR的代码改动范围过大
挑战2:CR对评审者全局知识要求很高
- public Level queryLevel(LevelQueryRequest request) {
+ public Level queryLevelWithExpireRefresh(LevelQueryRequest request) {
Level result = levelRepository.findLevelWithoutInit(request.getId());
if (null == result || isExpired(result.getEndTime())) {
// 如果等级为空,兜底返回L0;等级已过期,实时返回默认等级,并异步刷新
if (result == null) {
result = levelRepository.buildInitLevel(request.getId(), LevelEnum.L0);
}
//查询为空,或者已过期发送消息,刷新等级
- LevelRefreshRequest refreshRequest = buildRefreshRequest(request);
- levelWriteService.refreshLevel(message.getId(), refreshRequest);
+ RefreshMessage refreshMessage = buildRefreshMessage(request);
+ refreshMessageProducer.sendMessage(refreshMessage);
}
return result;
}
- public class RefreshMessageListener extends AbstractMessageListener {
+ public class RefreshMessageListener extends AbstractOrderlyMessageListener {
@Autowired
- private LevelWriteService levelWriteService;
+ private LevelWriteRegionalService levelWriteRegionalService;
@Override
protected boolean process(String tags, String msgId, String receivedMsg) {
RefreshMessage message = JSON.parseObject(receivedMsg, RefreshMessage.class);
if (message == null || message.getId() == null) {
log.warn("message is invalid, ignored, src={}", receivedMsg);
return true;
}
LevelRefreshRequest refreshRequest = buildRefreshRequest(message);
- levelWriteService.refreshLevel(message.getId(), refreshRequest);
+ levelWriteRegionalService.refreshLevel(message.getId(), refreshRequest);
return true;
}
}
-
为什么存在等级为空的情况?
-
为什么要设计成读时写?
-
为什么不是直接计算等级,而需要用消息队列?
-
为什么要用Regional(区域化)接口和有序消息刷新等级?
挑战3:CR价值最大化需要团队具备卓越工程基因
CASE1:一个业务使用3个时间穿越开关
背景
private static final String CODE = "BENEFIT_TIME_THROUGH";
public Date driftedNow(String userId) {
try {
TimeMockResult<Long> result = timeThroughService.getFutureTime(CODE, userId);
if (result.isSuccess()) {
return new Date(result.getData());
}
} catch (Throwable t) {
log.error("timeThroughService error. userId={}", userId, t);
}
return new Date();
}
观点1:彻底服务化
观点2:富客户端
观点3:配置统一,重复代码三处收拢为两处
总结:
CASE2:SSR(服务端渲染)API稳定性优化
背景
// 提交任务
ioTaskList.stream().forEach(t -> futures.add(pool.submit(() -> t.service.invoke())));
// 阻塞获取任务结果
futures.stream().forEach(f -> {
try {
result.add(f.get());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
});
Step1:增加固定超时控制
// 提交任务
ioTaskList.stream().forEach(t -> futures.add(pool.submit(() -> t.service.invoke())));
// 阻塞获取任务结果
futures.stream().forEach(f -> {
try {
- result.add(f.get());
+ result.add(f.get(1000, TimeUnit.MICROSECONDS));
} catch (Exception e) {
log.error(e.getMessage(), e);
}
});
Step2:自适应超时控制
public abstract class BaseService<T> implements Service {
@Override
public T invoke(ServiceContext context) {
Entry entry = null;
try {
// 根据service类别构造降级资源
String resourceName = "RESOURCE_" + name();
entry = SphU.entry(resourceName);
try {
// 未触发降级,正常调用后端服务
return realInvoke(context);
} catch (Exception e) {
// 业务异常,记录错误日志,返回出错信息
return failureResult(context);
}
} catch (BlockException e) {
// 被降级,可以fail fast或返回兜底数据
return degradeResult(context);
} finally {
entry.exit();
}
}
public abstract T realInvoke();
}
Step3:自适应超时控制+自定义资源key
public abstract class BaseService<T> implements Service {
@Override
public T invoke(ServiceContext context) {
Entry entry = null;
try {
// 这里的key由service实现,融合了服务类型和自定义key构造降级资源
String resourceName = "RESOURCE_" + key(context);
entry = SphU.entry(resourceName);
try {
// 未触发降级,正常调用后端服务
return realInvoke(context);
} catch (Exception e) {
// 业务异常,记录错误日志,返回出错信息
return failureResult(context);
}
} catch (BlockException e) {
// 被降级,可以fail fast或返回兜底数据
return degradeResult(context);
} finally {
entry.exit();
}
}
public abstract String key(ServiceContext context);
public abstract T realInvoke();
}
总结:
CR有没有最佳实践?
Code Review的边界
出发点:程序员的初心
看不见的手:自动代码扫描
看得见的手:Team Leader的重视
参考:
-
https://en.wikipedia.org/wiki/Code_review -
https://smartbear.com/learn/code-review/agile-code-review-process/ -
Lessons From Google: How Code Reviews Build Company Culture -
阿里巴巴Java编码规约:https://github.com/alibaba/p3c -
五种Code Review反模式:https://blogs.oracle.com/javamagazine/post/five-code-review-antipatterns -
Capers Jones对软件质量的研究分享:http://sqgne.org/presentations/2012-13/Jones-Sep-2012.pdf -
Modern Code Review: A Case Study at Google:https://sback.it/publications/icse2018seip.pdf -
智能编码插件:https://developer.aliyun.com/tool/cosy
作者| 文章来源地址https://www.toymoban.com/news/detail-608824.html
到了这里,关于卓越工程之如何做好Code Review的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!