Bootstrap

Spring Cloud 入门,一篇搞定!

一、微服务介绍

1、简介

微服务(或称微服务架构)是一种分布式架构方案,即,一个应用应该是一组小型服务,每个服务器只负责一种服务,服务之间可以通过 HTTP 的方式进行互通。每一个功能元素最终都是一个可独立替换和独立升级的软件单元。

微服务架构特征

  • 单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发
  • 面向服务:微服务对外暴露业务接口
  • 自治:团队独立、技术独立、数据独立、部署独立
  • 隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题

微服务:一种良好的分布式架构方案

优点:拆分粒度更小、服务更独立、耦合度更低

缺点:架构非常复杂,运维、监控、部署难度提高

2、学习的知识点

3、学习路线


二、单体架构和分布式架构

1、单体架构

简单方便,高度耦合,扩展性差,适合小型项目。例如:学生管理系统

2、分布式架构

松耦合,扩展性好,但架构复杂,难度大。适合大型互联网项目,例如:京东、淘宝


三、微服务结构 与 主流技术对比

1、微服务结构

2、微服务技术对比


四、Spring Cloud 介绍

1、简介

  • SpringCloud是目前国内使用最广泛的微服务框架。官网地址:https://spring.io/projects/spring-cloud。
  • SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了这些组件的自动装配,从而提供了良好的开箱即用体验。

2、兼容的 SpringBoot 版本


五、服务拆分

1、注意事项

  • 单一职责:不同微服务,不要重复开发相同业务
  • 数据独立:不要访问其它微服务的数据库
  • 面向服务:将自己的业务暴露为接口,供其它微服务调用

2、服务拆分项目

 这是一个拆分好的基于 SpringBoot 的 Spring Cloud 项目,如下:

链接:https://pan.baidu.com/s/1DG4B-Hlyab1bVDRxjSh5nQ?pwd=k1f4 
提取码:k1f4 


六、服务远程调用(RestTemplate)

各服务之间可以通过发起 http 请求获取对方数据

1、注册 RestTemplate 工具类

Spring 提供了 RestTemplate 工具类,可以用于各服务之间发起 HTTP 请求

通过编写配置类,将 RestTemplate 注入到 Spring 容器中

2、发起HTTP请求

在消费者端的 Service 层编写代码

例如 OrderService 向 UserService 发起请求获取数据:

getForObject 方法是发起 Get 方式请求,具体的请求方式以 要请求的接口规范更改


 七、提供者 与 消费者概念

  • 服务提供者:一次业务中,被其它微服务调用的服务。(提供接口给其它微服务)
  • 服务消费者:一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)

服务调用关系

  • 服务提供者:暴露接口给其它微服务调用
  • 服务消费者:调用其它微服务提供的接口
  • 提供者与消费者角色其实是相对的
  • 一个服务可以同时是服务提供者和服务消费者


八、Eureka 注册中心组件

1、没有注册中心引出的问题

根据前面的服务远程调用案例来看,从一个服务消费者向一个服务提供者发起请求,需要将请求路径写死在代码中,容易引发如下问题:

  • 若服务提供者地址有变动时,需要手动修改请求路径,并重新启动服务器才能生效。
  • 若有多个服务提供者(服务器集群),消费者想要向不同的服务提供者发起请求,也是需要每次手动修改请求路径,并重新启动服务器才能生效。

2、Eureka 注册中心作用

  • 消费者该如何获取服务提供者具体信息?
    • 服务提供者启动时向eureka注册自己的信息
    • eureka保存这些信息
    • 消费者根据服务名称向eureka拉取提供者信息
  • 如果有多个服务提供者,消费者该如何选择?
    • 服务消费者利用负载均衡算法,从服务列表中挑选一个
  • 消费者如何感知服务提供者健康状态?
    • 服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态
    • eureka会更新记录服务列表信息,心跳不正常会被剔除
    • 消费者就可以拉取到最新的信息

Eureka-Server:注册中心,存放 Eureka 客户端信息

Euraka-Client:Euraka 客户端,包含服务提供者和服务消费者。

在Eureka架构中,微服务角色有两类

  • EurekaServer:服务端,注册中心
    • 记录服务信息
    • 心跳监控
  • EurekaClient:客户端
    • Provider:服务提供者,例如案例中的 user-service
      • 注册自己的信息到EurekaServer
      • 每隔30秒向EurekaServer发送心跳
    • consumer:服务消费者,例如案例中的 order-service
      • 根据服务名称从EurekaServer拉取服务列表
      • 基于服务列表做负载均衡,选中一个微服务后发起远程调用


