当前位置: 首页 > 科技观察

微服务架构:基于微服务和Docker容器技术的PaaS云平台架构设计(微服务架构实现原理)

时间:2023-03-15 20:51:12 科技观察

构建基于微服务架构和Docker容器技术的PaaS云平台的目标是为我们的开发者提供一套快速的服务开发、部署、运维管理,持续开发和持续集成的过程。平台提供基础设施、中间件、数据服务、云服务器等资源。开发者只需要开发业务代码提交到平台代码库,并进行一些必要的配置即可。系统自动构建和部署,实现应用的敏捷开发和快速迭代。在系统架构方面,PaaS云平台主要分为三个部分:微服务架构、Docker容器技术、DveOps。本文重点介绍微服务架构的实现。实施微服务需要投入大量的技术力量来开发基础设施,这对很多公司来说显然是不现实的。不用担心,业界已经有优秀的开源框架供我们参考。目前业界比较成熟的微服务框架有Netflix、SpringCloud、阿里的Dubbo等。SpringCloud是一套基于SpringBoot实现微服务的框架。它提供了开发微服务所需的组件。如果与SpringBoot配合使用,开发微服务架构的云服务会非常方便。SpringCloud包含了很多子框架,其中SpringCloudNetflix是框架之一。在我们的微服务架构设计中,使用了很多SpringCloudNetflix框架的组件。SpringCloudNetflix项目成立时间不长,相关文档也很少。当时博主研究这个框架,啃了一大堆英文文档,非常痛苦。对于刚接触这个框架的同学来说,如果要搭建一个微服务应用架构,可能会无从下手。接下来介绍我们的微服务架构构建过程,需要哪些框架或者组件来支持微服务架构。为了直观清晰的展示微服务架构的组成和原理,博主画了一张系统架构图,如下:从上图可以看出,微服务访问的一般路径是:外部请求→负载均衡→服务网关(GateWay)→微服务→数据服务/消息服务。服务网关和微服务都使用服务注册和发现来调用其他依赖的服务,每个服务集群都可以通过配置中心服务获取配置信息。服务网关(GateWay)网关是连接外部系统(如客户端浏览器、移动设备等)和企业内部系统的门户。所有客户端请求通过网关访问后台服务。为了应对高并发访问,服务网关以集群的形式部署,这就意味着需要负载均衡。我们使用AmazonEC2作为虚拟云服务器,使用ELB(ElasticLoadBalancing)进行负载均衡。EC2具有自动配置容量的功能。当用户流量达到峰值时,EC2可以自动增加更多的容量来维持虚拟主机的性能。ELB弹性负载均衡自动将应用传入的流量分配到多个实例中。为了保证安全,客户端请求需要进行https加密保护,这就需要我们进行SSL分流,使用Nginx分流加密请求。外部请求经过ELB负载均衡后路由到GateWay集群中的一个GateWay服务,由GateWay服务转发给微服务。服务网关作为内部系统的边界,具有以下基本能力:1.动态路由:将请求动态路由到所需的后端服务集群。虽然内部是一个复杂的分布式微服务网络结构,但外部系统从网关看就像一个整体的服务,网关屏蔽了后端服务的复杂性。2.限流容错:为每类请求分配容量,当请求数超过阈值时丢弃外部请求,限制流量,保护后台服务不被大流量淹没;内部方服务失败时直接在边界上创建对于一些响应,着重于容错处理,而不是将请求转发到内部集群,以保证良好的用户体验。3、身份认证和安全控制:对每个外部请求进行用户认证,认证失败的请求将被拒绝,还可以通过访问模式分析实现反爬虫功能。4.监控:网关可以收集有意义的数据和统计数据,为后台服务优化提供数据支持。5、访问日志:网关可以收集访问日志信息,比如访问了哪些服务?过程(什么例外)和结果?需要多少时间?通过分析日志内容,进一步优化后台系统。我们使用SpringCloudNetflix框架的开源组件Zuul来实现网关服务。Zuul使用了一系列不同类型的过滤器(Filter),通过重写过滤器,我们可以灵活的实现网关(GateWay)的各种功能。服务注册与发现由于微服务架构是由一系列职责单一的细粒度服务组成的网络结构,服务之间通过轻量级机制进行通信,这就引入了服务注册与发现的问题。服务提供者必须注册报表服务地址,服务调用必须能够发现目标服务。我们的微服务架构使用Eureka组件来实现服务注册和发现。所有微服务(通过配置Eureka服务信息)向Eureka服务器注册,并定时发送心跳进行健康检查。Eureka默认配置是每30秒发送一次心跳,表示服务还活着。发送心跳的时间间隔可以通过Eureka的配置参数自行配置。Eureka服务器收到服务实例的最后一次心跳后,需要等待90秒(默认配置为90秒,可通过配置参数修改)后,才确定服务已经挂掉(即有连续3次无心跳)。Heartbeatreceived),服务的注册信息在关闭Eureka自我保护模式时会被清除。所谓自我保护模式是指当发生网络分区,Eureka在短时间内丢失过多服务时,会进入自我保护模式,即如果一个服务有一段时间没有发送过心跳时间长了,Eureka也不会删除。自我保护模式默认开启,可通过配置参数设置为关闭。Eureka服务是集群部署的(Eureka集群的部署方法在博主的另一篇文章中有详细介绍),集群中的所有Eureka节点会定时自动同步微服务的注册信息,这样所有的Eureka服务都可以保证服务注册信息保持一致。那么在Eureka集群中,Eureka节点是如何发现其他节点的呢?我们使用DNS服务器来建立所有Eureka节点的关联。除了部署Eureka集群,我们还需要搭建一个DNS服务器。当网关服务转发外部请求或者后台微服务之间相互调用时,会去Eureka服务器中查找目标服务的注册信息,找到目标服务并调用,从而形成服务注册和发现的全过程.Eureka的配置参数非常多,多达上百个,博主会在另一篇文章中详细讲解。微服务部署微服务是一系列单一职责、细粒度的服务。它将我们的业务拆分为独立的服务单元。它具有良好的可扩展性和低耦合性。可以使用不同的语言开发不同的微服务。由服务处理的单个业务。微服务可以分为前端服务(也叫边缘服务)和后端服务(也叫中间服务)。前端服务在对后端服务进行必要的聚合和裁剪后,暴露给不同的外部设备(PC、Phone等),所有服务在启动时都会向Eureka服务器注册,服务之间会有错综复杂的依赖关系。当网关服务转发外部请求调用前端服务时,可以通过查询服务注册中心找到目标服务进行调用。前端服务调用后端服务时也是如此。一个请求可能涉及多个服务之间的相互调用。由于每个微服务都是以集群的形式部署的,服务之间相互调用时需要进行负载均衡,所以每个服务都有一个LB组件来实现负载均衡。微服务以镜像的形式运行在Docker容器中。Docker容器技术让我们的服务部署变得简单高效。传统的部署方式需要在每台服务器上安装运行环境。如果我们有大量的服务器,在每台服务器上安装运行环境将是一项极其繁重的工作。一旦运行环境发生变化,就必须重新安装,这简直是灾难性的。有了Docker容器技术,我们只需要为需要的基础镜像(jdk等)和微服务生成新的镜像,并将最终镜像部署到Docker容器中运行即可。这种方法简单、高效,可以快速部署。服务。每个Docker容器中可以运行多个微服务,Docker容器以集群方式部署,使用DockerSwarm来管理这些容器。我们创建一个镜像仓库来存放所有的基础镜像和最终生成的交付镜像,并管理镜像仓库中的所有镜像。服务容错微服务之间存在错综复杂的依赖关系。一个请求可能依赖于多个后端服务。在实际生产中,这些服务可能会导致失败或延迟。在大流量的系统中,一旦某个服务出现延迟,可能会在短时间内耗尽系统资源,拖累整个系统。因此,如果一个服务不能隔离和容错它的故障,它本身就是灾难性的。Hystrix组件在我们的微服务架构中用于容错。Hystrix是Netflix的一个开源组件。通过熔断模式、隔离模式、回退、限流等机制对服务进行弹性容错保护,保证系统稳定性。1、熔断方式:熔断方式的原理类似于电路熔断器。当电路发生短路时,保险丝会熔断以保护电路免受灾难性损失。当服务异常或者有大量延迟时,服务调用者会在满足熔断条件时主动发起熔断,执行fallback逻辑直接返回,不会继续调用服务进一步拖累系统。熔断默认配置服务调用错误率阈值为50%,超过阈值将自动开启熔断模式。服务隔离一段时间后,熔断器会进入半熔断状态,允许尝试少量的请求。如果调用仍然失败,则返回熔断状态。如果调用成功,熔断模式将被关闭。2、隔离方式:Hystrix默认采用线程隔离。不同的服务使用不同的线程池,互不影响。当一个服务出现故障,耗尽其线程池资源时,不影响其他服务的正常运行,达到隔离的效果。例如,我们配置一个服务使用名为TestThreadPool的线程池,通过andThreadPoolKey实现与其他命名线程池的隔离。3.回退:回退机制实际上是服务失败时的一种容错方法。原理类似于Java中的异常处理。只需要继承HystixCommand重写getFallBack()方法,在这个方法中写处理逻辑,比如直接抛出异常(快速失败),返回null或者默认值,或者返回备份数据等。当异常发生时在服务调用中,它会转向执行getFallBack()。以下情况会触发回退:1)程序抛出非HystrixBadRequestException异常。当抛出HystrixBadRequestException异常时,调用程序可以捕获异常并且不会触发回退。当抛出其他异常时,会触发回退;2)程序运行超时;3)熔断器启动;4)线程池已满。4、限流:限流是指限制一个服务的并发访问数,设置单位时间内的并发访问数,拒绝超过限制的请求回退,防止后台服务不堪重负。Hystix使用命令方式HystrixCommand来包装依赖的调用逻辑,使得相关调用自动处于Hystrix的弹性容错保护之下。调用者需要继承HystrixCommand并将调用逻辑写在run()中,使用execute()(同步阻塞)或queue()(异步非阻塞)触发run()的执行。动态配置中心微服务有很多依赖配置,在服务运行过程中可能需要动态修改一些配置参数,例如:根据访问流量动态调整熔断阈值。传统的信息配置实现方式,如放在xml、yml等配置文件中,与应用程序一起打包,需要重新提交代码、打包构建、生成新镜像、重启服务每次修改,效率太低。显然这是不合理的,所以我们需要构建一个动态配置中心服务来支持微服务的动态配置。我们使用SpringCloud的configserver服务来帮助我们构建动态配置中心。我们开发的微服务代码存放在git服务器的私有仓库中。所有需要动态配置的配置文件都存放在git服务器下的configserver(配置中心,也是微服务)服务中。部署在Docker容器中的微服务都是从git服务器动态读取配置文件的信息。当本地git仓库修改代码推送到git服务器仓库时,git服务器钩子(post-receive,服务器完成代码更新后会自动调用)自动检测是否有配置文件更新。如果是,git服务器通过消息队列发送消息给配置中心(configserver,部署在容器中的微服务),通知配置中心刷新对应的配置文件。这样微服务就可以获取到最新的配置文件信息,实现动态配置。以上框架或组件是支撑微服务架构实现的核心。在实际生产中,我们还会用到很多其他的组件,比如日志服务组件、消息服务组件等,根据业务需要选择使用。在我们的微服务架构实现案例中,我们参考了SpringCloudNetflix框架的很多开源组件,包括Zuul(服务网关)、Eureka(服务注册与发现)、Hystrix(服务容错)、Ribbon(客户端负载均衡)等.这些优秀的开源组件为我们实现微服务架构提供了捷径。以上空间主要介绍了微服务架构的基本原理,其中一些比较详细,比如Eureka的参数配置说明,动态配置中心的搭建过程等,博主会在其他文章中做详细的讲解,供大家参考。供你参考。