浅谈微服务之Springcloud

笔者是19年6月毕业的,最近刚刚经历离职、跳槽,在家办公期间闲来无事,撸一下自己在前公司对于微服务和springcloud的一些见解,新手小白,有说的不对的地方望大神指正。
微服务是什么?
在讲述一件新事物的同时,不妨去了解一下它出现的背景,以及它的出现解决了什么问题。
在Java开发web应用过程中,一个较为典型的架构风格就是把前端(Front-end)和后端(Back-end)的所有文件统统放在同一个工程之下,通过maven或者gradle等构建工具打成war包,丢进tomcat或者jetty等服务容器中run起来。 类似下图:

浅谈微服务之Springcloud_第1张图片
这种架构的缺点在于:
1.复杂且单一。笔者第一家公司所用的是SSH架构(Spring+Struts+hibernate),典型的javaweb应用,当时还没有用maven来管理项目依赖,在开发当中经常在改动了一行代码需要手动打war再丢到服务器tomcat中,查进程杀进程,重启tomcat。所以我们所有项目小组有一个群,只要是谁在重启都要说一下,经常其他组的实习生在测试bug的时候,我们本地开发就连接超时了,这个时候就可以出去抽根烟了哈哈。
2.不利于技术拓展和更新。这个很容易理解,项目结构只有一个,后端采用java,那只能是java语言,用php只能是php,一旦哪天要项目重构,脑瓜子能给你干烂。
3.不易维护与理解。可以想象一下应届生刚进入公司的时候,一个后端项目十几个模块,每个模块几十个包,在打断点调试的时候你可能就忘了你为什么要断点调试的原因了。
经历了单体地狱之后,业界便在寻找一种更好的解决方案,微服务(MicroService)应运而生~
微服务架构可以说是如何将功能分解成一系列服务的一种架构模式。简单理解就是一分为多,比如你本来一个博客系统就可以拆分成用户服务、社区服务、积分服务等等,每一个服务都可以是一个单体应用,可以运行在特定的容器当中,实现应用的解耦。
浅谈微服务之Springcloud_第2张图片
如上图是我画的一个简单的微服务的草图,将原来单体应用根据业务进行拆分成多个服务,每个服务就相当于一个web应用,他们之间通过网络协议进行信息的交互,就不会经常出现A改了A服务,C在开发的时候要等A把整个项目重启这样的窘境。
微服务划分一般是根据业务需求来的,存在一个服务粒度的概念。粒度不宜过粗和过细,如果你一个简单的用户登录接口硬是以dao和service拆成了两个服务,这其实是没有必要的,反而放大了项目整体的复杂性;相反一个庞大的电商系统,你只分成了仓库服务和订单服务,但是在订单当中可能存在积分、邮件等等不小的模块,这种情况耦合度还是相当高的。

什么是SpringCloud?

Springcloud是Pivotal团队根据Netflix OSS 的基础之上推出的构建微服务的架构方案。
首先,SpringCloud不是一个开箱即用的框架,这个在很多初学者学习的时候经常会混淆这个概念。你可以理解成,SpringCloud是一个思想,一个方法,一套完整的微服务架构理念或者是一个全家桶(类似肯德基哈哈),它将业界成熟的各种微服务架构的组件做了一个整合,例如服务治理、服务网关、服务熔断、统一配置、服务通信、链路追踪、服务监控等等一个成熟的微服务架构所需要的组件,springcloud将它们放置在自己的桶中,并没有去重复造轮子。
谈及微服务,就不得不提到它几个核心的概念:
1.服务治理

当我们开始搭建微服务架构的时候首先遇到的一个问题就是:作为消费者如何访问并且调用提供服务提供者所提供的服务;作为服务提供者如何能让自己提供的服务让其他的消费者所调用。在传统应用当中,我们都是直接在开发语言层面去解决这个问题,例如A类->调用->B类方法,就算是多模块项目,可能仅仅是用Http客户端工具类进行远程调用,假设A服务有100个实例,分别部署在100台机器上,那你是在代码中使用一个数组存贮这100个实例地址并且用Random去实现服务调用吗,那可能都不用等到明天,你现在就会对自己这种做法感到羞愧。在微服务架构中,每一个服务可能存在多个实例,并且这些实例在不停的上线下线,那么它们如何相知?使用物理地址肯定是不可取的,因为你根本不知道你明天会不会因为流量巨大又买了台服务器部署了几个服务(别问,问就是有钱)。如果一个服务已经不在线,那么当你调用的时候就会出现长时间的网络等待,最终造成失败。
服务治理就是提出来解决以上的问题。通过服务发现,消费者不需要知道提供者的物理地址,只需要通过实现定义好的服务名就可以实现服务的调用;提供者也不用关心自己的服务最终会被谁调用。服务的注册机制就是让服务提供者在上线的时候讲所提供的服务信息注册到服务治理服务器中,并且在下线的时候通知治理服务器将自己实例信息删除,避免流量进入错误的地址。