九、搭建 Eureka 服务

1、搭建 Eureka 服务端

  1. 创建项目,引入spring-cloud-starter-netflix-eureka-server的依赖
    1. <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
      </dependency>
      
  2. 编写启动类,添加@EnableEurekaServer注解
  3. 添加application.yml文件,编写下面的配置:
    1. server:
        port: 10086    # 服务端口
      spring:
        application:
          name: eurekaserver   # eureka 的服务名称
      eureka:
        client:
          service-url:      # eureka 服务的地址信息,若有多个 eureka 服务地址用空格隔开,组成集群
            defaultZone: http://127.0.0.1:10086/eureka/
      
  4. 启动 Eureka 服务

2、搭建 Eureka 客户端

多个客户端的注册步骤相同

注册成功示例:

所有注册到 Eureka 的服务都会在实例列表中展示出来

3、在 IDEA 中多开实例(拓展)

4、Eureka 服务拉取

示例:

5、Eureka 注册中心搭建总结


十、Ribbon 负载均衡

1、负载均衡原理

原理流程:

Ribbon 通过 @LoadBalanced 注解标记了 RestTemplate 工具类,所以 Ribbon 就会去拦截 RestTemplate 所发起的 HTTP 请求,并做出一系列对策。

首先,Ribbon 底层通过 LoadBalancerInterceptor 拦截器对 RestTemplate 的HTTP请求进行拦截,再将拦截到的服务名称传递给 Ribbon 的负载均衡客户端 RibbonLoadBalancerClient

负载均衡客户端会根据服务名称去找 Eureka 拉取服务列表

负载均衡客户端再通过 IRule 接口选出负载均衡策略,并根据策略返回服务地址

最后 RestTemplate 会将返回的服务地址替换掉原本服务名称,并通过HTTP请求访问真实的服务地址,最终实现负载均衡。

2、负载均衡策略

Ribbon的负载均衡规则是一个叫做IRule的接口来定义的,每一个子接口都是一种规则:

3、配置负载均衡策略

可知默认的负载均衡策略是 RoundRobinRule 轮询策略,想要修改轮询策略可以通过以下两种方式:

1)方式一:通过 @Bean 注解注入到容器

创建新的 IRule 策略对象,并注入到 Spring 容器中

示例:

2)方式二:修改配置文件

示例:

4、配置饥饿加载策略

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

示例:

多个服务名称,换行并用 - 隔开

懒加载,第一次访问耗时约:

饥饿加载,第一次访问耗时约:

5、Ribbon 负载均衡小结

  1. Ribbon负载均衡规则
    1. 规则接口是IRule
    2. 默认实现是ZoneAvoidanceRule,根据zone选择服务列表,然后轮询
  2. 负载均衡自定义方式
    1. 代码方式:配置灵活,但修改时需要重新打包发布
    2. 配置方式:直观,方便,无需重新打包发布,但是无法做全局配置
  3. 饥饿加载
    1. 开启饥饿加载
    2. 指定饥饿加载的微服务名称


十一、Nacos 注册中心组件

Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高。

1、安装

Nacos 安装指南:

链接:https://pan.baidu.com/s/1WpYPm9qIx_CXE8RIGxCJHA?pwd=l827 
提取码:l827 

1)下载安装包

在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码:

GitHub主页:https://github.com/alibaba/nacos

GitHub的Release下载页:https://github.com/alibaba/nacos/releases

2)解压

将这个包解压到任意非中文目录下,如图:

目录说明:

  • bin:启动脚本

  • conf:配置文件

3)端口配置

Nacos的默认端口是8848,如果你电脑上的其它进程占用了8848端口,请先尝试关闭该进程。

如果无法关闭占用8848端口的进程,也可以进入nacos的conf目录,修改配置文件中的端口:

修改其中的内容:

4)启动

启动非常简单,进入bin目录,结构如下:

然后执行命令即可:

  • windows命令:

    startup.cmd -m standalone

执行后的效果如图:

5)访问

在浏览器输入地址:http://127.0.0.1:8848/nacos即可:

默认的账号和密码是nacos,进入:

2、Nacos 服务注册和发现

  1. 在cloud-demo父工程中添加spring-cloud-alilbaba的管理依赖:
  2. 注释掉order-service和user-service中原有的eureka依赖。
  3. 添加nacos的客户端依赖:
  4. 修改user-service&order-service中的application.yml文件,注释eureka地址,添加nacos地址:
  5.  启动并测试

3、Nacos 服务集群分级和部署

