springcloud学习笔记

SpringCloud学习笔记

  • 1.学习前言
    • 学习前提
    • 1.2常见的面试题
  • 2.微服务概述
    • 2.1什么是微服务?
    • 2.2微服务与微服务架构
    • 2.3微服务的优缺点
  • 3.springCloud入门概述
    • 3.1springcloud是什么?
    • 3.2springcloud和springboot的关系
    • 3.3Dubbo和springcloud技术选型
    • 3.5springcloud能干啥?
  • 4.springcloud Rest学习环境搭建:服务提供者
    • 4.1介绍
    • 4.2springcloud版本选择
    • 4.3创建父工程
  • 5.Eureka服务注册中心
    • 5.1什么是EureKa
    • 5.2原理理解
    • 5.3构建步骤
  • Eureka配置
  • 6.负载均衡Ribbon
    • 6.1什么是负载均衡
    • 6.2负载均衡的实现方式
    • 6.3负载均衡策略
    • 6.4负载均衡饥饿加载
  • 7.Nacos注册中心
    • 7.1认识Nacos
    • 7.2服务注册到nacos中
    • 7.3nacos服务分级模型
    • 7.4nacos环境隔离-namespace
  • 8.nacos配置管理
    • 8.1新建配置
    • 8.2获取nacos中的配置文件
    • 8.3nacos配置热更新
    • 8.4多环境配置共享
  • 9.Feign远程调用
    • 9.1定义和使用Feign客户端
    • 9.2feign自定义配置
    • 9.3feign的性能优化
      • feign添加httpclient的支持:
    • 9.4feign的最佳实践
    • 9.4抽取feignClient
  • 10.网关Gateway
    • 10.1什么是网关
    • 10.2网关功能
    • 10.3网关的技术实现
    • 10.4搭建网关服务
    • 10.5路由断言工厂
    • 10.6路有过滤器GatewayFilter
    • 10.7全局过滤器GlobalFilter
    • 10.8过滤器执行顺序
    • 10.8跨域问题处理
  • 11.初识MQ
    • 11.1.rabbitMq快速入门
    • 11.2.RabbitMq的结构和概念
    • 11.3.SpringAMQP
    • 步骤3:在consumer中编写消费逻辑,监听simple.queue

1.学习前言

学习前提

  • 熟练使用SpringBoot 微服务快速开发框架
  • 了解过Dubbo + Zookeeper 分布式基础

1.2常见的面试题

1. 什么是我服务?
2. 微服务之间是如何独立通讯的?
3. springcloud和dubbo有哪些区别?
4. springboot和springcloud之前有神区别,谈谈对他们的理解。
5. 什么是微服务熔断?什么是微服务降级?
6. 微服务的优缺点分别是什么?说下你在项目开发中遇到的坑。
7. 你所知道的微服务技术栈有哪些?列举一二。
8. Eureka和Zookeeper都可以提供微服务注册与发现的功能,说说两者区别。

2.微服务概述

2.1什么是微服务?

  • 微服务(Microservice Architecture)是近几年流行的一种思想架构。
    • 就目前而言,业内并没有对微服务有一个统一的定义。
    • 但通常而言,微服务是一种架构,或者说是一种风格,他是将单一的应用划分为一组小的服务,每个服务运行在独立的自己的进程内,服务之间互相协作,互相配置,服务之间采用轻量级的通信机制(HTTP)互相沟通,每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境中,另外,应用尽量避免统一的集中式的服务管理机制,对具体的一个服务而言,应该根据上下文,选择合适的语言,工具(maven)对其进行构建,可以有一个非常轻量级的集中式管理协调这些服务,可以使用不同的语言来编写服务,可以使用不同的数据存储。
  • 再从技术角度分析
    • 微服务的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底的去耦合,每一个服务提供单个业务功能,一个服务做一件事,从技术角度看就是一种小而独立的处理过程,类似进程的概念,能够自行独立的启动或者销毁,拥有自己独立的数据库。

