zuul 路由不生效_111、服务网关Zuul

本文介绍了Zuul作为服务网关的角色,包括其四个典型步骤:常用处理、服务标识、端点路由和特定服务处理。接着,通过创建入门案例展示了如何配置路由规则,如URL指定、服务名称指定、排除和添加前缀方法。此外,文章详细讲解了自定义网关过滤器,包括编写过滤器、过滤器类型、请求生命周期,以及如何实现权限验证和异常处理。
摘要由CSDN通过智能技术生成

一、 什么是网关服务

网关服务是单一访问点,并充当多项服务的代理。服务网关启用了跨所有服务的变换、路由和公共处理。

基本原理

服务网关模块是单一调解,用于处理对多个服务使用者和提供者的请求。任何服务网关都有如下四个典型步骤:

1)常用处理 - 一旦网关接收到消息,就对所有消息执行常用处理,例如添加协议级的头或者记录该消息。

2)服务标识 - 必须将网关所处理的消息标识为特定服务类型。例如,查询消息以确定它是针对服务提供者 A、B 还是 C。

3)端点路由 - 当它确定某消息将传递到特定服务提供者时,它将映射到网络可寻址端点,以便可以将该消息转发到服务提供者。

4)特定于服务的处理 - 执行特定目标服务所需的任何处理。

用户可以根据不同的场景更改这四个步骤的顺序。

1 为什么要使用网关

协调请求与服务的调用关系,协调服务之间的关系。

2 网关解决了什么问题

996cb76c68ba2ace754127f9f16673f5.png

二、 编写网关服务入门案例

1 创建项目

1376aea17aaeaa0d9f3f695b5f2503f3.png

修改 pom 文件

<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.sxt</groupId>
  <artifactId>zuul-gateway</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.13.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>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR5</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		<dependency>
	      <groupId>org.springframework.cloud</groupId>
	      <artifactId>spring-cloud-starter-zuul</artifactId>
	    </dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

修改配置文件

spring.application.name=zuul-gateway
server.port=9020

eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

修改启动类

@SpringBootApplication
@EnableZuulProxy
public class UserApplication {
	public static void main(String[] args) {
		SpringApplication.run(UserApplication.class, args);
	}
}

通过网关访问请求服务

800252a9515e0400d94bfe0887da61fc.png

http://网关服务地址:网关服务端口/访问的服务的名称/访问的服务中的接口的地址

三、 路由器的 4 种路由规则方法

1 创建项目

8c03fe53db4b366510b6dcf47561bd65.png

2 采用 URL 指定路由方式

修改配置文件配置路由规则

spring.application.name=zuul-gateway-route
server.port=9030

eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

