版本:SpringCloud 格林威治

目录

SpringCloud基础

什么是软件架构?

​编辑软件架构类型:(根据产品来进行如何选择架构)

微服务架构:

SpringCloud优缺点:

为什么选择SpringCloud作为微服务框架的解决方案?

SpringCloud Netflix五大组件:Euraka,Ribbon,Feign,Hystrix,Zuul

Eureka注册中心

Ribbon实现负载均衡策略

Feign负载均衡

Hystrix(黑吹死)

Zuul路由网关


SpringCloud基础

什么是软件架构?

软件架构是软件产品的灵魂

应用架构发展演变

软件架构类型:(根据产品来进行如何选择架构)

1.单体应用 (例:jsp+javabean)

2.基于mvc三层架构

3.分布式架构开发

4.基于SOA(面向服务编程)架构开发

5.微服务架构开发

最流行的两大服务架构:Dubbo和SpringCloud

Dubbo一般和Zookeeper注册中心联合使用————服务治理开发框架(阿里发明)

当当扩展后:Dubbox+Zookeeper

SpringCloud微服务架构开发

微服务架构:

定义:微服务架构是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分为一组小的服务,每个 服务运行在其独立的自己的进程中,服务之间相互协调、互相配合,为用户提供最终价值。服务之间采 用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API),每个服务都围绕着具体的业务进行构建,并且能够被独立的构建在生产环境、类生产环境等。另外,应避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务,可以使用不同的语言来编写服务,也可以使用不同的数据存储。

技术维度理解:微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底的去耦合,每个微服务提供单个业务功能的服务,一个服务做一件事,从技术角度看就是一种小儿独立的处理过程。

微服务:强调是服务的大小,它关注的是某一个点,是具体解决某一个问题而提供落地对应服务的一个服务应用。

SpringBoot是为了独立开发微服务,springCloud是微服务治理(协调)框架

SpringCloud优缺点:

优点:

  1. 每个服务足够内聚,足够小,代码容易理解这样的能聚集一个指定的业务功能或业务需求
  2. 开发简单,效率高,一个服务可能就是专一的只做一件事
  3. 微服务是松耦合,由功能意义的服务,无论是开发阶段还是部署阶段都是独立的
  4. 微服务能使用不同的语言开发——跨语言
  5. 易于与第三方继承,微服务允许容易以灵活的方式集成自动部署,通过持续集成工具。Docker+Jenkins
  6. 微服务易于被一个开发人员立即修改和维护,这样小团队能够更关注自己的工作成果,无需合作才能体现价值

缺点:

  1. 开发人员要处理分布式系统的复杂性
  2. 多服务运维难度,随着服务数量增加,运维压力也在增大
  3. 系统部署依赖
  4. 服务间通信成本
  5. 数据一致性
  6. 系统集成测试
  7. 性能监控

微服务架构并不是完美的!需要在项目的需求分析下来进行规划整体的架构。

SpringCloud提供了一站式微服务架构

Dubbo是半自动,SpringCloud是全自动。

为什么选择SpringCloud作为微服务框架的解决方案?

  • 整体解决方案和框架成熟度
  • 社区热度(spring在java有很大的影响)
  • 可维护性
  • 学习曲线

当前互联网公司微服务架构有哪些?

阿里:Dubbo/HSF

京东:JSF

新浪微博:Motan

当当网:Dubbox

阿里云:SpringCloud

SpringCloud Netflix五大组件:Euraka,Ribbon,Feign,Hystrix,Zuul

Eureka注册中心

Netfilx在设计eureka时,遵循的就是AP原则

Eureka集群策略

本地:

在c://windows/system32/driver/etc/hosts目录中添加

在项目中创建多个eureka并分配

集群:相当于将多个服务器环境捆绑在一起统一向外提供服务

常见集群环境:Eureka集群环境,Tomcat集群环境,MySql集群环境,Solr集群环境…

集群主要是为了解决高可抗,高并发,高负载场景

CAP原则(CAP定理):
CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。

在微服务架构中是不能同时满足CAP原则的,所i有Eureka和Zookeeper的区别就在这里。

Zookeeper保证的是CP原则 可用性降低

当向注册中心查询服务列表时,可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down掉不可用。

Eureka保证的是AP原则 一致性降低

