《阿里巴巴Java开发手册》条例解读(一)

简介: 《阿里Java开发规范》应该是众多程序猿多年来,在使用Java的过程中,根据踩过的雷趟过的坑,总结出来的“血的教训”或“踩坑手册”。但就像《葵花宝典》,即便是读过一百遍也成功自宫,也不见得能马上能成为武林高手,因为没练过。

《阿里Java开发规范》应该是众多程序猿多年来,在使用Java的过程中,根据踩过的雷趟过的坑,总结出来的“血的教训”或“踩坑手册”。但就像《葵花宝典》,即便是读过一百遍也成功自宫,也不见得能马上能成为武林高手,因为没练过。搞软件工程就像练武功需要实操,没有实战经验很难成为高手。评判是不是高手的标准是什么?如果仅从软件工程的角度看,很重要的一点就是交付的软件在各种高业务压力、异常情况下压不垮、跑不死、业务正常运行。而新手往往很难做出这样健壮的系统,因为健壮的系统需要规避无数的雷和坑。如果不知道这些可能存在的这样或那样的坑或雷,自然谈不上填上这些坑、避开这些雷。而且,就算在书本或规范上看过这些“宝典”,也知道这些坑的存在,但没有跌坑踩雷的亲身经历,在碰到跌坑踩雷的场景时,也可能忽略而忘记“宝典”中的“金玉良言”。为什么会忽略、为什么会不够重视,因为你没有真的痛过。痛过才能成熟,相信我,这是真的^o^
所以,聊一聊为什么会有这样的开发条例,如果不按规范来可能出现哪些问题,了解背后的故事,可能比读一百遍规范来得更有效果。

> 【6.11】【强制】并发修改同一记录时,避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存 加锁,要么在数据库层使用乐观锁,使用 version 作为更新依据”。

到底什么是“更新丢失”呢?到底会导致多严重的问题?初看这个描述,说实话一点感觉没有,如果你没有碰到过这类并发问题导致的严重事故,看完这条规范后,大概率情况下该踩的雷还得踩。
从我碰到的出镜率比较高的问题开始,分享一下开发系统中遇到过的场景。

在IOT场景下,不同的终端设备需要分配不同的物联网卡进行数据通信,最基本的限制就是一张卡只能分给一个设备。如果,一张卡分给多个设备将会导致卡被交替使用,不同的终端使用同一张卡交替上线下线,进一步导致运营商停卡和客户投诉。即便是少量的一卡多分在业务上也是很难接受的。而分卡服务必定需要部署多个服务节点,单个节点肯定无法满足大业务量需要,并发/并行地选中并占用同一张卡是必然会出现的(并发/并行处理的概念请自修)。由于大量终端请求到达服务端后,会被后端无状态服务的多个节点处理,不同的终端分卡请求会落在不同的节点上,这时不同的终端可能会被不同的服务节点分配同一张卡。比如节点A的终端TA请求占卡1,表示为1-TA,和节点B的终端请求TB占卡1,表示为1-TB。如果这2个不同节点上的请求请求以前后相差1毫秒的时间更新了数据库,导致的结果是TA分到了卡1,并返回给终端,紧接着TB也被认为分到了卡1并返回给终端,一卡多分。但系统中的最终记录是1-TB,终端TB占有卡1。可一毫秒前从业务的角度看是终端TA占的卡1。于是在接下的一段时间,终端TA和终端TB轮流使用用卡1,卡1会被不断地上线又踢下线又上线,循环反复。如下图
_