1)服务分级存储模型

  1. 一级是服务,例如userservice
  2. 二级是集群,例如杭州或上海
  3. 三级是实例,例如杭州机房的某台部署了userservice的服务器

2)服务跨集群调用问题

服务调用尽可能选择本地集群的服务,跨集群调用延迟较高

本地集群不可访问时,再去访问其它集群

3)服务集群属性配置

给实例分配集群

  1. 修改application.yml,添加如下内容 
  2.  在Nacos控制台可以看到集群变化
    1.  

可以配置多个集群,如下:

4、Nacos 负载均衡

1)配置负载均衡

Nacos 注册中心的默认策略方案是 NacosRule

NacosRule策略特点:

  • 优先选择同集群服务实例列表
  • 本地集群找不到提供者,才去其它集群寻找,并且会报警告
  • 确定了可用实例列表后,再采用随机负载均衡挑选实例

NacosRule 策略会优先访问本地集群,然后在通过随机策略访问集群中的服务实例。

(只有本地集群无法访问到才会访问外地集群,访问外地集群时,会输出类似以下的提醒信息)

  1. 修改order-service中的application.yml,设置集群为HZ:
  2. 然后在order-service中设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务

2)权重负载均衡策略

权重负载均衡策略特点:

  • Nacos控制台可以设置实例的权重值,0~1之间
  • 同集群内的多个实例,权重越高被访问的频率越高
  • 权重设置为0则完全不会被访问

进入 Nacos 注册中心控制台,可直接编辑实例的权重值,如下图:

5、Nacos 环境隔离

1)环境隔离概念

Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离

2)环境隔离配置

特点:

  • 每个namespace都有唯一id
  • 服务设置namespace时要写id而不是名称
  • 不同namespace下的服务互相不可见(无法相互访问)
  1. 在Nacos控制台可以创建namespace,用来隔离不同环境
  2.  填写一个新的命名空间信息
  3.  保存后会在控制台看到这个命名空间的id
    1.  
  4. 修改order-service(消费者)的application.yml,添加namespace 
    1.  
  5.  重启order-service后,再来查看控制台
    1.  
  6.  此时访问order-service,因为namespace不同,会导致找不到userservice,控制台会报错
    1.  


十二、Nacos 注册中心与 Eureka 注册中心的对比

1、Nacos 注册中心原理图

2、Nacos 配置临时实例和非临时实例

服务注册到Nacos时,可以选择注册为临时或非临时实例,通过下面的配置来设置:

临时实例宕机时,会从nacos的服务列表中剔除,而非临时实例则不会

3、Nacos 注册中心与 Eureka 注册中心的共同点和区别

共同点:

  • 都支持服务注册和服务拉取
  • 都支持服务提供者心跳方式做健康检测

区别:

  • Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
  • 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
  • Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
  • Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式

(AP模式:强调集群的可用性;CP模式:强调集群的可靠性、一致性)


十三、Nacos 配置管理

1、添加统一配置


  1. 在Nacos中添加配置信息:
    1.  
  2.  在弹出表单中填写配置信息
    1.  
    2. profile:指的是环境名称,例如:dev开发环境,test测试环境等
    3. 配置内容:填写所有服务中有热更新需求的内容(可以开关的内容),例如上面的时间展示功能
  3.  发布
    1.  

2、拉取统一配置

1)项目启动路线的变更

2)拉取配置步骤

  1. 在 userservice 引入Nacos的配置管理客户端依赖
    1.  
  2.  在userservice中的resource目录添加一个bootstrap.yml文件,这个文件是引导文件,优先级高于application.yml:
      1. 注:服务名称 + 开发环境 + 文件后缀名 = 配置文件id
  3.  属性注入,我们将配置文件中的pattern.dateformat属性通过@Value注解注入到dateformat属性中做测试
    1.  

3、配置热更新(自动更新)

Nacos中的配置文件变更后,微服务无需重启就可以感知。有以下两种方式实现:

1)方式一:在@Value注入的变量所在类上添加注解@RefreshScope

2)方式二:使用@ConfigurationProperties注解

通过定义配置类的方式注册到 Spring 容器中,再通过 @Autowired 注解实现属性注入 

prefix 是统一配置文件中属性的前缀

 可以写多个属性

3、多环境配置共享

微服务启动时会从nacos读取多个配置文件:

  • [spring.application.name]-[spring.profiles.active].yaml,例如:userservice-dev.yaml
  • [spring.application.name].yaml,例如:userservice.yaml

无论profile如何变化,[spring.application.name].yaml这个文件一定会加载,因此多环境共享配置可以写入这个文件