2.2微服务与微服务架构

  • 微服务

    • 强调的是服务的大小,它关注的是某一个点,是具体解决某一个问题/提供落地对应服务的一个服务应用,狭义的看,可以看作是IDEA中的一个个微服务工程,或者Moudel。IDEA 工具里面使用Maven开发的一个个独立的小Moudel,它具体是使用SpringBoot开发的一个小模块,专业的事情交给专业的模块来做,一个模块就做着一件事情。强调的是一个个的个体,每个个体完成一个具体的任务或者功能。
  • 微服务架构

    • 一种新的架构形式,Martin Fowler 于2014年提出。微服务架构是一种架构模式,它体长将单一应用程序划分成一组小的服务,服务之间相互协调,互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务之间采用轻量级的通信机制(如HTTP)互相协作,每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境中,另外,应尽量避免统一的,集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具(如Maven)对其进行构建。

2.3微服务的优缺点

  • 优点

    • 单一职责原则
    • 每个服务足够内聚,足够小,代码容易理解,这样能聚焦一个指定的业务功能或者业务需求。
    • 开发简单,开发效率高,一个服务可能就是专一的只干一件事
    • 微服务能够被小团队单独开发,这个团队只需2-5个开发人员组成
    • 微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的
    • 微服务能使用不同的语言开发
    • 易于和第三方集成,微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如jenkins,Hudson,bamboo
    • 微服务易于被一个开发人员理解,修改和维护,这样小团队能够更关注自己的工作成果,无需通过合作才能体现价值
    • 微服务允许利用和融合最新技术
    • 微服务只是业务逻辑的代码,不会和HTML,CSS,或其他的界面混合
    • 每个微服务都有自己的存储能力,可以有自己的数据库,也可以有统一的数据库
  • 缺点

    • 开发人员要处理分布式系统的复杂性
    • 多服务运维难度,随着服务的增加,运维的压力也在增大
    • 系统部署依赖问题
    • 服务间通信成本问题
    • 数据一致性问题
    • 系统集成测试问题
    • 性能和监控问题
  • 微服务的技术栈有哪些?

    springcloud学习笔记_第1张图片

3.springCloud入门概述

3.1springcloud是什么?

springcloud官网:https://spring.io/

springcloud学习笔记_第2张图片

springcloud学习笔记_第3张图片

3.2springcloud和springboot的关系

  • SpringBoot专注于开发方便的开发单个个体微服务
  • SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务,整合并管理起来,为各个微服务之间提供:配置管理、服务发现、断路器、路由、为代理、事件总栈、全局锁、决策竞选、分布式会话等等集成服务
  • SpringBoot可以离开SpringCloud独立使用,开发项目,但SpringCloud离不开SpringBoot,属于依赖关系
  • SpringBoot专注于快速、方便的开发单个个体微服务,SpringCloud关注全局的服务治理框架

3.3Dubbo和springcloud技术选型

  • 1.分布式+服务治理 Dubbo
    目前成熟的互联网架构,应用服务化拆分 + 消息中间件

  • 2.Dubbo 和 SpringCloud对比
    可以看一下社区活跃度:
    https://github.com/dubbo
    https://github.com/spring-cloud

  • 对比结果:

Dubbo SpringCloud
服务注册中心 Zookeeper Spring Cloud Netfilx Eureka
服务调用方式 RPC REST API
服务监控 Dubbo-monitor Spring Boot Admin
断路器 不完善 Spring Cloud Netfilx Hystrix
服务网关 Spring Cloud Netfilx Zuul
分布式配置 Spring Cloud Config
服务跟踪 Spring Cloud Sleuth
消息总栈 Spring Cloud Bus
数据流 Spring Cloud Stream
批量任务 Spring Cloud Task

最大区别:Spring Cloud 抛弃了Dubbo的RPC通信,采用的是基于HTTP的REST方式
严格来说,这两种方式各有优劣。虽然从一定程度上来说,后者牺牲了服务调用的性能,但也避免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这个优点在当下强调快速演化的微服务环境下,显得更加合适。

3.5springcloud能干啥?

  • Distributed/versioned configuration 分布式/版本控制配置
  • Service registration and discovery 服务注册与发现
  • Routing 路由
  • Service-to-service calls 服务到服务的调用
  • Load balancing 负载均衡配置
  • Circuit Breakers 断路器
  • Distributed messaging 分布式消息管理

4.springcloud Rest学习环境搭建:服务提供者

