[代码重构](master): 更新了文档

Java避坑建议
master
土豆兄弟 2 years ago
parent e24127e961
commit bfd944ba4a

@ -1574,6 +1574,65 @@ return orderDO;
- TODO 借助这个话题来讨论设计模式在实际开发中的使用, 来优化我们的代码设计 - TODO 借助这个话题来讨论设计模式在实际开发中的使用, 来优化我们的代码设计
### 3.22 设计 - 接口设计:系统间对话的语言,一定要统一 ### 3.22 设计 - 接口设计:系统间对话的语言,一定要统一
- 开发一个服务的第一步就是设计接口。接口的设计需要考虑的点非常多,比如
- 接口的命名、参数列表、包装结构体、接口粒度、版本策略、幂等性实现、同步异步处理方式等。
- 和接口设计相关比较重要的点有三个
- 分别是包装结构体、版本策略、同步异步处理方式。
#### A. 接口的响应要明确表示接口的处理结果
- 我曾遇到过一个处理收单的收单中心项目,下单接口返回的响应体中,包含了 success、code、info、message 等属性,以及二级嵌套对象 data 结构体。在对项目进行重构的时候,我们发现真的是无从入手,接口缺少文档,代码一有改动就出错。
- 有时候下单操作的响应结果是这样的success 是 true、message 是 OK貌似代表下单成功了但 info 里却提示订单存在风险code 是一个 5001 的错误码data 中能看到订单状态是 Cancelled订单 ID 是 -1好像又说明没有下单成功。
```json
{
"success": true,
"code": 5001,
"info": "Risk order detected",
"message": "OK",
"data": {
"orderStatus": "Cancelled",
"orderId": -1
}
}
```
- 有些时候这个下单接口又会返回这样的结果success 是 falsemessage 提示非法用户ID看上去下单失败但 data 里的 orderStatus 是 Created、info 是空、code 是 0。那么这次下单到底是成功还是失败呢
```json
{
"success": false,
"code": 0,
"info": "",
"message": "Illegal userId",
"data": {
"orderStatus": "Created",
"orderId": 0
}
}
```
- 这样的结果,让我们非常疑惑:
- 结构体的 code 和 HTTP 响应状态码,是什么关系?
- success 到底代表下单成功还是失败?
- info 和 message 的区别是什么?
- data 中永远都有数据吗?什么时候应该去查询 data
- 造成如此混乱的原因是:这个收单服务本身并不真正处理下单操作,只是做一些预校验和预处理;真正的下单操作,需要在收单服务内部调用另一个订单服务来处理;订单服务处理完成后,会返回订单状态和 ID
- 为了将接口设计得更合理,我们需要考虑如下两个原则:
- 对外隐藏内部实现。虽然说收单服务调用订单服务进行真正的下单操作,但是直接接口其实是收单服务提供的,收单服务不应该“直接”暴露其背后订单服务的状态码、错误描述。
- 设计接口结构时,明确每个字段的含义,以及客户端的处理方式。
-
### 3.23 设计 - 缓存设计:缓存可以锦上添花也可以落井下石 ### 3.23 设计 - 缓存设计:缓存可以锦上添花也可以落井下石
@ -2003,3 +2062,33 @@ wrk -t 10 -c 50 10s http://localhost:45678/redisvsmysql/mysql --latency
- mongo数据库的使用建议 - mongo数据库的使用建议
- 非重要数据并且数据结构不固定的插入量又很大的原始数据比如爬虫原始数据可以考虑Mongo。从个人喜好而言综合性NOSQL我更喜欢ES而不是MongoMongo在数据量到TB级别我感觉不稳定Sharding也不那么好用 - 非重要数据并且数据结构不固定的插入量又很大的原始数据比如爬虫原始数据可以考虑Mongo。从个人喜好而言综合性NOSQL我更喜欢ES而不是MongoMongo在数据量到TB级别我感觉不稳定Sharding也不那么好用
### 3.30 安全 - 如何正确保存和传输敏感数据
### n. 总结
#### n.1 Java避坑建议
- 1- 遇到自己不熟悉的新类,在不了解之前不要随意使用
- CopyOnWriteArrayList。如果你仅仅认为CopyOnWriteArrayList 是 ArrayList 的线程安全版本,在不知晓原理之前把它用于大量写操作的场景,那么很可能会遇到性能问题。
- 越普适的工具类通常用起来越简单,越高级的类用起来越复杂,也更容易踩坑。代码加锁这一讲中提到的,锁工具类 StampedLock 就比 ReentrantLock 或者 synchronized 的用法复杂得多,很容易踩坑。
- 2- 尽量使用更高层次的框架
- 偏底层的框架趋向于提供更多细节的配置,尽可能让使用者根据自己的需求来进行不同的配置,而较少考虑最佳实践的问题;而高层次的框架,则会更多地考虑怎么方便开发者开箱即用。
- 谈到 Apache HttpClient 的并发数限制问题。如果你使用 Spring Cloud Feign 搭配 HttpClient就不会遇到单域名默认 2 个并发连接的问题。因为Spring Cloud Feign 已经把这个参数设置为了 50。
- 3- 关注各种框架和组件的安全补丁和版本更新
- 更新升级,以避免组件和框架本身的性能问题或安全问题带来的大坑。
- 4- 尽量少自己造轮子,使用流行的框架
- 如果我们自己去开发框架的话,很可能会踩一些别人已经踩过的坑。使用 Netty 开发 NIO 网络程序,不但简单而且可以少踩很多坑。
- 5- 开发的时候遇到错误,除了搜索解决方案外,更重要的是理解原理
- 只有知其所以然,才能从根本上避免踩坑。
- 6- 网络上的资料有很多,但不一定可靠,最可靠的还是官方文档
- 对于系统学习某个组件或框架,我最推荐的还是 JDK 或者三方库的官方文档。这些文档基本不会出现错误的示例,一般也会提到使用的最佳实践,以及最需要注意的点
- 7- 做好单元测试和性能测试
- 没有经过性能测试的代码,只能认为是完成了功能,还不能确保健壮性、可扩展性和可靠性。
- 8- 做好设计评审和代码审查工作
- 人都会犯错,而且任何一个人的知识都有盲区。每一段代码都能有至少三个人进行代码审核,就可以极大地减少犯错的可能性。
- 9- 借助工具帮我们避坑
- 使用工具来检测,就可以避免大量的低级错误
- 10- 做好完善的监控报警
- 基于合理阈值设置报警,那么可能就能在事故的婴儿阶段及时发现问题、解决问题。

Loading…
Cancel
Save