1.什么是路由网关

截至目前为止的例子中,我们创建了一个service,叫做:HelloService,然后我们把它部署到了两台服务器(即提供了两个provider),然后我们又使用ribbon将其做了负载均衡。目前为止这一切都看上运作的很好,我们通过地址访问地址http://localhost:9291/hello,实际是路由到了http://localhost:9191/hello和http://localhost:9192/hello两个服务器上。

紧接着,随着业务更进一步,我们又创建了UserService,又创建了ProductService,我们提供的服务器也越来越多,但是我们发现一个问题,即:即提供一种服务,前端程序员都需要通过IP+端口的形式去访问,很快URL地址就多的爆炸了,而且,甚至某些别有用心的同学因为知道了这些目标地址,开始采用非常规的手段去做些坏事。所以,我们必须做些手段来规避这些糟糕的事情。

路由网关出现了。

当我们输入URL,比如zuikc.com/hello或者zuikc.com/user的时候,路由网关会去分析这个地址,并且根据地址的pattern,

1:去决定到底是访问helloservice还是userservice;

2:到eureka注册中心拿到该服务的id;

3:通过ribbon去访问该服务id中的一台provider;

4:拿到response,返回给调用者;

并且,由于路由网关能做这些事情,还有额外的一些事情,比如权限验证(shiro,springsecurity等),就天然的适合放到路由网关也一并实现了。

关于路由网关,以前有zuul,但是zuul已经停止更新了,Spring Cloud Gateway被Spring Cloud官方推出来,作为第二代网关框架,取代Zuul网关。

总结一下,路由网关的作用就是:路由转发、权限校验、限流控制。

2.路由网关原理

来看Spring Cloud Gateway官方提供的架构图,

客户端向Spring Cloud Gateway发出请求。 Gateway Handler Mapping匹配路径并将其发送到Gateway web handler处理。 Gateway web handler处理请求,将其发送给过滤器链。

过滤器链主要分两大类:pre和post。“pre”过滤器一般进行权限、限流、日志输出等功能,以及请求头的更改、协议的转换;“post”过滤器是在收到响应后,可以对响应数据做统一修改,比如响应头、协议的转换等。

3.实现

现在,让我们用代码实现一下吧。

首先,创建子模块,在我们的例子中,创建完毕后,解决方案像如下这样,

现在,导入依赖如下:

<?xml version="1.0" encoding="UTF-8"?>

<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/maven-v4_0_0.xsd">

<parent>

<artifactId>springcloud.parent</artifactId>

<groupId>com.zuikc</groupId>

<version>1.0-SNAPSHOT</version>

</parent>

<modelVersion>4.0.0</modelVersion>

<packaging>war</packaging>

<name>gateway</name>

<artifactId>gateway</artifactId>

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>Greenwich.RELEASE</version>

<type>pom</type>

<scope>import</scope>

</dependency>

</dependencies>

</dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-gateway</artifactId>

</dependency>

</dependencies>

</project>

先创建一个最简单的application.yml,

server:

port: 8880

然后,让我们创建application类,

package com.zuikc;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.gateway.route.RouteLocator;

import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;

import org.springframework.context.annotation.Bean;

import org.springframework.web.bind.annotation.RestController;

/**

* @ClassName GatewayApplication

* @Description 我们提供咨询和培训服务,关于本文有任何困惑,请关注并联系“码农星球”

* @Author 码农星球

**/

@SpringBootApplication

@RestController

public class GatewayApplication {

public static void main(String[] args) {

SpringApplication.run(GatewayApplication.class, args);

}

@Bean

public RouteLocator myRoutes(RouteLocatorBuilder builder) {

return builder.routes()

.route("host_route", r -> r.path("/hello/**").filters(f -> f.stripPrefix(1)).uri("http://localhost:9291"))

.route("host_route", r -> r.path("/user/**").filters(f -> f.stripPrefix(1)).uri("http://localhost:9391"))

.build();

}

}

在这个类中,我们将“域名/hello”下的所有请求转发到了HelloService所在ribbon服务器中,将“域名/user”下所有的请求转到User所在的ribbon下。

然后,启动application。这个时候,让我们输入地址:http://localhost:8880/hello/hello,可以看到结果类似如下:

服务将在两个provider中切换。注意,上述url中,第一个hello,是指路由到helloservice中,第二个hello,是具体的服务。

接下来,让我们试一下,http://localhost:8880/user/something。由于我们目前并没有开发UserService,所以就出现errorpage了~~

4.使用配置实现

我们也可以使用配置来实现路由。

在上面的代码中,我们首先去掉application中的bean,

package com.zuikc;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.gateway.route.RouteLocator;

import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;

import org.springframework.context.annotation.Bean;

import org.springframework.web.bind.annotation.RestController;

/**

* @ClassName GatewayApplication

* @Description 我们提供咨询和培训服务,关于本文有任何困惑,请关注并联系“码农星球”

* @Author 码农星球

**/

@SpringBootApplication

@RestController

public class GatewayApplication {

public static void main(String[] args) {

SpringApplication.run(GatewayApplication.class, args);

}

}

然后,修改application.yml,

server:

port: 8880

spring:

cloud:

gateway:

routes:

- id: host_route

uri: http://localhost:9291

predicates:

- Path=/hello/**

filters:

- StripPrefix=1

- id: host_route

uri: http://localhost:9391

predicates:

- Path=/user/**

filters:

- StripPrefix=1

然后,重启application,得到的效果是一样一样滴。

5.通过filters使用Hystrix

如果注意上文中的http://localhost:8880/user/something,我们发现原来在gateway中也是可以指定熔断器fallback的。

那就好办了,首先,让我们引入hystrix,

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>

</dependency>

其次,创建一个fallback,

package com.zuikc;

import org.springframework.stereotype.Component;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**

* @ClassName FallBack

* @Description 我们提供咨询和培训服务,关于本文有任何困惑,请关注并联系“码农星球”

* @Author 码农星球

**/