4.1介绍

  • 我们会使用一个Dept部门模块做一个微服务通用案例Consumer消费者(Client)通过REST调用Provider提供者(Server)提供的服务。

  • 回顾Spring,SpringMVC,Mybatis等以往学习的知识。

  • Maven的分包分模块架构复习。
    一个简单的Maven模块结构是这样的:

    • app-parent: 一个父项目(app-parent)聚合了很多子项目(app-util\app-dao\app-web…)
      • pom.xml
      • app-core
        • pom.xml
      • app-web
        • pom.xml

一个工程带多个Moudule子模块。
MicroServiceCloud父工程(Project)下初次带着3个子模块(Module)

  • microservicecloud-api 【封装的整体entity/接口/公共配置等】
  • microservicecloud-consumer-dept-80 【服务提供者】
  • microservicecloud-provider-dept-8001 【服务消费者】

4.2springcloud版本选择

SpringBoot SpringCloud 关系
1.2.x Angel版本(天使) 兼容SpringBoot1.2x
1.3.x Brixton版本(布里克斯顿) 兼容SpringBoot1.3x,也兼容SpringBoot1.4x
1.4.x Camden版本(卡姆登) 兼容SpringBoot1.4x,也兼容SpringBoot1.5x
1.5.x Dalston版本(多尔斯顿) 兼容SpringBoot1.5x,不兼容SpringBoot2.0x
1.5.x Edgware版本(埃奇韦尔) 兼容SpringBoot1.5x,不兼容SpringBoot2.0x
2.0.x Finchley版本(芬奇利) 兼容SpringBoot2.0x,不兼容SpringBoot1.5x
2.1.x Greenwich版本(格林威治)

4.3创建父工程

  • 新建父工程项目springcloud,切记Packageing是pom模式
  • 主要是定义POM文件,将后续各个子模块公用的jar包等统一提取出来,类似一个抽象父类
    springcloud学习笔记_第4张图片

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <groupId>com.haustgroupId>
    <artifactId>springcloudartifactId>
    <version>1.0-SNAPSHOTversion>
    <modules>
        <module>springcloud-apimodule>
        <module>springcloud-provider-dept-8001module>
        <module>springcloud-consumer-dept-80module>
        <module>springcloud-eureka-7001module>
        <module>springcloud-eureka-7002module>
        <module>springcloud-eureka-7003module>
        <module>springcloud-provider-dept-8002module>
        <module>springcloud-provider-dept-8003module>
        <module>springcloud-consumer-dept-feignmodule>
        <module>springcloud-provider-dept-hystrix-8001module>
        <module>springcloud-consumer-hystrix-dashboardmodule>
        <module>springcloud-zuul-9527module>
        <module>springcloud-config-server-3344module>
        <module>springcloud-config-client-3355module>
        <module>springcloud-config-eureka-7001module>
        <module>springcloud-config-dept-8001module>
    modules>
    
    <packaging>pompackaging>
    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <maven.compiler.source>1.8maven.compiler.source>
        <maven.compiler.target>1.8maven.compiler.target>
        <junit.version>4.12junit.version>
        <log4j.version>1.2.17log4j.version>
        <lombok.version>1.16.18lombok.version>
    properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                <version>0.2.0.RELEASEversion>
                <type>pomtype>
                <scope>importscope>
            dependency>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>Greenwich.SR1version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-dependenciesartifactId>
                <version>2.1.4.RELEASEversion>
                <type>pomtype>
                <scope>importscope>
            dependency>
            
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>5.1.47version>
            dependency>
            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>druidartifactId>
                <version>1.1.10version>
            dependency>
            
            <dependency>
                <groupId>org.mybatis.spring.bootgroupId>
                <artifactId>mybatis-spring-boot-starterartifactId>
                <version>1.3.2version>
            dependency>
            
            <dependency>
                <groupId>ch.qos.logbackgroupId>
                <artifactId>logback-coreartifactId>
                <version>1.2.3version>
            dependency>
            <dependency>
                <groupId>junitgroupId>
                <artifactId>junitartifactId>
                <version>${junit.version}version>
            dependency>
            <dependency>
                <groupId>log4jgroupId>
                <artifactId>log4jartifactId>
                <version>${log4j.version}version>
            dependency>
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <version>${lombok.version}version>
            dependency>
        dependencies>
    dependencyManagement>
project>

