微服务概念
什么是微服务
“微服务”一词来源于 Martin Fowler 的《Microservices》一文。微服务是一种架构风格,即将单体应用划分为小型的服务单元,微服务之间使用 HTTP 的 API (RESTFUL风格)进行资源访问与操作。如下图
-
左:all in one,单体架构下,应用紧耦合,所有的变更必须一起上线
-
中:传统SOA架构允许单独的变更,但是每一个部分必须很谨慎地修改以免破坏整体架构设计。
-
右:在微服务架构下,开发可以独立地创建、维护和改进服务。服务之间通过RESTFUL API连接。
下面来看看一个比较简单的微服务结构图:
在这里插入图片描述
从这幅图可以看出,每一个微服务单体应用(Microservice)都有自己一个单独的数据库进行连接(分库),这是要保证事物的一致性和避免脏数据以及减小响应的速度就非常有必要。以及如何保证每个服务之间的安全和持续通信,以及模块关联模块时,如何解决一整条模块链不会因为一个模块的宕机而引起服务雪崩。
微服务优点
整体架构一分再分,降低了每个模块的耦合性,每个服务单独进行专门的维护和开发,使分工更加明确,职责更加专一
-
服务的独立部署
- 每个服务都是一个独立的项目,可以独立部署,不依赖于其他服务,耦合性低。
-
服务的快速启动
- 拆分之后服务启动的速度必然要比拆分之前快很多,因为依赖的库少了,代码量也少了。
-
更加适合敏捷开发
- 敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行。服务拆分可以快速发布新版本,修改哪个服务只需要发布对应的服务即可,不用整体重新发布。
-
职责专一,由专门的团队负责专门的服务
- 业务发展迅速时,研发人员也会越来越多,每个团队可以负责对应的业务线,服务的拆分有利于团队之间的分工。
-
服务可以动态按需扩容
- 当某个服务的访问量较大时,我们只需要将这个服务扩容即可。
-
代码的复用
- 每个服务都提供 REST API,所有的基础服务都必须抽出来,很多的底层实现都可以以接口方式提供。
微服务缺点
-
分布式部署,调用的复杂性高
- 单体应用的时候,所有模块之前的调用都是在本地进行的,在微服务中,每个模块都是独立部署的,通过 HTTP 来进行通信,这当中会产生很多问题,比如网络问题、容错问题、调用关系等。
-
独立的数据库,分布式事务的挑战
- 每个微服务都有自己的数据库,这就是所谓的去中心化的数据管理。这种模式的优点在于不同的服务,可以选择适合自身业务的数据,比如订单服务可以用 MySQL、评论服务可以用 Mongodb、商品搜索服务可以用 Elasticsearch。缺点就是事务的问题了,目前最理想的解决方案就是柔性事务中的最终一致性(解决脏读、幻读、事务不一致)
-
测试的难度提升
- 服务和服务之间通过接口来交互,当接口有改变的时候,对所有的调用方都是有影响的,这时自动化测试就显得非常重要了,如果要靠人工一个个接口去测试,那工作量就太大了。这里要强调一点,就是 API 文档的管理尤为重要。
-
运维难度的提升
- 在采用传统的单体应用时,我们可能只需要关注一个 Tomcat 的集群、一个 MySQL 的集群就可以了,但这在微服务架构下是行不通的。当业务增加时,服务也将越来越多,服务的部署、监控将变得非常复杂,这个时候对于运维的要求就高了。
因此微服务背后一个重要的理念就是持续集成、快速交付,而在服务内部使用一个统一的技术框架,显然比将分散的技术组合到一起更有效率。(服务是上散开的,但是整个系统采用统一的技术选型和开发框架)
下面我们来看一下问题,带着这些问题来学习SpringCloud这个一站式解决方案。
微服务架构的四个核心问题
-
服务很多,客户端该如何访问?
-
这么多服务?服务之间如何通信?
-
这么多服务如何治理?
-
服务挂了怎么办?
微服务常见面试题
-
什么是微服务?
-
微服务之间是怎么独立通信的?
-
SpringCloud和SpringBoot,请谈谈你对他们的理解?
-
什么是服务熔断,什么是服务降级?
-
微服务的优缺点分别是什么,说下你在项目开发中遇到的坑?
-
你所知道的微服务的技术栈有哪些?请列举一二?
-
eureka和zookeeper都可以提供服务注册与发现的功能,请说出两个的区别?
SpringCloud学习
SpringCloud模块
-
Eureka:服务注册中心,用于服务管理。(类似于zookeeper)
-
Ribbon:基于客户端的负载均衡组件。
-
Hystrix:容错框架,能够防止服务的雪崩效应。
-
Feign:**Web **服务客户端,能够简化 HTTP 接口的调用。
-
Zuul:**API **网关,提供路由转发、请求过滤等功能。
-
Config:分布式配置管理。
-
Sleuth:服务跟踪。
-
Stream:构建消息驱动的微服务应用程序的框架。
-
Bus:消息代理的集群消息总线
-
。。。等等
SPringCloud版本对照表
Release Train | Boot Version |
---|---|
2020.0.x aka Ilford | 2.4.x |
Hoxton | 2.2.x, 2.3.x (Starting with SR5) |
Greenwich | 2.1.x |
Finchley | 2.0.x |
Edgware | 1.5.x |
Dalston | 1.5.x |
Spring官网的微服务实例图
SpringCloud和Dubbo的区别
dubbo介绍(具体点击):
首先明确一点,dubbo+zookeeper这种调用模式是基于RPC协议的,且它只是用来解决远程接口调用的。下面来看看dubbo的provider和customer调用图
图例说明:
-
图中小方块 Protocol, Cluster, Proxy, Service, Container, Registry, Monitor 代表层或模块,蓝色的表示与业务有交互,绿色的表示只对 Dubbo 内部交互。
-
图中背景方块 Consumer, Provider, Registry, Monitor 代表部署逻辑拓扑节点。
-
图中蓝色虚线为初始化时调用,红色虚线为运行时异步调用,红色实线为运行时同步调用。
-
图中只包含 RPC 的层,不包含 Remoting 的层,Remoting 整体都隐含在 Protocol 中。
图例说明:
-
调用中间层变成了可选组件,消费方可以直接访问服务提供方;
-
服务信息被集中到 Registry 中,形成了服务治理的中心组件;
-
通过 Monitor 监控系统,可以直观地展示服务调用的统计信息;
-
服务消费者可以进行负载均衡、服务降级的选择。
可以看出dubbo灵活性(可自行选择Redis或者Zookeeper作为注册中心),以及使用RPC协议传输速度比HTTP远程调用数据更快
但是站在微服务架构的角度考虑,dubbo还是有一些不足的:
-
首先,provider端以及customer端必须依赖Interface接口所在的依赖,provider端需要不断将包含interface的Jar 包打包出来供customer端使用。一旦打包出现问题,就会导致服务调用出错。
-
dubbo服务调用时,严重依赖第三方组件(zookeeper/redis)作为注册器(Registry),但这些组件出现问题时,消费-服务链也会中断
也是当前由于 RPC 协议、注册中心元数据不匹配等问题,在面临微服务基础框架选型时 Dubbo 与 Spring Cloud 只能二选一。
SpringCloud介绍
官网说明:开发分布式系统具有挑战性。复杂性从应用层转移到网络层,并要求服务之间进行更大的交互。使代码成为“云本地”意味着要处理12个因素的问题,比如外部配置、无状态、日志记录和连接到后备服务。项目的Spring Cloud套件包含许多使应用程序在云中运行所需的服务。这意味着SpringCloud是完全面向分布式以及云开发的,是一个完整的一站式的生态系统。
SpringCloud与dubbo功能对比表:
功能名称 | Dubbo | Spring Cloud |
---|---|---|
服务注册中心 | ZooKeeper | Spring Cloud Netflix Eureka |
服务调用方式 | RPC | REST API(Http协议) |
服务网关 | 无 | Spring Cloud Netflix Zuul |
断路器 | 不完善(可以集成Hystrix) | Spring Cloud Netflix Hystrix |
分布式配置 | 无 | Spring Cloud Config |
服务跟踪 | 无 | Spring Cloud Sleuth |
消息总线 | 无 | Spring Cloud Bus |
数据流 | 无 | Spring Cloud Stream |
批量任务 | 无 | Spring Cloud Task |
Spring Cloud 抛弃了 Dubbo 的 RPC 通信,采用的是基于 HTTP 的 REST 方式。严格来说,这两种方式各有优劣。虽然从一定程度上来说,后者牺牲了服务调用的性能,但也避免了上面提到的原生 RPC 带来的问题。而且 REST 相比 RPC 更为灵活,服务提供方和调用方,不存在代码级别的强依赖,这在强调快速演化的微服务环境下显得更加合适。
很明显,Spring Cloud 的功能比 Dubbo 更加强大,涵盖面更广,Spring Cloud是一站式开发框架,它也能够与 Spring Framework、Spring Boot、Spring Data、Spring Batch 等其他 Spring 项目完美融合,这些对于微服务而言是至关重要的。
前面提到,微服务背后一个重要的理念就是持续集成、快速交付,而在服务内部使用一个统一的技术框架,显然比将分散的技术组合到一起更有效率。