只以服务名称命名的配置文件,就是多环境共享的。

例如:下图的 userservice.yaml 

案例测试:

  1. 新建一个 userservic.yaml 共享的统一配置文件,并定义一个变量为:envSharedValue
    1.  
    2.  如下图所示,之前配置了一个 dev 环境的配置文件,里面有个属性是 dateformat,现在一共有两个统一配置文件
  2. 将共享配置文件的属性页配置到配置类中,并注入到 Controller 类中
    1.  

      1. 页面会将对象类型的 方法返回值解析为JSON格式,并展示到页面
  3. 启动两个不同环境的服务 userservice1(dev环境,8081端口)、userservice2(test环境,8082端口),会发现两个不同环境的服务都能共享到 userservice.yaml 配置文件中的 envSharedValue 属性。
    1.  
    2.  

4、配置文件的优先级

当本地配置 和 nacos 的远端配置 都定义了同名的属性时,遵循以下优先级:

服务名-开发环境.yaml  >  服务名.yaml  >  本地配置

注:本地配置 是指 application.yml 

举例:

当有三个配置文件 userservice-dev.yaml 、 userservice.yaml 、application.yml 都有 name 属性时,优先级为:userservice-dev.yaml  > userservice.yaml  > application.yml


十四、搭建 nacos 集群

nacos 集群搭建教程:

链接:https://pan.baidu.com/s/1dk9sAOXJOZ1QSJqNTNH6Fg?pwd=quw5 
提取码:quw5 

集群搭建步骤

  1. 搭建MySQL集群并初始化数据库表
  2. 下载解压nacos
  3. 修改集群配置(节点信息)、数据库配置
  4. 分别启动多个nacos节点
  5. nginx反向代理

由于只有一台机器,不方便搭建集群。所以就不演示了


十五、Feign 客户端

1、Feign 介绍

Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign

其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。

为什么要学习?

先来看我们以前利用RestTemplate发起远程调用的代码:

存在下面的问题:

  • 代码可读性差,编程体验不统一
  • 参数复杂URL难以维护

RestTemplate 如果在 URL 上传递多个参数时,会变得很复杂,难以维护。

例如:

百度搜索时,URL 的复杂程度就知道了

2、定义和使用 Feign 客户端

使用Feign的步骤如下:

  1. 引入依赖:
    1.  
  2.  在 order-service 的启动类添加注解开启 Feign 的功能:
  3.  编写Feign客户端:

    1.  
    2.   
    3. 主要是基于SpringMVC的注解来声明远程调用的信息,比如:
    4. 目标服务名称:userservice
    5. 请求方式:GET
    6. 请求路径:/user/{id}
    7. 请求参数:Long id
    8. 返回值类型:User
  4.  用 Feign 客户端代替RestTemplate
    1.  UserClient 本质是个接口,是无法直接创建对象的。所以底层通过动态代理的技术创建对象。
  5. 启动 orderservice 服务,向 userservice 发起请求即可


十六、Feign 自定义配置

Feign运行自定义配置来覆盖默认配置,可以修改的配置如下:

一般我们需要配置的就是日志级别。

1、配置 Feign 日志

日志等级建议:一般推荐 NONE 或 BASIC,需要调试错误时 FULL(因为更详细)

1)方式一:通过配置文件 application.yml

①全局生效配置:

②局部生效配置:

若是局部生效就写服务名,若是全局生效就写 default

2)方式二:通过自定义配置类

①先定义配置类

②全局生效配置:

如果是全局配置,则把它放到@EnableFeignClients这个注解中:

③局部生效配置:

如果是局部配置,则把它放到@FeignClient这个注解中:


十七、Feign 性能优化

1、前言

由于 Feign 是基于 HTTP 技术实现的,HTTP 底层又使用的 TCP 协议,建立连接时需要“三次握手四次挥手”,所以使用 Feign 每次发起请求时都会有性能消耗,这时候可以采用 连接池 的方式对 Feign 进行性能优化。

Feign 底层客户端实现:

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

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

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

2、连接池配置

  1. 引入 HttpClient 依赖
    1.  
  2.  配置连接池
    1.  application.yml

十八、Feign 最佳实践

  1. 让controller和FeignClient继承同一接口
  2. 将FeignClient、POJO、Feign的默认配置都定义到一个项目中,供所有消费者使用

原因:

消费者的客户端 FeignClient 代码与提供者的 Controller 层代码高度重合。

1、方式一(统一接口)(不推荐)

给消费者的 Feign 客户端与提供者的 controller 定义统一的父接口作为标准。