父工程为springcloud,其下有多个子mudule,详情参考完整代码了解
springcloud学习笔记_第5张图片
springcloud-consumer-dept-80访问springcloud-provider-dept-8001下的controller使用REST方式

如DeptConsumerController.java

/**
 * @Auther: csp1999
 * @Date: 2020/05/17/22:44
 * @Description:
 */
@RestController
public class DeptConsumerController {
    /**
     * 理解:消费者,不应该有service层~
     * RestTemplate .... 供我们直接调用就可以了! 注册到Spring中
     * (地址:url, 实体:Map ,Class responseType)
     * 

* 提供多种便捷访问远程http服务的方法,简单的Restful服务模板~ */ @Autowired private RestTemplate restTemplate; /** * 服务提供方地址前缀 *

* Ribbon:我们这里的地址,应该是一个变量,通过服务名来访问 */ private static final String REST_URL_PREFIX = "http://localhost:8001"; //private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT"; /** * 消费方添加部门信息 * @param dept * @return */ @RequestMapping("/consumer/dept/add") public boolean add(Dept dept) { // postForObject(服务提供方地址(接口),参数实体,返回类型.class) return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class); } /** * 消费方根据id查询部门信息 * @param id * @return */ @RequestMapping("/consumer/dept/get/{id}") public Dept get(@PathVariable("id") Long id) { // getForObject(服务提供方地址(接口),返回类型.class) return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class); } /** * 消费方查询部门信息列表 * @return */ @RequestMapping("/consumer/dept/list") public List<Dept> list() { return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class); } }

使用RestTemplete先需要放入Spring容器中

ConfigBean.java

@Configuration
public class ConfigBean {
    //@Configuration -- spring  applicationContext.xml
    //配置负载均衡实现RestTemplate
    // IRule
    // RoundRobinRule 轮询
    // RandomRule 随机
    // AvailabilityFilteringRule : 会先过滤掉,跳闸,访问故障的服务~,对剩下的进行轮询~
    // RetryRule : 会先按照轮询获取服务~,如果服务获取失败,则会在指定的时间内进行,重试
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

springcloud-provider-dept-8001的dao接口调用springcloud-api模块下的pojo,可使用在springcloud-provider-dept-8001的pom文件导入springcloud-api模块依赖的方式:


        <dependency>
            <groupId>com.haustgroupId>
            <artifactId>springcloud-apiartifactId>
            <version>1.0-SNAPSHOTversion>
        dependency>

springcloud-consumer-dept-80和springcloud-provider-dept-8001的pom.xml和父工程下的依赖基本一样,直接看完整代码即可,不再添加重复笔记。

5.Eureka服务注册中心

5.1什么是EureKa

  • Netflix在设计Eureka,遵循的就是api原则。
  • Eureka是Netflix的子模块,也是核心模块之一。Eureka是基于REST的服务,用于定位服务,以实现云端中间件层服务发现和故障转移,服务注册与发现对于微服务来说是非常重要的,有了服务注册与发现,只需要使用服务的标识符,就可以访问到服务,而不是修改服务调用的配置文件,功能类似于Dubbo的注册中心,比如Zookeeper

5.2原理理解

  • Eureka基本的架构

    • springcloud封装了Netflix公司开发的eureka模块来实现服务的注册与发现。
    • eureka采用了C-S的架构设计,eurekaServer作为服务注册功能的服务器,他是服务注册中心。
    • 系统中的其他服务,使用eureka的客户端连接到eurekaserver并维持心跳连接,这样系统维护人员就可以通过eurekaserver来监控系统中各个微服务是否正常运行,springcloud的一些其他模块就可以通过eurekaserver来发现系统中的其他微服务并执行相关逻辑。
      springcloud学习笔记_第6张图片
  • 和Dubbo架构对比。
    springcloud学习笔记_第7张图片

  • Eureka包含两个组件:EurekaServer和EurekaClient.

  • Eureka server提供服务注册,各个节点启动后,回到EurekaServer中进行注册,这样eureka server中的服务注册表中将会存储所有可用服务节点信息,服务节点的信息可以在界面中直观的看到。

  • Eureka client 是一个Java客户端,用于简化Eureka server的交互,客户端同事也具备一个内置的,使用轮询负载算法的负载均衡器。在应用启动后,将会向EurekaServcer发送心跳,如果EurekaServer在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册中心把这个服务节点移除掉。(默认周期为90S)

