springcloud微服务架构快速上手

目录

springcloud全家桶 学习笔记

1.什么是微服务

  • 官方定义:微服务就是由一系列围绕自己业务开发的微小服务构成,他们独立部署运行在自己的进程里,基于分布式的管理
  • 通俗定义:微服务是一种架构,这种架构是将单个的整体应用程序分割成更小的项目关联的独立的服务。一个服务通常实现一组独立的特性或功能,包含自己的业务逻辑和适配器。各个微服务之间的关联通过暴露api来实现。这些独立的微服务不需要部署在同一个虚拟机,同一个系统和同一个应用服务器中。

2.为什么是微服务?

在这里插入图片描述

  1. 优点
  • 单一架构模式在项目初期很小的时候开发方便,测试方便,部署方便,运行良好。
  1. 缺点
  • 应用随着时间的推进,加入的功能越来越多,最终会变得巨大,一个项目中很有可能数百万行的代码,互相之间繁琐的jar包。
  • 久而久之,开发效率低,代码维护困难
  • 还有一个如果想整体应用采用新的技术,新的框架或者语言,那是不可能的。
  • 任意模块的漏洞或者错误都会影响这个应用,降低系统的可靠性

微服务架构应用

  1. 优点
  • 将服务拆分成多个单一职责的小的服务,进行单独部署,服务之间通过网络进行通信
  • 每个服务应该有自己单独的管理团队,高度自治
  • 服务各自有自己单独的职责,服务之间松耦合,避免因一个模块的问题导致服务崩溃
  1. 缺点
  • 开发人员要处理分布式系统的复杂性
  • 多服务运维难度,随着服务的增加,运维的压力也在增大
  • 服务治理 和 服务监控 关键

架构的演变

  1. 架构的演变过程
    [单一应用架构] ===> [垂直应用架构] ===> [分布式服务架构] ===> [流动计算架构]||[微服务架构] ===> [未知]

在这里插入图片描述

1. All in One Application 单一架构

  • 起初当网站流量很小时,将所有功能都写在一个应用里面,对整个应用进行部署,以减少部署节点和成本。对于这个架构简化增删改查的工作量的数据访问框架(ORM)是关键。

2. Vertical Application 垂直架构

  • 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,提升效率的方法之一是将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。

3. Distributed Service 分布式服务架构

  • 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC)是关键。

4. Elastic Computing 流动计算架构即微服务架构

  • 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键

3.微服务的解决方案

1.Dubbo (阿里系)

  • 初出茅庐:2011年末,阿里巴巴在GitHub上开源了基于Java的分布式服务治理框架Dubbo,之后它成为了国内该类开源项目的佼佼者,许多开发者对其表示青睐。同时,先后有不少公司在实践中基于Dubbo进行分布式系统架构,目前在GitHub上,它的fork、star数均已破万。Dubbo致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案,使得应用可通过高性能RPC实现服务的输出、输入功能和Spring框架无缝集成。Dubbo包含远程通讯、集群容错和自动发现三个核心部分。

  • 停止维护:从2012年10月23日Dubbo 2.5.3发布后,在Dubbo开源将满一周年之际,阿里基本停止了对Dubbo的主要升级。只在之后的2013年和2014年更新过2次对Dubbo
    2.4的维护版本,然后停止了所有维护工作。Dubbo对Srping的支持也停留在了Spring 2.5.6版本上。

  • 死而复生:多年漫长的等待,随着微服务的火热兴起,在国内外开发者对阿里不再升级维护Dubbo的吐槽声中,阿里终于开始重新对Dubbo的升级和维护工作。在2017年9月7日,阿里发布了Dubbo的2.5.4版本,距离上一个版本2.5.3发布已经接近快5年时间了。在随后的几个月中,阿里Dubbo开发团队以差不多每月一版本的速度开始快速升级迭代,修补了Dubbo老版本多年来存在的诸多bug,并对Spring等组件的支持进行了全面升级。

  • 2018年1月8日,Dubbo创始人之一梁飞在Dubbo交流群里透露了Dubbo 3.0正在动工的消息。Dubbo 3.0内核与Dubbo 2.0完全不同,但兼容Dubbo 2.0。Dubbo 3.0将以Streaming为内核,不再是Dubbo 时代的RPC,但是RPC会在Dubbo
    3.0中变成远程Streaming对接的一种可选形态。从Dubbo新版本的路线规划上可以看出,新版本的Dubbo在原有服务治理的功能基础上,将全面拥抱微服务解决方案。

  • 结论:当前由于RPC协议、注册中心元数据不匹配等问题,在面临微服务基础框架选型时Dubbo与Spring Cloud是只能二选一,这也是为什么大家总是拿Dubbo和Spring
    Cloud做对比的原因之一。Dubbo之后会积极寻求适配到Spring Cloud生态,比如作为Spring
    Cloud的二进制通信方案来发挥Dubbo的性能优势,或者Dubbo通过模块化以及对http的支持适配到Spring Cloud。

