简述微服务架构

一、什么是微服务

微服务是一种用于构建应用的架构方案。其中每个功能都被称为一项服务,每个服务都维护着自身的数据存储、业务开发、自动化测试案例,服务与服务间采用轻量级的通信机制互相沟通。每个服务都围绕着具体业务进行构建,并且能够独立的部署到生产环境。

二、微服务的由来

微服务早由MartinFowler与JamesLewis于2014年共同提出,微服务架构风格是一种使用一套小服务来开发单个应用的方式途径,每个服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTPAPI,这些服务基于业务能力构建,可以使用不同的编程语言实现,以及不同数据存储技术,并保持低限度的集中式管理。

三、微服务和单体系统的区别

1.单体架构所有的模块全都耦合在一块,代码量大,维护困难,微服务每个模块就相当于一个单独的项目,代码量明显减少,遇到问题也相对来说比较好解决。

2.单体架构所有的模块都共用一个数据库,存储方式比较单一,微服务每个模块都可以使用不同的存储方式(比如有的用redis,有的用mysql等),数据库也是单个模块对应自己的数据库。

3.单体架构所有的模块开发所使用的技术一样,微服务每个模块都可以使用不同的开发技术,开发模式更灵活。

四、如何实施微服务

1、服务组件化
组件,是一个可以独立更换和升级的单元。就像PC中的CPU、内存、显卡、硬盘一样,独立且可以更换升级而不影响其他单元。
在微服务架构中,需要我们对服务进行组件化分解。服务,是一种进程外的组件,它通过http等通信协议进行协作,而不是传统组件以嵌入的方式协同工作。
服务都独立开发、部署,可以有效的避免一个服务的修改引起整个系统的重新部署。

2、按业务组织团队
当我们开始决定如何划分微服务时,通常也意味着我们要开始对团队进行重新规划与组织。按以往的方式,我们往往会以技术的层面去划分多个不同的团队,比如:DBA团队、运维团队、后端团队、前端团队、设计师团队等等。若我们继续按这种方式组织团队来实施微服务架构开发时,当有一个有问题需要更改,可能是一个非常简单的变动,比如:对人物描述增加一个字段,这就需要从数据存储开始考虑一直到设计和前端,虽然大家的修改都非常小,但这会引起跨团队的时间和预算审批。在实施微服务架构时,需要采用不同的团队分割方法。由于每一个微服务都是针对特定业务的宽栈或是全栈实现,既要负责数据的持久化存储,又要负责用户的接口定义等各种跨专业领域的职能。因此,面对大型项目时候,对于微服务团队拆分更加建议按业务线的方式进行拆分,一方面可以有效减少服务内部修改所产生的内耗;另一方面,团队边界可以变得更为清晰。

3、轻量化通信机制
在单体应用中,组件间直接通过函数调用的方式进行交互协作。而在微服务架构中,服务由于不在一个进程中,组件间的通信模式发生了改变,若仅仅将原本在进程内的方法调用改成RPC方式的调用,会导致微服务之间产生繁琐的通信,使得系统表现更为糟糕,所以,我们需要更粗粒度的通信协议。
在微服务架构中,通常会使用这两个服务调用方式:
第一种,使用HTTP协议的RESTful API或轻量级的消息发送协议,来实现信息传递与服务调用的触发。
第二种,通过在轻量级消息总线上传递消息,类似RabbitMQ等一些提供可靠异步交换的结构。

4、去中心化治理
当我们采用集中化的架构治理方案时,通常在技术平台上都会做统一的标准,但是每一种技术平台都有其短板,这会导致在碰到短板时,不得不花费大力气去解决,并且可能还是因为其底层原因解决的不是很好。
在实施微服务架构时,通过采用轻量级的契约定义接口,使得我们对于服务本身的具体技术平台不再那么敏感,这样我们整个微服务架构的系统中的组件就能针对其不同的业务特点选择不同的技术平台,不会出现杀鸡用牛刀或是杀牛用指甲钳的尴尬处境了。

5、去中心化管理数据
我们在实施微服务架构时,都希望可以让每一个服务来管理其自有的数据库,这就是数据管理的去中心化。
在去中心化过程中,我们除了将原数据库中的存储内容拆分到新的同平台的其他数据库实例中之外(如:把原本存储在MySQL中的表拆分后,存储多几个不同的MySQL实例中),也可以针对一些具有特殊结构或业务特性的数据存储到一些其他技术的数据库实例中(如:把日志信息存储到MongoDB中、把用户登录信息存储到Redis中)。虽然,数据管理的去中心化可以让数据管理更加细致化,通过采用更合适的技术来让数据存储和性能达到最优。但是,由于数据存储于不同的数据库实例中后,数据一致性也成为微服务架构中急需解决的问题之一。分布式事务的实现,本身难度就非常大,所以在微服务架构中,我们更强调在各服务之间进行“无事务”的调用,而对于数据一致性,只要求数据在最后的处理状态是一致的效果;若在过程中发现错误,通过补偿机制来进行处理,使得错误数据能够达到最终的一致性。