缺点:

2、方式二(抽取模块)

将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用。

实现步骤

实现方式二的步骤如下:

  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. 在消费者启动类中,添加 Feign 客户端扫描范围
    1.  扫描整个包
    2. 扫描单个类
    3.  
  6. 重启测试


十九、Gateway 统一网关

1、网关的作用

对用户请求进行:

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

2、搭建网关服务

  1. 创建新的 module,引入 SpringCloudGateway 的依赖、nacos 服务发现依赖
    1.   创建module
    2.  
    3.  引入依赖
    4.  编写启动类

 配置路由和 nacos 地址

网关路由可以配置的内容包括:

  • 路由id:路由唯一标示
  • uri:路由目的地,支持lb和http两种
  • predicates:路由断言,判断请求是否符合要求,符合则转发到路由目的地
  • filters:路由过滤器,处理请求或响应

 在 application 配置文件中编写

也可以配置多个路由

3、路由断言工厂 Route Predicate Factory

Predicate Factory 的作用:读取用户定义的断言规则,并解析成对应的判断条件

Path=/user/** 的含义:只匹配 /user 开头的请求路径

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

例:新增 Before 规则,只接收某个时间之前的用户请求

4、路由过滤器 GatewayFilter 介绍

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理

5、路由过滤器工厂 GatewayFilter Factory

1)路由过滤器

路由过滤器:只对当前路由的请求生效。

案例:给所有进入userservice的请求添加一个请求头

需要添加的请求头:Truth=itcast is freaking awesome!

实现方式:在gateway中修改application.yml文件,给userservice的路由添加过滤器

在 Controller 层获取请求头参数:

2)默认过滤器

以上案例中,采用的是局部过滤器,只对某个路由生效
  • 局部过滤器:对当前路由生效
  • 默认过滤器:对所有路由生效
默认过滤器配置如下

3)全局过滤器

全局过滤器是一个能对所有请求进行过滤的过滤器,可以通过编写代码来控制过滤逻辑业务。

默认过滤器与全局过滤器的区别:

  • 相同点:
    • 都是对所有的请求路由进行过滤。
  • 不同点:
    • 默认过滤器:通过配置文件方式定义,处理逻辑是固定的。
    • 全局过滤器:通过编写代码方式定义,处理逻辑是自定义的。

定义方式:实现 GlobalFilter接口,重写 filter 方法。

全局过滤器案例:定义全局过滤器,拦截并判断用户身份

需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件

  • 参数中是否有authorization
  • authorization参数值是否为admin

如果同时满足则放行,否则拦截

代码如下:

@Order注解是用于定义拦截器的优先级,值越小优先级越高。

定义拦截器优先级的方式有两种:

  • 通过 @Order 注解
  • 通过实现 Ordered 接口,并重写 getOrder 方法(与注解方式作用相同),如下图:

6、过滤器执行顺序

过滤器链的执行顺序:

在一整个过滤器链中,包含三个不同的过滤器,并且按照以下执行顺序排序:

默认过滤器  >  路由过滤器  >  全局过滤器

各过滤器执行优先级:

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

可以参考下面几个类的源码来查看:

过滤器链组成原理:

因为这三个过滤器都是相同的类型(GatewayFilter),所以才能组成一个过滤器链(集合)

        在过滤器工厂 GatewayFilter Factory 执行时,会去读取 application 文件中定义的 路由过滤器、默认过滤器的配置,并会根据配置生成一个真正的 GatewayFilter 类型的过滤器。

并且由于 全局过滤器 是 GlobalFilter类型的过滤器,则由网关过滤器适配器类 GatewayFilterAdapter 来将 GlobalFilter 类型的过滤器转换成 GatewayFilter 类型的过滤器。

​​​​​​​

7、跨域问题处理

1)跨域问题介绍和处理方式

跨域:地址不一致时,就是跨域,主要包括:

  • 域名不同:www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com
  • 域名相同,端口不同:localhost:8080 和 localhost:8081

跨域问题:浏览器禁止请求的发起者与服务端发生跨域Ajax请求,请求被浏览器拦截的问题

跨域问题解决方案:CORS

CORS 作用:允许浏览器发起跨域的Ajax请求。

(服务器之间互相访问时不会存在跨域问题,因为只是浏览器禁止Ajax请求跨域)

网关处理跨域采用的同样是CORS方案,并且只需要简单配置即可实现:

2)案例测试

前端页面代码,发起ajax跨域请求

后端服务器代码:

请求成功结果:

请求失败结果:

(提示 CORS 策略出问题)

;