目标:

创建一个Zuul 网关服务模块,通过服务网关访问内部的服务。

步骤:

1.创建网关服务模块 SpringbootGW ,在pom文件中加入Zuul的支持依赖,网关服务模块会通过注册中心访问服务提供者,同时也需要加入Eureka Client 支持。

2. 在Application.properties 中加入相关配置,使用默认Zuul的配置规则,暂时不配置Zuul的路由。

server.port=6060
spring.application.name=GW
eureka.client.serviceUrl.defaultZone=http://eureka1:9001/eureka/,http://eureka1:9002/eureka/,http://eureka1:9003/eureka/

3. 在启动类上加Zuul的注解

@EnableZuulProxy

4. 添加一个用户获取RestTemplate对象的 配置类

@Configuration
public class BeanConfig {@LoadBalanced@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}

5. 创建网关访问controller , 在测试controller 中网关通过Eureka 调用服务提供者。

package com.shamusoft.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;@RestController
public class GWController {@Autowiredprivate RestTemplate restTemplate;@RequestMapping("/sayGWHello")public String sayGWHello(){//   RestTemplate restTemplate = new RestTemplate();String message = restTemplate.getForEntity("http://provider/providerHello",String.class).getBody();return "GW Hello"+message;}}

6. 启动网关模块测试。

在浏览器中通过网关调用注册在Eureka 上的服务提供者. 请注意分析 地址 http://localhost:6060/provider/providerHello

6.1 通过网关访问服务时把Eureka上服务提供者名字换成自定义的服务名,例如加myapi . 修改Application.properties 文件.

两种方式,第一种:配置path 和servericeId.

第二种:直接配置服务提供者

server.port=6060
spring.application.name=GW
eureka.client.serviceUrl.defaultZone=http://eureka1:9001/eureka/,http://eureka1:9002/eureka/,http://eureka1:9003/eureka/#通过zuul 访问
zuul.routes.myapi.path=/myapi/**
zuul.routes.myapi.serviceId=provider#Zuul
zuul.routes.PROVIDER=/myapi2/**

打开浏览器测试:

第一种配置的访问规则:

第二种配置的访问规则:

默认的访问规则:

6.2 禁用默认的访问规则

6.2.1 创建一个子服务提供者SpringbootProvider3Sub,禁止网关外的访问提供服务

6.2.2 在pom文件中加入springboot 基础依赖和Eureka的依赖

<?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/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.shamusoft</groupId><artifactId>SpringbootProvider3Sub</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.5.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><spring-cloud.version>Greenwich.SR1</spring-cloud.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 增加Eureka的支持 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><dependencyManagement><dependencies><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><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

6.2.3 配置Apllication.properties 文件

server.port=8003
#不要用大小写字母 有可能会出问题
spring.application.name=provider-sub
#每间隔2s,向服务端发送一次心跳,证明自己依然"存活"
eureka.instance.lease-renewal-interval-in-seconds=2
#告诉服务端,如果我10s之内没有给你发心跳,就代表我故障了,将我踢出掉
eureka.instance.lease-expiration-duration-in-seconds=10
eureka.client.serviceUrl.defaultZone=http://eureka1:9001/eureka,http://eureka2:9002/eureka,http://eureka3:9003/eureka#springboot的监控端点访问权限,*表示所有的访问端点都允许访问
management.endpoints.web.exposure.include=*

6.2.4 在配置类上添加Euireka的注解

6.2.5 创建测试controller

@RestController
public class ProviderSay3Sub {@RequestMapping("/providerSubHello")public String providerHello(){return "provider3Sub hello";}
}

6.2.6 启动访问测试服务 ,刷新Eureka服务页面查看是否创建的服务注册成功.

6.2.7 因为没有给provider-sub 配置路由规则,所以启用默认路由规则。

http://192.168.242.1:6060/provider-sub/providerSubHello

6.2.7 禁用provider-sub 的默认路由配置规则,让provider-sub 通过网关对外不可访问。修改网关模块的Application.properties 文件。

server.port=6060
spring.application.name=GW
eureka.client.serviceUrl.defaultZone=http://eureka1:9001/eureka/,http://eureka1:9002/eureka/,http://eureka1:9003/eureka/###默认的路由规则
## http://192.168.242.1:6060/provider/providerHello#zuul.routes.provider.path=/provider/**
#zuul.routes.provider.serviceId=provider#通过zuul 访问
zuul.routes.myapi.path=/myapi/**
zuul.routes.myapi.serviceId=provider#Zuul
zuul.routes.PROVIDER=/myapi2/**#禁用zuul自带的过滤器
#zuul.SendErrorFilter.error.disable=true#忽略服务提供者的默认规则
zuul.ignored-services=provider-sub

6.2.8 重新启动网关模块访问 http://192.168.242.1:6060/provider-sub/providerSubHello

出现 404 页面.

7. 禁止服务提供者的某些服务不能通过网关对外访问。

7.1 在服务提供者中增加测试方法

package com.shamusoft.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ProviderSay1 {@RequestMapping("/providerHello")public String providerHello(){return "provider1 hello";}@RequestMapping("/system/sec")public String systemSec(){return "安全信息,不对外提供服务";}}

7.2 重新启动 SpringbootProvider1 ,测试是否能正常访问

URL : http://localhost:6060/provider/system/sec

7.3 在网关服务模块中配置禁用模块的服务地址对外访问

server.port=6060
spring.application.name=GW
eureka.client.serviceUrl.defaultZone=http://eureka1:9001/eureka/,http://eureka1:9002/eureka/,http://eureka1:9003/eureka/###默认的路由规则
## http://192.168.242.1:6060/provider/providerHello#zuul.routes.provider.path=/provider/**
#zuul.routes.provider.serviceId=provider#通过zuul 访问
zuul.routes.myapi.path=/myapi/**
zuul.routes.myapi.serviceId=provider#Zuul
zuul.routes.PROVIDER=/myapi2/**#zuul.routes.lgw.path=/lgw/**
#zuul.routes.lgw.url=forward:/mLocal/gwPage#禁用zuul自带的过滤器
#zuul.SendErrorFilter.error.disable=true#忽略服务提供者的默认规则
zuul.ignored-services=provider-sub##禁止某些匹配地址对外访问
zuul.ignored-patterns=/**/system/**

7.4 启动测试

http://localhost:6060/provider/system/sec  页面出现404

8.1 启用统一的网关访问前缀 , 修改网关模块的Application.properties 文件.

server.port=6060
spring.application.name=GW
eureka.client.serviceUrl.defaultZone=http://eureka1:9001/eureka/,http://eureka1:9002/eureka/,http://eureka1:9003/eureka/###默认的路由规则
## http://192.168.242.1:6060/provider/providerHello#zuul.routes.provider.path=/provider/**
#zuul.routes.provider.serviceId=provider#通过zuul 访问
zuul.routes.myapi.path=/myapi/**
zuul.routes.myapi.serviceId=provider#Zuul
zuul.routes.PROVIDER=/myapi2/**#zuul.routes.lgw.path=/lgw/**
#zuul.routes.lgw.url=forward:/mLocal/gwPage#禁用zuul自带的过滤器
#zuul.SendErrorFilter.error.disable=true#忽略服务提供者的默认规则
zuul.ignored-services=provider-sub##禁止某些匹配地址对外访问
zuul.ignored-patterns=/**/system/**
###为路由统一提供前缀
zuul.prefix=/papi

8.12重新启动网关模块测试:

之前访问地址:http://192.168.242.1:6060/myapi2/providerHello

加入统一前缀后的地址:http://192.168.242.1:6060/papi/myapi2/providerHello

9.1 当访问某些路径的时候 ,可以让请求转发到某些指定的路径。在配置文件Application.properties中配置转发

server.port=6060
spring.application.name=GW
eureka.client.serviceUrl.defaultZone=http://eureka1:9001/eureka/,http://eureka1:9002/eureka/,http://eureka1:9003/eureka/###默认的路由规则
## http://192.168.242.1:6060/provider/providerHello#zuul.routes.provider.path=/provider/**
#zuul.routes.provider.serviceId=provider#通过zuul 访问
zuul.routes.myapi.path=/myapi/**
zuul.routes.myapi.serviceId=provider#Zuul
zuul.routes.PROVIDER=/myapi2/**#zuul.routes.lgw.path=/lgw/**
#zuul.routes.lgw.url=forward:/mLocal/gwPage#禁用zuul自带的过滤器
zuul.SendErrorFilter.error.disable=true#忽略服务提供者的默认规则
zuul.ignored-services=provider-sub##禁止某些匹配地址对外访问
zuul.ignored-patterns=/**/system/**
###为路由统一提供前缀
zuul.prefix=/papi# 注意这里转发只是把路径中的xxx 替换成转发路径,但是转发路径后面的参数任然不变
# /xxx/abcpage 转发后的地址是 /mlocal/abcpage
zuul.routes.xxx.path=/xxx/**
zuul.routes.xxx.url=forward:/mlocal

9.2 在网关controller中创建一个测试controller.


@RestController
public class GWController {@Autowiredprivate RestTemplate restTemplate;@RequestMapping("/sayGWHello")public String sayGWHello(){//   RestTemplate restTemplate = new RestTemplate();String message = restTemplate.getForEntity("http://provider/providerHello",String.class).getBody();return "GW Hello"+message;}@RequestMapping("/callError")public String callError(){String message = restTemplate.getForEntity("http://provider/errorPage",String.class).getBody();return "call Error";}@RequestMapping("/mlocal/gwpage")public String apiLocal(){return "show GW page content.";}}

9.3 重启网关模块测试转发请求.

在此实验中遇到的黑坑,以为转发会把 匹配的路径完全替换转发到新的路径,经过实验测试发现转发只是替换其中的匹配路径而不是全部路径。

例如: http://192.168.242.1:6060/xxx/gwpage?token=1231231 ,可以显示 show GW page content. 此路径中会把xxx 替换成 /mlocal

实际转发后的路径为: http://192.168.242.1:6060/mlocal/gwpage?token=1231231

但是我们任意输入一个路径 :http://192.168.242.1:6060/papi/xxx/gwpage1111?token=1231231

实际转发后的路径为:http://192.168.242.1:6060/papi/mlocal/gwpage1111?token=1231231 但是这个路径不存在,会出现404页面,测试实验中配置了全局异常页面所以进入了全局异常控制处理器。

10 .Zuul 过滤器,Zuul 过滤器类型包括 pre,routing , post ,和error . 当pre ,routing , post 中有Zuul Exception 抛出时, error 类型的过滤器就会捕获异常进行处理。

10.1 定义一个pre 过滤器,当有请求到达时候,判断请求路径是否包含token , 如果不包含token 返回非法访问信息。

@Component
public class AuthFilter extends ZuulFilter {@Overridepublic String filterType() {return "pre";}@Overridepublic int filterOrder() {return 0;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() throws ZuulException {//int i = 1/0;//http://192.168.242.1:6060/provider/providerHello?token=12333System.out.println(">>>>>this is pre filter");RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();String token = request.getParameter("token");if (token == null) {ctx.setSendZuulResponse(false); //非法访问首先设置response 为falsectx.setResponseStatusCode(401);ctx.addZuulResponseHeader("content-type","text/html;charset=utf-8");ctx.setResponseBody("非法访问");}return null;}
}

10.2 重启网关服务模块 ,输入访问地址:

http://192.168.242.1:6060/papi/provider/providerHello

http://192.168.242.1:6060/papi/provider/providerHello?token=1231231

11.定义错误error过滤器,是在pre, routing, post 中发生的异常都可以被error 拦截器拦截。 修改配置文件Application.properties 禁用自带的错误过滤器.

server.port=6060
spring.application.name=GW
eureka.client.serviceUrl.defaultZone=http://eureka1:9001/eureka/,http://eureka1:9002/eureka/,http://eureka1:9003/eureka/###默认的路由规则
## http://192.168.242.1:6060/provider/providerHello#zuul.routes.provider.path=/provider/**
#zuul.routes.provider.serviceId=provider#通过zuul 访问
zuul.routes.myapi.path=/myapi/**
zuul.routes.myapi.serviceId=provider#Zuul
zuul.routes.PROVIDER=/myapi2/**#zuul.routes.lgw.path=/lgw/**
#zuul.routes.lgw.url=forward:/mLocal/gwPage#禁用zuul自带的过滤器
zuul.SendErrorFilter.error.disable=true#忽略服务提供者的默认规则
zuul.ignored-services=provider-sub##禁止某些匹配地址对外访问
zuul.ignored-patterns=/**/system/**
###为路由统一提供前缀
zuul.prefix=/papi# 必须设置prefix 否则不会被zuul转发
zuul.routes.index.path=/index/**
zuul.routes.index.url=forward:/mlocal/gwpage

11.1 编写error 过滤器 MErrorFilter


@Component
public class MErrorFilter extends ZuulFilter {@Overridepublic String filterType() {//只有pre routing,post 中发生的异常才可以拦截。对于服务提供方发生的异常不能拦截return "error";}@Overridepublic int filterOrder() {return 1;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() throws ZuulException {try {RequestContext context = RequestContext.getCurrentContext();ZuulException exception = (ZuulException)context.getThrowable();HttpServletResponse response = context.getResponse();response.setContentType("application/json; charset=utf8");response.setStatus(exception.nStatusCode);PrintWriter writer = null;try {writer = response.getWriter();writer.print("{code:"+ exception.nStatusCode +", message:\""+ exception.getMessage() +"\"}");} catch (IOException e) {e.printStackTrace();} finally {if(writer!=null){writer.close();}}} catch (Exception e) {e.printStackTrace();}return null;}
}

11.2  在 pre 过滤器AuthFilter中增加错误异常代码

@Component
public class AuthFilter extends ZuulFilter {@Overridepublic String filterType() {return "pre";}@Overridepublic int filterOrder() {return 0;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() throws ZuulException {int i = 1/0;//http://192.168.242.1:6060/provider/providerHello?token=12333System.out.println(">>>>>this is pre filter");RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();String token = request.getParameter("token");if (token == null) {ctx.setSendZuulResponse(false); //非法访问首先设置response 为falsectx.setResponseStatusCode(401);ctx.addZuulResponseHeader("content-type","text/html;charset=utf-8");ctx.setResponseBody("非法访问");}return null;}
}

11.3 重启网关服务模块访问测试。

URL : http://192.168.242.1:6060/papi/provider/providerHello?token=1231231

出现以下界面说明被error 拦截器拦住了,进入到了我们error自定义的处理方法中。

11.4  移除 pre 过滤器中的 错误代码 int i = 1/0 ,直接访问有异常的提供者观察是否可以被error拦截器拦截。

11.4.1 在provider 1 中增加错误访问方法controller

11.4.2 浏览器测试访问:

URL : http://192.168.242.1:6060/papi/provider/errorPage?token=1231231

出现此页面说明没有被定义的拦截方法拦截。

11.4.3 增加一个post 过滤器,在过滤器中获取远程服务返回的code ,如果code 不是200就抛出一个Zuul 异常.

@Component
public class MPostFilter extends ZuulFilter {@Overridepublic String filterType() {return "post";}@Overridepublic int filterOrder() {return 1;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() throws ZuulException {RequestContext context = RequestContext.getCurrentContext();int code =context.getResponse().getStatus();Throwable t =context.getThrowable();System.out.println("获取服务访问返回的code:" + code);if(code !=200){System.out.println("抛出异常,远程服务出错");throw new ZuulException("抛出异常",code,"远程服务出错");}System.out.println("这是post tt过滤器........."+t+"---code:"+code);System.out.println(">>>>>this is post filter");return null;}

11.4.4 重启网关模块测试

URL :http://192.168.242.1:6060/papi/provider/errorPage?token=1231231

进入到了定义的错误方法拦截器 。

12 . 自定义全局的错误页面

@RestController
public class MyErrorHandlerController implements ErrorController {@Overridepublic String getErrorPath() {System.out.println(">>>>>>ErrorHandlerController  -->getErrorPath");return "/error";}@RequestMapping("/error")public Object error() {
//        RequestContext ctx = RequestContext.getCurrentContext();
//        ZuulException exception = (ZuulException)ctx.getThrowable();
//        return exception.nStatusCode + "--" + exception.getMessage();return "全局异常:服务器忙.....";}
}

SpringCloud Study - (七) Zuul 网关相关推荐

  1. SpringCloud微服务Zuul网关动态路由

    SpringCloud微服务Zuul网关动态路由 zuul动态路由 1. 网关层动态配置路由映射规则 2. 将同一个请求根据自定义的规则,路由到不同服务中 FeignClient动态请求 实现功能 实 ...

  2. properties 配置回车_非常全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了!...

    本文同步Java知音社区,专注于Java 作者:kosamino http://www.cnblogs.com/jing99/p/11696192.html Zuul是spring cloud中的微服 ...

  3. 非常全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了!

    作者:kosamino www.cnblogs.com/jing99/p/11696192.html Zuul是spring cloud中的微服务网关.网关:是一个网络整体系统中的前置门户入口.请求首 ...

  4. properties 配置回车_非常全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了! - 风平浪静如码

    Zuul是spring cloud中的微服务网关.网关:是一个网络整体系统中的前置门户入口.请求首先通过网关,进行路径的路由,定位到具体的服务节点上. Zuul是一个微服务网关,首先是一个微服务.也是 ...

  5. 全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了

    Zuul是spring cloud中的微服务网关.网关:是一个网络整体系统中的前置门户入口.请求首先通过网关,进行路径的路由,定位到具体的服务节点上. Zuul是一个微服务网关,首先是一个微服务.也是 ...

  6. SpringCloud之Zuul网关服务

    Zuul是spring cloud中的微服务网关.网关: 是一个网络整体系统中的前置门户入口.请求首先通过网关,进行路径的路由,定位到具体的服务节点上. Zuul是一个微服务网关,首先是一个微服务.也 ...

  7. 网关的作用是什么_SpringCloud中Zuul网关原理及其配置,看它就够了

    正文 Zuul是spring cloud中的微服务网关.网关:是一个网络整体系统中的前置门户入口.请求首先通过网关,进行路径的路由,定位到具体的服务节点上. Zuul是一个微服务网关,首先是一个微服务 ...

  8. SpringCloud学习笔记(十四)Zuul网关

    专辑目录:SpringCloud学习日志 网关的概念: 我举个例子,我们到银行取钱,但是我们不能自己到金库里去拿钱,而是通过柜台服务员取钱.这时候柜台服务员就是网关,如果你没有存折和密码(相当于账号和 ...

  9. 认识微服务(七)之 Zuul 网关

    认识微服务(七)之 Zuul 网关 1 简介 2 Zuul 加入后的架构 3 快速入门 3.1 新建工程 3.2 编写启动类 3.3 编写配置 3.4 编写路由规则 3.5 启动测试 4 面向服务的路 ...

  10. SpringCloud 之 Zuul 网关搭建及配置

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:Anakki blog.csdn.net/qq_29 ...

最新文章

  1. Android studio 开发工具,试图预览工具不见了找会设置
  2. mysql 常规命令操作_mysql数据库常规命令操作
  3. Python 让所有奇数都在偶数前面,而且奇数升序排列,偶数降序排序
  4. how is SAP UI5 component.js called in the beginning
  5. 如何在vs2010中修改栈的大小
  6. 数据链路层(学习笔记)
  7. linux 内存查看_Linux终端查看最消耗CPU内存的进程
  8. 从 Eclipse 到 IDEA,就像从金字塔到太空堡垒!
  9. java多线程-基础知识
  10. Oracle--Oracle 11.2.0.1客户端安装
  11. 三星4k3d电视测试软件,三大硬性指标 揭开伪4K电视真实面目
  12. 百度SEO与SEM的区别
  13. python(1)汇率换算
  14. 如何判断一个指定的位置点坐标(GPS上的经纬度)是否落在一个多边形区域内?
  15. 【GDKOI2013】琪露诺的完美算法课
  16. LOJ#6198. 谢特 SAM+启发式合并+01trie
  17. vitrualbox虚拟机64位安装报错解决
  18. springboot项目集成大数据第三方dolphinscheduler调度器
  19. vue3 +Ts后导包出现红色波浪线【vscode】
  20. 简单的使用css画勾、叉、三角、大于号

热门文章

  1. 回文数例子,在10000以内每求出5个回文数,就进行换行操作.
  2. 科技生活第一季:解读数字孪生概念 —— 智慧城市大脑
  3. try except Exception as e 检查异常
  4. SaaS行业验尸报告:他们死于资本狂欢前夜
  5. Structure-Revealing联合去噪增强模型论文解读
  6. 无损音乐刻录成cd有意义吗_无损和CD不一样?无损音乐的“玄学”知多少?
  7. 最新的AOC有源光缆介绍,看这一篇就够了
  8. 沈阳移动打造“爱贝通”、“校讯通”业务助少年儿童健康成长
  9. java实现普通图片转黑白图片
  10. python+pygame之飞机大战-第一版源代码分析