软件架构设计原则 Srinath
words: 3.9k views: time: 16min本文作者叫Srinath,是一位科学家,软件架构师,也是一名在分布式系统上工作的程序员。他是Apache Axis2项目的联合创始人,也是Apache Software基金会的成员。他是WSO2流处理器(wso2.com/analytics)的联席架构师。Srinath撰写了两本关于MapReduce和许多技术文章的书。他获得了博士学位。来自美国印第安纳大学。
Srinath 通过不懈的努力最终总结出了30条架构原则,他主张架构师的角色应该由开发团队本身去扮演,而不是专门有个架构师团队或部门。Srinath 认为架构师应该扮演的角色是一个引导者,讨论发起者,花草修建者,而不是定义者和构建者。Srinath为了解决团队内部的架构纷争和抉择,制定了以下30条原则,这些原则被成员们广泛认可,也成为了新手架构师的学习途径。
基本原则 The basic principle of
1、KISS(Keep it simple, keep it sutpid) And keep everything as simple as possible. Solve problems with the simplest solution.
保持每件事情都尽可能的简单。用最简单的解决方案来解决问题。
简单即是复杂,比如写代码,如果想写得简单且容易理解,就需要花更多的时间去思考
2、YAGNI(You aren’t gonna need it)- Don’t do something you don’t need, Do it when you need it.
不要去搞一些不需要的东西,需要的时候再搞吧。
不要做你当下不需要做的事情,当你需要的时候才做
3、climb, go, run. In other words, make sure you get through first, And then optimize to get better, And then continue to optimize to make it great. Iterate to do things, Agile development ideas. For each function point, Create milestones(Up to two weeks), And then iterate.
爬,走,跑。换句话说就是先保证跑通,然后再优化变得更好,然后继续优化让其变得伟大。迭代着去做事情,敏捷开发的思路。对于每个功能点,创建里程碑(最大两周),然后去迭代。
先完成,再完美,先运行起来,再优化迭代直到做得更好
4、Create stability、 The only way to produce high quality products is to automate testing. Everything can be automated, When you design, Think about this.
创建稳定、高质量的产品的唯一方法就是自动化测试。所有的都可以自动化,当你设计时,不妨想想这一点。
单元测试、系统测试、集成测试,多考虑自动化,代替人为的不准确而影响面评估
5、Always think about the input-output ratio(ROI). It’s worth it. No.
时刻要想投入产出比,就是划得来不。
6、Know your users, And then balance that with what you need to do. Don’t spend months making one devops The user interface, In the end, you only find that people like the command line. This principle is principle 5 A concrete manifestation of.
了解你的用户,然后基于此来平衡你需要做哪些事情。不要花了几个月时间做了一个 devops 用户界面,最后你发现那些人只喜欢命令行。此原则是原则5的一个具体表现。
应该站在用户的角度思考问题,不要自嗨,不要花费大量时间做用户并不喜欢的产品
7、Design and test a function as independent as possible. When you do design, Think about this one. In the long run, it can solve a lot of problems for you, Otherwise, your function can only be tested after all other functions of the system are ready, It’s obviously not good. With this principle, Your version will be smoother.
设计和测试一个功能,尽可能的独立。当你做设计时,应该想想这一条。从长远来看这能给你解决很多问题,否则你的功能只能等待系统其他所有的功能都就绪了才能测试,这显然很不好。有了这个原则,你的版本将会更加的顺畅。
敏捷开发
8、Don’t make fancy. We all like high-end cool design. Finally, we put a lot of functions and solutions into our architecture, And then these things won’t be used at all.
不要花里胡哨,我们都喜欢炫酷的设计。最后,我们把很多功能和解决方案都放进了这些架构中,然后这些东西就完全不用了。
解决问题是第一要义,不要炫技引入不必要的复杂度。应该是架构为需求服务,而不是需求为架构服务
产品功能 Functional selection
9、It’s impossible to predict how users will use our products. So embrace MVP(Minimal Viable Product), Minimum runnable version. The main idea of this point of view is that you can pick out a few very few usage scenarios, And get it out, And then release it online for users to use, Then decide what to do next based on the experience and user feedback.
不可能预测到用户将会如何使用我们的产品。所以要拥抱MVP,最小可运行版本。这个观点主要思想就是你挑几个很少的使用场景,然后把它搞出来,然后发布上线让用户使用,然后基于体验和用户反馈再决定下一步要做什么。
拒绝主观臆测,不要想当然的去做,要以用户实际需求为准,多次小功能迭代+灰度/AB测试
10、Do as few functions as possible. When in doubt, Don’t do it, Even kill. Many features are never used. At most, an extension point is enough.
尽量少做功能。当有疑问时,就不要做,甚至杀人(这里应该指产品经理)。很多功能从未使用过,最多一个扩展点即可。
产品功能要少而精,尽量保证每一个功能都是用户切实需要的。不要轻易妥协,除非你认可这个功能的价值
11、Wait until someone asks(Unless it’s affecting the core process, Or wait until you need to).
直到有人提出再说(除非是影响核心流程,否则就等到需要的时候再去做)。
12、Sometimes you have to have the courage to say no to the client. At this point, you need to find a better solution to solve. Remember what Henry Ford once said:”If I ask people what they need, They would say I need a faster horse”. remember: You’re the expert, You have to guide and lead. To do the right thing, It’s not a popular thing. End users will thank you for providing them with a car.
有时候你要有勇气和客户说不。这时候你需要找到一个更好的解决方案来去解决。记住亨利福特曾经说过的:”如果我问人们他们需要什么,他们会说我需要一匹速度更快的马”。记住:你是那个专家,你要去引导和领导。要去做正确的事情,而不是流行的事情,最终用户会感谢你为他们提供了汽车。
学会变通,面对问题,不能一层不变的思考解决方案,有时候需要换位思考
服务端设计和并发 Server design and concurrency
13、You need to know one server How it works, From hardware to operating system, Until the programming language. Optimize IO The number of calls is your preferred path to the best architecture. 要知道一个 server 是如何运行的,从硬件到操作系统,直到编程语言。优化IO调用的数量是你通往最好架构的首选之路。
14、To understand Amdhal The law of synchronization. Sharing variable data between threads can slow down your program. Use concurrent data structures only when necessary, Only when you have to use synchronization(synchronization)When you use synchronization. If you want to use a lock, Also make sure you have as little time as possible to hold Lock. If you want to do something after locking, Make sure you do what you do inside the lock.
要了解Amdhal同步定律。在线程之间共享可变数据会让你的程序变慢。只在必要的时候才去使用并发的数据结构,只在必须使用同步的时候才去使用同步。如果要用锁,也要确保尽可能少的时间去 hold 住锁。如果要在加锁后做一些事情,要确保自己在锁内会做哪些事情。
15、If your design is a non blocking, event driven architecture, Then never block threads or do something in them IO operation, If you do, Your system will slow down like a mule.
如果你的设计是一个无阻塞且事件驱动的架构,那么千万不要阻塞线程或者在这些线程中做一些IO操作,如果你做了,你的系统会慢的像骡子一样。
分布式系统 Distributed systems
16、Stateless systems are scalable and direct. Think about it all the time, Don’t make it extensible, Come out of the state, It’s the minimum.
无状态的系统的是可扩展的和直接的。任何时候都要考虑这一点,不要搞个不可扩展的,有状态的东东出来,这是起码的。
17、Make sure the message is delivered only once, Regardless of failure, It’s very hard, Unless you want to control both the client and the server. Try to make your system lighter(Usage principle 18). You need to know most of the promises exactly-once-delivery The system is streamlined.
保证消息只被传递一次,不管失败,这很难,除非你要在客户端和服务端都做控制。试着让你的系统更轻便(使用原则18)。你要知道大部分承诺exactly-once-delivery的系统都是做了精简的。
18、Implement an operation as idempotent as possible. It’s better to recover in this way, And you’re still in at least one pass(at least once delivery)The state of. The problem of distributed lock and idempotency, How to solve? It’s recommended to have a look at.
尽量将操作实现为幂等的。这样更容易恢复,并且你仍然处于“至少一次传递”的状态。关于分布式锁和幂等性的问题,该如何解决?建议你看一下(相关资料)。
实际上很多系统都是at least once + 幂等的设计
19、know CAP theory. Scalable transactions(Distributed transactions)It’s hard. If possible, Use compensation mechanisms as much as possible. RDBMS Transactions are not scalable.
了解CAP理论。可扩展的事务(分布式事务)是很难的。如果可能的的话,尽可能的使用补偿机制。RDBMS事务是无法扩展的。
20、Distributed consistency cannot be extended, Group communication is also not possible, It is also impossible for reliable communication within the cluster. Ideally, the maximum node limit is 8 Nodes.
分布式一致性无法扩展,也无法进行组通信,也无法进行集群范围内的可靠通信。理想情况下最大的节点限制为8个节点。
分布式集群是需要保持数据一致的,节点过多肯定会因为同步带来一些延迟,而且出错概率更大
21、In distributed systems, You can never avoid delays and failures.
在分布式系统中,你永远无法避免延迟和失败。
墨菲定律,任何理论上可能发生的问题,在实际长期运行过程中,迟早会发生
用户体验 User experience
22、Get to know your users and know their goals. They’re new、Experts or casual users? The extent to which they understand computer science. Geeks like to expand, Developers love examples and scripts, Ordinary people like UI.
要了解你的用户和清楚他们的目标。他们是新手、专家还是偶然的用户?他们了解计算机科学的程度。极客喜欢扩展点,开发者喜欢示例和脚本,而普通人则喜欢UI。
23、The best products don’t need a manual.
最好的产品不需要说明书
这个很难,很难,总的来说产品要好用易用,傻瓜都不需要教的那种
24、When you can’t decide between two choices, Please do not pass this problem directly to users by providing configuration options. This can only make users more confused. If you’re an expert, you can’t choose, Is it appropriate to give it to someone less than you know? The best thing to do is to find a workable option every time; The next best thing to do is to give the options Automatically, The third best way is to add a configuration parameter, Then set a reasonable default value.
当你无法在两个选择中做决定的时候,请不要直接把这个问题通过提供配置选项的方式传递给用户。这样只能让用户更加的发懵。如果连你这个专家都无法选择的情况下,交给一个比你了解的还少的人这样合适吗?最好的做法的是每次都找到一个可行的选项;次好的做法是自动的给出选项,第三好的做法是增加一个配置参数,然后设置一个合理的默认值。
25、Always set a reasonable default value for the configuration.
总是要为配置设置一个合理的默认值。
26、Poorly designed configurations can cause some problems. You should always provide some sample values for the configuration.
设计不良的配置会造成一些困扰。应该总是为配置提供一些示例值。
27、The configuration value must be understandable and directly filled in by the user. such as: The user cannot be asked to fill in the maximum number of cache entries, Instead, the user should be asked to fill in the maximum memory that can be used for caching.
配置值必须是用户能够理解和直接填写的。比如:不能让用户填写最大缓存条目的数量,而是应该让用户填写可被用于缓存的最大内存。
28、If an unknown configuration is entered, an error is thrown. Never ignore. Quietly ignoring configuration errors is often to find bug The culprit who spent hours.
如果输入了未知的配置要抛出错误。永远不要悄悄的忽略。悄悄的忽略配置错误往往是找 bug 花了数小时的罪魁祸首。
棘手的问题 Tough questions
29、Dream of a new programming language that will be simple and clear, But it’s often hard to really master. Don’t change programming language easily.
梦想着新的编程语言就会变得简单和明了,但往往要想真正掌握会很难。不要轻易的去换编程语言。
30、The complex drag and drop interface is tough, Don’t try this effect, Unless you’re ready to 10 The team in the year of man.
复杂的拖拉拽的界面是艰难的,不要去尝试这样的效果,除非你准备好了10人年的团队。
Last, Tell me how I feel. In an ideal world, A platform should be composed of multiple orthogonal components - Each component is responsible for one aspect(such as, security, messaging, registry, mdidation, analytics). It’s like a system built like this is perfect. But unfortunately, In reality, it’s hard for us to achieve such a state. Because in the initial state of the project, Many things are uncertain, You can’t do that independence, Now I’m more inclined to start with a proper repetition, When you try to get rid of them, You’ll find that new complexity is introduced, Distribution itself means complexity. Sometimes the healing process is worse than the disease itself.
最后,说一个我的感受。在一个理想的世界里,一个平台应该是有多个正交组件组成-每个组件都负责一个方面(比如security,messaging,registry,mdidation,analytics)。好像一个系统构建成这样才是完美的。但不幸的是,现实中我们很难达到这样的状态。因为在项目初始状态时,很多事情是不确定的,你无法做到这样的独立性,现在我更倾向于在开始的时候适当的重复是必要的,当你尝试铲除他们的时候,你会发现引入了新的复杂性,分布本身就意味着复杂。有时候治愈的过程要比疾病本身更加的糟糕。
总结
作为一个架构师,应该像园丁一般,更多的是修剪花草,除草而不是去定义和构建,你应该策划而不是指挥,你应该去修剪而不是去定义,应该是讨论而不是贴标签。
虽然在短期内可能会觉得也没什么,但从长远看,指导团队找到自己的方式会带来好处。如果你稍不留神,就很容易让架构成为一个空洞的词汇。比如设计者会说他的架构是错误的,但不知道为什么是错误的。一个避免这种情况的好办法就是有一个原则列表,这个列表是被广泛接受和讨论问题的锚点。
参考: