微服架构简介

xiaoxiao2022-06-03  49

什么是微服务?

专业解释:

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。、

通俗解释:

a 、一组小的服务(大小没有特别的标准,只要同一团队的工程师理解服务的标识一致即可)

b、独立的进程(java的tomcat,nodejs等)

c、轻量级的通信(不是soap,是http协议)

d、基于业务能力(类似用户服务,商品服务等等)

e、独立部署(迭代速度快)

f、无集中式管理(无须统一技术栈,可以根据不同的服务或者团队进行灵活选择)

微服的利与弊:

利:强模块边界 。(模块化的演化过程:类-->组件/类库(sdk)-->服务(service),方式越来越灵活)。可独立部署。技术多样性

弊:分布式复杂性。最终一致性。(各个服务的团队,数据也是分散式治理,会出现不一致的问题)运维复杂性。测试复杂性。

企业什么时候引入微服?

从生产力和系统复杂性以及各方面综合考虑,一开始,系统复杂度不高,又在商业模式验证过程中,业务简单,用单体服务效率最高。随着公司生产力提高,业务越来越复杂,这时候可以考虑微服来提升效率。但这个转化点是需要架构师进行各方面的权衡,就个人经验来说,团队上百人,采用微服就很有必要了。

常用的微服架构

Spring Boot、Spring Cloud、Dubbo

什么是Spring Boot

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。用我的话来理解,就是Spring Boot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,Spring Boot整合了所有的框架(不知道这样比喻是否合适)。

Spring Boot简化了基于Spring的应用开发,通过少量的代码就能创建一个独立的、产品级别的Spring应用。 Spring Boot为Spring平台及第三方库提供开箱即用的设置,这样你就可以有条不紊地开始。Spring Boot的核心思想就是约定大于配置,多数Spring Boot应用只需要很少的Spring配置。采用Spring Boot可以大大的简化你的开发模式,所有你想集成的常用框架,它都有对应的组件支持。  

Spring Cloud都做了哪些事

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包

以下为Spring Cloud的核心功能:

分布式/版本化配置服务注册和发现路由服务和服务之间的调用负载均衡断路器分布式消息传递

我们再来看一张图:

通过这张图,我们来了解一下各组件配置使用运行流程:

1、请求统一通过API网关(Zuul)来访问内部服务.2、网关接收到请求后,从注册中心(Eureka)获取可用服务3、由Ribbon进行均衡负载后,分发到后端具体实例4、微服务之间通过Feign进行通信处理业务5、Hystrix负责处理服务超时熔断6、Turbine监控服务间的调用和熔断相关指标

 

Spring Cloud体系介绍

上图只是Spring Cloud体系的一部分,Spring Cloud共集成了19个子项目,里面都包含一个或者多个第三方的组件或者框架!

Spring Cloud 工具框架

1、Spring Cloud Config 配置中心,利用git集中管理程序的配置。 2、Spring Cloud Netflix 集成众多Netflix的开源软件 3、Spring Cloud Bus 消息总线,利用分布式消息将服务和服务实例连接在一起,用于在一个集群中传播状态的变化 4、Spring Cloud for Cloud Foundry 利用Pivotal Cloudfoundry集成你的应用程序 5、Spring Cloud Cloud Foundry Service Broker 为建立管理云托管服务的服务代理提供了一个起点。 6、Spring Cloud Cluster 基于Zookeeper, Redis, Hazelcast, Consul实现的领导选举和平民状态模式的抽象和实现。 7、Spring Cloud Consul 基于Hashicorp Consul实现的服务发现和配置管理。 8、Spring Cloud Security 在Zuul代理中为OAuth2 rest客户端和认证头转发提供负载均衡 9、Spring Cloud Sleuth SpringCloud应用的分布式追踪系统,和Zipkin,HTrace,ELK兼容。 10、Spring Cloud Data Flow 一个云本地程序和操作模型,组成数据微服务在一个结构化的平台上。 11、Spring Cloud Stream 基于Redis,Rabbit,Kafka实现的消息微服务,简单声明模型用以在Spring Cloud应用中收发消息。 12、Spring Cloud Stream App Starters 基于Spring Boot为外部系统提供spring的集成 13、Spring Cloud Task 短生命周期的微服务,为SpringBooot应用简单声明添加功能和非功能特性。 14、Spring Cloud Task App Starters 15、Spring Cloud Zookeeper 服务发现和配置管理基于Apache Zookeeper。 16、Spring Cloud for Amazon Web Services 快速和亚马逊网络服务集成。 17、Spring Cloud Connectors 便于PaaS应用在各种平台上连接到后端像数据库和消息经纪服务。 18、Spring Cloud Starters (项目已经终止并且在Angel.SR2后的版本和其他项目合并) 19、Spring Cloud CLI 插件用Groovy快速的创建Spring Cloud组件应用。

 