  • 三大角色

    • Eureka Server:提供服务的注册与发现
    • Service Provider:服务生产方,将自身服务注册到Eureka中,从而使服务消费方能够找到
    • Service Consumer:服务消费方,从Eureka中获取注册服务列表,从而找到消费服务。

5.3构建步骤

  • Eureka-server
    springcloud学习笔记_第8张图片
  • pom.xml 文件
<!--导包~-->
<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
    <!--导入Eureka Server依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--热部署工具-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>
  • applicaltion.yml
    server:
    port: 7001

Eureka配置

server:
  port: 7001

#Eureka配置
eureka:
  instance:
    hostname: localhost  #Eureka服务端的实例名称
  client:
    register-with-eureka: false #表示是否向eureka注册中心注册自己
    fetch-registry: false  # fetch-registry如果为false,则表示自己是注册中心
    service-url:  #监控页面
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      
  • EurekaServer启动类
@SpringBootApplication
@EnableEurekaServer  //EnableEurekaServer服务端的启动类,可以接受别人注册进来
public class EurekaServer {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer.class,args);
    }
}
  • 启动成功后访问http://localhost:7001/得到以下页面
    springcloud学习笔记_第9张图片
  • eureka client
    springcloud学习笔记_第10张图片
  • 导入Eureka依赖
	

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-eurekaartifactId>
    <version>1.4.6.RELEASEversion>
dependency>
  • application中新增Eureka配置
#Eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/
  instance:
    instance-id: springCloud-provider-dept #修改eureka上面的默认描述信息
  • 主启动类上加上@EnableEurekaClient注解
@SpringBootApplication
@MapperScan(basePackages = {"com.cy.*.dao"})
@EnableEurekaClient //在服务启动后自动注册到eureka服务中
public class DeptProvider_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_8001.class,args);
    }
}
  • 可以在Eureka注册管理页面中看到SPRINGCLOUD-PROVIDER-DEPT服务已经注册进去了
    springcloud学习笔记_第11张图片
  • 修改Eureka上的默认描述信息
    springcloud学习笔记_第12张图片
    如果停掉SPRINGCLOUD-PROVIDER-DEPT服务,等待30秒后,监控会开启保护机制:
    springcloud学习笔记_第13张图片
  • 配置关于服务加载的监控信息
    springcloud学习笔记_第14张图片
  • pom.xml中添加依赖

<dependency>
 <groupId>org.springframework.bootgroupId>
 <artifactId>spring-boot-starter-actuatorartifactId>
dependency>
  • application.yml中的配置
# info配置
info:
  # 项目的名称
  app.name: cy.springCloud
  # 公司的名称
  company.name: cy.springCloud.com

点击后会跳转到页面
springcloud学习笔记_第15张图片

6.负载均衡Ribbon

6.1什么是负载均衡

Ribbon是一个基于Http和tcp的客户端负载均衡工具,基于Netflix Ribbon实现的,它不像spring cloud 服务注册中心、配置中心、API网关那样独立部署,但是它几乎存在于每个Spring Cloud微服务中.包括Fegin提供的声明式服务调用也是基于Ribbon实现的.Ribbon默认提供很多种负载均衡算法,列入轮询,随机等。

6.2负载均衡的实现方式

  • @LoadBalanced 注解
@Configuration
public class ConfigBean {

    @Bean
    @LoadBalanced  //负载均衡的实现方式
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
  • ClientHttpRequestInterceptor接口
    ClientHttpRequestInterceptor是一个客户端发送请求的拦截器,而restful正是使用http请求方式,所以会被拦截。ClientHttpRequestInterceptor中只有一个intercept()方法。
@FunctionalInterface
public interface ClientHttpRequestInterceptor {
    ClientHttpResponse intercept(HttpRequest var1, byte[] var2, ClientHttpRequestExecution var3) throws IOException;
}
  • LoadBalancerInterceptor
    LoadBalancerInterceptor实现了ClientHttpRequestInterceptor ,所以也实现了intercept()方法。
    springcloud学习笔记_第16张图片
    在这里插入图片描述
    当我们在客户端发起请求的时候,我们的请求会被拦截。
    在这里插入图片描述
    会获取到一个请求路径,并且通过请求路径会获得一个服务名称,这个服务名称就是我们在eureka中注册的服务名,然后再将服务名称交给loadBalancer对象去执行。
    springcloud学习笔记_第17张图片
    通过代码中得知,loadBalancer对象是RibbonLoadBalancerClient,它实现了LoadBalancerClient接口。
    在这里插入图片描述

当我们点进execute方法中,会根据我们的serverID拿到loadBalancer对象,这里面包含了注册的服务,然后再通过getServer完成负载均衡筛选。
在这里插入图片描述
loadBalancer对象中注册的服务。
springcloud学习笔记_第18张图片

6.3负载均衡策略

Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口就是一种规则:
springcloud学习笔记_第19张图片

springcloud学习笔记_第20张图片