Eureka看明白了这一点,因此在设计时将优先保证可用性。Eureka各个节点都是平等的,几个节点挂掉不会影响正常节点工作,剩余的节点依然可以提供注册和查询服务。通过Eureka自我保护机制+心跳检查确保微服务高可用。

CAP原则是NOSQL数据库的基石。Consistency(一致性)。 Availability(可用性)。Partition tolerance(分区容错性)。

分布式系统的CAP理论:理论首先把分布式系统中的三个特性进行了如下归纳:
一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
定理:任何分布式系统只可同时满足二点,没法三者兼顾。
架构师不要将精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍
实践:
比如现在有三台机器:Server1、Server2和Server3.在高可用方案中,三台机器要两两注册。比如S1要向S2、S3分别进行注册,目前他无法实现注册的传递性。 这样一来,如果Server1宕机,我们还可以继续从Server2和3中获取服务。
在CAP理论中,zookeeper更看重C和P,即一致性和分区容错性。但Eureka更在意的是A和P,A为高可用。zookeeper中有master和follower区别,当进入选举模式时,就无法正常对外提供服务。但Eureka中,集群是对等的,地位是相同的,虽不能保证一致性,但至少可以提供注册服务。 根据不同的业务场景,具体分析使用。

Ribbon实现负载均衡策略

负载均衡的前提是需要集群环境

什么是负载均衡? 就是将请求分摊在不同的服务器上进行处理

LB即负载均衡,在微服务或分布式集群中常用的一种fuz

负载均衡就是将请求分摊在不同的服务器上进行处理,从而达到高可用

常见的负载均衡软件有Nginx+Tomcat搭建集群环境,Lvs(linux虚拟化服务)等等

dubbo(服务治理开发框架),springcloud(微服务架构开发)中均给我提供了负载均衡

分类:

软负载

1.集中式LB

就是在服务的消费方和提供方之间使用独立的LB设施,如Nginx,由该设施负责把访问请求通过某种策略转发至服务的提供方

2.进程式LB

1.将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器。

2Ribbon就属于进程内LB,她只是一个类库,集成与消费方进程,消费方通过它来获取到服务提供方。

硬负载(采购负载均衡服务器)

Ribbon默认是使用轮询规则实现负载均衡

通过Ribbon实现负载均衡策略的步骤:

1.pom

org.springframework.cloudspring-cloud-starter-ribbon1.4.6.RELEASE

2.在RestTemplate的Bean上添加@LoadBalance注解

Feign负载均衡

简介

Feign主要是社区,大家都习惯面向接口编程。这个是很多开发人员的规范。调用微服务的两种方法:1.Ribbon(RestTemplate) 2.Feign

Feign的作用?

1.Feign使编写java http客户端变得更容易

2.在使用Ribbon+Rest Template时,利用RestTemplate对http请求的封装处理,形成了一套模板化的调用方法。但在实际开发中,由于服务以来的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了一些封装,由他来帮助我们定义和实现依赖服务接口的定义,在Feign的实现下,我们之需要创建一个接口并使用注解的方式来配置它(类似于以前Dao接口上标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可)即可完成对服务提供方的接口绑定,简化了使用springCloud Ribbon时,自动封装服调用客户端的开发量。

Feign实现步骤:

1.pom api模块和消费方导入依赖

org.springframework.cloudspring-cloud-starter-feign1.4.6.RELEASE

2.在api添加实体Client

@Component@FeignClient(value = "DEMOSPRINGCLOUDPROVIDER-8080")public interface UserClient {@GetMapping("/get")List get();}

3.在消费者修改Controller

@Resourceprivate UserClient userClient;@GetMapping("/getUser")public List get(){return userClient.get();}

Hystrix(黑吹死)

服务雪崩效应

分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。如下图

如果各个服务正常运行,那大家齐乐融融,高高兴兴的,但是如果其中一个服务崩坏掉会出现什么样的情况呢?如下图

当Service A的流量波动很大,流量经常会突然性增加!那么在这种情况下,就算Service A能扛得住请求,Service B和Service C未必能扛得住这突发的请求。
此时,如果Service C因为抗不住请求,变得不可用。那么Service B的请求也会阻塞,慢慢耗尽Service B的线程资源,Service B就会变得不可用。紧接着,Service A也会不可用。