架构演化的步骤

在确定使用Spring Boot/Cloud这套技术栈进行微服务改造之前,先梳理平台的服务,对不同的服务进行分类,以确认演化的节奏。先让团队熟悉Spring Boot技术,并且优先在基础服务上进行技术改造,推动改动后的项目投产上线当团队熟悉Spring Boot之后,再推进使用Spring Cloud对原有的项目进行改造。在进行微服务改造过程中,优先应用于新业务系统,前期可以只是少量的项目进行了微服务化改造,随着大家对技术的熟悉度增加,可以加快加大微服务改造的范围传统项目和微服务项目共存是一个很常见的情况,除非公司业务有大的变化,不建议直接迁移核心项目。

10个常用各spring cloud组建介绍(来源:https://www.jianshu.com/p/7468643ead77)

 

spring cloud config

远程配置服务。远程配置是每个都必不可少的中间件,远程配置的特点一般需要:多节点主备、配置化、动态修改、配置本地化缓存、动态修改的实时推送等。config允许配置文件放在git上或者svn上,和spring boot的集成非常容易,但是缺点就是修改了git上的配置以后,只能一个一个的请求每个service的接口,让他们去更新配置,没有修改配置的推送消息。而且,如果要根据配置文件的修改,做一些重新初始化操作的话(如线程池的容量变化等),会需要一些work around的方法,所以建议如果有其他方案,不建议选择spring cloud config。

spring cloud bus

事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化。经常与Spring Cloud Config联合使用。spring cloud config本身不能向注册过来的服务提供实时更新的推送。比如我们配置放在了git上,那么当修改github上配置内容的时候,最多可以配置webhook到一台config-server上,但是config-server自己不会将配置更新实时推送到各个服务上。bus的作用就是将大家链接在一条总线上,这条线上的所有server共享状态,当webhook到bus上的某一台server的时候,其他server也会收到相同的hook状态。但是bus的使用需要依赖于MQ,bus直接继承了RabbitMq & kafka,只需要在spring中直接配置地址即可,但是对于其他类型的MQ,就需要一些手动配置。最大的问题还是,如果仅仅因为spring cloud bus而让自己的系统引入MQ,显然会有些得不偿失。我理解系统应该在满足现有业务需求的基础上,越简单越好,依赖越少链路越短,越能减少出问题的风险。

eureka

spring cloud的服务发现组件。这个组件讲起来需要大篇幅,最好和consul一起讲。eureka负责服务注册和服务发现,为了高可用,一般需要多个eureka server相互注册,组成集群。Eureka Server的同步遵循着一个非常简单的原则:只要有一条边将节点连接,就可以进行信息传播与同步。eureka内部对于注册的service主要通过心跳来监控service是否已经挂掉,默认心跳时间是15s。这就意味着,当一个服务提供方挂掉以后,服务订阅者最长可能30s以后才发现。service启动连上eureka之后,会同步一份服务列表到本地缓存,服务注册有更新时,eureka会推送到每个service。eureka也会有一些策略防止由于某个服务所在网络的不稳定导致的所有服务心跳停止的雪崩现象。eureka自带web页面,在页面上能看到所有的服务注册情况 和 eureka集群状态。eureka支持服务自己主动下掉自己,请求service的下列地址,可以让服务从eureka上下掉自己,同时service进程也会自己停掉自己。curl -H 'Accept:application/json' -X POST localhost:${management.port}/shutdown

consul

也是一个服务发现工具,而且自带key-value存储服务、健康检查 和 web页面。听起来好像比eureka高大上一些,里面使用了gossip协议和Raft协议,但是他的缺点就是比eureka难维护。服务注册是微服务架构的关键节点。所以我们现阶段选择的是eureka,然后远程配置使用的是spring cloud config。如果要上容器和编排的话,会再看具体情况做选择。但是,后来发现其实consul提供了官方的docker镜像,直接使用docker-consul集群用户服务发现的话,运维成本会直线下降,后面会考虑把eureka + spring cloud config 换成consul。

ribbon:

客户端负载均衡组件。服务发现以后,每个service在本地知道自己要调用的服务有多少台机器,机器的ip是什么,端口号是多少,那这个service在本地需要有一个负载均衡策略,为每一次请求选择一台目标机器进行调用,而ribbon做的就是负载均衡策略的选择。ribbon提供了多种负载均衡策略,包括BestAvailableRule、AvailabilityFilteringRule、WeightedResponseTimeRule、RetryRule、RoundRobinRule、RandomRule、ZoneAvoidanceRule等,没记错的话,默认是ZoneAvoidanceRule。当然,也可以自定义自己的负载均衡策略,比如被调用服务需要灰度发布或者A/B测试的话,就可以在ribbon这一层做自定义。

feign

声明式、模板化的HTTP客户端。微服务之间的调用本质还是http请求,如果对于每个请求都需要写请求代码,增加请求参数,同时对请求结果做处理,就会存在大量重复工作,而feign非常优雅的帮助我们解决了这个问题,只需要定义一个interface,fegin就知道http请求的时候参数应该如何设置。同时,feign也集成了ribbon,只要在微服务中依赖了ribbon,feign默认会使用ribbon定义的负载均衡策略。最重要的是,feign并不是仅仅只能使用在有eureka或者ribbon的微服务系统中,任何系统中,只要涉及到http调用第三方服务,都可以使用feign,帮我们解决http请求的代码重复编写。

hystrix

断路器,类似于物理电路图中的断路器。正常情况下,当整个服务环境中,某一个服务提供方由于网络原因、数据库原因或者性能原因等,造成响应很慢的话,调用方就有可能短时间内累计大量的请求线程,最终造成调用方down,甚至整个系统崩溃。而加入hystrix之后,如果hystrix发现某个服务的某台机器调用非常缓慢或者多次调用失败,就会短时间内把这条路断掉,所有的请求都不会再发到这台机器上。如果某个服务所有的机器都挂了,hystrix会迅速失败,马上返回,保证被调用方不会有大量的线程堆积。Feign默认集成了hystrix。上面有提到,使用eureka时,当一个服务提供方挂掉以后,服务订阅者最长可能30s以后才知道,那这30s就会出现大量的调用失败。如果在系统里面集成了hystrix,就会马上把挂掉的这台服务提供方断路掉,让请求不再转发到这台机器上,大量减少调用失败。hystrix执行断路操作以后,并不表示这条路就永远断了,而是会一定时间间隔内缓慢尝试去请求这条路,如果能请求成功,断路就会恢复。有一点需要注意的是hystrix在做断路时,默认所有的调用请求都会放在一个的线程池中进行,线程池的作用很明显,有隔离性。比如gateway,集成了5个子业务系统,可能其中一个系统的调用量非常大,而另外四个系统的调用很小,如果没有线程池的话,显然第一个系统的大量调用会影响到后面四个系统的调用性能。hystrix的线程池和java标准线程池一样,可以配置一些参数:coreSize、maximumSize、maxQueueSize、queueSizeRejectionThreshold、allowMaximumSizeToDivergeFromCoreSize、keepAliveTimeMinutes等,如果某一个子系统的调用量突然激增,超过了线程池的容量,也会迅速失败,直接返回,起到降级和保护系统本身的作用。当然hystrix也支持非线程池的方式,在本地请求线程中做调用,即semaphore模式,官方不建议,除非系统qps真的很大。

zuul

是一个网关组件。提供动态路由,监控,弹性,安全等边缘服务的框架。zuul主需要简单配置一下properties文件,不需要写具体的代码就可以实现将请求转发到相应的服务上去。还可以定制化一些filter做验证、隔离、限流、文件处理等切面,对于网关来说,使用zuul能减少大量的代码。不过我没有使用过,不太了解,现在我们的网关主要还是基于feignClient、ribbon、hystrix来实现的。zuul默认也集成了这些组件。有兴趣可以研究研究。

turbine

是聚合服务器发送事件流数据的一个工具,用来监控集群下hystrix的metrics情况.在复杂的分布式系统中,相同服务的节点经常需要部署上百甚至上千个,很多时候,运维人员希望能够把相同服务的节点状态以一个整体集群的形式展现出来,这样可以更好的把握整个系统的状态。turbine提供把多个hystrix.stream的内容聚合为一个数据源供Dashboard展示.

Spring Cloud Starters

spring boot热插拔、提供默认配置、开箱即用的依赖。starter 是spring boot框架非常基础的部分。可以自定义starter。

从上面可看出spring cloud bus、consul和zuul的问题还是比较多的。

 

总结:eureka发展到2.x后停止这个版本维护了。下个版本是否还继续维护还不太清楚。

          spring cloud采用的是其于HTTP 的 REST方式。 严格来说,这两种方式各有优劣。虽然从一定程度度上来说,后者牺牲了服务调用的性能,但也避免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依堂一纸契约,不存在代码级的强依赖,这在强调快速微服务环境下,显得更加合适。这也是dubbo和spring cloud最本质的区别

转载请注明原文地址: https://www.6miu.com/read-4915060.html

最新回复(0)