  • 通过定义IRule实现可以修改负载均衡规则,有两种方式:
    springcloud学习笔记_第21张图片
  • 配置文件方式:在application.yml文件中,添加新的配置修改规则
  • 在这里插入图片描述

6.4负载均衡饥饿加载

Ribbon默认采用是懒加载,即在第一次访问时才会去创建LoadBalanceClient,请求时间会很长,而饥饿加载则会在项目启动时去创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:
在这里插入图片描述

7.Nacos注册中心

7.1认识Nacos

nacos是阿里巴巴的产品,现在是springcloud中的一个组件,想比eureka功能更加丰富,在国内受欢迎程度较高。
中文官网:https://nacos.io/zh-cn/
springcloud学习笔记_第22张图片
在GitHub中下载nacos安装包
springcloud学习笔记_第23张图片
1.4.4版本比较稳定,解压得到文件夹目录
springcloud学习笔记_第24张图片
在bin目录下,双击startup.cmd启动nacos
springcloud学习笔记_第25张图片
启动成功,http://192.168.3.160:8848/nacos/index.html这是nacos的地址
springcloud学习笔记_第26张图片

7.2服务注册到nacos中

  1. 在父工程中引入nacos的管理依赖

            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                <version>2.2.5.RELEASEversion>
                <type>pomtype>
                <scope>importscope>
            dependency>
  1. 注释掉原有服务中的eureka依赖
  2. 添加nacos的客户端依赖:
 		<dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
  1. 配置application.yml中nacos配置
spring:
  application:
    name: springCloud-consumer  #服务名称
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #nacos服务

7.3nacos服务分级模型

  1. nacos服务分级存储模型
    • 一级是服务,例如userserice
    • 二级是集群,例如上海南京
    • 三级是实例,例如上海机房某台部署了userservice的服务器
  2. 如何设置实例集群属性
    • 修改application.yml文件,添加spring.cloud.discovery.cluster-name属性
spring:
  application:
    name: springCloud-consumer  #服务名称
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #nacos服务
        cluster-name: SH #集群名称 代指南京

7.4nacos环境隔离-namespace

  1. 在NACOS 控制台可以创建namespace,用来隔离不同环境。
    springcloud学习笔记_第27张图片
  2. 然后填写一个新的命名空间信息
    springcloud学习笔记_第28张图片
  3. 保存后会在控制台看到这个命名空间的id
    springcloud学习笔记_第29张图片
  4. 修改application.yml,添加namespace:
    springcloud学习笔记_第30张图片

8.nacos配置管理

8.1新建配置

  1. 在nacos中添加配置信息:
    springcloud学习笔记_第31张图片
  2. 在弹出的表单中填写配置信息
    springcloud学习笔记_第32张图片

8.2获取nacos中的配置文件

  1. 配置文件获取步骤
    springcloud学习笔记_第33张图片
  2. 引入nacos的配置管理客户端依赖
    在这里插入图片描述
  3. 在项目的resource目录下添加一个bootstrap.yml文件,这个就是引导文件,优先级高于application.yml
    springcloud学习笔记_第34张图片
  4. 在服务中将pattern.dateformat这个属性注入到controller中
    springcloud学习笔记_第35张图片

8.3nacos配置热更新

nacos中的配置文件变更后,微服务无需重启就可以感知,不过需要通过下面两种配置实现。