在这里插入图片描述

Spring Cloud:

  • Spring Cloud NetFlix 基于美国Netflix公司开源的组件进行封装,提供了微服务一栈式的解决方案。

  • Spring Cloud alibaba 在Spring cloud netflix基础上封装了阿里巴巴的微服务解决方案。

  • Spring Cloud Spring 目前spring官方趋势正在逐渐吸收Netflix组件的精华,并在此基础进行二次封装优化,打造spring专有的解决方案。

4.什么是SpringCloud

4.1 定义

1.官方定义

官方网址:

https://cloud.spring.io/spring-cloud-static/Hoxton.SR5/reference/html/

springcloud为开发人员提供了在分布式系统中快速构建一些通用模式的工具(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线)
2. 通俗定义
springcloud含有众多子项目的工具集 tools collection 微服务工具集合

4.2.微服务

基于单体基于业务进行拆分,每个服务都是独立的应用 独立部署 运行在自己计算机进程 对于这些服务都是分布式管理

5.核心架构及其组件

1.核心组件说明

  • eurekaserver、consul、nacos 服务注册中心组件
  • rabbion & openfeign 服务负载均衡 和 服务调用组件
  • hystrix & hystrix dashboard 服务断路器 和 服务监控组件
  • zuul、gateway 服务网关组件
  • config 统一配置中心组件
  • bus 消息总线组件 …

在这里插入图片描述

6.环境搭建

  1. 版本选择官方建议