6、基础设施自动化
近年来云计算服务与容器化技术的不断成熟,运维基础设施的工作变得越来越不那么难了。但是,当我们实施微服务架构时,数据库、应用程序的个头虽然都变小了,但是因为拆分的原因,数量成倍的增长。这使得运维人员需要关注的内容也成倍的增长,并且操作性任务也会成倍的增长,这些问题若没有得到妥善的解决,必将成为运维人员的噩梦。所以,在微服务架构中,务必从一开始就构建起“持续交付”平台来支撑整个实施过程。
该平台需要两大内容,不可或缺:
自动化测试:每次部署前的强心剂,尽可能的获得对正在运行软件的信心。
自动化部署:解放繁琐枯燥的重复操作以及对多环境的配置管理。

7、容错设计
在单体应用中,一般不存在单个组件故障而其他还在运行的情况,通常是一挂全挂。而在微服务架构中,由于服务都运行在独立的进程中,所以是存在部分服务出现故障,而其他服务都正常运行的情况,比如:当正常运作的服务B调用到故障服务A时,因故障服务A没有返回,线程挂起开始等待,直到超时才能释放,而此时若触发服务B调用服务A的请求来自服务C,而服务C频繁调用服务B时,由于其依赖服务A,大量线程被挂起等待,最后导致服务C也不能正常服务,这时就会出现故障的蔓延。所以,在微服务架构中,快速的检测出故障源并尽可能的自动恢复服务是必须要被设计和考虑的。通常,我们都希望在每个服务中实现监控和日志记录的组件,比如:服务状态、断路器状态、吞吐量、网络延迟等关键数据的仪表盘等。

8、演进式设计
通过上面的几点特征,我们已经能够体会到,要实施一个完美的微服务架构,需要考虑的设计与成本并不小,对于没有足够经验的团队来说,甚至要比单体应用发付出更多的代价。所以,很多情况下,架构师们都会以演进的方式进行系统的构建,在初期系统以单体系统的方式来设计和实施,一方面系统体量初期并不会很大,构建和维护成本都不高。另一方面,初期的核心业务在后期通常也不会发生巨大的改变。随着系统的发展或者业务的需要,架构师们会将一些经常变动或是有一定时间效应的内容进行微服务处理,并逐渐地将原来在单体系统中多变的模块逐步拆分出来,而稳定不太变化的就形成了一个核心微服务存在于整个架构之中。

五、微服务如何实现

1.服务发现——Netflix Eureka
Eureka是由Netflix公司推出的服务注册和发现工具。现已被Spring Cloud集成,提供了开箱即用的支持。
Eureka中分为两个角色:Eureka Server(Eureka服务)和Eureka Client(Eureka客户端)。
服务端和客户端都是一个Java项目,在Spring Cloud中主要通过启动类上添加@EnableEurekaServer和@EnableEurekaClient来区分当前应用程序是服务端还是客户端。
Eureka Server可以理解为注册中心,只是现在使用的是Java项目实现的。
Eureka Client 可以理解成所有需要注册到Eureka Server中的项目。注册后可以通过注册中心获取到项目信息和项目所在服务器信息,通过这些信息调用这个项目。
Spring Cloud 中每个项目调用的信息都存储在了注册中心中(Eureka)。

2.客服端负载均衡——Netflix Ribbon
服务高可用的保证手段,为了保证高可用,每一个微服务都需要部署多个服务实例来提供服务。此时客户端进行服务的负载均衡。

2.1 负载均衡的常见策略
2.1.1 随机
把来自网络的请求随机分配给内部中的多个服务器。

2.1.2 轮询
每一个来自网络中的请求,轮流分配给内部的服务器,从1到N然后重新开始。

2.1.3 加权轮询
根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。

2.1.4 IP Hash
这种方式通过生成请求源IP的哈希值,并通过这个哈希值来找到正确的真实服务器。这意味着对于同一主机来说他对应的服务器总是相同。使用这种方式,你不需要保存任何源IP。但是需要注意,这种方式可能导致服务器负载不平衡。

