SpringBoot+SpringCloud

摘自《Java微服务分布式架构企业实战》

1 Spring Boot

  Spring Boot是用于构建微服务的基础框架,可以轻松地整合Spring Cloud实现系统服务化,在学习微服务之前学习Spring Boot的使用是非常有必要的,而且 Spring Boot与Spring MVC框架技术无缝衔接,使用自动化配置替代了原本需要手动完成的样板化配置,摒弃之前开发过程中繁多的配置文件,测试部署起来也更加便捷。

  Spring技术的出现,颠覆了传统的Java EE技术,如今Spring Boot框架的出现简化了Spring应用程序的开发,开箱即用,非常方便。相信大家都听说过“习惯优于配置”这句话,该框架采用了特定的方式进行配置,因此,程序员在开发的过程中无须再进行样板化配置,只需要少量配置和少量代码就能完成,使得开发更加简单、快速、方便。而且 Spring Boot内嵌 Servlet(Tomcat)容器,可以直接启动运行项目。Spring至今已经发行多个版本,而且版本更新迭代也非常迅速,下面列举版本更新的过程中的重要变更。

  1.Spring 1.x时代

  在Spring1.x时代,都是通过XML文件配置Bean,随着项目的不断扩大,需要将XML配置分放到不同的配置文件中,需要频繁地在Java类和XML配置文件中切换。

  2.Spring 2.x时代

  随着JDK 1. 5带来的注解支持,Spring 2.x可以使用注解对Bean进行声明和注入,大大地减少了XML配置文件,同时也大大简化了项目的开发。

  3.Spring 3.x时代

  从Spring 3.x开始提供了Java配置方式,使用Java配置方式可以更好地理解配置的Bean,并且 Spring 4.x和Spring Boot都推荐使用Java配置的方式,之前的XML配置将会被Java配置替换掉。
  4.Spring 5.x时代

  Spring 5.x是Java界首个支持响应式的Web框架,是Spring的一个重要版本,距离Spring 4.x差不多四年。在此期间,大多数增强都是在Spring Boot项目中完成的,其最大的亮点就是提供了完整的端到端响应式编程的支持(新增 Spring WebFlux模块)。

  Spring WebFlux同时支持使用旧的Spring MVC 注解声明 Reactive Controller.和传统的MVC Controller 不同、Reactive Controller操作的是非阻塞的ServerHttpRequest和ServerHttpResponse,而不再是Spring MVC里的 HttpServletRequest和HttpServletResponse.至此也代表着Java正式迎来了响应式异步编程的时代。

  在之前开发的过程中,通常会有以下几步来完成:

  (1)配置web.xml,加载Spring和Spring MVC;

  (2)配置数据库连接、配置Spring事务;

  (3)配置加载配置文件的读取,开启注解;

  (4)配置日志文件。

  配置完成之后部署Tomcat调试,但是如果使用Spring Boot将会变得更加简单,只需要非常少的几个配置就能够迅速地搭建起来一套Web项目或者构建一个微服务。

  5.Spring Boot的优缺点

  优点:快速构建项目,对主流开发框架的无配置集成,项目可独立运行,无须外部依赖Servlet容器,提供运行时的应用监控,极大地提高了开发、部署效率,与云计算的天然集成等。
  缺点:版本迭代速度很快,一些模块改动很大,由于不用自己做配置,报错时很难定位,网上现成的解决方案比较少等。

2.Spring Cloud

  在分布式、微服务系统中,当客户端或者API网关想要访问一个服务时,面对那么多的服务,怎样能够动态地准确获取某个服务的IP和端口成了一个挑战,此时提出服务注册与发现机制-每一个服务自动把自己的IP和端口注册到一个专门的服务器上,让调用方能够从计算机名或者应用ID、应用名称方便地调用到需要调用的服务,就可以很好地解决这个问题。

  Spring Cloud是一个提供了全套的分布式系统解决方案的微服务框架,它虽然是Spring 家族的新成员,但是更新的速度特别快。Spring Cloud为开发人员提供了一系列分布式系统的解决方案,包括配置管理、服务注册与发现、路由、控制总线、全局锁等,同时Spring Cloud还能够快速地对接云服务平台,快速地启动服务、构建应用,有了这些方案,让开发分布式系统更加简单,使开发人员真正享受到“开箱即用”特性所带来的便捷。