https://spring.io/projects/spring-cloud

  • Angel 版本基于springboot1.2.x版本构建与1.3版本不兼容
  • Brixton 版本基于springboot1.3.x版本构建与1.2版本不兼容 `2017年Brixton and Angel release官方宣布报废
  • Camden 版本基于springboot1.4.x版本构建并在1.5版本通过测试 `2018年Camden release官方宣布报废
  • Dalston、Edgware 版本基于springboot1.5.x版本构建目前不能再springboot2.0.x版本中使用
    `Dalston(达尔斯顿)将于2018年12月官方宣布报废。Edgware将遵循Spring Boot 1.5.x的生命周期结束。
  • Finchley 版本基于springboot2.0.x版本进行构建,不能兼容1.x版本
  • Greenwich 版本基于springboot2.1.x版本进行构建,不能兼容1.x版本
  • Hoxton 版本基于springboot2.2.x版本进行构建

Spring Cloud Dalston、Edgware、Finchley 和 Greenwich 都已达到生命周期结束状态,不再受支持。
在这里插入图片描述
2. 版本选择

  • springboot 2.2.5.RELEASE
  • springcloud Hoxton.SR6
  • jdk1.8
  • maven 3.3.6
  • idea 2020.1
  1. 环境搭建
  2. 创建springbootcloud_parent
  3. 在pom.xml添加如下代码
<!--继承springboot的父项目-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>


<!--自定义properties属性-->
    <properties>
        <spring.cloud-version>Hoxton.SR6</spring.cloud-version>
    </properties>
<!--    维护版本-->
    <dependencyManagement>
        <dependencies>
<!--            维护springcloud版本依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
  1. 完成上述操作springboot与springcloud环境搭建完成,接下来就是使用到具体的springcloud组件,在项目中引入具体的组件即可

7.eureka服务注册中心

  1. 服务注册中心组件
    定义:服务注册中心就是在整个微服务架构单独抽取一个服务,这个服务不完成项目中任何业务功能,仅仅用来在微服务中记录微服务以及对整个系统微服务进行健康状态检查,以及服务元数据信息存储
  • 可以对所有的微服务的信息进行存储,如微服务的名称、IP、端口等
  • 可以在进行服务调用时通过服务发现查询可用的微服务列表及网络地址进行服务调用
  • 可以对所有的微服务进行心跳检测,如发现某实例长时间无法访问,就会从服务注册表移除该实例。

在这里插入图片描述
2.服务注册中心组件开发
常用注册中心组件:eureka (netflix) 、 zookeeper (java) 、consul (co) 、nacos (java阿里巴巴)
3.eureka
简化:eureka是Netflix开发的服务发现框架 springcloud-netflix-eureka 服务注册中心 Eureka
Eureka包含两个组件: Eureka server和Eureka client

8.开发Eureka Server 服务注册中心

a.创建springboot子项目

b.引入eureka server依赖

<!--引入 eureka server-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

c.编写配置文件

#eureka server 端口号 默认就是8761
server.port=8761
#指定服务名称 唯一标识  注意:服务名不能出现下划线_ 默认服务名不区分大小写 推荐服务名大写
spring.application.name=eurekaserver
#指定服务注册中心的地址  暴露服务地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka

d.在入口类加入注解

@EnableEurekaServer //开启当前应用是一个服务中心

e.访问Eureka的服务注册页面

http://localhost:8761/eureka

f.在eureka server启动过程中报错:

在这里插入图片描述
出错解释:eureka 含有两个组件 eureka server、eureka client组件,当项目中引入eureka server 组件时,这个组件同时将eurekaclient引入到项目中,因此启动时即会将自己作为一个服务中心启动,同时也会将自己作为服务客户端进行注册,默认启动时立即注册,注册时服务还有没有准备完成因此会出现当前错误

g.如何关闭eureka server 自己注册自己

#关闭eureka client立即注册
eureka.client.fetch-registry=false
#让当前应用仅仅是服务注册中心
eureka.client.register-with-eureka=false

h.eureka client 开发

1. 开发eureka client就是日后基于业务拆分出来一个个微服务
2. 在父目录右键Module创建完成springboot应用 springcloud_02eureak_client
3. 在创建项目中引入eureka client相关依赖
<dependencies>
       <!--引入springboot-->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <!--引入eureka client-->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
       </dependency>
   </dependencies>
4.编马配置application.properties
#指定服务端口
server.port=9999
#指定服务名
spring.application.name=EUREKACLIENT
#指定服务注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
5.在入口类加入注解
@EnableEurekaClient     //让当前微服务作为一个eureka server客户端 进行服务注册

i.eureka自我保护机制

  1. 服务频繁启动时 EurekaServer出现错误
    在这里插入图片描述
  2. 自我保护机制 (self Preservation Mode)

注意:自我保护机制默认是开启的
现象:在自我保护模式下,eureka服务器将停止逐出所以实例。
机制:这样做是为了确保灾难性的网络事件不会清除eureka注册表数据,并将其传播到下游的所有客户端,触发自我保护机制
什么时候将客户端在服务注册中清除

  • 心跳的次数高于预期阈值
  • 自我保护被禁用
  1. eureka server 关闭自我保护机制
eureka.server.enable-self-preservation=false  #关闭自我保护
eureka.server.eviction-interval-timer-in-ms=3000 # 超时3s自动清除 60*1000 1分钟
  1. 客户端
eureka.instance.lease-expiration-duration-in-seconds=10  #用来修改eureka server默认接受心跳的最大时间默认是90s
eureka.instance.lease-renewal-interval-in-seconds=5 #指定客户端多久向eureka server发送一次心跳默认是30s
  1. 关闭自我保护机制官方不推荐关闭时 同样发出警告
    在这里插入图片描述
    j.eureka server 集群搭建

1.集群搭建
2.完全集群
a.创建3个springboot项目
b.引入 eureka server依赖
c 配置文件 application.properties
node1

server.port:8761
#指定服务注册中心的地址  暴露服务地址
eureka.client.service-url.defaultZone=http://127.0.0.1:8762/eureka,http://127.0.0.1:8763/eureka

node2

server.port:8761
#指定服务注册中心的地址  暴露服务地址
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka,http://127.0.0.1:8763/eureka

node3

server.port:8761
#指定服务注册中心的地址  暴露服务地址
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka,http://127.0.0.1:8762/eureka

在这里插入图片描述
d.在每个项目入口类加入

@EnableEurekaServer //开启当前应用是一个服务中心

9.consul 服务注册中心

1.springc loud netflix eureka

作用:微服务架构充当服务注册中心
两个角色: 服务注册中心、 微服务

2.服务注册中心组件

eureka(ui界面) 、 zookeeper (java shell查看服务注册)、consul (ui) . nacos (ui)

3 . consul服务注册中心

简介:consul基于go语言进行开发服务注册中心轻量级服务注册中心 google
作用:管理微服务中所有服务注册发现管理服务元数据信息存储(服务名地址列表)心跳健康检查

4 . consul服务注册中心安装

a.下载consul
consul官网下载
b.在指定目录进行解压缩注意:不建议目录中含有中文
C:\Users\92092\Desktop\文件\consul\consul.exe
c.启动服务注册中心

  • 在consul安装目录中打开cmd
  • 输入命令:consul agent -dev

d.访问consul管理界面
http:端口默认8500浏览器: localhost:8500
e.管理界面基本介绍
dc1:数据中心名称 datacenter 默认为:dc1
指定数据中心启动consul agent -dev -datacenter=abc

services:当前consul服务中注册服务列表︰默认:client server同时启动自己注册自己会出现一个consul服务nodes:用来查看consul的集群节点
f:推荐写个bat文件执行

10.consul client 服务客户端

  1. 创建独立springboot应用
  2. 引入consul和web依赖
     <!--web-->
    <dependencies>
    <dependency>       <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

        <!--consul client-->
        <dependency>           <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>      
  1. 编写application.properties
server.port=9999
#指定服务名称
spring.application.name=ORDERS

# consul server 服务注册地址
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500
  1. 在入口类上加入注解
@SpringBootApplication  //代表这是一个springboot入口应用
@EnableDiscoveryClient  //作用:通用服务注册客户端注解代表consul client zkclient nacos client
  1. 直接启动consul client 出现如下问题
    在这里插入图片描述
    原因:consul server 检测所有客户端心跳,
    但是发送心跳时client必须给予响应该服务才能正常使用在现有客户端中我们并没有引入健康检查依赖,
    所以导致健康检查始终不能通过,导致服务不能使用

解决:

<!-- 健康检查依赖 actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

11.微服务间通信

1.什么是微服务

定义:基于单体应用围绕业务进行服务拆分,拆分出来每一个服务独立应用独立运行独立都署运行在自己计算机进程中基于分布式服务管理

2.如何解决微服务的服务间通信问题?

a.Http Rest 方式 使用http协议进行数据传输 JSON (spring cloud 使用HTTP协议传递数据)
b.RPC 方式 远程过程调用 二进制
OST : 物理层 数据链路层 网络层 传输层(RPC) 会话层 表示层 应用层(Http)

3.如何在java代码中发起http方式请求?

a.spring框架提供Httpclient对象RestTemplate发起一个http请求

4.实现服务间通信写一个案列

a.开发两个测试服务用户服务users & 订单服务orders
b.用户服务 订单服务 都是两个独立springboot应用
c.两个服务都引入consul client 依赖 & 健康检查依赖

<!--web     -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--consul client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
<!--健康检查 actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

d.配置两个服务 application.properties
consul server 服务注册地址

spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500

e.在入口类加入服务注册 client注解

@SpringBootApplication  //代表这是一个springboot入口应用
@EnableDiscoveryClient  //作用:通用服务注册客户端注解代表consul client zkclient nacos client

12.使用RestTemplate对象实现服务间通信存在问题

a.在这里插入图片描述

  • 调用服务的路径主机和服务端口直接写死在url中无法实现服务集群时请求负载均衡
  • 调用服务的请求路径写死在代码中,日后提供服务服务路径发生变化时不利于后续维护工作

b.解决restTempalte负载均衡问题?
1.自定义负载均衡解决策略
问题:
1.1.无法实现服务健康检查
1.2.负载均衡策略过于单一(随机)
2.Ribbon springcloud-netflix-ribbon
作用:负载均衡客户端组件 就是用来实现请求调用时负载均衡

c.Ribbon负技均衡原理
在这里插入图片描述
通过源码得知Ribbon底层负载均衡策略父接口IRule父接口,在这个父接口中提供很多负载均衡策略轮询 随机 根据响应时间加权 默认是轮询
在这里插入图片描述

d.使用Ribbon+RestTemplate实现请求负载均衡
1.使用用户调用订单服务用户服务中引入ribbon依赖
注意:
consul client依赖中已经存在ribbon相关依赖无需项目中显示引入

    @Autowired     //服务注册与发现客户端对象
    private DiscoveryClient discoveryClient;

    @Autowired    //负载均衡客户端对象
    private LoadBalancerClient loadBalancerClient;

使用discovery Client形式调用+RestTemplate
原理:
服务发现客户端对象根据服务id去服务注册中心获取对应服务服务列表到本地中
缺点:没有负载均衡需整自己实现鱼载均衡

        //获取服务集合
        List<ServiceInstance> orders1 = discoveryClient.getInstances("ORDERS");

使用loadBalance Client形式调用+RestTemplate
原理:
负载均衡客户端对象根据服务id去服务注册中心获取对应服务列表,根据默认负载均衡策略选择列表中一台机器进行返回
缺点:
使用时需要每次先根据服务id获取一个负载均衡机器之后再通过restTemplate调用服务

根据负载均衡策略选取某一个服务调用
        ServiceInstance orders2 = loadBalancerClient.choose("ORDERS");

使用@loadBalanced+RestTemplate
缺点:路径写死在代码中不利于维护

//1.整合restTemplate + ribbon

修饰范围:用在方法上作用:让当前方法当前对象具有ribbon负载均衡特性
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
  return new RestTemplate();
}
//2.调用服务位置注入RestTemplate
@Autowired
private RestTemplate restTemplate;
//3.调用
String forObject = restTemplate.getForObject("http://ORDERS/order", String.class);
log.info("order响应信息: {}",forObject);

13.OpenFeign组件

1.为什么使用OpenFeign

  • 每次调用服务都需要写这些代码,存在大量的代码冗余
  • 服务地址如果修改,维护成本增高
  • 使用时不够灵活

2.什么Feign组件----->openFeign组件
历史: Feign (Netflix)---->维护状态---->SpringaCloud OpenFeign( spring) 这两个组件现在使用:特性使用方式—致
简介:

Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性(可以使用springmvc的注解),可使用Feign
注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,默认实现了负载均衡的效果并且springcloud为feign添加了springmvc注解的支持。

3.使用openFeign
3.1.创建两个springboot 服务 category product
3.2.引入依赖

<!--web     -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--consul client-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <!--健康检查 actuator-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

3.3.创建application.properties配置文件

server.port=8088
spring.application.name=CATEGORY

# consul server 注册中心
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500

3.4.在入口类加入注解开启OpenFeign支持

@SpringBootApplication  //代表这是一个springboot入口应用
@EnableDiscoveryClient  //作用:通用服务注册客户端注解代表consul client zkclient nacos client
@EnableFeignClients    //开启openFeign客户端调用
public class CategoryApplication {

    public static void main(String[] args) {
        SpringApplication.run(CategoryApplication.class,args);
    }
}

4.openFeign 服务使用
4.1.在服务调用方法中引入依赖OpenFeign依赖

<!--Open Feign依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

4.2.在category服务中创建一个客户端调用接口


```java
@FeignClient("PRODUCTS")
public interface ProductClient {
    @GetMapping("test")
    String test();
}