  1. 方式一:在@value注入的变量所在类上添加注解@RefreshScope
    springcloud学习笔记_第36张图片
    方式二:使用@ConfigurationProperties注解来实现
    springcloud学习笔记_第37张图片

8.4多环境配置共享

springcloud学习笔记_第38张图片

  • 配置文件的优先级
    • 服务名-profile.yaml > 服务名称.yaml > 本地配置

9.Feign远程调用

Feign 是一个声明式的 REST 客户端,它能让 REST 调用更加简单。Feign 供了 HTTP 请求的模板,通过编写简单的接口和插入注解,就可以定义好 HTTP 请求的参数、格式、地址等信息。官方地址:https://github.com/OpenFeign/feign
而 Feign 则会完全代理 HTTP 请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。

9.1定义和使用Feign客户端

  • 使用feign的步骤如下:
    1. 引入依赖
    在这里插入图片描述
  1. 在启动类上假如注解开启feign的功能。
    springcloud学习笔记_第39张图片
  2. 编写feign客户端
    在这里插入图片描述
    主要是基于springmvc的注解来声明远程调用的信息,比如:
  • 服务名称:userservice
  • 请求方式: get
  • 请求路径: /user/{id}
  • 请求参数: Long id
  • 返回值类型: User

9.2feign自定义配置

feign运行自定义配置来覆盖默认配置,可以修改的配置如下:
springcloud学习笔记_第40张图片

  • 配置feign日志有两种方式:
    • 方式一:配置文件方式
      1. 全局生效:
        在这里插入图片描述
      2. 局部生效
        springcloud学习笔记_第41张图片
  • 方式二:Java代码方式,需要先声明一个bean
    springcloud学习笔记_第42张图片
  1. 然后如果配置全局,则需要把它放到@EnableFeignClients这个注解中:
    springcloud学习笔记_第43张图片
  2. 如果是局部配置,则把它放到@FeignClient这个注解中:
    springcloud学习笔记_第44张图片

9.3feign的性能优化

feign底层的客户端实现:

  • URLConnection: 默认实现,不支持连接池
  • APACHE HttpClient: 支持连接池
  • OKHttp: 支持连接池

因此优化feign的性能主要包括:

  1. 使用连接池代替默认的URLConnection
  2. 日志级别,最好使用basic或者none

feign添加httpclient的支持:

引入依赖:
springcloud学习笔记_第45张图片
配置连接池:
springcloud学习笔记_第46张图片

9.4feign的最佳实践

方式一(继承):给消费者的FeignClient和提供者的Controller定义统一的父接口作为标准
方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用。
springcloud学习笔记_第47张图片

9.4抽取feignClient

实现最佳实践方式二的步骤如下:

  1. 首先创建一个module,命名为feign-api,然后引入feign的starter依赖
  2. 然后将order-service中编写的UserClient、user、defaultFeignConfiguration都复制到feign-api项目中
  3. 在order-service中引入feign-api依赖
  4. 修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包。
  5. 重启测试

当定义的feignClient不在springbootApplication的扫描包范围内,这些feignClient无法使用。有两种方式解决
方式一: 指定feignClient所在包
在这里插入图片描述
方式二:指定feignClient字节码
在这里插入图片描述

10.网关Gateway

10.1什么是网关

网关的角色是作为一个 API 架构,用来保护、增强和控制对于 API 服务的访问。
API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。因此,隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。

10.2网关功能

  • 身份认证和权限校验
  • 服务路由、负载均衡
  • 请求限流

10.3网关的技术实现

在springcloud中网关的实现包括两种

  • gateway
  • zuul
    Zuul是基于servlet的实现,属于阻塞式编程,而springcloudGateway则是基于spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。

10.4搭建网关服务

搭建网关服务的步骤:

  1. 创建新的module,引入springcloudGateway的依赖和nacos的服务发现和依赖:
    springcloud学习笔记_第48张图片
  2. 编写路由配置及nacos地址
    springcloud学习笔记_第49张图片

10.5路由断言工厂