3.Netfix Eureka
  Spring Cloud Netfix的Eureka是一个服务注册和发现模块,它的作用与ZooKeeper的作用相似。在微服务的开发过程中服务的治理是非常核心的模块,一个大型的应用程序通常由非常多的服务构成,然而每个服务不一定都会部署在一台服务器上,因此客户端在请求服务时通常要对服务的地址和IP进行解析,如图6. 6所示。

 

  Spring Cloud 是使用 Netfix Eureka来实现服务注册与发现的,Netfix Eureka 中不仅包含了客户端也有服务端。服务端称为服务注册中心,持续提供服务的发现和注册。客户端是通过注解在应用程序代码中开启的,当应用程序运行时,会将自身提供的服务注册到Eureka服务端,同时通过持续周期性地发送心跳来判定服务是否一直可用,还会将从服务注册中心查询到的服务IP、端口等相关信息缓存到本地。

4.Eureka高可用集群

  对于微服务系统来说,所有的服务都将会注册到注册中心,Eureka的可用性关乎整个应用程序能否继续正常地提供服务,一旦部署Eureka服务的机器发生宕机或一些网络因素的影响将可能致使整个应用处于瘫痪状态。因此,Eureka通常在企业的实际部署过程中都是以集群形式存在的,这样即使一个节点瘫痪,还有其他节点保证服务的可用性,降低了风险。

  Eureka的高可用实际上就是把一个或多个Eureka Server当作一个普通的服务,将Eureka Server本身像其他服务一样注册到另一个Eureka Server中,使服务注册中心达到相互注册的目的,这些注册中心的数据都是同步的,因此无论哪一个注册中心存在故障,都可以继续使用其他的处于存活状态的Eureka Server.

5.Spring Cloud 创建服务消费者(Ribbon)

  微服务是面向服务进行开发的,一个个服务之间的联系也是错综复杂的,随着项目的深人或者水平扩展,服务与服务之间就像蜘蛛网一样交织在一起,管理起来也会愈发困难,所以能够让服务的消费者更简单地调用服务,也是非常重要的。Spring Cloud也提供了相应的解决方案,能够使服务的调用轻松地实现REST模板请求,还能做到负载均衡的效果。

  Spring Cloud Ribbon 是基于Netflix Ribbon实现的HTTP和TCP客户端负载均衡工具框架。在微服务项目中服务之间的调用、API Gateway的请求都是通过Ribbon(或者对Ribbon进一步的封装框架)实现的。
(1)RestTemplate 详解
  Ribbon是通过 RestTemplate+@LoadBalance实现的,Spring为创建REST API提供了良好的支持,将资源的状态以最适合的形式进行传递。借助RestTemplate,Spring 应用能够方便地使用REST资源,Spring的 RestTemplate 访问使用了模板方法的设计模式。下面将详细介绍 RestTemplate实现不同请求和参数的服务调用。

6.负载均衡策略
  负载均衡在分布式系统中尤为重要,可以使系统实现高可用、提高系统的处理能力。实现负载均衡的方式有很多,包括硬件负载均衡和软件负载均衡。软件负载均衡的实现通常通过相应的模块来处理完成请求分发的功能,如反向代理负载均衡服务Nginx等,如图7. 1所示。

 

  在部署单台服务器时,如果这个服务器宕机了,那么用户自然也无法继续访问了,如果同时有很多用户试图访问服务器,超过了服务器本身处理能力的上限,就会出现加载速度缓慢或无法继续提供服务的情况。为了应对这种情况,可以将服务同时部署在多台服务器中,当客户端发起请求时,可以使用负载均衡服务作为一个请求访问节点,负载均衡服务器根据相应的策略(如轮询、权重、随机等)来指定提供服务的服务器。这样一来,可以防止单点故障或服务效率低下的问题发生,接下来将通过实例了解Ribbon中实现负载均衡的方式。

7.Spring Cloud 创建服务消费者Feign  

  Ribbon的使用,在服务的调度方面都会利用RestTemplate的拦截来实现接口的调用,它使用HttpClient或RestTemplate 模拟HTTP请求,调用的过程中步骤非常烦琐,而Feign是对Ribbon的进一步封装,简化了编写步骤,使用起来更加方便,接下来将学习声明式服务调用Feign的使用。

  Feign是一个声明式的REST客户端,它的目的就是让REST风格的API调用变得更加简单。使用Feign,只需要创建一个接口并加上注解来配置就可以实现服务提供者的接口绑定。它具有可插拔的注解特性,而且扩展了对 SpringMVC注解的支持,它本身就是对Ribbon的进一步封装,因此同样具备负载均衡调用。Feign会完全代理 HTTP请求,只需要像调用方法一样调用它就可以完成服务请求及相关处理。