4.3.在category服务中使用feignClient客户端对象调用服务

@RestController
public class CategoryController {
    @Autowired   //注入客户端对象
    private ProductClient productClient;

    @GetMapping("category")
    public String test(){
        String p1 = productClient.test();
        return "test ok!"+p1;
    }
}

4.4.在product服务中

@RestController
public class ProductController {
    private static final Logger log = LoggerFactory.getLogger(ProductApplication.class);
    @GetMapping("test")
    public String test(){
        return "product ok!!";
    }
}

4.5.浏览器访问
http://localhost:8088/category
在这里插入图片描述

14.OpenFeign服务间通信之参数传递和响应处理

1.微服务架构中服务间通信手段
http协议: springcloud两种方式:
1.1.RestTeamplate + Ribbon
1.2.openFeign 推荐
2.服务间通信,参数传递和响应处理
参数传递:

  • 传递零散类型参数
  • 传递对象类型
  • 数组或集合类型参数

3.零散参数传递

@FeignClient("PRODUCTS")
public interface ProductClient {
    //test1?name=dasuan&age=18 @RequestParam方式 注意:注解必须要添加,由于openfeign底层是使用http传参,在这里必须要通过注解告诉openfeign底层该使用哪个方式去对参数处理
    @GetMapping("test1")
    String test1(@RequestParam("name") String name,@RequestParam("age") Integer age);
    //test2/1/dasuan  @PathVariable 方式
    @GetMapping("test2/{id}/{name}")
    String test2 (@PathVariable("id") Integer id,@PathVariable("name") String name);
}

