springboot是由Pivotal团队开发的一款基于spring的全新框架,其设计初衷是为了简化spring的搭建以及开发过程。
1.约定大于配置的理念提高了开发效率,例如静态资源的位置,默认配置文件名称application
2.嵌入式web容器,例如tomcat,让开发人员不必过多的关注容器的调优配置
3.摒弃了大量的xml配置,降低开发人员的学习成本
4.整合了大量的开源框架。
web、security、thymeleaf、test、aop、log4j2、 actuator、atomikos、quarts、 data-jpa、data-jdbc、mybatis-spring-boot-starter、data-redis、kafka、rabbitmq、activemq、rocketmq
SpringBootApplication、Configuration、RestController、Value、Bean、PropertySource、ControllerAdvice、ExceptionHandler
、Repository(JPA的dao层注解)、MapperScan(mybatis-starter扫描mapper的注解)
spring常用注解:Controller、Service、Component、RequestMapping、Autowired、Resource、PathVariable、RequestParam、RequestBody、ResponseBody
@Value("#{'${key}'.split(',')}") 该注解中的el表达式可以获取到一个List属性
@ConfigurationProperties(prefix = "prefixKey") 该注解声明一个类为properties属性的配置类
* 微服务是一种架构风格,将单体应用划分为小型的服务单元,微服务之间基于Http协议通讯。
* 微服务的优点
1.降低模块与模块之间的耦合度
2.提高代码可用性
3.提升应用整体的容错性
*微服务的缺点
1.微服务最大的难题就在于前期的服务设计,及边界划分,糟糕的设计还不如单体应用
2.服务于服务之间基于http协议通过网络通讯,增加了通讯成本
3.分布式事务始终是分布式系统无法逾越的一个心病。
总之微服务是用设计理念去解决技术上的瓶颈,当然会衍生出新的瓶颈,可以理解
*springcloud并不是一个独立框架,是基于springboot对一些现有分布式系统框架的整合,进而可以使开发人员快速搭建分布式应用。
*springcloud的模块
Spring Cloud Netflix 模块 微服务集成主要框架(Eureka、Ribbon、Feign、Zuul、hystrix)
Spring Cloud Config 模块 微服务配置中心
Spring Cloud Sleuth 模块 服务跟踪,可以整合ELK
Spring Cloud Stream 模块 消息中间件,可以集成第三方如kafka、rocketMQ等等
*Eureka是一个基于Rest的服务,为集群中的其他服务提供注册信息
*eureka包括eureka-server和eureka-client两个组件
eureka-server:微服务集群中的所有服务依赖eureka-client注册到server端,并保存到内存中,eureka-server本身也可以作为一个客户端注册到其他eureka-server上,多个eureka-server可以相互注册来达到高可用。
eureka-client:基于java实现,集成的ribbon默认以轮询机制实现负载均衡
*eureka原理:eureka-server和eureka-client通过心跳机制来保持联系,client端向server端注册的同时并从server端拉取一份其他服务的注册表信息,保存在自身内存中,因此客户端调用其他服务其实是从自身存储的注册表信息中去取,当server端的注册信息被改变后,client端下次心跳就会感知到,并更新自己的注册表,当client端停止服务后,server端也会感知到并从注册表中移除该client的注册信息
*eureka常用配置:
spring.application.name #eureka实例名
eureka.client.service-url.defaultZone #注册中心eureka-server地址
eureka.instance.hostname #client端主机
eureka.instance.lease-renewal-interval-in-seconds #心跳时间间隔,默认30s
eureka.instance.lease-expiration-duration-in-seconds #心跳超时时间,默认90s
eureka.server.eviction-interval-timer-in-ms #注册表的清理间隔,默认60000ms
eureka.client.registry-fetch-interval-seconds #注册表抓取时间间隔,默认30s
eureka.client.register-with-eureka #自己注册自己,默认true
eureka.server.enable-self-preservation #自我保护模式,默认true
Ribbon在SpringCloud应用中起到负载均衡的作用,通常被集成在eureka中直接使用。
*ribbon包含的三大组件:
ribbon-core,这是其核心组件,包含负载均衡的接口定义及实现
ribbon-eureka,为eureka客户端提供的负载均衡实现
ribbon-httpclient,该模块含有实现负载均衡的rest客户端,是对Apache的HttpClient的封装
*ribbon实现负载均衡的三大组件:
Rule,逻辑处理,该组件决定会从服务列表中返回哪个服务实例
Ping,使用定时器确保服务器网络正常
ServerList,服务器列表,静态或动态的指定服务器列表
ribbon结合RestTemplate实现负载均衡(轮询机制)的代码片段
@Configurattion
public class CommonBean {
@Bean
@LoadBalanced
RestTetmplate restTemplate{
return new RestTetmplate();
}
}
//使用restTemplate
restTemplate.getForObject("http://" + serviceName + "/api",Object.class);
ribbon:
ConnectTimeout #请求连接超时,默认1000ms
ReadTimeout #请求处理超时,默认1000ms
OkToRetryOnAllOperations #对所有请求重试,默认false
MaxAutoRetriesNextServer #切换实例的重试次数,默认0
MaxAutoRetries #对当前实例的重试次数,默认0
*Fegin是一个开源的基于Rest的RPC框架,SpringCloud将其整合到Netflix框架里面极大的简化了微服务内部的服务交互
*Feign的几大组件:
1.基于插件的编码器GsonEncoder、解码器 GsonDecoder都实现自 Encoder 接口,也可以实现该接口自定义编解码器
2.基于插件的Client,也可以实现该接口来自定义Fegin客户端
3. 使用第三方注解需要依赖jaxrs ,Contract接口定义了解析注解的规范,可以继承它的实现BaseContract来解析自定义的注解
4.请求拦截器 Requestinterceptor,实现该接口可以处理请求,例如设置请求头信息
5.接口日志 logLevel(String 级别) 设置日志级别 .logger()处理日志记录方式
*SpringCloud中使用Fegin主要依赖以下几个注解,springcloud也重新实现了Fegin的客户端LoadBalancerFeignClient,并且定义了自己的注解
@FeignClient:用在Fegin接口上,属性为服务的实例名
@RequestMapping、@PathVariable、@RequestParam、@RequestHeader与SpringMVC使用方式一样
*SpringCloud中实现Fegin的核心API:
编码器: SpringEncoder feignDecoder
解码器: ResponseEntityDecoder feignEncoder
日志:Slf4jLogger feignLogger
注解解析:SpringMvcContract feignContract
Feign客户端:LoadBalancerFeignClient feignClient
*容错机制:
当并发量较大时,大量的http请求被阻塞等待服务A调用服务D的返回结果,而服务D故障无法即时返回,如果有了容错机制,那么可以判断服务D的健康状态而决定是否调用服务D,如果服务D故障,则直接调用回退逻辑,这样可以大大的降低服务A调用服务D的时间,而缓解被阻塞的请求可以正常去调用其他服务。
*hystrix的作用:
当所依赖的服务延迟或故障时,熔断故障服务
故障服务恢复时,取消熔断
调用服务失败时,可以快速执行回退
实时监控和报警
*hystrix详解:
1.命令执行HystrixCommand
observer()和toObserver()的区别,toObserver会返回一个Observable的实例,调用该实例的subscribe(Observer observer)方法才会执行命令。observer方法内部会自动执行上述逻辑,因此observer方法会执行命令
//伪代码
Observable ob= new HystrixCommand().to0bservable("commnd1") ;
//进行订阅 ,此时会执行命令
ob.subscribe(new Observer() {
public void onCompleted( ) {
System . out . println (” 命令执行完成”);
}
public void onError (Throwable e ) { }
publ VO onNext(String t ) {
System . out . println (” 命令执行结果:” t) ;
}
}) ;
2.回退执行
以下三种情况触发回退:断路器打开、信号量或线程池满载、命令执行失败
实现HystrixCommand的getFallBack()方法即回退逻辑
3.链式回退
在A命令的回退逻辑中调用B命令执行,当A执行失败时会调用B的命令
4.断路器开启
默认条件:10秒内产生20次请求,并且请求失败的比例超过50%,则开启断路器
5.断路器关闭
断路器打开后默认5秒内不会再开启,超过5秒,hystrix会执行一次命令,如果成功才更新健康状态,并关闭断路器。
6.隔离机制(限流机制)
线程池:池里有几个线程会执行几个命令,如果超过池的容量,则会执行回退,可异步,支持超时
信号量Semaphore:超过信号量的阈值,则执行回退,同步,阻塞不支持超时
7.请求缓存
在一次请求的过程中,多次调用同一个接口,可以使用缓存
开启缓存,重新HystrixCommand的getCacheKey
*SpringCloud中使用hystrix
*依赖的注解:@EnableCircuitBreaker、@HystrixCommand、@EnableHystrixDashboard(监控)
*与feign接口整合:@FeignClient中加一个属性,fallback用以指定Feign接口的容错实现类,也可以使用@HystrixCommand
@FeignClient (name =”provider-server”, fallback = ErrorFallback .class)
public interface TestHystrixClient {
@RequestMapping(method = RequestMethod.GET, value = "/hello" )
public String hello () ;
}
@Component
public class ErrorFallback implements TestHystrixClient {
public String hello() (
System.out.println("hello 方法的回退");
return "error";
}
}
hystrix配置注意:
hystrix.command.default和hystrix.threadpool.default中的default为默认CommandKey,在于feign整合后默认为feign接口的接口名+方法名
示例:
hystrix:
command:
FeignTestServer#test():
xxx
feign接口如下:
@FeignClient(name=xxx, fallbackFactory=XXX.class)
public interface FeignTestServer {
@GetMapping("/xxx/testXXX")
String test();
}
*常用配置属性:
feign.hystrix.enabled #开启feign的hystrix开关 默认false
hystrix.command.default.execution.timeout.enabled #是否启用超时,默认true
hystrix.command.default.execution.isolation.strategy #限流策略,默认值Thread,备用值Semaphore
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds #超时时间,默认1000ms
hystrix.command.default.circuitBreaker.requestVolumeThreshold #hystrix判断故障超时时间默认1000ms
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds #断路器开启的时间,默认5000ms后会尝试发一次请求判断接口是否恢复,如果恢复,则关闭断路器
hystrix.command.default.circuitBreaker.errorThresholdPercentage #错误比率阈值,默认50,默认10秒内20次请求错误比率超过50%,断路器会被打开
hystrix.threadpool.default.default.coreSize #线程池大小,默认10
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests #限流策略Semaphore时的最大并发数,默认值10
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests #执行回退方法的最大并发数,默认值为10
*zuul的作用:
路由,将请求路由到不同的服务集群上或其他服务
负载均衡,设置每种请求的处理能力,取消超出限制的请求
身份认证和安全:过滤需要身份认证的请求,将不符合认证的请求拒绝
静态响应:直接响应一些请求,不转发到集群内部
*zuul原理图:
post阶段抛异常会再次进入error阶段,然后结束
*spring-cloud使用zuul
依赖:spring-cloud-starter-zuul、httpclient
@EnableZuulProxy 启动zuul
微服务启动顺序:eureka-server>应用>zuul
*zuul的路由配置(default代表自定义名称)
zuul: #简单路由
routes:
default:
path:/default/**
url: https://www.xxx.com
zuul: #跳转路由
routes:
default:
path:/default/**
url:forward:/
zuul: #ribbon路由
routes:
default:
path:/default/**
serviceId: #eureka实例名
zuul: #忽略路由
ignoredPatterns: #此处配置的url无法被访问
routes:
default:
path:/default/**
serviceId: #eureka实例名
*zuul整合hystrix
当调用集群中的路由出错,或超时可以使用zuul的容错机制。
需要实现ZuulFallbackProvider接口的fallBackResponse方法来实现zuul的回退逻辑, getRoute()方法返回需要使用该回退逻辑的serviceId,如果要全局使用该回退逻辑,getRoute()方法返回 "*"即可,最后需要把ZuulFallbackProvider的实现注入spring的bean容器中
*zuul过滤器
Zuul过滤器的父类abstract class ZuulFilter
zuul过滤器的几种类型
pre类型,路由前执行
route类型,路由时执行
error类型,pre或route之后执行,post之前执行
*zuul动态过滤器
可以使用Groovy
核心API:
FilterLoader.getinstance() .setCompiler(new GroovyCompiler()); //开启groovy编译功能
*zuul动态路由
自定义一个模板类继承SimpleRouteLocator
重写SimpleRouteLocator.locateRoutes()方法加载路由
自定义一个方法refreshDefault()刷新路由,方法内super.doRefresh();
暴露接口调用refreshDefault()即可实现动态刷新路由