这个学习记录是学习自翟永超前辈的SpringCloud的基础教程。
自己写这个教程的目的主要是在于,想要更凝练总结一些其中的一些实用点,顺便做个汇总,这样自己在复习查看的时候更加方便,也能顺着自己的思路走。
在这里感谢一下翟永超前辈的教程与分享,希望自己以后有一定积累后,也能成为一个优秀的开源分享人。
注:pom文件可以去原链接找,顺便给前辈的网站增加访问量。
第一章服务注册与发现(基于eureka)
微服务框架(这个基于自己理解,可能会有错误,欢迎指正)
微服务框架:前一阵公司刚刚做了一个小的课题报告,同事分享了一下自己对于微服务的理解。
听后也有一定的收获,微服务可以说是在SOA的基础上的更进一步的凝练,即把每一个服务模块化,即编程一个单独的组件(项目),在需要使用可以通过简单的拔插就能够添加复杂的业务体系与功能。
SpringCloud同时又基于SpringBoot的快速式开发,这样可以简化很多开发中的配置问题。
服务治理
Spring Cloud为服务治理做了更进一步的抽象接口,可以支持多种服务治理框架(这里使用的是eureka)。
比如:Netflix Eureka、Consul、Zookeeper。
由于这层抽象,我们可以实现无缝切换服务治理实现,从而不影响服务注册、服务发现、服务调用。
Eureka
创建服务注册中心
创建一个普通的Spring Cloud的web应用,然后在启动类上添加注解@EnableEurekaServer即可。
然后在bootstrap.yml(我手动改名了2333)配置文件中添加以下配置:
创建服务提供者
创建SpringBoot项目,在其主类上添加注解@EnableDiscoveryClient
在bootstrap.yml中加入配置:
通过Spring.application.name属性,可以指定微服务名称在后续调用中的时候只要使用该名称就可以进行服务的访问。
eureka.client.serviceUrl.defultZone属性对应服务注册中心的配置内容,指定服务注册中心的位置。
第二章服务消费(基础)
使用LoadBalanceClient
创建服务消费者,并在配置文件中配置:
在启动类中加入注解@EnableDiscoveryClient,并初始化RestTemplate,用来发起REST请求:
创建接口消费eureka-client提供的接口:
第三章服务消费(Ribbon)
Spring Cloud Ribbon
是实现负载均衡的工具,基于一个HTTP和TCP的客户端负载均衡器,可以再客户端中配置ribbonServerList来设置服务端列表去轮询访问以达到负载均衡的作用。
当Ribbon与Eureka联合使用时,ribbonserverList会被DiscoveryEnableNIWSServerList重写,扩展成为Eureka注册中心获取服务实力列表。同时也会用NIWSDiscoveryPing来替代IPing,将其职责委托
给Eureka来确定服务端是否已经启动。
注:上述内容都是Spring自动实现配置的,我们只需要加入适当注解就可以快速开发。
示例
修改客户端中的主类,添加@LoadBalance注解:
修改Controller,去掉LoadBalanceClient,直接通过RestTemplate发起请求:
注:我们采用了服务名的方式组成访问的url,这里为什么不使用ip地址与端口形式能成功呢?
因为Spring Cloud Ribbon 有一个拦截器,它能够在进行调用时,自动地去选取服务实例,并将实际请求的IP地址和端口替换这里的服务名,从而完成服务接口的调用。
第四章服务消费(Feign)
Spring Cloud Feign
Spring Cloud Feign 是一套声明式服务调用客户端。
我们仅需要创建接口,并使用注解来配置它即可完成对web服务接口的绑定。
提供可拔插式注解支持、可拔插式编码器和解码器、支持SpringMVC注解、整合Ribbon和Eureka来提供负载均衡的HTTP客户端实现。
示例
在消费者主类上添加主类@EnableFeignClients:
创建Feign的客户端接口定义。同时使用@FeignClient注解指定接口要调用的服务名,接口中定义的各个函数使用SpringMVC的注解绑定服务方提供的REST接口。
修改Controller,通过定义的Feign客户端调用服务提供方的接口。
注:通过Spring Cloud Feign实现服务调用的方式更加简单,通过@FeignClient定义接口声明我们需要调用的微服务接口,在具体的使用中仅需要调用本地方法即可。
Feign是基于Ribbon实现的,所以自带客户端负载均衡功能。
Feign还整合Hystrix来实现服务的容错保护,在本示例中,Hystrix是默认关闭的,后面的章节会介绍熔断机制。
第五章分布式配置中心
个人理解是:可以通过把配置放在一个公共的地方,便利于通过对一些配置的修改对项目进行修改。也方便统一管理。
准备配置仓库
在自己的github上创建对应的配置文件:config-client.yml和config-client-dev.yml
并在其中放入信息:
构建配置中心
在主类上加上@EnableConfigServer注解:
在bootstrap.yml添加配置信息:
访问规则
构建客户端
就是一个常规的Spring Boot项目,添加相应的pom依赖就行。
创建bootstrap.yml配置,获取指定的config-server-git位置
第六章服务容错保护(Hystrix服务降级)
为了避免出现不同服务间的阻塞导致整个系统出现崩溃式的瘫痪,Spring Cloud Hystrix通过实现线程隔离、断路器等服务保护功能对上述问题进行解决。
Hystrix具备服务降级、服务熔断、线程隔离、请求缓存、请求合并以及服务监控等强大功能。
示例:
在主类上加@EnableCircuitBreaker或@EnableHystrix注解开启Hystrix的使用:
注:这里我全都用了,另外也可以使用@SpringCloudApplication注解,这个复合注解包括了需要的全部注解。
在调用的过程中添加一些“必要的逻辑”(这里选择的是线程睡眠):
注:基于@HystrixCommand注解与其fallbackMethod方法实现服务降级。
第七章服务容错保护(Hystrix依赖隔离)
实现原理:每一个Hystrix命令都有独立的线程池,这样可以避免影响其他服务。
实现:@HystrixCommand会自动为该函数实现调用的隔离。即依赖隔离与服务降级是一体的。
第八章服务容错保护(Hystrix断路器)
在第六章中,通过模拟的时间延迟实现了服务降级,但是因为超时时间的问题,仍然可能出现服务堆积的可能。
断路器在这时发挥作用,断路器起作用依赖于三个参数:快照时间窗、请求总数下限、错误百分比下限。
1)快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的十秒。
2)请求总数下限:在快照时间窗内,必须满足请求总数下限才有资格根据熔断。默认为20,意味着十秒内,如果该Hystrix命令的调用此时不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。
3)错误百分比下限:当请求总数在快照时间窗内超过了下限,比如发生了30次调用,如果在这30次调用中,有16次发生了异常,那么也就是说50%的错误百分比,在默认设定50%下限情况下,这时断路器打开。
那么熔断后会发生什么?
Hystrix命令将不会在执行主逻辑,而是直接执行降级逻辑,即降级逻辑会变为主逻辑。
那么在熔断后,原本的主逻辑如何恢复呢?
Hystrix实现了自动恢复功能,断路器打开,主逻辑进行熔断后,Hystrix会启动一个休眠时间窗,在这个时间窗内,降级逻辑会成为临时的主逻辑;当休眠时间窗到期时,断路器会进入半开状态,释放一次请求到主逻辑上,如果主逻辑能够返回,那么断路器将会闭合,主逻辑恢复;如果这次请求依然有问题,断路器会继续进入打开状态,休眠窗重新计时。
第九章Hystrix控制面板
创建一个Spring Boot项目,在主类上添加@EnableHystrixDashBoard注解,启动 Hystrix DashBoard功能。
配置文件中设置一下端口等信息。然后访问:http://localhost:1301/hystrix页面:
可以看到Hystrix DashBoard支持三种方式进行监控:
我们可以通过单体应用的监控实现我们对自己的程序的监控。
监控的具体信息可以在翟永超前辈的博客查看
第九章Hystrix监控数据聚合
第十章服务网关(基础)
服务网关:功能更加强大的均衡负载器,可以统一向外提供REST API,具有服务路由、负载均衡的功能,还具备权限控制的功能。
创建一个Spring Boot项目,并在主类上加@EnableZuulProxy,开启zuul功能。
在配置文件中配置:
当zuul注册在注册中心时,会根据在注册中心发现的服务创建服务规则(我们启动的服务为:eureka-client和eureka-consumer)。
我们可以通过路由访问到具体的服务去。
第十章服务网关(路由配置)
可以通过一组zuul.routes.<route>.path与zuul.routes.<route>.serviceId参数对配置即可(以第九章为主做示例):
zuul.routes.eureka-client.path=/eureka-client/**
zuul.routes.eureka-client.serviceId=/eureka-client
除了使用path与serviceId映射的配置外,还有一种更简洁的格式:zuul.routes.<serviceid>=<path>
注:其中serviceId用来指定路由的具体服务名,path用来配置请求表达式。
上面的例子改造后可以变为:
zuul.routes.eureka-client=/eureka-client/**
第十一章服务网关(过滤器)
会有一些非业务的且在各个服务入口处均有的逻辑需求。比如说,参数的一些校验,权限的一些校验。
如果在每一个模块中实现自己的校验那么不仅代码重复严重,后期维护起来也会有很多问题。Spring Cloud Zuul自带的过滤器可以帮我们实现对客户端请求的检验。帮助我们解决上述问题。
实现方式:继承ZuulFilter抽象类,并实现它定义的四个抽象函数就可以完成对请求的拦截和过滤了。
过滤器实现
自定义过滤器实现ZuulFilter然后重写方法即可:
需要重写下面的方法:
完成上面的步骤之后还需要将自定义拦截器注入容器中
基础的教程大致就这些,剩下的学习将从书籍开始。以后该分类的笔记也以书籍上的内容为主。