4.对象参数传递
注意:

    //传递对象      @RequestBody 方式 application/json
    @GetMapping("test3")
    String test3(@RequestBody Product product);

5.数组参数传递
**注意:**在openFeign传递数组类型参数时必须在声明时使用@RequestPar am注解标识

 //传递一个数组类型 /test4?ids=21&ids=22
    @GetMapping("test4")
    String test4(@RequestParam("ids") String[] ids);

6.集合类型的参数接收
a.在openfeign中使用

//在openfeign中调用   /test5?ids=21&ids=22
    @GetMapping("/test5")
    String test5(@RequestParam("ids") String [] ids);

b.在被调用的服务中
定义用来接收集合类型的对象
在这里插入图片描述

//springmvc不能直接接受集合类型参数,如果想要接收集合类型参数必须将集合放入对象中,使用对象的方式接收才行
    //oo: oriented(面向)object(对象)面向对象
    //vo (value object):用来传递数据对象称之为值对象
    //dto: (data transfer (传输)object):数据传输对象
    @GetMapping("test5")
    public String test5(CollectionVo collectionVo){
            collectionVo.getIds().forEach(id->log.info("id:{}",id));
        return "test5 ok";
    }

7.模仿分页信息发送与接收
a.在openfeign中使用

@GetMapping("/test6")
Map<String, Object> tset6(@RequestParam("page") Integer page,@RequestParam("pageSize") Integer pageSize,@RequestParam("categoryId") Integer categoryId);

b.在被调用的服务中

@GetMapping("test6")
    public Map<String, Object> test6(Integer page,Integer pageSize,Integer categoryId){
        log.info("page:{}------pageSize:{}-----categoryId:{}",page,pageSize,categoryId);
      List<Product> list = new ArrayList();
      list.add(new Product(1,"大蒜",1999.8));
      list.add(new Product(2,"小馨",8888.8));
        int total=100;
        Map<String, Object> map = new HashMap();
        map.put("total",total);
        map.put("list",list);
        return map;
    }

13.openfeign细节
1.openFeign默认超时处理
默认的调用超时:
使用openFeign组件在进行服务间通信时要求被调用服务必须在1s内给予响应,一旦服务执行业务逻辑时间超过1s ,openFeign组件将直接报错:
Read timed out executing GET http:/ /PRODUcT/product
2 .修改openFeign超时时间
a.指定服务修改某个服务调用超时时间

feign.client.config.PRODUCTS.readTimeout=5000   #配置指定服务连接超时
feign.client.config.PRODUCTS.readTimeout=5000   #配置指定服务等特超时