2.1.5 最少连接数
客户端的每一次请求服务在服务器停留的时间可能会有较大的差异,随着工作时间加长,如果采用简单的轮循或随机均衡算法,每一台服务器上的连接进程可能会产生极大的不同,并没有达到真正的负载均衡。

3.断路器——Netflix Hystrix
Hystrix是一个有关延迟和失败容错的开源库包,用来设计隔离访问远程系统端点或微服务等,防止级联爆炸式的失败,也就是由一个小问题引起接二连三扩大的疯狂的错误爆炸直至整个系统瘫痪,能够让复杂的分布式系统更加灵活具有弹性。

3.1熔断
当一个服务因为各种原因停止响应时,调用方通常会等待一段时间,然后超时或者收到错误返回。如果调用链路比较长,可能会导致请求堆积,整条链路占用大量资源一直在等待下游响应。所以当多次访问一个服务失败时,应熔断,标记该服务已停止工作,直接返回错误。直至该服务恢复正常后再重新建立连接。

3.2服务降级
当下游服务停止工作后,如果该服务并非核心业务,则上游服务应该降级,以保证核心业务不中断。比如网上超市下单界面有一个推荐商品凑单的功能,当推荐模块挂了后,下单功能不能一起挂掉,只需要暂时关闭推荐功能即可。

3.3限流
一个服务挂掉后,上游服务或者用户一般会习惯性地重试访问。这导致一旦服务恢复正常,很可能因为瞬间网络流量过大又立刻挂掉,在棺材里重复着仰卧起坐。
因此服务需要能够自我保护——限流。限流策略有很多,最简单的比如当单位时间内请求数过多时,丢弃多余的请求。另外,也可以考虑分区限流。仅拒绝来自产生大量请求的服务的请求。例如商品服务和订单服务都需要访问促销服务,商品服务由于代码问题发起了大量请求,促销服务则只限制来自商品服务的请求,来自订单服务的请求则正常响应。

4.服务网关——Netflix Zuul
服务网关 = 路由转发 + 过滤器
路由转发:接收一切外界请求,转发到后端的微服务上去;
过滤器:在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等,这些都可以通过过滤器完成(其实路由转发也是通过过滤器实现的)。

5.分布式配置——Spring Cloud Config
SpringCloudConfig是我们配置中心,在单体应用中,配置文件不多,可以很方便处理。但是对于微服务架构来说,每个微服务就有:测试环境、生产环境、线上环境等。而微服务项目又有多个,所以呢,我们可以采用配置中心来进行统一管理。

六、总结微服务的优点和缺点

优点:
逻辑清晰:可维护性高:微服务的单一职责可以很清楚服务是用来干什么的,修改时很容易分析到这个修改会产生什么影响。
简化部署:在一个单块系统中,只要修改了一行代码,就需要对整个系统进行重新的构建、测试,然后将整个系统进行部署。而微服务则可以对一个微服务进行部署。
可扩展:分布式系统中通常要采用横向的方式进行业务扩展。因为不同的功能会面对不同的负荷变化,因此采用微服务的系统相对单块系统具备更好的可扩展性。
灵活组合:在微服务架构中,可以通过组合已有的微服务以达到功能重用的目的。
技术异构:在一个大型系统中,不同的功能具有不同的特点,并且不同的团队可能具备不同的技术能力。因为微服务间松耦合,不同的微服务可以选择不同的技术栈进行开发。
高可靠:微服务间独立部署,一个微服务的异常不会导致其它微服务同时异常。通过隔离、融断等技术可以避免极大的提升微服务的可靠性。

缺点:
复杂度高:微服务间通过REST、RPC等形式交互,相对于单体架构下的API形式,需要考虑被调用方故障、过载、消息丢失等各种异常情况,代码逻辑更加复杂
运维复杂:在采用微服务架构时,系统由多个独立运行的微服务构成,需要一个设计良好的监控系统对各个微服务的运行状态进行监控。运维人员需要对系统有细致的了解才对够更好的运维系统。
影响性能:相对于单体架构,微服务的间通过REST、RPC等形式进行交互,通信的时延会受到较大的影响。

总结

微服务具备了灵活部署、可扩展、技术异构等优点,但同时也带来了开发、运维的复杂性,是否要采用微服务架构需要根据系统的特点,结合企业的组织架构、团队能力等多个方面进行综合的判断如果因为业务逻辑和系统边界还不是name清晰,可以采用演进式设计,在初期系统以单体系统的方式来设计和实施,后续将一些经常变动或是有一定时间效应的内容进行微服务处理,并逐渐地将原来在单体系统中多变的模块逐步拆分出来,而稳定不太变化的就形成了一个核心微服务存在于整个架构之中。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值