俗话说的好:厨师太多反而做不好汤。 我们都知道,要做好汤,我们需要把大厨房分为很多小厨房,每个小厨房都有自己的厨师、人员、货物供应和设备,饥饿的消费者协调各个分离的厨师做出美味的汤。然后得到好汤,这将我们引向了Microservice。 Microservice很棒 解决Monolithic应用的一个问题是将应用分为多个Microservice。Matin Fowler解释道:
Sir Cockroft 先生在DevOps咖啡店的一次访谈提到了Microservice的严格定义。概况如下:
我们所期待的目标是很好的。避免防御式编程,去耦合,关注点分离,迅速部署,错误隔离,快速反馈回路,开发者责任制,专注做好一件事情的app,独立升级路径,优化的版本控制,团队间分离……这些都是我们的目标。 问题是:Microservice是实现这些目标的唯一办法么?即使不是,Microservice是实现这些目标的最好办法么? 对于第一点,发布非独立功能时,如果一个功能失败了,所有的功能都要返工。这是分支和粒度发布策略(release granularity policies)的架构。Erst推测可以通过不缓存功能的方式来避免这个问题,功能一旦完成就进行发布。一天持续发布很多次意味着一天发布了很多变化,这些发布是独立可复原的,因此就不会有什么问题。功能标识是另一种应对产品功能问题的办法,不过没那么好。 尽管Microservice是解决返工问题的一个解决方案,但这不是唯一的解决方案,也不是最好的解决方案,Microservice只是这场论战中反复提到的一个模式。 服务不是什么新东西 很显然Microservice处于领先地位。故事是不是还有另一面呢?我同意Microservice是对已有服务的再造。我们一定需要一个新词么?我认为这可以让沟通更明晰,因此可以。那么服务的内容有什么变化呢?一个新的绑定需要新的词语。这就像语言方法进行版本控制。10年前Microservice的词也是不同的,所以我们需要用一个新词来描述现在。 真正的对比应该是和Unix和我们的老朋友/etc/services对比,etc/services中有很多独立的服务,例如nfs、ntp、smtp、whois、echo、time、ftp、quote和 hostnames。这些服务的复杂度各不相同,有些很简单,有些很复杂。这些服务都是独立的,因此它们可以都运行在同一台机器上,不需要类似于VM的容器。神奇吧! 服务是怎么创建的?阅读W.Richard Stevens的著作,使用本地TCP/IP和线程库创建自己的信息handler、格式和协议。在此之上你可以搭建Actor,状态机处理器,消息代理,发布和订阅机制,计数器handler,线程池,工作序列和高级CPU调度算法。或者你可以使用雷系ACE的框架帮助你。 很多服务都是按上述描述搭建的,它们性能很快,不需要HTTP、网络服务器或任何其他现代的“改进”。在移动领域,HTTP绝不是助力。因此服务总是在工作,没有什么理由去换新。 捍卫monolith—如上所述,因此: Monolith总是工作的。一个有任何复杂形式的服务通常也有复杂的现场和内部结构,因为服务是请求会话和响应会话的端点。这意味着服务的内部可以很复杂,需要很大的团队开发这些内容,需要严格的延迟控制和高可用性。 我们所看到的是复杂是保守的。都是你自己的代码时,不会因为简单的把一切都隔离到墙后面而导致复杂。复杂在什么地方。只有本质简单的简单才是真的简单,否则简单只是一种抽象的说法,大家很快就会识破。 去耦合和关注点分离的优点都可以在代码库中实现,如果你不能让复杂的代码工作,你可以查看代码结构,编程语言的选择,程序员,源代码控制策略,分支策略,故障修复策略,发布策略和搭建和部署系统。不要一下子就断定是Monolith的问题。 例如,一直以来去耦合都是通过库机制实现的。我知道这是软件工程,不是算法,请屈尊和我一起从软件工程的角度看问题吧。如果代码库分为了独立的库,有着清晰地接口,那么来自世界各地的上百个人都可以独立的工作于这些库。是的,库可以作为分离的产品放入源代码树,任何需要这些产品的工程都可以使用这些产品。这些产品有自己的发布策略,故障追踪等。接口必须保证真实有效,就像服务接口一样。如果接口变化了,那么另一个版本的库可以创建,就像一个服务。每个库可以单独测试,就像一个服务。每个团队都可以使用自己的流程和策略进行开发,就像一个服务。 不同的组件是如何在流程中协作的呢? 流程中的内部代码应该和将所有库组件聚集起来、安装、配置、管理所经历的引导顺序差不多。 所有运行代码的事项都必须这么做。Microservices一定有内部的方式来解决内部和外部的服务引用,以依赖顺序开启服务,启动时配置服务,运行时重新配置服务,处理失败,处理HA,使用度量监控等。 当OS启动时,OS也做同样的事情,OS上运行的每个流程也做同样的事情。每个服务也做同样的事情。每种情况下为达到目标调整的是机制而不是模式本身。每种情况都受制于自身的困难,这些困难不会藏置于抽象层后。 Monolith不能做的是支持不同语言的开发,因为必须要构建一个图形。不过这是要评估的权衡,不是一个强烈的反对理由。 因此,Microservices运动目标是完美无缺。实现这些目标的机制比支持者预想的灵活。可能成为Big Ball of Mud 。许多敏捷/TDD/极限编程都是管理代码熵的一种方法,服务也可以通过同样的方法,形成自己的Ball of Mud。一个有良好软件工程支持的Monolithic代码库可以良好工作,Etsy就是如此。 原文链接: The Great Microservices Vs Monolithic Apps Twitter Melee (翻译/蔡仁君 责编/仲浩) |