# 1 ###################### 路由指定:URL 指定 #############################
# URL 匹配关键字,如果包含关键字就跳转到指定的 URL 中
zuul.routes.e-book-product-provider.path=/e-book-product-provider/**
zuul.routes.e-book-product-provider.url=http://127.0.0.1:9001/

53c8d3bea17edadf1f8a7e7a794b93e4.png

通配符含义

3fda20ed31414a001c6827111c820a2c.png

3 采用服务名称指定路由方式

## 2 ###################### 路由指定:服务指定 1 #############################
##将路径的/suibian/引到 eureka 的 e-book-product-provider 服务上
##规则:zuul.routes.路径名.path
##规则:zuul.routes.路径名.serviceId=eureka 的服务名
#zuul.routes.e-book-product-provider.path=/suibian/**
#zuul.routes.e-book-product-provider.serviceId=e-book-product-provider

## 3 ###################### 路由指定:服务指定 2 #############################
#zuul.routes 后面跟着的是服务名,服务名后面跟着的是路径规则,这种配置方式更简单。
zuul.routes.e-book-product-provider.path=/suibian/**

4 路由的排除方法

## 4 ###################### 路由排除:排除某几个服务 ###############################排除后,这个地址将为空
http://127.0.0.1:9030/e-book-product-provider/product/findAll
## 多个服务逗号隔开
#zuul.ignored-services=e-book-product-provider
## 5 ###################### 路由排除:排除所有服务 #############################
#由于服务太多,不可能手工一个个加,故路由排除所有服务,然后针对要路由的服务进行手工加
#zuul.ignored-services=*
#zuul.routes.e-book-order-provider.path=/e-book-order-provider/**
## 6 ###################### 路由排除:排除指定关键字的路径 #############################
# 排除所有包括/list/的路径
zuul.ignored-patterns=/**/findAll/**
zuul.routes.e-book-order-provider.path=/suibian/**

b1d5f715a6f52834fc302ce834e04323.png

5 路由的添加前缀方法

##http://127.0.0.1:9030/suibian/product-provider/product/findAll
zuul.prefix=/suibian
zuul.routes.e-book-product-provider.path=/product-provider/**

四、自定义网关过滤器

1 编写网关过滤器

1.1创建项目

d2ed0929bf6bf9b364328941bb99a279.png

修改 pom 文件

<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.sxt</groupId>
  <artifactId>zuul-gateway-filter</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.13.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>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR5</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		
		<dependency>
	      <groupId>org.springframework.cloud</groupId>
	      <artifactId>spring-cloud-starter-zuul</artifactId>
	    </dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

修改配置文件

spring.application.name=zuul-gateway-filter
server.port=9020

eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

创建过滤器

package com.sxt.zuul.filter;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
@Component
public class LogFilter extends ZuulFilter{
	private static final Logger logger = LoggerFactory.getLogger(LogFilter.class);
	@Override
	public boolean shouldFilter() {
		return true;
	}

	@Override
	public Object run() {
		//获取请求上下文
		RequestContext rc = RequestContext.getCurrentContext();
		HttpServletRequest request = rc.getRequest();
		logger.info("LogFilter.....method={},url={}",request.getMethod(),request.getRequestURL().toString());
		return null;
	}

	@Override
	public String filterType() {
		return "pre";
	}

	@Override
	public int filterOrder() {
		return 0;
	}

}

42e421255791a0f0aa6ace1fa4625580.png

2 过滤器类型

58700abca351c3c155702f16cd0d2f01.png

3 Zuul 请求的生命周期

24fd4aa7543310748d2bbe9dfeb3b4ae.png

4 采用网关过滤器实现权限验证

需求:在网关过滤器中通过 Token 判断用户是否登录

4.1创建项目

bc7599b6c94f329c8a47009425b3566f.png

修改pom文件添加依赖

<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.sxt</groupId>
  <artifactId>zuul-gateway-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.13.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>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Dalston.SR5</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
		</dependency>
		
		<dependency>
	      <groupId>org.springframework.cloud</groupId>
	      <artifactId>spring-cloud-starter-zuul</artifactId>
	    </dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

修改配置文件

spring.application.name=zuul-gateway-example
server.port=9020

eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

创建 AccessFilter

package com.sxt.filter;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
@Component
public class AccessFilter extends ZuulFilter{
	private static final Logger logger = LoggerFactory.getLogger(AccessFilter.class);
	
	/**
	 * 是否开启过滤器,默认不开启
	 */
	@Override
	public boolean shouldFilter() {
		return true;
	}
	/**
	 * 过滤内容在:run方法中编写逻辑
	 */
	@Override
	public Object run() {
		//获取请求上下文
		RequestContext rc = RequestContext.getCurrentContext();
		HttpServletRequest request = rc.getRequest();
		logger.info("----------------------------------------");
		//获取表单中的token
		String token = request.getParameter("token");
		//对token做出判断
		if(token == null) {
			logger.warn("token is null....");
			rc.setSendZuulResponse(false);//代表请求结束,不在继续向下请求
			rc.setResponseStatusCode(401);//添加一个响应的状态码
			rc.setResponseBody("{"result":"token is null"}");//响应内容
			rc.getResponse().setContentType("text/html;charset=utf-8");
		}else {
			//访问Redis服务,进行验证
			logger.info("token is ok");
		}
		return null;
	}
	/**
	* 过滤器类型:通过过滤器类型决定了过滤器执行的时间
	*/
	@Override
	public String filterType() {
		return "pre";
	}
	/**
	* 过滤器的执行顺序:通过整数表示顺序,数值越小,优先级越高
	*/
	@Override
	public int filterOrder() {
		return 0;
	}

}

0e05d65335bef88e704094e79ab5517f.png

ffcb5a67c4821deb480b65669c85bd5f.png

2e10c444a06a32fc516c5be7bf50d188.png

5 网关过滤器执行顺序与 post 类型演示

5.1网关过滤器执行顺序演示

AccessFilter

package com.sxt.filter;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
/**
 * per类型演示
 */
@Component
public class AccessFilter extends ZuulFilter{
	private static final Logger logger = LoggerFactory.getLogger(AccessFilter.class);
	
