首先谈一下spring框架:springboot构建一切,springcloud连接一切。springcloud我认为主要是实现分布式,过个项目(服务)之间可以通过springcloud进行连接。
SpringBoot和SpringCloud之间的关系:
SpringBoot主要是构建项目,springboot的核心就是约定大于配置,专注于构建每个服务;
SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务,整合并管理起来;
SpringBoot可以离开SpringCloud单独使用,但是SpringCloud离不开SpringBoot。
谈到SpringCloud就离不开微服务。微服务主要是将一个项目中的各个功能或者模块抽象成一个服务,每个服务都可以单独的运行。之间的项目是all in one,所有的项目功能都在一个模块里面,只要有一个功能崩溃,那整个项目就崩溃,这种的耦合程度非常高;但是微服务达到了解耦的目的,各个服务抽象出来,一个服务崩溃,其他的服务还是可以运行。
那实现微服务就有以下几个问题:
这么多服务,客户端怎么访问
这么多服务,服务之间怎么通信
这么多服务,怎么治理服务
服务崩溃的问题
下面就是针对上面四个问题spring cloud netfix提出的解决方案
路由网关就是解决客户端访问服务的问题。SpringCloud当中是Zuul网关,主要是对客户端的请求进行路由和过滤。
概念:主要是对客户端请求的路由和过滤
有一个统一的访问地址,用gateway实现请求的路由(管理这些微服务)。
路由:将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础,
过滤:负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能的基础。
举个例子:
原来访问一个服务是:http://localhost:8001/dept/get/1(地址)
加了zuul网关之后:http://www.study.com:9527/springcloud-provider-dept/dept/get/1 www.cspStudy.com:9527前面是losthost的换了一种名字(在电脑的host里面改),后面的9527是端口号,springcloud-provider-dept是微服务的名字,后面的就是controller写的访问地址
但是这里没有配置zuul所有暴露出了微服务的名字
根据配置zuul之后:http://www.study.com:9527/haust/mydept/dept/get/1(/haust是统一前缀,/mydept替代了前面的微服务的名字)
//路由相关配置
//原来访问路由 eg:http://www.study.com:9527/springcloud-provider-dept/dept/get/1
//zull路由配置后访问路由 eg:http://www.study.com:9527/haust/mydept/dept/get/1
routes:
mydept.serviceId: springcloud-provider-dept # eureka注册中心的服务提供方路由名称
mydept.path: /mydept/** # 将eureka注册中心的服务提供方路由名称 改为自定义路由名称
//不能再使用这个路径访问了,*: 忽略,隐藏全部的服务名称~
ignored-services:
"*"
//设置公共的前缀(这是统一的前缀)
prefix: /haust
Ribbon和Feign两者都是实现负载均衡(LoadBalancer)。那负载均衡是什么?其实就是分配访问服务器,当存在很多个客户端请求,负载均衡可以实现将请求分散给各个服务器,不让一个服务器承受压力。Ribbon是基于Restful风格,利用restTemplate进行处理;而feign是基于注解和接口编程,更加符合java编程的习惯。
Ribbon:
Step1:新建一个配置类:
@Configuration public class ConfigBean { @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
Step2:在controller中利用微服务名字进行访问
@RestController public class DeptConsumerController { /*** * 消费者不需要service层 * RestTemplate模板我们直接调用 * (url,实体,responseType) */ @Autowired private RestTemplate restTemplate; //提供多种便捷访问远程http服务的方法 private static final String REST_URL_PREFIX="http://localhost:8001"; @RequestMapping("/consumer/dept/get/{id}") public Dept get(@PathVariable("id") int id){ return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get"+id,Dept.class); } @RequestMapping("/consumer/dept/add") public boolean add(Dept dept){ return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class); } @RequestMapping("/consumer/dept/list") public List
getAll(){ return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class); } }
Feign:
Step1:写一个接口DeptConsumerClient
// @FeignClient:微服务客户端注解,value:指定微服务的名字,这样就可以使Feign客户端直接找到对应的微服务 @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT") public interface DeptClientService { @GetMapping("/dept/get/{id}") public Dept queryById(@PathVariable("id") Long id); @GetMapping("/dept/list") public Dept queryAll(); @GetMapping("/dept/add") public Dept addDept(Dept dept);
Step2:在controller层中直接调用
@RestController public class DeptConsumerController { @Autowired private DeptClientService deptClientService; /** * 消费方添加部门信息 * @param dept * @return */ @RequestMapping("/consumer/dept/add") public boolean add(Dept dept) { return deptClientService.addDept(dept); } /** * 消费方根据id查询部门信息 * @param id * @return */ @RequestMapping("/consumer/dept/get/{id}") public Dept get(@PathVariable("id") Long id) { return deptClientService.queryById(id); } /** * 消费方查询部门信息列表 * @return */ @RequestMapping("/consumer/dept/list") public List
list() { return deptClientService.queryAll(); } }
Euraka主要是为了解决服务之间治理的问题。Euraka是一个服务注册中心,所有的服务都需要在Euraka中注册。
系统中的其他微服务:使用Euraka的客户端连接到EurakaServer并维持心跳连接,可以通过EurakaServer监控系统中的各个微服务是否正常运行。
两个组件:Eureka Server 和 Eureka Client.
Eureka Server: 提供服务注册,各个节点启动后,回在EurekaServer中进行注册,这样Eureka Server中的服务注册表中将会储存所有课用服务节点的信息,服务节点的信息可以在界面中直观的看到.
Eureka Client :一个Java客户端,用于简化EurekaServer的交互,客户端同时也具备一个内置的,使用轮询负载算法的负载均衡器。在应用启动后,将会向EurekaServer发送心跳 (默认周期为30秒) 。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除掉 (默认周期为90s).
EureKa自我保护机制:
某时刻某一个微服务不可用,eureka不会立即清理,依旧会对该微服务的信息进行保存!(该保护机制的目的是避免网络连接故障,在发生网络故障时,微服务和注册中心之间无法正常通信,但服务本身是健康的,不应该注销该服务,保护机制就先不注销该服务)
对比Zookeeper:
CAP理论:一致性、可用性、分区容忍性
zookeeper:主要是保证CP原则(主要是保证了一致性)
eureka:主要是保证AP原则(主要是保证可用性)
Hystrix主要是解决服务挂了的问题。主要就是服务崩溃或者访问有错后,客户不会有什么异常,就算后端在报错,但是前端不会报错,会出现相应的提示信息(比如为空等等)
服务雪崩:分布式系统中有多个服务器,出现服务器崩溃的现象(可能出现一个服务崩溃导致整个分布式系统都出现崩溃的情况)
Hystrix保证一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障
作用:服务降级、服务熔断、服务限流、接近实时的监控
Hystrix机制:与保险丝类似:当某个服务单元发生故障之后,通过断路器的故障监控 (类似熔断保险丝) ,向调用方返回一个服务预期的,可处理的备选响应 (FallBack) ,而不是长时间的等待或者抛出调用方法无法处理的异常,这样就可以保证了服务调用方的线程不会被长时间,不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。(调用备份)
一定阀值缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是:@HystrixCommand
其中重要的部分是服务熔断和服务降级。
服务熔断:走备选方法:(在服务端写的) 某个服务超时或者异常
服务降级:把系统资源让给优先级高的服务,将其他服务关闭(比如双11的时候关闭查看历史订单、关闭退款功能)(在客户端写的) 从整体网站请求负载考虑,客户还是可以发请求,但是这个服务不走服务器