  • 我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
  • 例如Path=/user/**是按照路径匹配,这个规则是由org.springframework.cloud.handler.predicate.PathRoutePredicateFactory类来处理的
  • 像这样的断言工厂springcloudGateway还有十几个
    springcloud学习笔记_第50张图片

10.6路有过滤器GatewayFilter

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:
spring提供了31种不同的路由过滤器工厂,例如:
springcloud学习笔记_第51张图片
案例:给所有进入userservice的请求添加一个请求头Truth,123456
实现方式:在gateway中修改application.yml文件,给userservice的路由添加过滤器
springcloud学习笔记_第52张图片
springcloud学习笔记_第53张图片

10.7全局过滤器GlobalFilter

全局过滤器的作用也是出力一切进入网关的请求和微服务响应,与gatewayFilter的作用一样,区别在于gatewayFilter通过配置定义,处理逻辑是固定的。而globalFilter的逻辑需要自己去写代码实现。
定义方式是实现GlobalFilter接口。
springcloud学习笔记_第54张图片
springcloud学习笔记_第55张图片
总结:

  1. 实现GlobalFilter接口
  2. 添加@Order注解或实现Ordered接口
  3. 编写处理逻辑

10.8过滤器执行顺序

请求进入网关会碰到三类过滤器:当前路由过滤器、DefaultFilter、GlobalFilter
请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器

  • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前,
  • GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定Order值,由我们自己定
  • 路由过滤器和DefaultFilter的order是由spring指定,默认是按照声明顺序从1递增
    springcloud学习笔记_第56张图片
  • 当过滤器的order值一样时,会按照DefaultFilter>路由过滤器>GlobalFilter顺序执行。

10.8跨域问题处理

跨域:域名不一致就是跨域,主要包括:

  • 域名不同:www.taobao.com和www.taobao.org和www.jd.com和miaosha.jd.com
  • 域名相同,端口不同:localhost:8080和localhost:8081
    跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截问题
    解决方案:cors
    网关处理跨域采用同样的CORS方案,并且只需要简单配置即可实现:
    springcloud学习笔记_第57张图片

11.初识MQ

什么是MQ
MQ(MessageQueue),中文是消息队列,字面来看就是存放消息的队列,也就是事件驱动架构中的broker。
springcloud学习笔记_第58张图片

11.1.rabbitMq快速入门

  • 下载镜像
    docker pull rabbitmq:3-management
  • 执行下面的命令来运行MQ容器
    springcloud学习笔记_第59张图片

11.2.RabbitMq的结构和概念

在这里插入图片描述
RabbitMQ中的几个概念:

  • channel:操作MQ的工具
  • exchange:路由消息到队列(交换机)
  • queue:缓存消息
  • virtual host:虚拟主机,是对queue、exchange等资源的逻辑分组

常见消息模型
MQ的官方文档中给出了5个MQ的Demo示例,对应了几种不同的用法:

  • 基本消息队列(BasicQueue)
  • 工作消息队列(WorkQueue)
    springcloud学习笔记_第60张图片
    springcloud学习笔记_第61张图片
  • 发布订阅(Publish、Subscribe),又根据交换机类型不同分为三种:
    • Fanout Exchange:广播
    • Direct Exchange: 路由
    • Topic Exchange: 主题
      springcloud学习笔记_第62张图片
      springcloud学习笔记_第63张图片
      springcloud学习笔记_第64张图片
      HelloWorld案例
      官方的HelloWorld是基于最基础的消息队列模型来实现的,只包括三个角色:
  • publisher:消息发布者,将消息发送到队列queue
  • queue:消息队列,负责接受并缓存消息
  • consumer:订阅队列,处理队列中的消息
    在这里插入图片描述

11.3.SpringAMQP

  • 步骤1:引入AMQP依赖
    因为publisher和consumer服务都是需要依赖AMQP,因此这里把依赖直接放到父工程mq-demo中:
    springcloud学习笔记_第65张图片
  • 步骤2:在publisher中编写测试方法,向simple.queue发送消息
  1. 在publisher服务中编写application.yml,添加mq链接信息:
    springcloud学习笔记_第66张图片
    2.在publisher服务中新建一个测试类,编写测试方法:
    springcloud学习笔记_第67张图片

步骤3:在consumer中编写消费逻辑,监听simple.queue

  1. zai consumer服务中编写application.yml,添加mq连接信息:
    springcloud学习笔记_第68张图片
  2. 在cpmsumer服务中新建一个类,编写消费逻辑:

springcloud学习笔记_第69张图片

你可能感兴趣的:(springcloud,spring,cloud,学习,java)