Skip to content

Commit

Permalink
fix: typo
Browse files Browse the repository at this point in the history
  • Loading branch information
mzlogin committed Jan 9, 2022
1 parent 54cb1bb commit d56fc4a
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public @interface NotConflictAccount {

```

另外一条建议是将不带业务含义的格式校验注解放到 Bean 的类定义之上,将带业务逻辑的校验放到 Bean 的类定义的外面。这两者的区别是放在类定义中的注解能够自动运行,而放到类外面这需要像前面代码那样,明确标出注解时才会运行。譬如用户账号实体中的部分代码为:
另外一条建议是将不带业务含义的格式校验注解放到 Bean 的类定义之上,将带业务逻辑的校验放到 Bean 的类定义的外面。这两者的区别是放在类定义中的注解能够自动运行,而放到类外面则需要像前面代码那样,明确标出注解时才会运行。譬如用户账号实体中的部分代码为:

```java
public class Account extends BaseEntity {
Expand Down
2 changes: 1 addition & 1 deletion introduction/about-the-fenix-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Anything that can go wrong will go wrong.<br/>如果事情可能出错就总会

## 架构的演进

软件架构风格从大型机(Mainframe),到[原始分布式](/architecture/architect-history/primitive-distribution.html)(Distributed),到[大型单体](/architecture/architect-history/monolithic.html)(Monolithic),到[面向服务](/architecture/architect-history/soa.html)(Service-Oriented),到[微服务](/architecture/architect-history/microservices.html)(Microservices),到[服务网格](/architecture/architect-history/post-microservices.html)(Service Mesh),到[无服务](/architecture/architect-history/serverless.html)(Serverless)……技术架构上确实呈现出“从大到小”的发展趋势。当近年来微服务兴起以后,涌现出各类文章去总结、赞美微服务带来的种种好处,诸如简化部署、逻辑拆分更清晰、便于技术异构、易于伸缩拓展应对更高的性能等等,这些当然都是重要优点和动力。可是,如果不拘泥于特定系统或特定某个问题,以更宏观的角度来看,前面所列这种种好处却都只能算是“锦上添花”、是属于让系统“活得更好”的动因,肯定比不上系统如何“确保生存”的需求来得关键、本质。笔者看来,架构演变最重要的驱动力,或者说这种“从大到小”趋势的最根本的驱动力,始终都是为了方便某个服务能够顺利地“死去”与“重生”而设计的,个体服务的生死更迭,是关系到整个系统能否可靠续存的关键因素。
软件架构风格从大型机(Mainframe),到[原始分布式](/architecture/architect-history/primitive-distribution.html)(Distributed),到[大型单体](/architecture/architect-history/monolithic.html)(Monolithic),到[面向服务](/architecture/architect-history/soa.html)(Service-Oriented),到[微服务](/architecture/architect-history/microservices.html)(Microservices),到[服务网格](/architecture/architect-history/post-microservices.html)(Service Mesh),到[无服务](/architecture/architect-history/serverless.html)(Serverless)……技术架构上确实呈现出“从大到小”的发展趋势。当近年来微服务兴起以后,涌现出各类文章去总结、赞美微服务带来的种种好处,诸如简化部署、逻辑拆分更清晰、便于技术异构、易于伸缩拓展应对更高的性能等等,这些当然都是重要优点和动力。可是,如果不拘泥于特定系统或特定某个问题,以更宏观的角度来看,前面所列这种种好处却都只能算是“锦上添花”、是属于让系统“活得更好”的动因,肯定比不上系统如何“确保生存”的需求来得关键、本质。在笔者看来,架构演变最重要的驱动力,或者说这种“从大到小”趋势的最根本的驱动力,始终都是为了方便某个服务能够顺利地“死去”与“重生”而设计的,个体服务的生死更迭,是关系到整个系统能否可靠续存的关键因素。

举个例子,譬如某企业中应用的单体架构的 Java 系统,其更新、升级都必须要有固定的停机计划,必须在特定的时间窗口内才能按时开始,必须按时结束。如果出现了非计划的宕机,那便是生产事故。但是软件的缺陷不会遵循领导定下的停机计划来“安排时间出错”,为了应对缺陷与变化,做到不停机地检修,Java 曾经搞出了 OSGi 和 JVMTI Instrumentation 等这样复杂的 HotSwap 方案,以实现给奔跑中的汽车更换轮胎这种匪夷所思却又无可奈何的需求;而在微服务架构的视角下,所谓系统检修,不过只是一次在线服务更新而已,先停掉 1/3 的机器,升级新的软件版本,再有条不紊地导流、测试、做金丝雀发布,一切都是显得如此理所当然、平淡寻常;而在无服务架构的视角下,我们甚至都不可能去关心服务所运行的基础设施,连机器是哪台都不必知道,停机升级什么的就根本无从谈起了。

Expand Down
12 changes: 6 additions & 6 deletions tricks/2021/arch/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# ArchSummit2021主题演讲:从软件的历史看架构的未来

1972 年,[Edsger Dijkstra](https://en.wikipedia.org/wiki/Edsger_W._Dijkstra) 在为图灵奖颁授典礼所写的[感言文章](https://www.cs.utexas.edu/users/EWD/transcriptions/EWD03xx/EWD340.html)中说到:“在没有计算机的时候,也就没有编程问题;当我们有了简单的计算机,编程只是个小问题;而现在我们有了算力规模庞大的计算机,那编程就成为了一个同样巨大的问题了”。半个世纪前,Dijkstra 已经敏锐洞见了机器算力的提升是编程方法发展的直接牵引,每当人类掌握了更强的算力,便按耐不住想去解决一些以前甚至都不敢去设想的新问题,由此引发软件设计模式的重大变革。
1972 年,[Edsger Dijkstra](https://en.wikipedia.org/wiki/Edsger_W._Dijkstra) 在为图灵奖颁授典礼所写的[感言文章](https://www.cs.utexas.edu/users/EWD/transcriptions/EWD03xx/EWD340.html)中说到:“在没有计算机的时候,也就没有编程问题;当我们有了简单的计算机,编程只是个小问题;而现在我们有了算力规模庞大的计算机,那编程就成为了一个同样巨大的问题了”。半个世纪前,Dijkstra 已经敏锐洞见了机器算力的提升是编程方法发展的直接牵引,每当人类掌握了更强的算力,便按捺不住想去解决一些以前甚至都不敢去设想的新问题,由此引发软件设计模式的重大变革。

## 历史上的软件危机和契机

计算机刚诞生的年代,硬件规模还很小,甚至程序员仅凭大脑就足够记住数据在几 KB 内存中的布局情况,理解每条指令在电路中的运行逻辑。此时的计算机尽管运算速度比人类快,但内部却并没有什么人所不知道的事情;此时的软件开发并没有独立的“架构”可言,软件架构与硬件架构是直接物理对齐的。

随着计算机的快速发展,直接面向硬件进行的软件开发很快触碰到了瓶颈,人脑的生物局限显然无法跟上机器算力前进的步伐,当机器强大到世界上最聪明的人都无法为它编写出合适的程序了,那计算机科学还能继续发展吗?这便是历史上第一次软件危机的根源。第一次软件危机,同时也是[结构化编程](https://en.wikipedia.org/wiki/Structured_programming)发展的契机,结构化编程扭转了当时直接面向全局数据、满屏 Goto 语句书写[面条式代码](https://en.wikipedia.org/wiki/Spaghetti_code)(Spaghetti Code)的编程风气,强调可独立编写、可重复利用的子过程/局部块的重要性,让软件的每个局部都能够设计专门的算法和数据结构,允许每一位程序员只关注自己所负责的部分,从而在整体上控制住了软件开发的复杂度。此时,软件的架构才开始独立于硬件物理架构而存在,软件业开始出现把控全局设计的架构师与聚焦局部实现的程序员的角色分工。

将软件从整体划分成若干个局部,人类能够以群体配合来共同开发软件,使得人与计算机又和谐共处了十余年。不过,机器的算力膨胀仍然在持续,人类群体的沟通协作能力却终有极限。人毕竟不是可复制的程序,每个人都有自己的理解与认知,如何让各个模块能准确地协同工作成了一场灾难,这就是第二次软件危机的根源。《[人月神话](https://en.wikipedia.org/wiki/The_Mythical_Man-Month)》中有一个几乎每位程序员都听过的案例:IBM 公司为开发的 OS/360 系统投入成本达到了美国的“曼哈顿”原子弹计划的 25%,共有 4000 多个模块,约 100 万条指令,超过 5000 人年,耗资数亿美元,即使如此,结果还是延期交付,在交付使用后的系统中仍发现大量的缺陷。
将软件从整体划分成若干个局部,人类能够以群体配合来共同开发软件,使得人与计算机又和谐共处了十余年。不过,机器的算力膨胀仍然在持续,人类群体的沟通协作能力却终有极限。人毕竟不是可复制的程序,每个人都有自己的理解与认知,如何让各个模块能准确地协同工作成了一场灾难,这就是第二次软件危机的根源。《[人月神话](https://en.wikipedia.org/wiki/The_Mythical_Man-Month)》中有一个几乎每位程序员都听过的案例:IBM 公司为开发 OS/360 系统投入的成本达到了美国的“曼哈顿”原子弹计划的 25%,共有 4000 多个模块,约 100 万条指令,超过 5000 人年,耗资数亿美元,即使如此,结果还是延期交付,在交付使用后的系统中仍发现大量的缺陷。

渡过第二次软件危机的过程中,面向对象编程逐步取代了面向过程的结构化编程,成为主流的程序设计思想,这次思想转变宣告“追求最符合人类思维的视角来抽象问题”取代了“追求最符合机器运行特征的算法与数据结构”成为软件架构的最高优先级,并一直持续沿用至今。这次危机还直接导致软件工程的诞生, 如何以系统性的、规范化的、可定量的方法去高质量地开发和维护软件成为一门独立的科学。

## 云与分布式渐成为主流

如果说历史上的第一、二次软件危机分别是机器算力规模超过了人类个体的生理极限,超过了人类群体的沟通极限的话。那么在今天,在云计算的时代,数据中心所能提供的算力其实已经逼近到了人类协作的工程极限,与此算力相符的程序规模,几乎也到了无论采用何种工程措施去优化过程、无论采用什么管理手段去提升质量,都仍然不可避免会出现意外与异常的程度。大家都相信只要软件系统由大量人员共同研发,并使其分布在云中大量节点协同运行,随着项目规模的增大、时间变长,就肯定会有人疏忽犯错,会有代码携带缺陷,会有电脑宕机崩溃,会有网络堵塞中断,总之,必然会受到墨菲定律的无情打击。

软件架构要与硬件算力规模对齐,目前用来适配云计算与分布式的主流架构形式是微服务,微服务兴起之时,曾涌现出各类文章去总结、赞美微服务带来的种种好处,诸如简化部署、逻辑拆分更清晰、便于技术异构、易于伸缩拓展应对更高的性能,等等,这些当然都是重要优点。可是,如果不拘泥于特定场景定某个问题,以宏观的角度来看,前面所列这种种好处都只算是“锦上添花”、是属于让系统“更好”的动因,肯定比不上系统如何确保“生存”来得关键。笔者看来,从单体到微服务的最根本的推动力,是为了方便某个服务能够顺利地“消亡”与“重生”,局部个体的生死更迭,是关系到整个系统能否可靠续存的关键因素。
软件架构要与硬件算力规模对齐,目前用来适配云计算与分布式的主流架构形式是微服务,微服务兴起之时,曾涌现出各类文章去总结、赞美微服务带来的种种好处,诸如简化部署、逻辑拆分更清晰、便于技术异构、易于伸缩拓展应对更高的性能,等等,这些当然都是重要优点。可是,如果不拘泥于特定场景特定问题,以宏观的角度来看,前面所列这种种好处都只算是“锦上添花”、是属于让系统“更好”的动因,肯定比不上系统如何确保“生存”来得关键。在笔者看来,从单体到微服务的最根本的推动力,是为了方便某个服务能够顺利地“消亡”与“重生”,局部个体的生死更迭,是关系到整个系统能否可靠续存的关键因素。

举个例子,在很长的时间里面,企业应用中采用单体架构的 Java 系统,其更新、升级都必须要有固定的停机计划,必须在特定的时间窗口内才能按时开始,必须按时结束。如果出现了非计划的宕机,那便是生产事故。但是软件的缺陷不可能遵循停机计划来“安排时间出错”,为了应对缺陷与变化,做到不停机的检修,Java 曾经搞出了 OSGi 和 JVMTI Instrumentation 等复杂的 HotSwap 方案,以实现给奔跑中的汽车更换轮胎这种匪夷所思却又无可奈何的需求;而在微服务架构的视角下,所谓系统检修,充其量只是一次服务滚动更新而已,灰度部署新的程序版本,然后导流、测试、发布即可。

Expand All @@ -38,7 +38,7 @@

[ShardingSphere](https://shardingsphere.apache.org/) 的作者张亮曾经[在 InfoQ 撰文](https://www.infoq.cn/article/database-mesh-sharding-jdbc),提出过 Database Mesh 的设想,把数据库发现、访问路由、数据分片、读写分离、负载均衡等特性从程序代码中拿出去,也交给 Sidecar 来实现。既然 Service 和 Database 可以 Mesh 化,那 Cache Mesh、MessageQueue Mesh、Storage Mesh……等自然都有了登场的理由。更进一步,分布式中那些复杂却有共性的处理技巧,如并行、并发、状态、共识,等等,是不是也可以从程序代码中独立出去,由 Sidecar 引导至合适的、不特定的部件中妥善处理?最后,一旦云计算服务提供商的技术货架中大多数部件和能力被 Mesh 抹掉了差异化特性,剩下都是一致的标准操作,那 Serverless 一直倡导的"后端即服务"(BaaS)便立刻有了无比广泛的基础。此时,云数据中心就仿佛是一部拥有无限算力的机器与一套有标准接口的操作系统,开发者无需关心程序在哪里执行(FaaS),也不再关心程序有哪些依赖(BaaS)。

上面仅谈概念恐怕有些抽象,笔者以“如何在存储一个 K/V 值对”为例,来看一下当前的编程与未来设想的编程方式会有什么差别。下面这段代码是现在随处可见的大路货,它具有稍后列举的几点问题:
上面仅谈概念恐怕有些抽象,笔者以“如何存储一个 K/V 值对”为例,来看一下当前的编程与未来设想的编程方式会有什么差别。下面这段代码是现在随处可见的大路货,它具有稍后列举的几点问题:

```java
Set<HostAndPort> nodes = new LinkedHashSet<HostAndPort>();
Expand Down Expand Up @@ -86,9 +86,9 @@ curl http://localhost:3500/v1.0/state/users/icyfenix \

第一次软件危机在 1950 年代末期初现端倪,结构化编程思想在 1970 年才被正式提出;第二次软件危机(连同"软件危机"这个概念)是在 1970 年[北约 NATO 会议](https://en.wikipedia.org/wiki/NATO_Software_Engineering_Conferences)上被定义的,要一直到 1990 年代面向对象的设计方法成为主流,以及 Scrum、XP 等软件工程方法被提出后,这次危机才算是画上句号。从 2010 年左右开始兴起的云计算是程序的运行环境继“大型计算机”转变到“客户端-服务器”之后的[又一场巨变](https://zh.wikipedia.org/wiki/%E9%9B%B2%E7%AB%AF%E9%81%8B%E7%AE%97#%E6%B2%BF%E9%9D%A9),与前两次软件危机带来的变革契机一样,现有的许多软件架构和开发方法,一定也会在以十年计数单位的时间段内逐渐被颠覆,今天你我所谈的云原生、微服务等话题,仅仅是这次变革浪潮的开端。

与技术变革相伴的,是它对行业以及对程序员这个群体的影响。第一次软件危机期间,世界上最聪明的科学家/工程学家在开发软件;第二次软件危机期间,社会中的高智商高学历的精英群体在开发软件;云与分布式的时代,软件开发者恐怕也不可避免会受到下一轮冲击。未来的软件架构对普通程序员应该会是更友善更简单的,但是对普通程序员友善与简单的背后,预示着未来的信息技术行业很可能会出现“阶级分层”的现象,由于更先进的软件架构已经允许更平庸的开发者也同样能写出可运行、可用于生产的软件产品,同时又对精英开发者提出更多、更复杂的技术要求,长此以往,在开发者群体中会出现比现在还要更显著的[马太效应](https://en.wikipedia.org/wiki/Matthew_effect),迫使开发者逐渐分层,从如今所有开发者都普遍被认为是“高智商群体”的状态,转变为大部分工业化软件生产工人加上小部分软件设计专家的金字塔结构,就如同现在的建筑工人与建筑设计师的关系一般,今天我们经常自嘲的 CRUD Boy,随着软件产业日趋成熟,恐怕还会真的会成为现实
与技术变革相伴的,是它对行业以及对程序员这个群体的影响。第一次软件危机期间,世界上最聪明的科学家/工程学家在开发软件;第二次软件危机期间,社会中的高智商高学历的精英群体在开发软件;云与分布式的时代,软件开发者恐怕也不可避免会受到下一轮冲击。未来的软件架构对普通程序员应该会是更友善更简单的,但是对普通程序员友善与简单的背后,预示着未来的信息技术行业很可能会出现“阶级分层”的现象,由于更先进的软件架构已经允许更平庸的开发者也同样能写出可运行、可用于生产的软件产品,同时又对精英开发者提出更多、更复杂的技术要求,长此以往,在开发者群体中会出现比现在还要更显著的[马太效应](https://en.wikipedia.org/wiki/Matthew_effect),迫使开发者逐渐分层,从如今所有开发者都普遍被认为是“高智商群体”的状态,转变为大部分工业化软件生产工人加上小部分软件设计专家的金字塔结构,就如同现在的建筑工人与建筑设计师的关系一般,今天我们经常自嘲的 CRUD Boy,随着软件产业日趋成熟,恐怕还真的会成为现实

本篇文章里,笔者刻意在避免使用“第三次软件危机”这样有哗众取宠嫌疑的表述,危机总是与契机同时出现,未来的软件的一定是越来越贴近于普通平民百姓的软件,但软件的未来也一定有大量的挑战与机会在等待着优秀的程序员与架构师去承担。
本篇文章里,笔者刻意在避免使用“第三次软件危机”这样有哗众取宠嫌疑的表述,危机总是与契机同时出现,未来的软件一定是越来越贴近于普通平民百姓的软件,但软件的未来也一定有大量的挑战与机会在等待着优秀的程序员与架构师去承担。

:::tip 软件架构与硬件算力规模对齐

Expand Down

0 comments on commit d56fc4a

Please sign in to comment.