所以“更新丢失”更准确的描述是“更新覆盖”,当一个进程修改某条业务数据后会被另一个完全不知情的进程覆盖数据,导致在整个业务层面数据状态的不一致,因此“需要加锁”。但是规范中并没有明确应该怎么选择在什么样的场景下使用什么样的锁。
为了应用服务能够平滑横向扩容,没有对业务状态有特定要求的场景,我们通常会把应用设计成无状态应用,当业务压力增大只需要通过增加应用服务节点就能满足提升处理能力的要求。对于上述占卡的应用场景,系统选择多应用节点并行处理分卡请求,来提升系统吞吐量。如果仅仅选择在单应用节点上加锁,不能解决多节点多进程并行处理导致的数据冲突。但如果选用缓存(Redis)锁,把卡资源作为锁对象,则需要将数据库中的记录和缓存做同步,本身就涉及数据同步和数据一致性问题。在需要对大量数据加锁或长时间加锁时,不建议优先考虑使用悲观锁,因为一次分卡请求可能需要读取大量的卡资源做排序、过滤,锁住大量的卡会极大降低并发吞吐量。更好的方式是使用乐观锁,并且是直接在数据库层使用乐观锁,用version(UUID)作为更新依据。更新SQL ,UPDATE table XXX where version = UUID。(数据库乐观锁的原理请自修)。只是在选卡和占卡时,需要做一些功课来降低冲突的可能性,但能保证在任何时候卡数据不被过期(脏)数据覆盖。当然,这种一致性只是在服务端达成的一致性。终端和服务端对占用同一张卡达成的一致性问题,需要另外的分布式一致性方案才能解决。
_

相关文章
|
Java 关系型数据库 MySQL
兴奋!阿里巴巴首推“Java进阶必备宝典”,理论到实战,一键搞定
作为一名Java方向的程序员,打好夯实的基础是非常重要的,现在大厂面试对于程序员基础知识的掌握考察也越来越严格,虽然说现在技术更新比较快,但基础扎实才能够更深入的去理解每一个知识技术点。
|
8月前
|
数据采集 监控 Oracle
GraalVM 24 正式发布阿里巴巴贡献重要特性 —— 支持 Java Agent 插桩
阿里巴巴是 GraalVM 全球顾问委员会的唯一中国代表,阿里云程序语言与编译器团队和可观测团队合作实现了 GraalVM 应用的无侵入可观测能力,并在 ARMS 平台上线了该功能。目前在 GraalVM 24 中发布的是支持 Java agent 的第一步,其余能力将在 GraalVM 的后续版本中陆续发布。
573 22
电子书阅读分享《Java开发手册(嵩山版)》
电子书阅读分享《Java开发手册(嵩山版)》
|
算法 Oracle Java
Java字符串拼接技术演进及阿里巴巴的贡献
本文主要讲述了Java字符串拼接技术的演进历程,以及阿里巴巴贡献的最新实现 PR 20273。
418 12
|
算法 Oracle Java
Java字符串拼接技术演进及阿里巴巴的贡献
本文主要讲述了Java字符串拼接技术的演进历程,以及阿里巴巴贡献的最新实现 PR 20273。
291 12
|
安全 Java 关系型数据库
代码规范Java阿里巴巴
本文介绍了阿里巴巴的《Java开发手册》,这是一份业界公认的代码规范手册,涵盖编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约七个维度。手册通过强制、推荐、参考三大类规约,详细指导开发者编写高质量的Java代码。文中还提供了常见问题的正反例对比,如方法参数类型一致性、SimpleDateFormat线程安全等问题的解决方案。此外,还介绍了如何安装和使用阿里规范插件来提高编码效率。
1682 9
|
存储 Java 测试技术
阿里巴巴java开发手册
这篇文章是关于阿里巴巴Java开发手册的整理,内容包括编程规约、异常日志、单元测试、安全规约、MySQL数据库使用以及工程结构等方面的详细规范和建议,旨在帮助开发者编写更加规范、高效和安全的代码。
|
小程序 JavaScript Java
【资料】阿里Java开发手册
本文是关于分享阿里Java开发手册资源及促进编程规范学习的指南。作者以个人经历引入,讲述了公司领导通过细致讲解阿里Java开发手册,提升了团队对代码质量和编程规范的认识
1715 0
【资料】阿里Java开发手册
|
easyexcel Java 关系型数据库
阿里巴巴-EasyExcel 基于Java的简单、省内存的读写Excel
该文章主要介绍了在Java应用中如何使用EasyExcel技术完成对Excel文件的导入和导出操作,包括环境搭建、基本概念、快速入门、进阶操作和综合应用等内容,并提供了相关代码示例和注意事项。
 阿里巴巴-EasyExcel 基于Java的简单、省内存的读写Excel
电子书阅读分享《Java开发手册(泰山版)》
电子书阅读分享《Java开发手册(泰山版)》
电子书阅读分享《Java开发手册(泰山版)》