Spring Boot 2从入门到入坟 | 基础入门篇:Spring Boot的大时代背景
Posted 李阿昀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot 2从入门到入坟 | 基础入门篇:Spring Boot的大时代背景相关的知识,希望对你有一定的参考价值。
在前一讲中,我为大家介绍Spring Boot时,提出了一些概念,例如微服务、分布式等等,所以,我觉得有必要在本讲给大家说一下Spring Boot现在所处的大时代背景。首先,我先给大家介绍一下微服务。
微服务
早在2014年,James Lewis和Martin Fowler就提出了微服务的完整概念。大家不妨点开如下地址去看一下微服务的完整概念。
点开以上地址之后,你就能一睹微服务的完整概念了,如下图所示。
这里,我也将其英文介绍复制了下来,好让大家更清楚地看个明白!
In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.
– James Lewis and Martin Fowler (2014)
有些童鞋可能就说了,我本身英文就差,你还让我看英文,这不是欺负人嘛?没关系啊,如果大家看不懂以上微服务的英文介绍,那么接下来我就为大家详细解释一番。
根据以上微服务的英文介绍,这里我就粗略来翻译了一下,如有翻译的不确之处,还请大家指出,我一定修改!
-
微服务是一种架构风格。
-
一个应用拆分为一组小型服务。
这里说的是在使用微服务开发一个单个应用的时候,应该将其拆分成一组小型服务,也就是我们之前所说的一个大型应用应拆分成一个一个的小模块。
-
每个服务应运行在自己的进程内,也就是可以独立部署和升级。
这说的又是啥意思呢?意思就是说每一个小模块都可以独立部署到某一台服务器上,部署成功之后就可以进行迭代升级了。这就跟我们之前开发的单个应用一样,每一个微服务都是一个完整的单个应用。
-
服务之间使用轻量级HTTP交互。
微服务之间是使用轻量级通信机制来进行交互的,我们经常推荐使用的便是HTTP。现在我们将一个大型应用拆分成一个一个的小模块以后,模块之间肯定是会牵扯到互联互调的,例如一个大型的电商项目会有订单、购物车、用户信息等模块,最终结算时我们就要从购物车里面拿到订单数据,除此之外,我们还得拿到用户信息。由于每一个模块都可以独立部署和升级,那么在将这些模块独立部署到不同服务器上时,它们相互之间的交互就会成为一个问题,所以这里我们我们推荐使用轻量级的HTTP来进行交互。
-
服务围绕业务功能拆分。
我们也推荐整个微服务的构建应围绕着业务逻辑来进行,即只要整个大型应用的业务功能有多少,我们就应该将微服务拆分成多少。
-
可以由全自动部署机制独立部署。
这里说的是整个微服务还应该依赖于全自动化部署机制,为什么这么说呢?因为一个大型应用被拆分成许多许多模块之后,例如拆分成了100多个模块,那么一旦整个大型应用要上线部署,你再一个一个模块手动部署就会显得特别特别的麻烦,所以全自动部署机制就应运而生了。
-
去中心化,服务自治。服务可以使用不同的语言、不同的存储技术。
微服务是去中心化的,而且每一个服务既可以使用不同的语言开发,也可以使用不同的存储技术。这也就是说,微服务不再局限于语言,也不再局限于后端所使用的技术。因此,你可以感觉得到,微服务流行之后,各种语言开始竞相百家争鸣了。
以前我们总感觉Java将要一统天下了,可人算不如天算,自从微服务这种架构风格一出来,其他的语言也开始活跃起来了,如果你觉得使用世界上最好的语言(即php)开发一个后台管理系统很快,那么你就使用PHP来开发。
分布式
由于微服务这种架构风格的出现,所以我们就可以将一个大型应用拆分成一组小型服务并且独立部署了,此时必然就会产生分布式。
分布式的困难
一旦产生了分布式,那么接踵而至的就会出现各种分布式的问题,下面我会给大家详细阐述一下这些问题。
远程调用
先看一下下面张图。
如果A服务代表的是购物车模块,B服务代表的是订单模块,C服务代表的是用户模块,那么A服务想要调用B服务,B服务想要调用C服务,即互相远程调用,此时应该怎么办呢?
其实,在介绍微服务的时候,我就已经说过了,微服务之间是使用轻量级通信机制来进行交互的,我们经常推荐使用的便是HTTP。
服务发现
为什么会有服务发现呢?
还是参照上图来说,现在A服务想要调用B服务,而B服务又被部署到4台服务器上了,所以A服务在调用B服务时,随便调哪一台服务器都是可以的。此时,问题就出现了,A服务怎么知道部署B服务的4台服务器哪一台是好的呢?例如某一台服务器突然出现故障了,然后过了一会,它又起来了,这种现象是时有发生的。所以,咱们就想知道B服务在哪一台服务器上是好使的,知道之后,A服务就可以方便地来调用了。
正是在这样的背景下,服务发现机制就应运而生了。
负载均衡
如果我们发现B服务在4台服务器上都是好使的以后,那么A服务在调用B服务时,随便调哪一台服务器都是调用的同样的服务。既然调哪一台都行,那么这就涉及到负载均衡了,负载均衡怎么做这又是一个问题。
服务容错
服务容错是啥呢?
如果还是像我们之前那样,把所有的代码都写在一个单体应用里面,并部署到一台服务器上,那么A服务调用B服务,调用失败了,了不起B服务就向上抛一个异常出去。但是,现在不可同日而语了,咱们微服务这种架构风格出现了,像上图中那样,现在A服务想要调用B服务,而B服务又被部署到了4台服务器上,如果调用失败了的话,那么此时问题出现的原因就有很多了,有可能是B服务中写的代码有问题,有可能是网络不通了等各种故障。
所以,正是在这样的背景下,服务容错机制就应运而生了。一旦B服务的网络不通了,那么A服务应该怎么办呢?是要重置到其他服务器上吗?如果其他服务器都不通了呢,那么A服务又应该怎么办呢?是要返回一个什么样的默认数据吗?
配置管理
A服务既然在10台服务器上都部署了,那么我们想要修改其配置,应该怎么办呢?反正不管怎么样,我们都不可能去修改A服务所在的源代码,然后再将其重新部署到10台服务器上。聪明的做法就应该是这样的,将所有服务的配置放到一个配置中心里面。
如果你想要修改的话,那么只须去配置中心里面修改你想要修改的配置即可,这样,其他服务器部署的服务自个就会从配置中心里面将最新的配置给同步过来了。大家试想一下,这样修改是不是非常方便啊!
服务监控
将一个大型应用拆分成一组小型服务并且上到整个云平台之后,那么每一个服务所占的CPU资源、消耗的内存以及其健康状况等等,我们都应该全部监控起来。此时,问题就出现了,服务监控应该怎么做呢?
链路追踪
还是参照上图来说,如果A服务调用了B服务,B服务又调用了C服务,一旦服务调用出现了问题,那么我们是不是就要搜索整个链路究竟是哪一个环节导致整个链路调用失败了啊?在这种情况下,链路追踪应该怎么做呢?
日志管理
整个大型的分布式应用网,之间的日志又该怎么去管理呢?
任务调度
如果现在我们想要A服务去执行一个定时任务,那么我们就不得不来思考一些问题了,该定时任务一旦触发了,到底是要求部署A服务的10台服务器同时触发呢,还是只要求某一台触发?触发时,究竟是以并行的方式触发呢,还是以串行的方式触发?
以上就是微服务一旦拆分,形成了整个大型的分布式应用网之后,所产生的分布式问题。那这些分布式问题又该如何解决呢?
分布式的解决
对于上面出现的各种分布式问题,Spring生态圈也有相应的解决方案,即Spring Boot + Spring Cloud
。
大家不妨先看一下Spring官网之前的一个经典的案例图。
可以看到,首先我们会使用Spring Boot来帮我们快速地构建出一个应用,然后由于我们的应用会被拆分成众多的微服务模块,所以我们就要使用Spring Cloud把它们网状的互联互调起来,最后我们再使用Spring Cloud Data Flow将网状之间的数据流弄成响应式数据流。
所以,Spring Boot + Spring Cloud
就是我们的整套解决方案。可以这样说,只要我们使用了Spring Boot,那么我们就能享有Spring整个生态圈给我们带来的全能力。
云原生
最后,我们来看一下Spring Boot所处的第三个大时代背景,即云原生。
服务开发好之后,最终我们要部署,要让大家应用起来,这就牵扯到我们原生开发的应用如何上云的问题了?相信大家也能看到最近几年抛出的一个新概念,即Cloud Native
。
上云的困难
原生应用想要上云,那么这又会牵扯出一大堆的困难,下面我会给大家详细阐述一下这些困难。
服务自愈
假设现在A服务被部署到了5台服务器上,B服务被部署到了3台服务器上,C服务被部署到了2台服务器上,而且此时A服务想要调用B服务,B服务想要调用C服务,那么大家有没有想过这样一种情况,就是某一天部署C服务的2台服务器突然有一台炸了,服务还能自愈吗?
所谓的服务自愈就是既然某一台服务器上部署的服务出现问题了,那么还能不能在别台服务器自动又拉起一份服务呢?
弹性伸缩
同样地,假设现在A服务被部署到了5台服务器上,B服务被部署到了3台服务器上,C服务被部署到了2台服务器上,此时,突然间流量高峰进来了,A服务要大量的调用B服务,B服务要大量的调用C服务,但是C服务只被部署到了2台服务器上,明显不够,那么我们就要希望在流量高峰期间部署C服务的服务器能自动扩充几台,例如3台,等流量高峰过去一阵以后,我们再下线这几台服务器。而这就是所谓的弹性伸缩。
服务隔离
一台服务器是可以部署C服务,但你有没有想过,可能跟C服务在该台服务器部署的同时还有D、E服务,那么此时我们就要希望D、E等其他服务出现故障以后别影响C服务的调用,这就是所谓的服务隔离。
自动化部署
整个微服务全部部署到云平台以后,我们总不可能人肉运维、手工部署吧!所以,此时我们就希望能有自动化部署机制。
灰度发布
同样地,假设现在A服务被部署到了5台服务器上,B服务被部署到了3台服务器上,C服务被部署到了2台服务器上。如果B服务的版本此时都是v 1.0
,那么A服务调用B服务,肯定是先默认调用v 1.0
版的,是不是啊!
但软件总是要不停迭代升级的,我们想更新B服务的版本,于是我们又开发了一个v 2.0
版本的,现在如果我们直接将原先的v 1.0
版全部替换成v 2.0
版的,那么就极有可能会出现故障,例如服务调用的链路突然就炸了,原因可能就是新开发的v 2.0
版本的代码不稳定。那么,此时我们该怎么办呢?
这时,我们可以先只替换其中一台服务器上所部署的B服务,将其替换成v 2.0
版的,这样,在A服务调用B服务时,由于有负载均衡,那么A服务就有可能调用到新版本的B服务,也可以说A服务就有可能调用到一个新版API。经过长时间的验证,发现新版API没问题了,也就是新老版并存了,而且新版没问题了,那么我们再把老版一个一个的慢慢下线,如此一来,我们就完成了灰度发布。
流量治理
同样地,假设现在A服务被部署到了5台服务器上,B服务被部署到了3台服务器上,C服务被部署到了2台服务器上,而且此时A服务想要调用B服务,B服务想要调用C服务。
如果部署B服务的某一台服务器的性能本来就不高,那么很显然此时就不应该把大量流量拿给它,怎么做到这一点呢?我们可以通过流量治理手段来限制这台服务器只接收少量流量,而让其他服务器接收大量流量。
包括流量之间净出率的监控,以及根据净出率来动态扩缩容等等这些困难,都是我们服务部署到线上以后,所要解决的各种问题。
最终,你会发现云原生其实大多跟我们运维人员有很大关系,是不是啊?
上云的解决
后续,我应该会写一系列关于云原生的教程,不过这就要看我的时间多少了,我想将来不久我肯定是要写的,这是毋庸置疑的!如果大家有兴趣了解云原生的整个系列教程,那么不妨关注我一下,敬请期待我后续发布的文章哟!
当然了,这里我还是要给大家说一下整个云原生系列教程的大纲,如下图所示,如果你实在等不及了,那么不妨先按照这份大纲试着去学习一下云原生。
从以上大纲中可以看到,我们会从认识云原生的基本概念开始,然后再深入理解Docker容器化技术,接着再掌握Kubernetes,直至构建出整个自动化运维平台(即企业云平台)为止。当然了,我们还会拥抱新一代的架构,即Service Mesh与Serverless,Serverless这个概念我想大家一定听说过,因为在上一讲中我就讲过了,就是无服务开发。
而且,我还说过,使用Spring大家就可以简单快速地开发出一个函数式服务,开发出来以后,你可以直接将其部署到云平台上,很可能该函数式服务只占用1核的CPU、10MB的内存就足够了,如此一来,就不会浪费大量的系统资源了,而且整个系统的吞吐力还会得到一个质的提升。
以上是关于Spring Boot 2从入门到入坟 | 基础入门篇:Spring Boot的大时代背景的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 2从入门到入坟 | 基础入门篇:Spring Boot的大时代背景
Spring Boot 2从入门到入坟 | 基础入门篇:你会看Spring Boot的官方文档吗?
Spring Boot 2从入门到入坟 | 基础入门篇:你会看Spring Boot的官方文档吗?
Spring Boot 2从入门到入坟 | 基础入门篇:Spring Boot的大时代背景