8.使用Hystrix 服务容错保护
  微服务架构中,服务被拆分得很细,每个服务都不在一个进程中,网络的不稳定性则会造成服务在远程调用的过程中出现故障或延迟的情况发生。由于HTTP请求是同步的,如果不采取补救措施,服务调用方会一直处在等待的地步。后续的请求一旦造成积压,线程同步就会造成阻塞,阻塞就会引起服务雪崩的效应,最终导致服务瘫痪。面对这种问题,Spring Cloud也给出了解决方案-Spring Cloud Hystrix熔断器的使用。
(1)熔断器简介
  在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过RPC相互调用,在Spring Cloud中可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。由于服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。为了解决这个问题,业界提出了熔断器模型。
  Netflix开源了 Hystrix组件,实现了熔断器模式,Spring Cloud对这一组件进行了整合。在微服务架构中,一个请求需要调用多个服务是非常常见的,如图7. 9所示。

  请求通过浏览器或移动端发送至API网关,调用服务A、服务B、服务C、服务D四个服务,而服务A又会继续调用服务AI,较底层的服务AI如果出现故障则不能及时返回结果,而服务A此时也没有做服务降级处理,可能会导致服务A甚至整个系统的瘫痪。为了避免这种情况的发生可以在系统设计时使用一定的降级策略,保证即使出现某个服务提供方的服务不可用,即服务的调用的不可用达到一个阈值(Hystrix是5秒20次)时,熔断器将会打开,服务调用方仍然可以切换到降级后的策略继续执行,如图7. 10所示。

  图7. 10中,当服务AI出现故障后,服务熔断开启,服务A和服务AI之间启动断路器熔断机制,为了避免连锁故障,还可以通过Fallback()方法直接返回一个固定值,接下来将结合案例讲解熔断器的使用。

 9.路由网关分布式配置

  在微服务架构中,需要几个基础的服务治理组件,包括服务注册与发现、服务提供、服务消费、负载均囊、熔断器、智能路由、配置管理等,这几个基础组件相互协作,共同组建了一个简单的微服务系统,本章将继续学习路由网关服务和分布式配置中心的实现。

  (1)如果选择将原有的单体应用构建成一组微服务时,首先就要考虑如何解决程序的客户端与服务之间进行交互的问题,如果一个微服务架构的应用中有很多服务,那么客户端与微服务之间要想直接通信必然要在客户端存储每个服务的IP和端口,当系统规模不断增大时,服务也会越来越多,显然这种做法是不现实的。因此,需要使用API网关服务器统一维护服务的IP和端口,这样不仅可以完成请求路由的功能,还能实现负载均衡、验证过滤等其他功能,一个简单的微服务系统如图8. 1所示。

  在图8. 1中的Spring Cloud微服务系统中,一种常见的负载均衡方式是,客户端的请求首先经过负载均衡(Ngnix),再到达服务网关(Zuul集群),然后再到具体的服务。所有的服务将会统一注册到高可用的服务注册中心集群中,服务的所有的配置文件将交由配置服务来统一管理,配置服务的配置文件放在Git仓库,方便开发人员可以随时更改配置文件。Spring Cloud Zuul和Eureka结合,将自身服务注册到Eureka服务注册中心,同时获取到其他服务的实例信息。

  Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,如通过REST接口访问/api/user就可以将请求转发到User服务,访问/api/shop就可以将请求转发到Shop服务。Zuul默认和Ribbon结合实现了负载均衡的功能。

 10.Spring Cloud服务追踪

     随着项目的不断扩展,微服务的问题也会不断地显现出来,一个客户端请求在调用服务得到返回结果的过程中,也许会形成一条复杂的调用链路,一个服务可能会有多个链路依赖,几个服务协同完成。这样一来,如果其中一条链路发生故障或者出现延迟,都可能会引起请求的失败。这时,就可以通过实现对请求调用的追踪来迅速发现故障,监控每条链路的性能并及时地排查解决问题。

  1)ZipKin简介
  ZipKin是一个开放源代码的分布式跟踪系统,由Twitter公司研发,它致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储、查找和展现。它的理论模型来自于Google Dapper的论文。

  每个服务向ZipKin报告计时数据,ZipKin会根据调用关系通过ZipKin UI生成依赖关系图,显示了多少跟踪请求通过每个服务,该系统让开发者可通过一个Web前端轻松地收集和分析数据,例如用户每次请求服务的处理时间等,可方便地监测系统中存在的瓶颈。

  微服务架构是通过业务来划分服务的,使用REST调用。对外暴露的一个接口,可能需要很多个服务协同才能完成这个接口功能,如果链路上任何一个服务出现问题或者网络超时,都会形成导致接口调用失败。随着业务的不断扩张,服务之间互相调用会越来越复杂,如图9. 1所示。

posted @ 2022-04-14 16:17  嘉禾世兴  阅读(1034)  评论(0编辑  收藏  举报