- 在以前,项目都是单体开发,随着功能的不断复杂,开发难度越来越高,当修改某一个单独功能时,还得将整个系统进行重新测试,部署。当某模块出现问题,可能就整个系统瘫痪,业务扩展也很麻烦,耦合性也较高,局限性很大。
- 而现在,我们开发时,会做到在架构阶段解耦合,出现了分布式开发,以及集群的概念
- 集群:一台服务器,往往无法承载高并发的数据访问量,这时需要多台服务器一起合作承载,这些服务器的集合体共同完成同一件工作就是集群,是在物理上解决问题,但如果一个项目仅仅某一个功能需要高并发呢?必须对整个项目进行集群处理么?单体开发是一定的,因为没办法,但分布式就不一样了。
- 分布式:将一个复杂共合体,拆分成简单集群,将一个大项目,按不同功能划分,分成若干个微服务,每个服务独立开发,提供对外的可调用接口,同一个微服务可以对多个项目提供服务
- 举例:搜索服务,用于提供搜索功能,那么,百度,淘宝,京东都有搜索功能,他们就都可以对此服务接口进行实现,而不用自己再开发一个一模一样的服务。
- 一个大项目只需整合不同微服务即可,而微服务一般由spring开发,spring boot可以快速搭建spring架构进行微服务开发,整合微服务就可以交给spring cloud
- 这时,当搜索功能数据访问量极大时,这时就可以单独对此服务进行集群处理,配置多台服务器分担压力,而不用整个项目进行集群处理
spring cloud 依赖(供日后查阅使用)
- spring boot父依赖:spring-boot-starter-parent
- spring cloud依赖:spring-cloud-dependencies
- 注册中心依赖:spring-cloud-starter-netflix-eureka-server
- 服务提供者&服务消费者依赖:spring-cloud-starter-netflix-eureka-client
- Zuul网关依赖:spring-cloud-starter-netflix-zuul
- Feign均衡负载依赖:spring-cloud-starter-openfeign
- Hystrix熔断:spring-cloud-starter-netflix-hystrix
- 监控管理依赖:spring-boot-starter-actuator
- 监控可视化:spring-cloud-starter-netflix-hystrix-dashboard
- 配置服务器(配置中心):spring-cloud-config-server
- 使用配置中心:spring-cloud-starter-config
- JDK9以后去掉的jar包,spring cloud需要这些
- jaxb-api 在javax.xml.bind包下
- jaxb-impl 在com.sun.xml.bind包下
- jaxb-core 在com.sun.xml.bind包下
- activation 在javax.activation包下
spring cloud 注解(供日后查阅使用)
- @SpringBootApplication:spring boot注解,配置一个类为服务启动类
- @EnableAutoConfiguration //自动装载,可省略SpirngBootApplication注解,它自动扫描装载@Configuration配置文件
- @EnableEurekaServer:spring cloud注解,配置在启动类上,表明此服务是一个注册中心
- @EnableZuulProxy :生成网关代理,配置一个类为网关启动类
- @LoadBalanced:开启Ribbon负载均衡,一般注入到RestTemplate的Bean上面
- @EnableFeignClients:标注一个类为Feign客户端,使当前模块启用Feign服务
- @FeignClient(value=“服务提供者的注册中心注册名”,fallback = 接口熔断机制实现类.class):标注Feign接口处理哪个微服务,并添加出错后的熔断机制实现类,处理服务出错
- @EnableCircuitBreaker:启用数据监控
- @EnableHystrixDashboard:启用可视化数据监控
- @EnableConfigServer:声明配置中心
spring cloud 配置文件(供日后查阅使用)
- 配置注册中心服务器端口(server.port)
- 是否将自己也当成微服务注册(eureka.client.register-with-eureka)
- 是否同步其它注册中心数据(eureka.client.fetch-registry)
- 配置注册中心访问路径(eureka.client.service-url.defaultZone)
- 配置当前微服务名字,注册在注册中心后显示的名字(spring.application.name)
- 配置当前微服务注册到哪个注册中心(注册中心访问地址)(eureka.client.service-url.defaultZone)
- 配置将当前微服务ip注册到指定注册中心(eureka.instance.perfer-ip-address)
- 配置网关(zuul.routes.eurekaClient)
- 配置Feign熔断(feign.hystrix.enable)
- 配置Actuator服务监控(management.endpoints.web.exposure.include)
- 指定配置中心从本地拿配置文件native表示本地(spring.profiles.active)
- 指定本地配置文件路径(spring.cloud.config.server.native.search-locations)
- bootstart引用配置文件
1、spring cloud入门
服务治理
- spring cloud是由spring boot实现的,可以很好的与spring boot结合,而它时用来治理各种用spring boot开发的服务的,spring cloud提供的主要功能就是服务治理
- 服务治理由3部分组成:
- 服务提供者:由spring boot 开发的服务
- 服务消费者:使用服务的群体
- 注册中心:用来注册服务,只有注册了,才能被消费
- 服务治理的过程(简单描述):
- 服务治理分布式架构中,每个微服务在启动时,就自己的信息存储在注册中心,简称服务注册
- 服务消费者会从注册中心找到服务提供者信息,然后调用对应服务,简称服务发现
服务治理由什么组件实现
- 前期spring cloud一直都是搜集世界上最好的组件做集成,成为spring cloud,但现在这些框架只是spring cloud的一小部分了
- spirng cloud的服务治理使用Eureka实现,Eureka 是由 Netflix 提供的基于REST风格的开源组件
- 提供了服务注册和服务发现功能,和spring boot开发的微服务可以很好的整合,可以直接使用(开箱即用),而spring cloud集成了Eureka 形成了spring cloud Eureka
- spring cloud Eureka由两部分组成
- Eureka Server:注册中心
- Eureka Client:微服务通过Eureka Client连接Eureka Server完成注册
2、环境搭建
- 小提示:在idea中直接用maven导入依赖时,很可能因为网速而无法获得提示,这时可以到中央仓库搜索
- spring-boot-starter-parent:spring boot父依赖
- spring-cloud-dependencies:spring cloud依赖
- 1、搭建spring boot环境
- 1.1创建启动类,用于测试spring boot是否搭建成功,点击运行后,若成功部署即可删掉,当然留下也不会有影响
- 2、搭建spring cloud环境
3、注册中心
- 1、创建子工程注册中心
- 2、在子工程pom.xml中引入注册中心 (中央仓库:spring-cloud-starter-netflix-eureka-server)
- 3、application.yml文件中配置注册中心信息
- 4、配置子工程为注册中心项目
- 5、启动并测试
- 5、解决jdk无jaxb冲突(idea无提示请到中央仓库寻找,文章最上面有jar包汇总,将名字复制查询即可)
- 常见错误
4、服务提供者
1、创建服务提供者子模块,引入依赖spring-cloud-starter-netflix-eureka-client
- 2、配置application.yml文件
- 3、创建微服务启动类
- 测试
- 先启动注册中心
- 启动刚创建的微服务,注意不要关闭注册中心
5、基于spring cloud模拟增删改查中的查询(不使用数据库)
- 1、父工程导入通用依赖
- 2、编写实体类
- 编写接口与实现类(这里我只定义一个查询方法,剩下的有兴趣可以自己补上)
- 这里不要忘记用注解将实现类注入到容器
- 编写service(直接写了实现类,就不写接口了)
- Controller层
- 启动注册中心,启动微服务并测试
6、RestTemplate组件实现不同服务间通信
- 了解什么是RestTemplate
- 多个微服务之间能够通信,是因为每个微服务对外都提供了一个Rest风格接口,这样不同服务之间可以相互调用,而RestTemplate为我们封装了HTTP的请求与响应,提供了大量访问Rest服务的方法,可以使我们不同服务之间方便的联系在一起
- 以下通过例子了解此组件如何使用,我们要使用testRestTemplate这个模块拿到eurekaclient模块中的Ssm实体类数据
- 1、创建子模块testRestTemplate(此模块我们不使用eureka client将其注册到注册中心,所以这个模块不是微服务,只是个调用微服务的模块)设置一个端口号
- 2、编写启动类和eureka client相同的实体类,因为要拿对应的数据
- 3、获取RestTemplate的Bean实例
- 4、编写Controller调用其他微服务功能
- 5、依次启动注册中心、服务提供者,和我们写的调用服务模块,进行测试
- 拓展知识:如何传参查询
- 1、修改提供查询服务的Controller代码
- 2、编写普通模块(这里简单介绍两种方法)
- 3、测试
- 4、保存数据,就是将get换成post,因为是存储,在Rest风格中get表示查询,post表示存储,put表示修改,delete表示删除
7、服务消费者
- 什么是服务消费者:
- 就是使用服务提供者提供的服务,与服务提供者一模一样,都会在注册中心注册,而且不论是引入何种依赖,还是配置信息都大相庭径。唯一区别就是一个用来提供服务,一个用来消费服务。
- 简单的说:一般服务提供者用来完成增删改查业务逻辑提供相应接口,而服务消费者调用相应接口,然后封装取到的信息,在提供一个接口,将信息响应出去
- 1、改变上面例子中的普通模块,使其变成一个服务消费者(只需要引入依赖,然后配置其注册到注册中心即可成为服务消费者)
8、服务网关(Zuul组件)
- 大白话说,只在web方面做考虑的话,网关就是在访问某微服务的某个请求时,不用再记住所有请求了,而是统一到网关,使用网关统一访问请求,不用在意不同服务的不同端口号,不用记住所有请求的名字
- 为什么要有服务网关
- 当客户端完成某功能需要多个服务时,每个服务又有属于自己的端口和地址,而一个服务又有多个请求,那么我们需要每个地址都记住并请求一遍么?有了网关就解决了这种问题
- 一个API网关管理若干服务,客户端请求时,只需要请求网关即可
- 说白了就类似过滤器Filter,解决中文乱码,国际化等问题时,不用每个servlet都配置一遍,只需配置在过滤器即可,既访问所有请求时,都得先通过特定的过滤器
- 网关也大同小异,使用特定的服务,只需要调用网关接口即可,然后网关帮我们调用服务
- spring cloud集成了Zuul组件实现网关
- Zuul组件
- 和eureka一样也是Netflix提供的组件,Zuul是一个开源的API网关服务器,
- 此网关介于客户端和服务器后端之间,对外面客户端只提供一个开放性API,将所有客户端请求都经由统一入口接入到服务器,而封装服务器逻辑实现细节
- 可实现反向代理,内部可实现动态路由、身份认证、IP过滤、数据监控,负载均衡等功能,spring cloud集成整合了Zuul组件
- 需要的依赖
- Zuul网关依赖:spring-cloud-starter-netflix-zuul
- 服务提供者&服务消费者依赖:spring-cloud-starter-netflix-eureka-client
- 1、创建一个子模块,并引入相关依赖
- 2、配置application.yml文件
- 3、编写启动类
- 依次启动注册中心,服务提供者,网关进行测试
- 4、测试Zuul的负载均衡
- 1、编写Controller请求
- 2、创建两个启动类,以表示一个服务被两个服务器共同部署
- 3、启动网关然后以8010端口号启动服务一
- 2、以8011端口启动服务二
- 3、测试(可见不断访问index请求,会两个服务交替处理,达到均衡负载,这里不是每次都去访问配置文件,而是在内存中的瞬时值,所以可以交替变化,不是配置文件中在做改变)
9、Ribbon负载均衡
- 为什么学Ribbon
- 同样是Netflix发布的负载均衡器,spring cloud将其集成
- 当我们处理大型项目,高并发的数据访问,实在不堪重负,这时如果Zuul不仅处理网关,还考虑负载均衡,可能出现某些问题
- 所以我们使用这个专门处理负载均衡的组件Ribbon来处理高并发数据访问
- 对比Zuul,它提供了针对不同时刻的负载均衡算法,如轮询、随机、加权轮询、加权随机等等。是一款专业处理负载均衡的组件
- 它只是提供负载均衡功能,帮助我们调用需要的服务,比如一个服务部署到100台服务器,它的作用就是通过算法,帮我们转到目前压力较小的服务器上处理请求,组件本身不是服务
- spring cloud集成后成为 spring cloud ribbon,同样需要注册到注册中心使用,需要通过算法调用其它服务,所以需要RestTemplate
- 实现Ribbon只需要一个注解@LoadBalanced
- 1、创建一个子模块,将其注册到注册中心
- 2、编写启动类,注入RestTemplate,并让RestTemplate具有负载均衡功能
- 创建Controller层编写Handler进行测试
- 解释:为什么写Controller在用RestTemplate的get方法写localhost会报错呢?
- 我们注册中心,一个名字的微服务有两个服务器端口在负责
- 这时我们用localhost进行访问必须指定特定端口号,既然指定了端口,就无法访问其他端口了,无法实现均衡负载
- 而在注册中心,我们就可以使用微服务在注册中心的名字,实现均衡负载
- 同样zuul能实现均衡负载,也是因为zuul也是不直接指定端口的,它也同样对外提供自己网关地址,用户调用时通过网关地址调用服务
10、Feign 负载均衡
- Feign与Ribbon
- 都是Netflix提供的组件
- Ribbon是通用Http客户端工具,使用 HttpClient 或 RestTemplate 模拟http请求,步骤较为繁琐。
- Feign是Ribbon改进版,由Ribbon实现,只需要创建一个接口,然后添加注解即可调用HTTP API,简化了开发
- 是一个声明式的Web server客户端,支持Feign、SpringMvc、JAX-RS等注解,spring cloud集成了Hystrix,拥有了服务熔断功能
- 需要调用的服务的方法定义成抽象方法即可, 不需要自己构建http请求
- spring cloud集成了此注解,称为spring cloud Feign,进行了二次开发,整合了Ribbon和Hystrix
- 具有可插拔、基于注解、负载均衡、服务熔断等特性和功能
- 1、创建子模块并引入eureka client和feign的依赖
- 需要的jar包spring-cloud-starter-openfeign
- 2、配置yml文件
- 3、编写启动类
- 需要注解@EnableFeignClients
- 4、编写接口(Feign无需配合RestTemplate,而是采用接口配合注解方式进行处理)
- 注解:@FeignClient(value=“服务提供者在注册中心的注册名”)
- 编写Controller
- 启动注册中心,Feign,两个相同微服务(8010和8011)进行测试
11、Feign开启容错机制中的降级处理
- spring cloud Feign集成了Hystrix,所以具有Hystrix的熔断机制
- 容错:就是在我们执行一个功能需要多个微服务共同工作时,中间某个微服务出现错误,这时进行一些紧急处理。
- 1、yml配置Feign容错
- 2、编写接口实现类,将出现错误后需要处理的逻辑代码填入,并使用@Component注解注入容器,然后指定此类到接口
- 3、只启动注册中心和Feign进行测试
12、Hystrix容错机制
-
什么是容错机制
- 虽然有熔断机制的存在,但是若问题得不到解决,就会无限的错误下去,最后可能促使整个系统瘫痪崩溃
- Hystrix容错机制就是在,不改变各微服务调用关系的情况下,针对错误进行预先处理
- 设计原则
- 1、服务隔离机制:防止某个服务出现问题,而影响整个系统运行
- 2、服务降级机制:服务出现问题,使用fallback,就是我们上面讲的,出错就转到错误处理实现类
- 3、熔断机制:当一个错误发生到某个特定值,使用熔断机制立即对错误进行处理
- 4、实时监控和报警功能
- 5、配置实时修改功能
- Hystrix实时监控需要配合spring boot Actuator来使用
- Actuator组件提供了对服务的健康监控、数据统计,可通过hystrix.stream节点获取监控的请求数据,提供了可视化的监控界面
-
1、创建子模块导入依赖
-
需要的依赖
-
需要jar包
- 服务监控spring-boot-starter-actuator
- 容错spring-cloud-starter-netflix-hystrix
- 监控可视化spring-cloud-starter-netflix-hystrix-dashboard
-
2、编写配置文件
-
3、编写启动类,添加注解
-
需要注解
- @EnableCircuitBreaker:启用数据监控
- @EnableHystrixDashboard:启用可视化数据监控
-
4、编写Feign接口
-
5、编写Controller
-
6、启动注册中心,服务提供者和hystrix监控,然后通过actuator组件访问节点hystrix.stream
-
7、可视化界面
13、Spring cloud配置中心
- 为什么要有配置中心
- 我们学习到现在,不难发现,几乎所有模块的配置文件都有eureka client的配置,以及注册到哪个注册中心等等,那么将重复内容定义成共用,整个程序中只写一遍,这样的思想,从刚学java面向对象时就已经了解了。
- spring cloud config组件就是用来定义配置中心的,定义一个共用的配置文件,供所有微服务共享
- 所配置的文件可以存放在本地或者上传到Git仓库上
- 创建config server管理配置文件,当我们需要修改配置文件时,实时在本地修改然后上传到仓库即可
1)、本地文件系统
- 1、新建子模块并导入相关依赖
- 2、配置yml
- 3、写通用配置文件
- 4、编写启动类
- 使用注解@EnableConfigServer:声明配置中心
- 5、想使用配置中心,其他服务需要导入依赖
- 需要依赖spring-cloud-starter-config:使用配置中心
- 6、编写配置文件bootstrap.yml(application.yml是默认配置文件,bootstrap.yml是引用配置文件)
- bootstrap.yml配置文件优先级比application.yml配置文件优先级高
- 一次启动注册中心,配置中心和服务提供者测试
2)、远程配置中心,网络git仓库
- 本人在学校,用手机流量实在太慢,日后有机会,心情好就补上
14、Zipkin服务跟踪
- 为什么要有服务跟踪
- 一般一个项目都有几十个上百个微服务,而这时如果我们跟踪一个请求,而这些请求,在通过某个服务时出错或者有延迟,可以很准确的得到信息,而不用费时费力排查错误
- spring cloud集成了Zipkin组件进行二次开发,我们使用spring cloud zipkin组件完成服务跟踪
- 同样有server服务端和client客户端,服务端用来采集信息,客户端用来展示
- 1、创建子模块,引入相关依赖