b.修改openfeign默认调用所有服务超时间

feign.client.config.default.connectTimeout=5000   #配智所有服务连接超时
feign.client.config.default.readTimeout=5000   #配置所有服务等待超时

3 . openFeign日志展示
OpenFeign伪HttpClient客户端对象,用来帮助我们完成服务间通信,底层用http协议完成服务间调用
日志:openFeign为了更好方便在开发过程中调试openFeign数据传递,和响应处理, openFeign在设计时添加了日志功能,默认openFeign白志功能需要手动开启的

日志使用:

  1. 展示openfeign日志
logging.level.com.baizhi.feignclient=debug
  1. feign每一个客户端提供—个日志对象
    HONE:不记录任何白志
    BASIC:仅仅记录请求方法,url,响应状态代码及执行时间
    HEADERS记录Basic级别的基础上,记录请求和响应的header
    FULL:记录请求和响应的header,body和元数据 展示全部http协议状态
feign.client.config.PRODUCTS.loggerLevel=full  #开启指定服务日志展示
feign.client.config.default.loggerLevel=full  #全局开启服务日志展示

15.微服务中的重要概念 服务雪崩 服务熔断 服务降级

1.服务雪崩

现象:
在微服务之间进行服务调用是由于某一个服务故障,导致级联服务故障的现象,称为雪崩效应。雪崩效应描述的是提供方不可用,导致消费方不可用并将不可用逐渐放大的过程

图解雪崩效应
如存在如下调用链路:
在这里插入图片描述

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

在这里插入图片描述
3.服务熔断

“熔断器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器(hystrix)的故障监控,某个异常条件被触发,直接熔断整个服务。向调用方法返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常,就保证了服务调用方的线程不会被长时间占用,避免故障在分布式系统中蔓延,乃至雪崩。如果目标服务情况好转则恢复调用。服务熔断是解决服务雪崩的重要手段。

服务熔断图示:
在这里插入图片描述
4.服务降级

服务降级说明:
服务压力剧增的时候根据当前的业务情况及流量对一些服务和页面有策略的降级,以此缓解服务器的压力,以保证核心任务的进行。同时保证部分甚至大部分任务客户能得到正确的响应。也就是当前的请求处理不了了或者出错了,给一个默认的返回。

服务降级: 关闭微服务系统中某些边缘服务 保证系统核心服务正常运行 12 淘宝 京东 删除订单 — 关闭订单 确认收货
----> 服务繁忙,!!!

服务降级图示
在这里插入图片描述
5.降级和熔断总结

1.共同点

  • 目的很一致,都是从可用性可靠性着想,为防止系统的整体缓慢甚至崩溃,采用的技术手段;
  • 最终表现类似,对于两者来说,最终让用户体验到的是某些功能暂时不可达或不可用;
  • 粒度一般都是服务级别,当然,业界也有不少更细粒度的做法,比如做到数据持久层(允许查询,不允许增删改);
  • 自治性要求很高,熔断模式一般都是服务基于策略的自动触发,降级虽说可人工干预,但在微服务架构下,完全靠人显然不可能,开关预置、配置中心都是必要手段;sentinel

2.异同点

  • 触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;
  • 管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务边缘服务开始)

3.总结

  • 熔断必会触发降级,所以熔断也是降级一种,区别在于熔断是对调用链路的保护,而降级是对系统过载的一种保护处理

15.Hystrix组件(防雪崩利器)

  1. Hystrix家猪
    起源:netFlix springcloud-netflix-hystrix
    作用:
    用来防止微服务系统中服务雪崩现象,实现服务熔断 熔断防止雪崩的手段
  2. 如何项目中使用Hystrix组件
    a.在所有微服务项目中引入hystrix依赖
<!--引入hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

b. 开启熔断功能在入口类加入注解

@SpringBootApplication
@EnableDiscoveryClient  //服务注册中心客户端
@EnableCircuitBreaker   //开启hystrix服务熔断
public class HystrixApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixApplication.class,args);
    }
}

c.在控制器方法中加入备选处理

@GetMapping("/hystrix")
    @HystrixCommand(fallbackMethod = "testBreakFall" )
    public String testBreak(int id){
        log.info("接收的商品id为: "+ id);
        if(id<=0){
            throw new RuntimeException("数据不合法!!!");
        }
        return "当前接收商品id: "+id;
    }

    public String testBreakFall(int id){
        return "当前数据不合法: "+id;
    }

16.Hystrix服务熔断器细节

  1. Hystrix 断路器打开条件
    a.当满足一定的阀值的时候〔默认10秒内超过20个请求次数失败)
    b.当失败率达到一定的时候(默认10秒内超过50%的诸求失败)
    注意:一旦断路开启之后所有到这个服务请求均不可用,只有在断路关闭之后才可用
  2. Hystrix监控流程 触发熔断器机制流程
    在这里插入图片描述
    整个流程:

