微服务与spring cloud
理解微服务
软件架构演进
软件架构的发展经历了从单体结构、垂直架构、SOA架构到微服务架构的过程。
单体架构
特点:
1、所有的功能集成在一个项目工程中。
2、所有的功能打一个war包部署到服务器。
3、应用与数据库分开部署。
4、通过部署应用集群和数据库集群来提高系统的性能。
优点:
1、项目架构简单,前期开发成本低,周期短,小型项目的首选。
缺点:
1、全部功能集成在一个工程中,对于大型项目不易开发、扩展及维护。
2、系统性能扩展只能通过扩展集群结点,成本高、有瓶颈。
3、技术栈受限。
垂直架构
特点:
1、以单体结构规模的项目为单位进行垂直划分项目即将一个大项目拆分成一个一个单体结构项目。
2、项目与项目之间的存在数据冗余,耦合性较大,比如上图中三个项目都存在客户信息。
3、项目之间的接口多为数据同步功能,如:数据库之间的数据库,通过网络接口进行数据库同步。
优点:
1、项目架构简单,前期开发成本低,周期短,小型项目的首选。
2、通过垂直拆分,原来的单体项目不至于无限扩大。
3、不同的项目可采用不同的技术。
缺点:
1、全部功能集成在一个工程中,对于大型项目不易开发、扩展及维护。
2、系统性能扩展只能通过扩展集群结点,成本高、有瓶颈。
SOA架构
特点:
1、基于SOA的架构思想将重复公用的功能抽取为组件,以服务的方式给各各系统提供服务。
2、各各项目(系统)与服务之间采用webservice、rpc等方式进行通信。
3、ESB企业服务总线作为项目与服务之间通信的桥梁。
优点:
1、将重复的功能抽取为服务,提高开发效率,提高系统的可重用性、可维护性。
2、可以针对不同服务的特点制定集群及优化方案。
3、采用ESB减少系统中的接口耦合。
缺点:
1、系统与服务的界限模糊,不利于开发及维护。
2、虽然使用了ESB,但是服务的接口协议不固定,种类繁多,不利于系统维护。
3、抽取的服务的粒度过大,系统与服务之间耦合性高。
- 微服务架构
特点:1.按业务划分为独立的应用程序,及服务单元。
2.服务之间通过http协议相互通信。
3.自动化部署。
4.可以采用不同的编程语言和储存技术。
5.服务集中化管理。
6.分布式系统。
优点:
1、服务拆分粒度更细,有利于资源重复利用,提高开发效率。
2、可以更加精准的制定每个服务的优化方案,提高系统可维护性。
3、微服务架构采用去中心化思想,服务之间采用RESTful等轻量协议通信,相比ESB更轻量。
4、适用于互联网时代,产品迭代周期更短。
缺点:
1、微服务过多,服务治理成本高,不利于系统维护。
2、分布式系统开发的技术成本高(网路延迟,分布式事务,异步消息等),对团队挑战大。
3.运维挑战,微服务构架需要维护多个进程,难度加大。
4.接口一致性,服务间通过接口通信,当对原有接口进行修改后,交互方也需要做出协调改变发布,保证接口的正确调用
什么是微服务
为适应企业的业务发展,提高软件研发的生产力,降低软件研发的成本,软件架构也作了升级和优化,将一个独立的系统拆分成若干小的服务,每个小服务运行在不同的进程中,服务与服务之间采用http 轻量协议(比如流行的RESTful)传输数据,每个服务所拥有的功能具有独立性强、高内聚的特点,这样的设计就实现了单个服务的高内聚,服务与服务之间的低耦合效果,这一个一个的小服务就是微服务,基于这种方法设计的系统架构即微服务架构。
Spring Cloud技术栈
- 微服务的技术栈
负载均衡,网关路由:高可用、集群部署,校验、请求转发、服务集成。
服务治理:服务注册、发现。
容错:避免雪崩。
监控跟踪:监控资源利用、服务响应、容器资源利用情况。
消息总线:消息队列、异步通信。
配置管理:统一配置管理。
- Spring Cloud是什么
Spring Cloud为开发人员构建微服务架构提供了完整的解决方案,SpringCloud是若干个框架的集合。
Spring Cloud Netfix:核心组件,对多个Netflix OSS开源套件进行整合。
Eureka:服务治理组件,包含服务注册中心,服务注册与发现机制。
Ribbon:客户端负载均衡的服务调用组件。
Hystrix: 容错管理组件,实现断路器模式,帮助服务依赖中心出现的延迟和故障提供强大的容错能力。
Feign:于Ribbon和Hystrix的声明式服务调用组件。
Zuul:网关组件,提供智能路由,访问过滤等功能。
Spring Cloud Config:分布式调用中心,配置管理工具,支持使用存储配置内容,实现应用配置的外部存储,支持客户端配置信息刷新,加密,解密配置内容。
Spring Cloud Bus:事件,消息总线,用于传播集群中状态变化或事件,以触发后续处理,比如动态刷新配置。
Spring Cloud Stream:消息驱动的微服务,通过Redis,Rabbit或Kafka实现的消费微服务,可以通过简单的声明式模型来发送和接收消息。
Spring Cloud Sleuth:Spring Cloud应用的分布式跟踪实现,可以完美整合Zipkin.
- Spring Cloud技术栈
微服务的兴起出现了很多优秀的公司和技术:
服务治理:Dubbo(阿里巴巴)、Dubbox(当当)、Eureka(Netflix)等 。
配置管理:Disconf(百度)、QConf(360)、Diamood(淘宝)等 。
服务跟踪:Hydra(京东)、Zipkin(Twitter)、Sleuth(Spring Cloud)等 。
Spring Cloud 提供一站式的微服务架构解决方案,如下图:
- 为什么使用Spring Cloud
微服务架构的优点表明它可以提高我们的生产力,但是分布式系统本身的技术成本问题给互联网那些创业型公司不少的挑战,阿里、百度等巨头所提供的微服务技术只是解决其中某个问题,而整合封装这些优秀的技术恐怕是Spring最擅长的领域了,Spring Cloud也正因为此而诞生。
使用Spring Cloud来构建微服务架构可以省去你整合各家技术的成本,Spring Cloud为我们构建微服务架构提供了一站式的解决方案,就好比当初Spring诞生是为解决EJB企业应用开发的众多问题而提供的一站式轻量级企业应用开发解决方案一样,随着使用Spring Cloud公司数量的增加,相信微服务将被Spring Cloud一统江湖。
- Netflix公司介绍
Spring Cloud的很多技术来源于Netflix(https://netflix.github.io/),摘自百度百科的信息如下:
- 服务治理:Spring Cloud Eureka
什么是服务治理
微服务架构的缺点中最主要的就是由于微服务数量众多导致维护成本巨大,服务治理为解决此问题而产生的。服务治理的作用是让维护人员从人工维护中解放出来,由服务自维护,微服务作为服务提供方主动向服务治理中心注册,服务的消费方通过服务治理中心查询需要的服务并进行调用。
如下图:
Spring Cloud Eureka
Spring Cloud Eureka 是对Netflix公司的Eureka的二次封装,它实现了服务治理的功能,Spring Cloud Eureka提供服务端与客户端,服务端即是服务注册中心,客户端完成服务的注册与发现。服务端和客户端均采用Java语言编写(Eureka支持多语言)。
如下图显示了Eureka Server与Eureka Client的关系:
架构
- 流程图
- 开发并部署Eureka Server
创建eureka server
- 添加依赖
2. 配置application.yml
3、在启动类上添加@EnableEurekaServer注解。
4.在浏览器中输入http://localhost:8761 就会显示:
。
- 服务注册
服务注册完成将用户信息服务注册到Eureka Server中,供服务消费方查询。
- 添加依赖
2、配置application.yml
#应用(服务)名称
spring.application.name=hello-service
server.port=8762
#注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
3.在启动类上添加EnbleDiscoverClient注解
@EnableDiscoveryClient
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(HelloApplication.class).web(true).run(args);
}
}
4.在浏览器中输入http://localhost:8761 就会显示:
- 负载均衡:Spring Cloud Ribbon
什么是负载均衡
负载均衡是微服务架构中必须使用的技术,通过负载均衡来实现系统的高可用、集群扩容等功能。负载均衡可通过硬件设备及软件来实现,硬件比如:F5、Array等 ,软件比如:LVS、Nginx等 。
如下图是负载均衡的架构图:
用户请求先到达负载均衡器(也相当于一个服务),负载均衡器根据负载均衡算法将请求转发到微服务。负载均衡算法有:轮训、随机、加权轮训、加权随机、地址哈希等方法,负载均衡器维护一份服务列表,根据负载均衡算法将请求转发到相应的微服务上,所以负载均衡可以为微服务集群分担请求,降低系统的压力。
Spring Cloud Ribbon
Spring Cloud Ribbon是基于客户端的负载均衡工具,负载均衡分为服务端负载均衡和客户端负载均衡,3.1小节的图形指的是服务端负载均衡,客户端负载均衡与服务端负载均衡的区别在于客户端要维护一份服务列表,Ribbon从Eureka Server获取服务列表,Ribbon根据负载均衡算法直接请求到具体的微服务,中间省去了负载均衡服务。
如下图是Ribbon负载均衡的流程图:
1、在消费微服务中使用Ribbon实现负载均衡,Ribbon先从Eureka Server中获取服务列表。
2、Ribbon根据负载均衡的算法进行负载均衡,将请求转发到其它微服务。
- 开发单点登录服务
单点登录服务提供用户登录、用户退出等功能。
单点登录服务需要调用用户信息服务查询用户信息。
单点登录服务采用Spring Boot、SpringMVC开发。
- 服务发现
单点登录服务需要从EurekaServer查询用户信息服务。
1、配置Eureka Server服务地址。
2、在启动类中添加注解@EnableDiscoveryClient
- Ribbon编程
1、定义RestTemplate对象
2、配置 @LoadBalanced
3、设置负载均衡算法。
4、使用RestTemplate调用微服务。
- 容错保护:Spring Cloud Hystrix
什么是容错保护
在微服务构架中,将系统拆分成很多的服务单元,各单元之间通过服务注册与订阅的方式相互依赖,由于每个单元都运行在不同的进程中,依赖通过远程调用方式执行,这样可能因为网络原因或依赖服务自身的问题出现调用故障或延迟,而这些问题直接导致了调用方的对外服务也出现延迟,若此时调用方的请求不断增加,最后就会因为等待出现故障的依赖方相应形成任务积压,最终导致自身服务瘫痪。
断路器模式的作用就是当某个服务单元发生故障,通过断路器的故障监控,向调用方返回一个错误响应,而不是长时间的等待,这样就不会使线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统上蔓延。
容错保护简单来说就是微服务在执行过程中出现错误并从错误中恢复的能力。微服务容错性不好很容易导致雪崩效应,什么是雪崩效应?摘自百度百科中的定义:
微服务的雪崩效应表现在服务与服务之间调用,当其中一个服务无法提供服务可能导致其它服务也死掉,比如:单点登录服务调用用户信息服务查询用户信息,由于用户信息服务无法提供服务导致单点登录服务一直等待,从而导致用户登录、用户退出功能无法使用,像这样由一个服务所引起的一连串的多个服务无法提供服务即是微服务的雪崩效应。
Spring Cloud Hystrix
Spring Cloud Hystrix 是基于Netflix的开源框架Hystrix的整合,它实现了断路器、线程隔离、信号隔离等容错功能。
下图是Hystrix断路器示意图:
1.要在服务消费方添加hystrix。
2、使用Hystrix实现容错。
3. 在Spring boot的启动类上添加@enableHystrix注解
- 声明式服务调用: Spring Cloud Feign
Feign
Feign在RestTemplate的基础上对其封装,由它来帮助我们定义和实现依赖服务接口的定义。Spring Cloud Feign 基于Netflix Feign 实现的,整理Spring Cloud Ribbon 与 Spring Cloud Hystrix,并且实现了声明式的Web服务客户端定义方式。
1. 添加依赖
2. 在启动类添加@EnableFeignClients开启Spring Cloud Feign的支持
3.application.yml文件配置如下
spring:
application:
name: movie-service
server:
port: 9092
eureka:
client:
healthcheck:
enabled: true
serviceUrl:
defaultZone: http://localhost:1111/eureka
4.USER-SERVICE接口
5.UserFeignClient接口
在定义各参数绑定时,@RequestParam和@RequestHeader等可以指定参数名称的注解,他们的value千万不能省略,在SpringMVC中这些注解会根据参数名作为默认值但在Feign中必须显示指定,否则会抛出异常
6. 在Controller中添加测试接口进行测试
7.结果
- 服务网关:Spring Cloud zuul
什么是服务网关
服务网关是在微服务前边设置一道屏障,请求先到服务网关,网关会对请求进行过虑、校验、路由等处理。有了服务网关可以提高微服务的安全性,校验不通过的请求将被拒绝访问。
前边介绍的Ribbon客户端负载均衡技术可以不用经过网关,因为通常使用Ribbon完成微服务与微服务之间的内部调用,而对那些对外提供服务的微服务,比如:用户登录、提交订单等,则必须经过网关来保证微服务的安全。
Spring Cloud Zuul
Spring Cloud Zuul是整合Netflix公司的Zuul开源项目实现的微服务网关,它实现了请求路由、负载均衡、校验过虑等 功能。
1、部署用户信息服务A、单点登录服务B,每个服务部署至少两台机器。
2、将用户信息服务A、单点登录服务B注册到EurekaServer中。
3、开发并部署zuul。
4、在zuul中配置路由
5、可以定义filter,需要集成zuul提供filter类,进行校验拦截。
6、在spring boot的启动类中配置注解
7、根据上边的路由配置访问微服务。
凡是以/sso/打头的请求,路由到 itcast-microservice-sso微服务。
总结
zuul网关,不仅提供对外服务访问 ,微服务也可以通过zuul请求其它的微服务。
- 分布式配置中心:Spring Cloud Config
Spring Cloud Config
Spring Cloud Config 用来为分布式系统中的基础设施和微服务应用 提供集中化的外部配置支持,分为客户端和服务端两部分。服务端称为配置中心,它是一个独立的微服务应用,用来连接配置仓库,并为客户端提供配置信息,加密,解密等信息的访问接口。客户端是微服务构架中的各个微服务应用或基础设施,通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动时从配置中心获取和加载配置信息。由于Spring Cloud Config实现的配置中心默认采用Git来存储配置信息,所以使用Spring Cloud Config构建的配置服务器,天然就支持微服务应用配置信息的版本管理,并且可以通过Git客户端工具方便管理和访问配置内容。
构建服务端Config Server
1.添加依赖
2. 在程序的入口Application类加上@EnableConfigServer注解开启配置服务器的功能
3. application.properties文件配置以下:
spring.application.name=config-server
server.port=8888
spring.cloud.config.server.git.uri=https://github.com/xjmxjm/SpringcloudConfig/
spring.cloud.config.server.git.searchPaths=respo
spring.cloud.config.label=master
spring.cloud.config.server.git.username=username
spring.cloud.config.server.git.password=password
- spring.cloud.config.server.git.uri:配置git仓库地址
- spring.cloud.config.server.git.searchPaths:配置仓库路径
- spring.cloud.config.label:配置仓库的分支
- spring.cloud.config.server.git.username:访问git仓库的用户名
- spring.cloud.config.server.git.password:访问git仓库的用户密码
如果Git仓库为公开仓库,可以不填写用户名和密码,如果是私有仓库需要填写,本例子是公开仓库,放心使用。
远程仓库https://github.com/xjmxjm/SpringcloudConfig/ 中有个文件config-client-dev.properties文件中有一个属性:
启动程序:访问http://localhost:8888/foo/dev
证明配置服务中心可以从远程程序获取配置信息。
http请求地址和资源文件映射如下:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
构建客户端config client
- 添加依赖
2其配置文件bootstrap.properties:
- spring.cloud.config.label 指明远程仓库的分支
-
spring.cloud.config.profile
- dev开发环境配置文件
- test测试环境
- pro正式环境
- spring.cloud.config.uri= http://localhost:8888/ 指明配置服务中心的网址。
3.程序的入口类,写一个API接口“/hi”,返回从配置中心读取的foo变量的值
打开网址访问:http://localhost:8881/hi,网页显示
这就说明,config-client从config-server获取了foo的属性,而config-server是从git仓库读取的。