单体架构
单体架构是什么
单体架构会把一个完整的应用当成一开发单元。
一般企业应用包含三个部分:
- 客户端界面(由HTML、Javascript组成,使用浏览器进行访问)
- 数据库(由许多的表组件构成一个通用的、相互关联的数据管理系统)
- 服务端应用
服务端应用处理HTTP请求、执行领域逻辑、检索并更新数据库中的数据、使用适当的HTML视图发送给客户端,服务端应用是完整的并且由单一的逻辑层次执行,系统中任务变更都会导到服务端的应用重新编辑并发布一个新的版本。虽然利用开发语言基础特性会把应用封装成类、函数,但是业务中所有逻辑(前后端)都要在单一的进程中处理完成。所以被称为单体应用。可以直接打包成war包部署到单一机器上,也可以通过负载均衡将应用部署到多台服务器上。
适用场景
- 业务场景简单,功能不复杂研发人员较少的场景
- 创业公司初期
单体架构的优点
- 易于开发
- 易于测试
- 易于部署
- 易于拓展
单体架构存在的缺点
- 系统耦合性高,复杂性逐渐变高,部署速度逐渐变慢,开发效率会越来越低
- 技术选型很单一,阻碍技术创新
- 无法按需伸缩
架构拆分思路:分库分表
分库-垂直拆分-业务维度拆分
分表-同样的信息分成很多表-水平拆分
这是建立索引?
架构:垂直拆分和水平拆分:业务和功能维度
面向服务(SOA)/水平分层架构
水平分层架构
水平分层架构是什么
在水平方向分层多个独立进程
一般有如下几个部分:
APP-(http)-Nginx-(TCP)-网关层(Gateway)-(消息队列:同步->异步-提高吞吐量)-业务逻辑service-数据访问-存储层(database)
网关层:请求健全、数据完整性验证、服务治理(熔断、服务降级(数据量太大))、json->hashmap
数据访问层:1.CRUD(增删改查) 2.ORM 3.分层分类 4.抽象
面向服务架构(垂直分层:按业务划分)
面向服务架构是什么
面向服务的架构(SOA)是一个组件模型,它将应用程序的不同业务功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
服务的提出其实隐含了两个概念,服务提供者和服务消费者,这两者之间有一个合同约定,这非常类似我们实现生活中签订的服务合同,A单位和B单位分别是服务的提供者和消费者,两者签订了一个服务合同,规定A为B提供某项服务。服务就是提供一些公共需求的设施,通过一个工作过程能提供帮助让使用者收益。
服务两个重要特点:自治和管制,自治代表服务不能被外部势力牵制,比如如果一个服务内部处理中需要调用外部资源或等待外部流程结束,这种等待不能影响服务本身的调用,如果一个服务分为显式对外和隐式内部两个部分,那么自治是针对隐式内部,意味着我们不能在具体一个服务中直接使用过同步代码实现复杂功能。
适用场景
面向服务架构的优点
- 松耦合:由于服务自治,有一定封装边界,服务调用交互是通过发布接口。
这意味着应用程序不感兴趣服务如何被实现 - 位置透明:服务的消费者不必关心服务位于什么地方
- 可在异构平台间复用。可以将遗留系统包装成服务
- 便于测试,能并行开发,较高可靠性和良好的可伸缩性
面向服务架构存在的缺点
- 虽然业务在垂直方向进行切分,但每个服务仍然是单体架构
- 过于依赖ESB
微服务架构(水平+垂直划分)
APP - 网关层 - 服务层 - 数据访问层 - 数据存储层
抽象的微服务定义
Adrian Cockcroft(曾任首席云架构师,被称为“让Netflix走向云端的人”,现为AWS VP)给微服务下了一个比较抽象的定义:
基于有限上下文构建的松散耦合的面向服务的架构(Loosely coupled service oriented architecture with bounded contexts…)。
松散耦合和有限上下文可以认为是一个硬币的两面,一个微服务是独立开发、测试、部署和升级的单位,如果你升级一个服务需要很多其他服务的 联动配合,
那么就不能称为松散耦合;如果开发人员在开发一个微服务的时候,他的大脑必须同时想着周边的服务,
不能轻松忽略,那么这个服务就不能称为有限上下文。
比较具体的微服务定义
Martin Fowler则给出一个比较具体的微服务定义:微服务是一种架构风格(architectural style),
主张互联网应用由一系列细粒度的,职责单一的服务组成,每个服务运行在各自独立的进程中,
服务之间通过轻量机制(如HTTP/JSON)进行通信。这些服务建立在业务领域之上,可通过全自动方式独立部署。
这些服务基本没有集中式的管理,服务可以用那个不同的编程语言编写,也可以使用不同的数据存储技术。
简单定义
微服务架构风格,就像是把小的服务开发成单一应用的形式,每个应用运行在单一的进程中,
并使用如HTTP这样的轻量级的API。这些服务满足某需求,并使用自动化部署工具进行独立发布。
这些服务可以使用不同的开发语言以及不同数据存储技术,并保持最低限制的集中式管理
微服务使用场景
- 微服务是两个维度上的拆分:水平拆分与垂直拆分
- 微服务其实并不是一个系统架构,而是业务架构与组织架构
- 项目需要快速迭代和持续交付
微服务的优势
技术异构性
在一个由多个服务相互协作的系统中,可以在不同的服务中心使用最合适该服务的技术,如果系统中的一部分需要做性能提升,可以使用性能更好的技术站重新构建该部分。系统中的不同部分也可使用不同的数据存储技术,比如对于社交网络来说,图数据库能更好地处理用户之间的交互操作,但是对于用户发布的帖子而言,文档数据库可能是一个更好的选择随着风险,这使得很多人望而却步。尤其是对于单块系统而言,采用一个新的语言、数据库或者框架都会对整个系统产生巨大的影响。对于微服务系统而言,总会存在一些地方让我们可以尝试新技术。你可以选择一个风险最小的服务来采用新技术,即便出现问题也容易处理。这种可以快速采用新技术的能力对很多组织而言是非常有价值的。
弹性
如果系统中的一个组件不可用了,但并没有导致级联故障,那么系统的其他部分还可以正常运行。在单体架构中,如果服务不可用,那么所有的功能都会不可用。对于单体系统而言,可以通过将同样的实例运行在不同的机器上来降低功能完全不可用的概率,然而微服务系统本身就可能够很好地处理服务不可用和功能降级问题。微服务系统可以改进系统弹性,但还是需要谨慎对待,因为一旦使用了分布式系统,网络就会是个问题。不但网络会是个问题,机器也如此,因此我们需要了解出现问题时应该如何对用户进行展示。
扩展
庞大的单块服务职能作为一个整体进行扩展。即使系统中只有一小部分存在性能问题,也需要对整个服务进行扩展。如果使用较小的多个服务,则可以只对需要扩展的服务进行扩展,这样就可以吧那些不需要扩展的服务运行在更小的、性能稍差的硬件上。这种架构使得每个服务都可以有专门的开发团队来开发。开发者可以自由选择开发技术,提供API服务。当然,许多公司试图避免混乱,只提供某些技术选择。甚至于,因为服务都是相对简单,即使用现在技术重写以前的代码也不是很困难的事情。
简化部署
在有几百万代码行的单块应用程序中,即使只修改了一行代码,也需要重新部署整个应用程序才能够发布该变更。这种部署的影响很大、风险很高,因此相关干系人不敢轻易做部署。于是在实际操作中,部署的频率就会变得很低。这意味着在两次发布之间我们对软件做了很多功能增强,但直到最后一刻才把这些大量的变更一次性发布到生产环境中。这时,另外一个问题就显现出来了:两次发布之间的差异越大,出错的可能性就越大!在微服务架构中,各个服务的部署是独立的,这样就可以更快地对特定部分的代码进行部署。如果真的出了问题,也只会影响一个服务,并且容易快速回滚,这也意味着客户可以更快地使用我们开发的新功能。Amazon和Netflix等组织采用这种架构主要就是基于上述考虑。这种架构很好地清除了软件发布过程中的种种障碍。
微服务架构中的不足
“there are no silver bullets”,像任何其它科技一样,微服务架构也有不足。
1.“微服务”强调了服务大小,尽管小服务更乐于被采用,但是不要忘了微服务只是结果,而不是最终目的,微服务的目的是有效的拆分应用,实现敏捷开发和部署。
2.微服务应用是分布式系统,由此会带来固有的复杂性。开发者需要在RPC或者消息传递之间选择并完成进程间通讯机制。此外,他们必须写代码来处理消息传递中速度过慢或者不可用等局部失效问题。当然这并不是什么难事,但相对于单体式应用中通过语言层级的方法或者进程调用,微服务下这种技术显得更复杂一些。
3.另外一个关于微服务的挑战来自于分区的数据库架构。同时更新多个业务主体的事务很普遍。这种事务对于单体式应用来说很容易,因为只有一个数据库。在微服务架构应用中,需要更新不同服务所使用的不同数据库。使用分布式事务并不一定是好的选择,不仅仅是因为CAP理论,还因为当前高扩展性的NoSQL数据库和消息传递中间件并不支持这以需求。最终你不得不是用一个最终一致性的方法,从而对开发者提出了更高的要求和挑战。
4.测试一个机遇微服务架构的应用也是很复杂的任务。比如,对于采用流行的Spring Boot架构的单体式web应用,测试他的REST API,是很容易的事情。反过来,同样的服务测试需要启动与它有关的所有服务(至少需要这些服务的stubs)。再重申一次,不能低估了采用微服务架构带来的复杂性。
5.另外一个挑战在于,微服务架构模式应用的改变将会波及多个服务。比如,假设你在完成一个案例,需要修改服务A、B、C,而A依赖B,B依赖C。在单体应用中,你只需要改变相关模块,整合变化,部署就好了。对比之下,微服务架构模式就需要考虑相关改变对不同服务的影响。比如,你需要更新服务C,然后是B,最后才是A。幸运的是,许多改变一般只影响一个服务,需要协调多服务的改变很少。
6.部署一个微服务应用也很复杂,一个单体应用只需要在负载均衡器后面部署各自的服务器就好了。每个应用实例是需要配置诸如数据库和消息中间件等基础服务。相比之下,一个微服务应用一般由大批服务构成。根据Adrian Cockcroft的分享,NetFlix则超过600个服务。每个服务都有多个实例,这就形成大量需要配置、部署、扩展和监控的部分。除此之外,你还需要完成一个服务发现机制, 以用来发现它通讯服务的地址(包括服务器地址和端口)。传统的解决问题办法并不能解决这么复杂的问题。最终,成功部署一个微服务应用需要开发者有足够的控制部署方法,并高度自动化。自动化的方法之一是使用譬如Cloud Foundery这样的PaaS服务。PaaS能让开发者轻松部署和管理微服务,让他们无需为获取并配置IT资源劳神。同时,配置PaaS的系统和网络专家可以采用最佳实践和策略来简化这些问题。另外一个自动部署微服务应用的方法是开发自己的PaaS系统。通常的起步方式是Mesos或Kubernetes这样的集群管理方案,配合Docker使用。