一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩。

在对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内保和,比失败更糟的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障,这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。

引起雪崩的原因和服务雪崩的三个阶段
原因大致有四:
1、硬件故障;
2、程序Bug;
3、缓存击穿(用户大量访问缓存中没有的键值,导致大量请求查询数据库,使数据库压力过大);
4、用户大量请求;

服务雪崩的第一阶段: 服务不可用;
第二阶段:调用端重试加大流量(用户重试/代码逻辑重试);
第三阶段:服务调用者不可用(同步等待造成的资源耗尽);

解决方案
1) 应用扩容(扩大服务器承受力)

加机器,升级硬件
2)流量控制(超出限定流量,返回类似重试页面让用户稍后再试)

限流,关闭重试
3) 缓存

将用户可能访问的数据大量的放入缓存中,减少访问数据库的请求。

4)服务降级

服务接口拒绝服务,页面拒绝服务,延迟持久化,随机拒绝服务
5) 服务熔断

什么是Hystrix?

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统中,许多依赖不可避免的会调用失败,比如超时,异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

”断路器“本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控,向调用方返回一个服务预期的,可处理的备选相应【fallback】,而不是长时间的等待或抛出调用的方法无法处理的异常,这样就可以保证了服务调用方的线程不会被长时间,不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

什么是服务熔断:熔断机制是对应雪崩效应的一种微服务链路保护机制。

当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现,Hystrix会监控微服务之间的调用情况,当失效的调用到一定的阈值,缺省5秒内20次调用失败就会启动熔断机制。熔断机制的注解时@HystrixCommand

服务降级:关闭不需要的微服务。

使用步骤:

1.在微服务添加pom

org.springframework.cloudspring-cloud-starter-hystrix1.4.6.RELEASE

2.在消费者main添加注解@EnableDiscoveryClient @EnableCircuitBreaker

@SpringBootApplication@EnableEurekaClient@EnableFeignClients(basePackages = {"cn.pro.api.service"})@EnableDiscoveryClient@EnableCircuitBreakerpublic class Demo1ConsumerApplication {public static void main(String[] args) {SpringApplication.run(Demo1ConsumerApplication.class,args);}}

3.在微服务启动类添加注解@EnableHystrix

4.在微服务中的接口设置

@RestControllerpublic class UserController {@GetMapping("/get")@HystrixCommand(fallbackMethod = "getByFallBack")public List get() throws Exception{List list= new ArrayList();list.add(new User(1001,"大娃",12));list.add(new User(1001,"大娃",12));list.add(new User(1001,"大娃",12));list.add(new User(1001,"大娃",12));if (list.size() != 0){throw new Exception("出错啦,进入雪崩");}return list;}public List getByFallBack(){List list= new ArrayList();list.add(new User(1001,"出错啦",12));list.add(new User(1001,"出错啦",12));list.add(new User(1001,"出错啦",12));list.add(new User(1001,"出错啦",12));return list;}}

Zuul路由网关

什么是Zuul:Zuul包含对请求的路由和过滤两个最主要的功能

Zuul服务最终还是会注册进Eureka

Zuul的作用:请求路由,请求过滤

网关步骤:

1.创建maven项目,导入pom

junitjunit4.11testorg.springframework.bootspring-boot-starter-weborg.projectlomboklombokcn.prodemo1-api1.0-SNAPSHOTcompileorg.springframework.cloudspring-cloud-starter-eureka1.4.6.RELEASEorg.springframework.cloudspring-cloud-starter-hystrix1.4.6.RELEASEorg.springframework.cloudspring-cloud-starter-zuul1.4.6.RELEASE

2.在启动类添加注解@EnableZuulProxy //开启网关代理

@SpringBootApplication@EnableZuulProxy //开启网关代理public class Demo1ZuulApplication {public static void main(String[] args) {SpringApplication.run(Demo1ZuulApplication.class,args);}}

3.在application.yml设置

server:port: 5050spring:application:name: demo1-zuuleureka:client:service-url:defaultZone: http://eureka7070:7070/eureka,http://eureka7071:7071/eureka,http://eureka7072:7072/eurekazuul:routes:provider8080.serviceId: DEMOSPRINGCLOUDPROVIDER-8080provider8080.path: /user/**