2.微服务的负载均衡
浅谈微服务之Springcloud_第3张图片
对于负载均衡的理解可以通过上图。传统的应用可能会在用户请求的入口通过负载均衡设备(Nginx)实现负载均衡。但是在微服务架构下,这种做法是行不通的,因为不仅要考虑用户请求,同时在服务之间调用也需要考虑负载,但是此时如果再继续使用这种方式的话,无疑是增加了系统结构的复杂性,并且你根本无法预料到你的服务实例将如何变化。因此,针对微服务调用的负载均衡需要另谋出路。因此,业界提出了客户端负载均衡想法,就是在服务消费客户端保存有一份治理服务器中其他所有服务的实例列表,在流量进来的时候,客户端根据自己的策略去实现。

3.微服务的统一入口

首先,微服务是多的,在企业级应用当中,如果选用微服务架构,不可能只有一两个实例,比如A服务可能有几十个实例,整个服务有几百上千个,那么问题来了,你是后端工程师,可能刚好你在负责某几个服务你比较清楚,但是有没有想过前端MM的心理阴影? (PS.妈耶,我要记住那么多个服务的地址吗。。。。) 这个时候可能友谊的小船说翻就翻。作为前端或者第三方来说,肯定是不愿意个你这么多的微服务打交道的,这个时候就需要提供一个微服务的统一入口,根据事先制定好的路由规则帮助客户端路由到需要的服务。

4.微服务的容错。

容错,其实换个说法也叫做熔断。想象一下,在电路系统当中如果没有保险丝的话,温度过高的情况下电路线直接烧起来,这是一件很可怕的事情, 在微服务架构当中也是一样。微服务架构从搭建初期就注定是高度分散的分布式结构,服务间的调用通过网络分散出去,很有可能一个服务的调用,下游涉及了多个服务。在电商系统当中,假设有100个用户请求下单,相当于启动了100个线程,下单涉及到订单服务、积分服务、仓储服务,订单服务下单之后需要通知仓储服务扣减相应库存,并且通知积分服务增加用户积分,假设在调用积分服务的时候,积分服务由于网络原因崩溃或者下线了,那么在没有熔断的情况下,用户可能只是看到界面一直在转圈圈,等到访问超时之后跳出一个500错误,什么鬼,一堆字母。 如果用户量十分巨大的情况下,所有的线程都会卡在积分服务这里,直到系统崩溃、内存溢出等等,就造成了业界比较经典的“服务雪崩”现象。
有了服务熔断,这个时候我们可以为积分服务指定超时规则,当检测到超时并且重试无效之后,我们可以自己提前定义好一个相对友好的响应,或者可以在数据库中持久化一条记录,待到网络恢复之后可以进行手动数据修改。没错,容错就是干这个事的。

5.微服务的统一配置

在单体应用当中,项目可能存在多个配置文件,在同一项目下可以统一修改和管理。但是在微服务架构当中,由于服务数量多,并且可能存在相同的配置数据等等,这时候如果还是分散在各个服务中进行分别的管理,那么面对成百上千个服务实例时候,这管理的难度无疑是非常巨大的,可以预览到你要变更一个配置文件的巨大难度。并且,我们也不希望每个系统进行配置文件的各自更改,这样有可能引起服务的巨大变更和混乱。

6.微服务的监控。

微服务的灵活和强大是一把双刃剑,为开发人员带来曙光的同时也为其带来了“噩梦”。一般的调试和跟踪分析在单体应用下是没有问题的,因为它是化零为整的一个概念,所有东西都在一个项目底下。对于调用和跟踪分析的重要性相信不用我说大家也都知道,特别是当应用正式上线的时候,有一个良好的日志分析可以快速定位到问题所在。但是在微服务场景下这是很难进行的,因为上面说过了,微服务的调用可能存在服务下游的多个服务之间,并且每一个服务都有自己的日志记录的话,如何将所有的日志整合成统一的日志系统,这将会是一个非常巨大的挑战。 当然,springcloud在微服务监控这块提供了日志聚合、日志可视化分析、调用链路跟踪等等解决方案,现在更有ELK等专为日志系统而生的技术栈,都可以为搭建强大的微服务监控系统提供强有力的帮助。

说了这么多,其实笔者只是对于想学习springcloud和微服务的童鞋们讲了自己的浅薄理解,须知,学习一门语言的开始必须理解它的核心思想以及各种应用场景,任何成熟的框架都是为了解决各种各样的业务难题而诞生的,而springcloud正是微服务架构的一个不错的解决方案。 有点乏了,第一篇博客有点简陋,如果有什么问题希望大家指正,从后面开始将持续更新有关Springcloud的搭建以及实战。

Last but not least,talk is cheap,show me the code

你可能感兴趣的:(java,分布式)