Spring cloud为开发人员提供了快速构建分布式系统中的一些常见模式的工具(列如,配置管理,服务发现,断路由,智能路由,微服务,控制总线),分布式系统的协调导致了样板模式,使用spring cloud开发人员可以快速的支持实现这些模式的服务
应用框架的演变
·单一应用架构 LNMP一体化
·垂直应用架构 LNMP分离部署
·分布式服务构架 每一部分都是一个集群
·流动计算架构 云计算
微服务的概念源于2014年3月Martin Fowler所写的一篇文章“Microservices”。微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间相互协调,相互配合,为用户提供最终价值,每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制相互沟通(通常是基于HTTP的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应尽量避免统一,集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言,工具对其进行微服务组成,一个大型复杂软件应用由一个或多个微服务组成,系统中的各个微服务可被独立部署,各个微服务之间是松解耦的,每个微服务仅关注于完成一件并很好的完成该任务,在所有情况下,每个任务代表这一个小的业务能力。
Spring boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新spring应用的初始化搭建以及开发过程。该框架使用了特定的方式进行配置,从而使开发人员不再需要定义模板化的配置,Spring Boot不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,Spring Boot简化了基于Spring的应用开发,通过少量的代码就能创建一个独立的,产品级别的Spring应用,Spring Boot为spring平台及第三方库提供开箱即用的配置,这样你就可以有条不紊大的开始,Spring boot的核心思想就是约定大于配置,多数Spring Boot应用只需要很少的Spring配置,采用Spring Boot可以大大简化你的开发模式,所有你想集成的常用框架,他都有对应的组件支持。
Spring cloud是一系列框架的有序集合,它利用spring Boot的开发便利性巧妙的简化了分布式系统基础设施的开发,如服务发现注册,配置中心、消息总线,负载均衡、断路器,数据监控等,都可以用Spring Cloud的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出一套简单易懂,易部署和易维护的分布式系统开发工具包
·Spring cloud 专注于提供良好的开箱即用的经验的典型用例和可扩展机制覆盖
·分布式/版本号配置
·服务注册和发现
·路由
·service-to-service调用
·均衡负载
·断路由
·分布式消息传递
Spring cloud config
·远程配置服务
·运程配置是每个都必不可少的中间件,运程配置的特点一般需要:多节点主备、配置化、动态修改、配置本地缓存、动态修改的实时推送等
·config允许配置文件放在git或者svn上,和spring boot的集成非常容易,但缺点就是修改了git上的配置以后,只能一个一个的请求每个service的接口,让他们去更新配置,需要配合消息总线和队列综合使用
·事件、消息总线,用于在集群(列如,配置变化事件)中传播状态变化,经常与spring cloud config联合使用
·spring cloud config本身不能向注册过来的服务实时更新的推送,比如我们配置放在git上,那么当修改github上配置内容的时候,最多可以配置webhook到一台config-server上,但是config-server自己不会将配置更新实时推送到各个服务器上
·bus的作用就是将大家连接在一条总线上,这条线上的所有server共享状态,
·spring cloud的服务发现组件
·eureka负责服务注册和服务发现,为了高可用,一般
·也是一种服务发现工具,而且自带key-value存储服务、健康检查和web界面
·consul提供了官方的docker镜像,直接使用docker-consul集群用户访问发现的话,运维成本会直线下降
·服务发现以后,每个service在本地知道自己要调用的服务有多少台机器,机器的ip是什么,端口号是什么,那这个service在本地需要有一个负载均衡策略,为每一次请求选择一台目标机器进行调用,而ribbon做的就是负载均衡策略的选择
·ribbon提供了多种负载均衡策略,包括BestAvailableRule、AvailabilityFileringRule、WeightedResponseTimeRule、RetryRule、RoundRobinRule、RandomRule、ZoneAvoidanceRule等,默认睡觉哦ZoneAvoidanceRule,也可以自己定义,比如被调用服务需要灰度发布或者A/B测试的话,就可以在ribbon这一层做自定义
·声明式、模块化的http客户端
·微服务之间的调用本质还是http请求,如果对于每个请求都需要写请求代码,增加请求参数,同时对请求结果做处理,就会存在大量重复工作,而feign非常优雅的帮助我们解决了这个问题,只需要定义一个interface,feign就知道http请求时参数应该如何设置,同时,feign也集成了ribbon,只要在微服务中依赖了ribbon,feign默认会使用ribbon定义的负载均衡策略
·feign并不是仅仅只能使用在有eureka或者ribbon微服务系统中,任何系统中,只要涉及到http调用第三方服务,都可以使用feign,帮我们解决http请求的代码重复编写
·断路器,类似于物理电路图中断路器
·如果某个服务所有的机器都挂了,hystrix会迅速失败,马上返回、保证
·是一个网关组件,提供动态路由、监控、弹性、安全等边缘服务的框架
·zuul只需要简单配置一下properties文件,不需要写具体的代码就可以实现将请求转发到相应的服务上去,还可以定制化一些filter做验证,隔离,限流,文件处理等切面,对于网关来说,使用zuul能够减少大量的代码
·是聚合服务器发送事件流数据的一个工具,用来监控集群下hystrix的metrics情况
·在复杂的分布式系统中,相同服务的节点经常需要部署上百甚至上千个,很多时候,运维人员希望能够把相同服务的节点状态以一个集群的形式展现出来,这样可以更好的把握整个系统的状态
·turbine提供把hystrix.stream的内容聚合为一个数据源供Dashboard展示
·spring boot热插拔,提供默认配置,开箱即用的依赖。
·starter是springboot宽假最基础的部分,可以定义starter
spring-cloud的组件功能实现基本基于Java代码实现,从运维角度来看需要了解运行机制和原理就可以,具体实现请参阅克隆下来的Java代码
·bootstrap.yaml(bootstrap.properties)用来程序引导时执行,应用与刚早时期配置信息读取,如可以使用配置application.yaml中使用到的参数等
·application.yaml(application.properties)应用程序特有配置信息,可以用来配置后续各个模板中需要使用的公共参数等
·bootstrap.yaml先于aplication.yml加载
·maven目录结构下的是src/main/resources/下有两种配置文件,一种是application。Propertirs,另一种是application.yml,两种都可以配置springboot项目中的一些变量的定义,参数的设置
·配置文件一般有多个(多环境),一般在应用启动的时候需要指定要启动的配置文件
先打包后运行mvn clean package,Java -jar target/xxxx.jar
直接运行spring-boot项目mvn spring-boot:run
Eureka是netfix开发的服务发现框架,springCloudEureka是springcloudNetfix的下一个子项目,它对Eureka进行了二次封装,通过为Eureka添加springboot风格的自动化配置,我们只需要简单的引入依赖和注册就能在springBoot构建的微服务应用轻松的与Eureka服务治理体系进行整合
服务发现组件(Eureka Server)
服务消费者(Eureka Consumer) 服务提供者(Eureka Provider)
Eureka Server:提供服务注册和发现
Eureka Consumer:服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到
Eureka Provider:服务消费方,从Eureka获取注册服务列表,从而能够消费服务
两台服务器都配置jdk和maven环境
第一台:192.168.50.100
第二台:192.168.50.104
添加环境变量
vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_201/
export JRE_HOME=/usr/local/jdk1.8.0_201/jre
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
export MAVEN_HOME=/usr/local/maven
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH:$MAVEN_HOME/bin
以下操作除指明哪一台外,其它均是在两台虚拟机上操作
关闭防火墙
systemctl stop firewalld
yum install git -y
git clone https://github.com/luojunyong/spring-cloud-examples.git
cd spring-cloud-examples/spring-cloud-eureka/spring-cloud-eureka
vim src/main/resources/application.properties
mvn clean package
java -jar target/spring-cloud-eureka-0.0.1-SNAPSHOT.jar
第二台:
firefox http://192.168.50.100:8000
添加生产者
以下操作除指明哪一台外,其它均是在两台虚拟机上操作
cd /root/spring-cloud-examples/eureka-producer-consumer/spring-cloud-producer
vim src/main/resources/application.properties
修改第一台的源代码
vim src/main/java/com/neo/controller/HelloController.java
mvn clean package
java -jar target/spring-cloud-producer-0.0.1-SNAPSHOT.jar
第二台:
firefox http://192.168.50.100:8000
添加消费者(消费者只需要在一台虚拟机上添加就可以了)
第一台
cd /root/spring-cloud-examples/eureka-producer-consumer/spring-cloud-consumer/
vim src/main/resources/application.properties
mvn clean package
java -jar target/spring-cloud-consumer-0.0.1-SNAPSHOT.jar
firefox http://192.168.50.100:8000
测试消费者是否可用
curl http://192.168.50.100:9001/hello/test
微服务会到注册中心进行注册,消费者也会到注册中心进行注册
所以当消费者访问时,因为注册中心存在ribbon组件,生产者会进行轮询
将消费者的终端停掉
雪崩效应
在IO型服务中,假设服务依赖服务A依赖服务B和服务C,而服务B和服务C有可能继续依赖其他的服务。继续下去会使得调用链路过长。
如果在A的链路上某个或几个被调用的子服务不可用或延迟较高,则会导致调用A服务的请求被堵住。堵住的请求会消耗占用掉系统的线程、io等资源,当该类请求越来越多,占用的计算机资源越来越多的时候,会导致系统瓶颈出现,造成其它的请求同样不可用,最终导致业务系统崩溃,又称为雪崩效应
解决方案
断路器可以实现快速失败,如果它在一段时间内侦测到许多类似的错误(譬如超时),就会强迫其以后的多个调用快速失败,不在请求所依赖的服务,从而防止应用程序不断地尝试可能执行会失败的操作,这样应用程序可以继续执行而不用等待修正错误,或者浪费CPU时间去等待长时间的超时。断路器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作
Feigen hystrix
因为熔断只是作用在服务调用这一段,因此我们只需要改动spring-cloud-consumer项目相关代码就可以。因为feign中已经依赖了hystrix,所在maven配置上不用做任何改动
配置断路器(类似健康检查
断路器:当感觉到提供者出错之后,就不会想提供者发送消息(负载均衡虽然已经察觉到后端服务器出错,但是还是会向坏了的服务器发送请求,很容易就会造成该服务器宕机现象)
在第一台上重新添加一个带hystrix的消费者
cd /root/spring-cloud-examples/spring-cloud-hystrix/spring-cloud-consumer-hystrix/
vim src/main/resources/application.properties
mvn clean package
java -jar target/spring-cloud-consumer-hystrix-0.0.1-SNAPSHOT.jar
测试一下消费者
现在已经不再进行轮询了
这个访问失败的提示能够在以下这个文件里看到
cd /root/spring-cloud-examples/spring-cloud-hystrix/spring-cloud-consumer-hystrix
vim src/main/java/com/neo/remote/HelloRemoteHystrix.java
Sleuth组件
微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性,如果出现了错误和异常,很难去定位。主要体现在,一个请求可能需要调用很多个服务,而内部服务的调用复杂性,决定了问题难以定位。所以微服务架构中,必须实现分布式链路追踪,去跟进一个请求到底有哪些服务参与,参与的顺秀又是怎样的,从而达到每个请求的步骤清晰可见,出来问题,很快定位
在微服务系统中,一个来自用户的请求,请求先到达前端A(如前端界面),然后通过远程调用,达到系统的中间件B、C(如负载均衡、网关等),最后到达后端服务D、E,后端经过一系列的业务逻辑计算最后将数据返回给用户,对于这样一个请求,经历了这么多个服务,怎么样将它的请求过程的数据记录下来呢?这就需要用到服务链路追踪
一个分布式服务追踪系统,主要有三部分:数据收集、数据存储和数据展示
服务追踪的追踪单元是从客户发起的请求(request)抵达被追踪系统的便捷开始,到被追踪系统向客户返回响应(response)为止的过程,称为一个”trace”。每个trace中会调用若干个服务,为了记录调用了哪些服务,以及每次调用的消耗时间等信息,在每次调用服务时,埋入一个调用记录,称为一个”span”,这样,若干个有序的span就组成了一个trace。在系统向外界提供服务的过程中,会不断地有请求和响应发生,也就会不断生成trace,把这些带有span的trace记录下来,就可以描绘出一幅系统能够的服务拓扑图。附带上span中的响应时间,以及请求成功与否等信息,就可以在发生问题的时候,找到异常的服务;根据历史数据,还可以从系统整体层面分析出哪里性能差,定位性能优化的目标
spring cloud sleuth可以结合zipkin,将信息发送到zipkin,利用zipkin的存储来存储信息,利用zipkin来展示数据
spring cloud sleuth微服务之间调用提供链路追踪。Sleuth可以很清楚的了解到一个请求经过了哪些服务,每个服务的处理花费了多久。从而我们可以很方便的清理各微服务间的调用关系,此外,sleuth还可以帮助我们:
①耗时分析:同构sleuth可以很方便的了解到每个采样请求的耗时,从而分析可以哪些服务调用比较耗时
②可视化错误:对于程序未捕捉的异常,可以通过zipkin服务界面上看到
③链路优化:对于调用比较频繁的服务,可以针对这些服务实施一些优化措施
zipkin组件:
可插拔数据存储方式
数据存储和分析
spring cloud sleuth是对zipkin的一个封装,对于span、trace等信息的生成、介入HTTP request,以及向zipkin server发送采集信息等全部自动完成
Spring cloud 提供的spring-cloud-sleuth-zipkin来方便集成zipkin实现(指的是zipkin client),将采集的数据传到zipkin服务器进行存储,并由zipkin服务进行展示
每个服务向zipkin报告计时数据,zipkin会根据调用关系通过zipkin ui生成依赖关系图,显示了多少追踪请求通过每个服务,该系统让开发者可通过一个web前端轻松的收集和分析数据,例如用户每次请求服务的出来时间等,可方便的检测系统中存在的瓶颈
Zipkin提供了可插拔数据存储方式:In-Memory Mysql Cassandra以及elasticsearch
在第一台上操作:
cd /root/spring-cloud-examples/spring-cloud-sleuth-zipkin/zipkin-server/
vim src/main/resources/application.yml
打包编译:
第一种方式:
mvn clean package
java -jar target/zipkin-server-1.0.0.BUILD-SNAPSHOT.jar
第二种方式:
mvn spring-boot:run
这种方式等于打包完成后直接运行
添加生产者:
cd /root/spring-cloud-examples/spring-cloud-sleuth-zipkin/spring-cloud-producer/
vi src/main/resources/application.yml
mvn spring-boot:run
添加网关
cd /root/spring-cloud-examples/spring-cloud-sleuth-zipkin/spring-cloud-zuul/
vim src/main/resources/application.yml
mvn spring-boot:run
firefox http://192.168.50.100:8000
curl http://192.168.50.100:8888/producer/hello?name=test
firefox http://192.168.50.100:9000
停止所有终端
spring boot admin
==>spring应用监控
在第一台虚拟机上操作
添加一个注册中心
cd /root/spring-cloud-examples/spring-boot-admin-eureka/spring-cloud-eureka/
mvn spring-boot:run
添加一个生产者
cd /root/spring-cloud-examples/spring-boot-admin-eureka/spring-cloud-producer
mvn spring-boot:run
添加第二个生产者
cd /root/spring-cloud-examples/spring-boot-admin-eureka/spring-cloud-producer-2/
mvn spring-boot:run
添加管理者
cd /root/spring-cloud-examples/spring-boot-admin-eureka/spring-boot-admin-server/
vi src/main/resources/application.yml
进入你自己的QQ邮箱获取smtp服务器的授权码
mvn spring-boot:run
firefox http://192.168.50.100:8000
可以查看详细的监控信息 Details–细节