1、 当满足一定的阀值的时候(默认10秒内超过20个请求次数)
2、 当失败率达到一定的时候(默认10秒内超过50%的请求失败)
3、 到达以上阀值,断路器将会开启
4、 当开启的时候,所有请求都不会进行转发
5、一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5。

17.客户端openfeign + hystrix实现服务降级实现

  1. 引入Hystrix依赖
    注意:openfeign组件底层自动依赖Hystrix依赖项目中无须显示引入
  2. 开启openfeign对Hystrix支持
#开启openfeign 在调用服务过程中开启hystrix支持 默认:没有开启
feign.hystrix.enabled=true
  1. 在openfeign客户端中加如Hystrix
@FeignClient(value = "PRODUCTS",fallback = ProductFallBack.class)
public interface ProductClient {
    @GetMapping("test")
    String test(@RequestParam("id") Integer id);
}
  1. 开发fallback处理类
@Component
public class ProductFallBack implements ProductClient {
    @Override
    public String test(Integer id) {
        return "我是客户端的Hystrix服务实现!!!---id:"+id;
    }  
}
  1. 当调用服务不可用时,直接执行默认自定义处理
    在这里插入图片描述

18.Hystrix Dashboard(仪表盘)

  1. 目前状态
    a.Hystrix不再处于积极开发中,目前处于维护模式。
    b.Hystrix DashBoard已经被废弃。

The hystrix-dashboard component of this project has been deprecated and moved to
替换产品:letflix- skunkworks /hystrix-dashboard.

  1. 日后如何解决服务雪崩
    a.Hystrix(版本1.5.18)足够稳定,可以满足Hetflix对我们现有应用程序的需求
    b.resilience4j 替换 Hystrix 实时自适应系统熔断 springcloud resilience4j
    c . sentinel 流量卫兵―流量控制、降低策略(根据异常)
    推荐sentinel & sentinel dashboard

19.GateWay网关组件

  1. 什么是网关Gateway( service Gateway)服务网关
  • 网关统一服务入口,可方便实现对平台众多服务接口进行管控
  1. 网关作用
  • a.网关统─所有微服务入口
  • b.网关可以实现请求路由转发(router dispatcher)以及请求过程负载均衡
  • c.访问服务的身份认证防报文重放与防数据篡改功能调用的业务鉴权﹑响应数据的脱敏、流量与并发控制,甚至基于AI调用的计量或者计费等等
  1. springcloud提供网关组件
  • netflix zuul1.x(效率) zuul2.x(近两年)
  • spring cloud gateway组件(webFlux异步非阻塞Io模型) 推荐
  1. springcloud gateway
    -gateway: 动态路由 服务统─管理 请求过滤
    -gateway = 路由转发(router)+请求过滤(filter)

  2. gateway 网关使用

  • a.开发独立springboot应用
  • b.引入网关依赖 注意:去掉项目springboot-starter-web存在冲突
  <!--引入gateway网关依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
  • c. 配置编写