@RestController

@RequestMapping("/fallback")

public class FallBack {

@RequestMapping("")

public String fallback(){

return "error";

}

}

再次,修改我们的配置文件,

server:

port: 8880

spring:

cloud:

gateway:

routes:

- id: host_route

uri: http://localhost:9291

predicates:

- Path=/hello/**

filters:

- StripPrefix=1

- id: host_route

uri: http://localhost:9391

predicates:

- Path=/user/**

filters:

- StripPrefix=1

- name: Hystrix

args:

name: fallbackcmd

fallbackUri: forward:/fallback

重启application。

这个时候,再次访问http://localhost:8880/user/something,页面输出为error。

感谢关注“码农星球”。本文版权属于“码农星球”。我们提供咨询和培训服务,关于本文有任何困惑,请关注并联系我们。

本文参考:https://spring.io/guides/gs/gateway/

一些官方的例子在:

http://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.0.0.RELEASE/single/spring-cloud-gateway.html

SpringCloud无废话入门05:Spring Cloud Gateway路由、filter、熔断的更多相关文章

  1. 跟我学SpringCloud | 第十三篇:Spring Cloud Gateway服务化和过滤器

    SpringCloud系列教程 | 第十三篇:Spring Cloud Gateway服务化和过滤器 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich. ...

  2. springcloud(十七):服务网关 Spring Cloud GateWay 熔断、限流、重试

    上篇文章介绍了 Gataway 和注册中心的使用,以及 Gataway 中 Filter 的基本使用,这篇文章我们将继续介绍 Filter 的一些常用功能. 修改请求路径的过滤器 StripPrefi ...

  3. spring cloud gateway之filter篇

    转载请标明出处: https://www.fangzhipeng.com 本文出自方志朋的博客 在上一篇文章详细的介绍了Gateway的Predict,Predict决定了请求由哪一个路由处理,在路由 ...

  4. 深入学习spring cloud gateway 限流熔断

    前言 Spring Cloud Gateway 目前,Spring Cloud Gateway是仅次于Spring Cloud Netflix的第二个最受欢迎的Spring Cloud项目(就GitH ...

  5. Spring Cloud Gateway - 路由法则

    1. After Route Predicate Factory 输入一个参数:时间,匹配该时间之后的请求,示例配置: spring: cloud: gateway: routes: - id: af ...

  6. Spring cloud gateway自定义filter以及负载均衡

    自定义全局filter package com.example.demo; import java.nio.charset.StandardCharsets; import org.apache.co ...

  7. SpringCloud无废话入门01:最简SpringCloud应用

    1.创建Parent Parent很简单,创建一个空的maven项目,pom如下: <?xml version="1.0" encoding="UTF-8" ...

  8. SpringCloud无废话入门04:Hystrix熔断器及监控

    1.断路器(Circuit Breaker)模式 在上文中,我们人为停掉了一个provider,在实际的生产环境中,因为意外某个服务down掉,甚至某一层服务down掉也是会是有发生的.一旦发生这种情 ...

  9. SpringCloud无废话入门02:Ribbon负载均衡

    1.白话负载均衡 在上一篇的介绍中,我们创建了两个一模一样的服务提供者:Provider1和Provider2,然后它们提供的服务也一模一样,都叫Hello-Service.为什么一样的服务我们要部署 ...

随机推荐

  1. 【转】git shell 命令大全

    http://www.cnblogs.com/bugs/p/3384339.html 常用命令 git branch 查看本地所有分支 git status 查看当前状态 git commit 提交 ...

  2. 在ionic2中集成swiper插件

    1. 下载官方的js和css文件分别放在assets下的js和css文件夹,然后在index.html中引入 <!DOCTYPE html> <html lang="en& ...

  3. linux查看文件的后几行

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAu4AAABiCAIAAACAksEXAAAZuUlEQVR4nO2dzdmzuq6G0wRV0ARNMM

  4. P1182 数列分段`Section II` P1316 丢瓶盖 二分答案

    题目描述 对于给定的一个长度为N的正整数数列A-iA−i,现要将其分成M(M≤N)M(M≤N)段,并要求每段连续,且每段和的最大值最小. 关于最大值最小: 例如一数列4 2 4 5 142451要分成 ...

  5. 使用soupUI做接口测试

    第一步:点击“file”,选择测试项目采用的协议:(这里我们测试的是http协议的,所以选择第三项)   第二步:在弹窗中输入测试项目的接口URL,并点击“OK”: 第三步:设置和填写请求项的内容并点 ...

  6. elementui command绑定变量对象方法

    command绑定变量对象方法 使用v-bind : command绑定 简写 :command

  7. linux定时任务相关

    定时任务所在文件夹 /etc/crontab 定时任务重启命令 service crond restart

  8. Python import错误

    今天将一个文件命名为select,在其中import了  A文件 再然后发现 B文件import A文件,会将select也一起运行. 还出现的问题是 A中的类实例的时候说找不到. 最后想到selec ...

  9. js算法初窥07(算法复杂度)

    算法复杂度是我们来衡量一个算法执行效率的一个度量标准,算法复杂度通常主要有时间复杂度和空间复杂度两种.时间复杂度就是指算法代码在运行最终得到我们想要的结果时所消耗的时间,而空间复杂度则是指算法中用来存 ...

  10. JAVA导入表格功能总结

    表格结构: SheetName:sheet名称(辅材采购申请单) RowNum:行数 FirstCellNum/LastCellNum:第一竖列/最后一竖列(从0开始),例:getCell(0) = ...