	/**
	 * 是否开启过滤器,默认不开启
	 */
	@Override
	public boolean shouldFilter() {
		return true;
	}
	/**
	 * 过滤内容在:run方法中编写逻辑
	 */
	@Override
	public Object run() {
		//获取请求上下文
		RequestContext rc = RequestContext.getCurrentContext();
		HttpServletRequest request = rc.getRequest();
		logger.info("------------------pre1----------------------");
		//获取表单中的token
		String token = request.getParameter("token");
		//对token做出判断
		if(token == null) {
			logger.warn("token is null....");
			rc.setSendZuulResponse(false);//代表请求结束,不在继续向下请求
			rc.setResponseStatusCode(401);//添加一个响应的状态码
			rc.setResponseBody("{"result":"token is null"}");//响应内容
			rc.getResponse().setContentType("text/html;charset=utf-8");
		}else {
			//访问Redis服务,进行验证
			logger.info("token is ok");
		}
		return null;
	}
	/**
	* 过滤器类型:通过过滤器类型决定了过滤器执行的时间
	*/
	@Override
	public String filterType() {
		return "pre";
	}
	/**
	* 过滤器的执行顺序:通过整数表示顺序,数值越小,优先级越高
	*/
	@Override
	public int filterOrder() {
		return 0;
	}

}

AccessFilter 2

/**
 * 执行顺序演示
 */
@Component
public class AccessFilter2 extends ZuulFilter{
	private static final Logger logger = LoggerFactory.getLogger(AccessFilter2.class);
	
	/**
	 * 是否开启过滤器,默认不开启
	 */
	@Override
	public boolean shouldFilter() {
		return true;
	}
	/**
	 * 过滤内容在:run方法中编写逻辑
	 */
	@Override
	public Object run() {
		//获取请求上下文
		RequestContext rc = RequestContext.getCurrentContext();
		HttpServletRequest request = rc.getRequest();
		logger.info("------------------pre2----------------------");
		
		return null;
	}
	/**
	* 过滤器类型:通过过滤器类型决定了过滤器执行的时间
	*/
	@Override
	public String filterType() {
		return "pre";
	}
	/**
	* 过滤器的执行顺序:通过整数表示顺序,数值越小,优先级越高
	*/
	@Override
	public int filterOrder() {
		return 1;
	}

}

26cf311e86340c4f6bb8c0ee5dc31b83.png

post 类型演示

/**
 * Post类型演示
 */
@Component
public class PostFilter extends ZuulFilter{
	private static final Logger logger = LoggerFactory.getLogger(PostFilter.class);
	
	/**
	 * 是否开启过滤器,默认不开启
	 */
	@Override
	public boolean shouldFilter() {
		return true;
	}
	/**
	 * 过滤内容在:run方法中编写逻辑
	 */
	@Override
	public Object run() {
		//获取请求上下文
		RequestContext rc = RequestContext.getCurrentContext();
		HttpServletRequest request = rc.getRequest();
		logger.info("------------------Post----------------------");
		
		return null;
	}
	/**
	* 过滤器类型:通过过滤器类型决定了过滤器执行的时间
	*/
	@Override
	public String filterType() {
		return "post";
	}
	/**
	* 过滤器的执行顺序:通过整数表示顺序,数值越小,优先级越高
	*/
	@Override
	public int filterOrder() {
		return 0;
	}

}

dd09491ee618901fa1907d9946fc2e93.png

6.采用网关过滤器对系统异常同一处理

6.1创建 ErrorFilter

/**
 * 异常处理演示
 */
@Component
public class ErrorFilter extends ZuulFilter{
	private static final Logger logger = LoggerFactory.getLogger(ErrorFilter.class);
	
	/**
	 * 是否开启过滤器,默认不开启
	 */
	@Override
	public boolean shouldFilter() {
		return true;
	}
	/**
	 * 过滤内容在:run方法中编写逻辑
	 */
	@Override
	public Object run() {
		//获取请求上下文
		RequestContext rc = RequestContext.getCurrentContext();
		HttpServletRequest request = rc.getRequest();
		logger.info("------------------error----------------------");
		
		return null;
	}
	/**
	* 过滤器类型:通过过滤器类型决定了过滤器执行的时间
	*/
	@Override
	public String filterType() {
		return "error";
	}
	/**
	* 过滤器的执行顺序:通过整数表示顺序,数值越小,优先级越高
	*/
	@Override
	public int filterOrder() {
		return 1;
	}

}

创建处理异常响应的控制器

/**
 * 对异常响应内容进行处理
 */
@RestController
public class ExceptionHandler implements ErrorController {

	@Override
	public String getErrorPath() {
		return "/error";
	}
	
	@RequestMapping(value="/error")
	public String error() {
		return "{"result":"500 error!!!"}";
	}
	
}

d42260b13d5d2e80e4fcfdb241213dc9.png

a41a8c44823b546000e22876ab2eb33e.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值