Spring 是当下 Java 行业的开发标准,Spring Boot、Spring Cloud 更是热门话题,出门遇见同行,不会 Spring 你可能都不好意思跟别人打招呼,企业的招聘信息中也越来越多地出现对于 Spring 技术栈开发能力的要求,不会 Spring 技术栈找工作别说有优势了,先被别人落下一大截,可以说 Spring 技术栈已经成为 Java 开发人员的必备技能,同时随着互联网技术的发展和业务量不断增长,越来越多的公司选择使用分布式架构进行项目开发,Spring Cloud 是业内公认最优秀的解决方案之一,是每一个 Java 开发都需要掌握的技术。
无论你是初级菜鸟还是有一定经验的老鸟,都应该好好学习 Spring Cloud 的使用,这一点毋庸置疑。但遗憾的是目前市面上有关于 Spring Cloud 详细全面且实用的教程比较少,尤其对于初学者来讲,学习成本依旧很高。
目前市面上很多课程都侧重于理论讲解,缺乏相应的实战案例,这对于初学者来讲也是挺痛苦的,看似学了很多,真正需要写代码时又不知如何下手,完全没有思路,学了一堆技术却不知道如何应用,那不就背离了我们最初的学习目的了吗?我们学技术就是为了实际应用,提高自己的竞争力,去争取更优质的资源。
我写这门专栏就是希望能帮助初学者解决这个问题,结合实战案例让读者能够快速掌握实际开发能力,以输出为结果导向是最高效的学习方法,希望通过我的这门专栏,让所有需要掌握 Spring Cloud 的读者都能够快速上手,具备使用 Spring Cloud 进行实际开发的能力。
宁楠,资深 Java 开发工程师,技术总监,拥有丰富的软件研发、系统架构经验。热衷于知识分享,乐于将自己的行业经验分享给初学者,互联网讲师,《Java零基础实战》一书作者、B站认证UP主、头条认证作者。
从本节课开始,我们进入 Spring Boot 框架的学习,Spring Boot 是当前 Java 领域主流的技术栈,同时也是整个 Spring 全家桶中非常重要的一个模块。
Spring 作为一个软件设计层面的框架,在 Java 企业级开发中应用非常广泛,但是 Spring 框架的配置非常繁琐,且大多是重复性的工作,Spring Boot 的诞生就解决了这一问题,通过 Spring Boot 可以快速搭建一个基于 Spring 的 Java 应用程序。Spring Boot 对常用的第三方库提供了配置方案,可以很好地与 Spring 进行整合,如 MyBatis、Spring Data JPA 等,可以一键式搭建功能完备的 Java 企业级应用程序。
Spring Boot 的优势:
简而言之,Spring Boot 就是一个用很少的配置就可以快速搭建 Spring 应用的框架,并且很好的集成了常用第三方库,让开发者能够快速进行企业级项目开发。
有 3 种常用方式可以快速创建一个 Spring Boot 工程,接下来详细给大家介绍每种方式的具体操作。
打开浏览器访问 https://start.spring.io,可在线创建一个 Spring Boot 工程,页面如下图所示。
这这个页面中可以选择创建工程的方式和语言,我们选择 Maven 和 Java,Spring Boot 的版本选择 2.1.5,接下来需要输入 Group Id 和 Artifact Id,以及选择需要依赖的模块。以上这些信息设置完毕之后,点击下方的 Generate Project
按钮即可下载模版的压缩文件,解压后用 IDEA 打开即可。
1、打开 IDEA,选择 Create New Project。
2、选择 Spring Initializr,点击 Next
,可以看到实际上 IDEA 还是通过 https://start.spring.io 来创建工程的。
3、输入 GroupId、ArtifactId 等基本信息,点击 Next
。
4、选择需要依赖的模块,点击 Next
。
5、选择项目路径,点击 Finish
即可完成创建。
1、打开 IDEA,选择 Create New Project。
2、选择 Maven,点击 Next
。
3、输入 GroupId 和 ArtifactId,点击 Next
。
4、选择项目路径,点击 Finish
即可创建一个空的 Maven 工程。
5、手动添加 Spring Boot 相关依赖,在 parent 标签中配置 spring-boot-starter-parent 的依赖,相当于给整个工程配置了一个 Spring Boot 的父依赖,其他模块直接在继承父依赖的基础上添加特定依赖即可。
比如现在要集成 Web MVC 组件,直接在 dependencies 中添加一个 spring-boot-starter-web 依赖即可,默认使用 Tomcat 作为 Web 容器,pom.xml 如下所示。
org.springframework.boot spring-boot-starter-parent 2.1.5.RELEASE org.springframework.boot spring-boot-starter-web
通过以上任意一种方式都可快速搭建一个 Spring Boot 工程,然后就可以根据需求添加各种子模块依赖了,比如上述的第 3 种方式,我们添加了 Web MVC 组件,当前工程就成为了一个 Spring MVC 框架项目,开发者可以按照 Spring MVC 的开发步骤直接写代码了,同时 Spring Boot 还帮助我们大大简化了配置文件。
你可以拿当前的工程和之前课程中我们创建的 Spring MVC 工程对比一下,会发现不需要在 web.xml 中配置 DispatcherServlet,同时也不需要创建 springmvc.xml 了。
传统 Spring MVC 工程的 springmvc.xml 中主要添加三个配置,一是启用注解驱动,二是自动扫包,三是视图解析器。Spring Boot 自动帮我们搞定了前两个配置,第三个视图解析器需要开发者手动配置,因为视图层资源的存储路径和文件类型框架是没有办法自动获取的,不同工程的具体方式也不一样,像这种个性化的配置,Spring Boot 框架是无法自动完成的,需要开发者在 Spring Boot 特定的配置文件中自己完成。
好了,接下来我们就一起来学习用 Spring Boot 启动 Web 应用的具体操作。
1、创建 HelloHandler,具体步骤与 Spring MVC 一样。
@RestControllerpublic class HelloHandler { @GetMapping("/index") public String index(){ return "Hello World"; }}
2、创建 Spring Boot 启动类 Application。
@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); }}
这个类是整个 Spring Boot 应用的入口,可以看到在类定义处添加了一个 @SpringBootApplication
注解,这个注解是 Spring Boot 的核心,它开启了 Spring Boot 的自动化配置,开发者可以使用自定义配置来覆盖自动化配置,同时它完成了自动扫包,默认的范围是该类所在包的所有子包,当然也包括所在包本身,因此我们在实际开发中应该将启动类放在跟目录下。
要启动 Spring Boot 应用,直接运行启动类的 main 方法即可,会自动将项目部署到内置 Tomcat 中,并启动 Tomcat,看到控制台输出如下信息。
启动成功,并且默认端口为 8080,打开浏览器,输入 localhost:8080/index 即可看到返回 Hello World
同时需要注意 Application 一定要覆盖 HelloHandler,因为 Application 启动之后会自动进行扫描,将需要的类交给 Spring IoC 容器来管理,这些类必须被 Application 所覆盖,如何实现覆盖呢?很简单,只需要设置它们的层级关系即可,被扫描的类和 Application 在同一个包下,或者被扫描类所在的包是 Application 所在包的子包,如下图所示。
即 Application 和 HelloHandler 都在 com.southwind.controller 包中,或者 Application 放在 com.southwind 包中,HelloHandler 放在 com.southwind.controller 包中。
如果不按照上述规则设置,将 Application 和 HelloHandler 放在两个同级包中,如下所示。
启动之后,访问 localhost:8080/index ,则无法访问到 HelloHandler 资源,抛出 404 异常,,如下图所示。
很好理解,因此此时的 HelloHandler 并没有被 Spring 管理,IoC 容器中不存在这个资源。
本节课作为整个 Spring Boot 阶段的开篇课程,我们主要讲解了 Spring Boot 的基本概念,Spring Boot 应用的创建方式,以及 Spring Boot 的基本使用。相信大家已经可以感受到使用 Spring Boot 搭建一个 Spring 应用是多么简单快捷,后续的课程会在此基础上讲解更多 Spring Boot 技术栈的实用模块。
https://github.com/southwind9801/gcspringboot.git
本节课我们来学习服务跟踪,首先来思考一个问题,为什么要有服务跟踪,我们知道一个分布式系统中往往会部署很多个微服务,这些服务彼此之间会相互调用,整个过程就会较为复杂,我们在进行问题排查或者优化的时候工作量就会比较大。如果能准确跟踪每一个网络请求的整个运行流程,获取它在每个微服务上的访问情况、是否有延迟、耗费时间等,这样的话我们分析系统性能,排查解决问题就会容易很多,我们使用 Zipkin 组件来实现服务跟踪。
Zipkin 是一个可以采集并且跟踪分布式系统中请求数据的组件,可以为开发者采集某个请求在多个微服务之间的追踪数据,并以可视化的形式呈现出来,让开发者可以更加直观地了解到请求在各个微服务中所耗费的时间等信息。
ZipKin 组件包括两部分:Zipkin Server 和 Zipkin Client,服务端用来采集微服务之间的追踪数据,再通过客户端完成数据的生成和展示,Spring Cloud 为服务跟踪提供了解决方案,Spring Cloud Sleuth 集成了 Zipkin 组件。
接下来我们通过实际代码来完成服务跟踪的实现,首先来实现 Zipkin Server。
1. 在父工程下创建 Module。
2. 输入 ArtifactId,点击 Next。
3. 设置工程名和工程存放路径,点击 Finish。
4. 在 pom.xml 中添加 Zipkin Server 依赖。
org.springframework.boot spring-boot-starter-web io.zipkin.java zipkin-server 2.9.4 io.zipkin.java zipkin-autoconfigure-ui 2.9.4
5. 在 resources 路径下创建配置文件 application.yml,添加 Zipkin 相关配置。
server: port: 9090
属性说明:
6. 在 java 路径下创建启动类 ZipkinApplication。
@SpringBootApplication@EnableZipkinServerpublic class ZipkinApplication { public static void main(String[] args) { SpringApplication.run(ZipkinApplication.class,args); }}
注解说明:
Zipkin Server 搭建成功,接下来创建 Zipkin Client。
7. 在父工程下创建 Module。
8. 输入 ArtifactId,点击 Next。
9. 设置工程名和工程存放路径,点击 Finish。
10. 在 pom.xml 中添加 Zipkin 依赖。
org.springframework.cloud spring-cloud-starter-zipkin
11. 在 resources 路径下创建配置文件 application.yml,添加 Zipkin 相关配置。
server: port: 8090spring: application: name: zipkinclient sleuth: web: client: enabled: true sampler: probability: 1.0 zipkin: base-url: http://localhost:9090/eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
属性说明:
12. 在 java 路径下创建启动类 ZipkinClientApplication。
@SpringBootApplicationpublic class ZipkinClientApplication { public static void main(String[] args) { SpringApplication.run(ZipkinClientApplication.class,args); }}
注解说明:
13. 创建 ZipkinHandler,定义相关业务方法。
package com.southwind.controller;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/zipkin")public class ZipkinHandler { @Value("${server.port}") private String port; @GetMapping("/index") public String index(){ return "当前端口:"+this.port; }}
14. 依次启动注册中心、Zipkin、ZipkinClient,如下图所示。
15. 打开浏览器访问 http://localhost:9090/zipkin/,可看到 Zipkin 首页,如下图所示。
16. 点击 Find Traces 按钮可看到监控数据情况,当前没有监控到任何数据,如下图所。
17. 通过 Postman 访问 http://localhost:8090/zipkin/index,如下图所示。
18. 再次刷新 http://localhost:9090/zipkin/,可看到监控数据,如下图所示。
19. 点击可查看详情,如下图所示。
本节课我们讲解了使用 Zipkin 来实现服务链路追踪的具体操作,通过服务跟踪,我们可以追踪到每个网络请求,了解它整个运行流程,经过了哪些微服务、是否有延迟、耗费时间等,在此基础上我们能够更好的分析系统性能,解决系统问题。
请点击这里查看源码
至此,本专栏为大家详细讲解 Spring 全家桶最热门的模块 Spring Cloud 的使用,包括服务网关、Ribbon、Feign、Hystrix、Spring Cloud Config 等,涵盖了实际开发中常用的技能点,理论结合实践的方式不仅仅让读者掌握基本概念,同时具备使用 Spring Cloud 搭建微服务架构的能力。
Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发。服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。为了解决微服务架构中服务治理而提供的具备一系列功能的开发框架,并且 Spring Cloud 是完全基于 Spring Boot 进行开发的,Spring Cloud 利用 Spring Boot 特性整合了开源行业中优秀的组件,整体对外提供了一套在微服务架构中服务治理的解决方案。
Ribbon 和 Feign 都是用于调用其他服务的,不过方式不同。
Feign 则是在 Ribbon 的基础上进行了一次改进,采用接口的方式,将需要调用的其他服务的方法定义成抽象方法即可。不需要自己构建 HTTP 请求,不过要注意的是抽象方法的注解、方法签名要和提供服务的方法完全一致。
点击获取更多 Spring Cloud 面试题详解
当一个服务调用另一个服务,由于网络原因或者自身原因出现问题时 ,调用者就会等待被调者的响应,当更多的服务请求到这些资源时,导致更多的请求等待,这样就会发生连锁效应,断路器就是解决这一问题的。
断路器的状态有以下几种:
Hystrix 是一个延迟和容错库,旨在隔离远程系统,服务和第三方库的访问点,当出现故障是不可避免的故障时,停止级联故障并在复杂的分布式系统中实现弹性。通常对于使用微服务架构开发的系统,涉及到许多微服务,这些微服务彼此协作, 随着微服务数量的增加,这个问题变得更加复杂。我们将使用 Hystrix 的 Fallback 方法来处理,假设由于某种原因,公开的服务接口抛出异常,我们在这种情况下使用 Hystrix 定义一个回退方法。这种后备方法应该具有与公开服务相同的返回类型,如果暴露服务中出现异常,回退方法将返回对应信息。
在程序运行时,负载平衡可以改善跨计算机、计算机集群、网络链接、中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源的过载。使用多个组件进行负载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性,负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程。
当我们开始一个项目时,通常在属性文件中进行所有的配置,随着越来越多的服务开发和部署,添加和修改这些属性变得更加复杂。有些服务可能会下降,而某些位置可能会发生变化,手动更改属性可能会产生问题。Eureka 服务注册和发现可以在这种情况下提供帮助,由于所有服务都在 Eureka 服务器上注册并通过调用 Eureka 服务器完成查找,因此无需处理服务地点的任何更改和处理。
阅读全文: http://gitbook.cn/gitchat/column/5e38e68dec8d9033cf91a047