spring:
  application:
    name: gateway
  cloud:
    consul:
      host: localhost
      port: 8500
    gateway:
      routes:
        - id: user_route					  # 指定路由唯一标识
          uri: http://localhost:8088/         # 指定路由服务的地址
          predicates:
            - Path=/test/**					  # 指定路由规则
server:
  port: 7979
  1. 配置路由服务负载均衡

现有路由配置方式,都是基于服务地址写死的路由转发,能不能根据服务名称进行路由转发同时实现负载均衡的呢?

  • 动态路由以及负载均衡转发配置
spring:
  application:
    name: gateway
  cloud:
    consul:
      host: localhost
      port: 8500
    gateway:
      routes:
        - id: user_route
          #uri: http://localhost:9999/
          uri: lb://users							# lb代表转发后台服务使用负载均衡,users代表服务注册中心上的服务名
          predicates:
            - Path=/user/**

        - id: product_route
          #uri: http://localhost:9998/
          uri: lb://products          # lb(loadbalance)代表负载均衡转发路由
          predicates:
            - Path=/product/**
      discovery:
        locator:
          enabled: true 							#开启根据服务名动态获取路由

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xAJtdPHX-1647776980490)(SpringCloud 微服务工具集v1.1.assets/image-20200721110013966.png)]
在这里插入图片描述

  1. 常用路由predicate(断言,验证)
  • Gateway支持多种方式的predicate
    在这里插入图片描述
  • After=2020-07-21T11:33:33.993+08:00[Asia/Shanghai] `指定日期之后的请求进行路由

  • Before=2020-07-21T11:33:33.993+08:00[Asia/Shanghai] `指定日期之前的请求进行路由

  • Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

  • Cookie=username,chenyn `基于指定cookie的请求进行路由

  • Cookie=username,[A-Za-z0-9]+ 基于指定cookie的请求进行路由curl http://localhost:8989/user/findAll --cookie “username=zhangsna”

  • Header=X-Request-Id, \d+ ``基于请求头中的指定属性的正则匹配路由(这里全是整数) `curl http://localhost:8989/user/findAll
    -H “X-Request-Id:11”

  • Method=GET,POST `基于指定的请求方式请求进行路由

  • 官方更多: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#the-cookie-route-predicate-factory

  • 使用predicate
spring:
  application:
    name: gateway
  cloud:
    consul:
      host: localhost
      port: 8500
    gateway:
      routes:
        - id: user_route
          #uri: http://localhost:9999/
          uri: lb://users
          predicates:
            - Path=/user/**
            - After=2020-07-21T11:39:33.993+08:00[Asia/Shanghai]
            - Cookie=username,[A-Za-z0-9]+
            -  Header=X-Request-Id, \d+

在这里插入图片描述

20.config 组件 (配置)统一配置中心

  1. config 组件 统一配置中心
    作用:用来实现微服务系统中服务配置统―管理组件netflix config ===>spring config
    组件:统—配置中心服务端(集中管理配置文件)、统一配置中心客户端client
    在这里插入图片描述
  2. config组件使用config client —>config server---->远端git仓库
    a.选择—个远端git仓库
    1.使用githubgitee
    2.创建新仓库
    3.获取仓库地址https://gitee.com/chenyn-java_admin/config.git
    b.搭建config server统─配置中心服务
    1.独立springboot应用
    2.引入config server依赖
<!--引入统一配置中心-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-config-server</artifactId>
</dependency>
  1. 配置application.properties远程仓库地址
server.port=7878
spring.application.name=configserver
spring.cloud.consul.host=localhost
spring.cloud.consul.port=8500

spring.cloud.config.server.git.uri=https://github.com/chenyn-java/configservers.git   //指定仓库的url
spring.cloud.config.server.git.default-label=master		 //指定访问的分支							
#spring.cloud.config.server.git.username=       私有仓库访问用户名
#spring.cloud.config.server.git.password=		私有仓库访问密码
  1. 开启统─配置中心在入口类加入注解
@SpringBootApplication
@EnableConfigServer
public class ConfigserverApplication {
	public static void main(String[] args) {
		SpringApplication.run(Configserver7878Application.class, args);
	}
}
  1. 拉取远端配置 (三种方式)
    • http://localhost:7878/test-xxxx.properties
    • http://localhost:7878/test-xxxx.json
    • http://localhost:7878/test-xxxx.yml

注意:如果匹配文件名不可以找到,则返回公共配置文件信息;如果可以找到,则返回此配置文件信息和公共配置文件信息的组合

21.Config Client 开发

  1. config client微服务
  2. 创建——个独立springboot应用
  3. 将自身配置文给远端git仓库管理
  4. 项目中引入config client依赖
<!--引入config client-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
  1. 编写配置文件
spring.cloud.config.discovery.enabled=true                #开启统一配置中心服务
spring.cloud.config.discovery.service-id=CONFIGSERVER     #指定统一配置服务中心的服务唯一标识
spring.cloud.config.label=master													#指定从仓库的那个分支拉取配置	
spring.cloud.config.name=client														#指定拉取配置文件的名称
spring.cloud.config.profile=dev														#指定拉取配置文件的环境
  1. 远程仓库创建配置文件
- client.properties						//用来存放公共配置
	spring.application.name=configclient
	spring.cloud.consul.host=localhost
	spring.cloud.consul.port=8500

- client-dev.properties  				//用来存放研发相关配置  注意:这里端口为例,以后不同配置分别存放
	server.port=9099

- client-prod.properties				//用来存放生产相关配置
	server.port=9098
  1. 修改配置文件名
    a.直接启动过程中发现无法启动直接报错
    在这里插入图片描述

b.报错原因:

项目中目前使用的是application.properties启动项目,使用这个配置文件在springboot项目启动过程中不会等待远程配置拉取,直接根据配置文件中内容启动,因此当需要注册中心,服务端口等信息时,远程配置还没有拉取到,所以直接报错

在这里插入图片描述
c.解决方法
将配置文件名称修改为bootstrap.properties
在这里插入图片描述

22.config client手动配置刷新

  1. 为什么配置手动刷新
    当远端git仓库中配置发生变化时,不需要重启微服务就可以直接读取远端修改之后配置信息,这种就叫手动配置届新

  2. 配置手动刷新
    a.在config client端加入刷新暴露端点

management.endpoints.web.exposure.include=*          #开启所有web端点暴露

在这里插入图片描述
b.在需要刷新代码的类中加入刷新配置的注解

@RestController
@RefreshScope
@Slf4j
public class TestController {
    @Value("${name}")
    private String name;
    @GetMapping("/test/test")
    public String test(){
      log.info("当前加载配置文件信息为:[{}]",name);
      return name;
    }
}

c.手动调用刷新配置接口

curl -X POST http://localhost:9099/actuator/refresh

23.Bus组件的使用

未完待续…持续更新中…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值