SpringCloud 基础——Zuul 路由网关

源码地址:https://pan.baidu.com/s/1Hmvh1Bbss_Z1w1I7I1mwDw 提取码:e41h

在实际生产的项目中,很多项目并不是输入路径就直接调用服务的,通常在中间进行了一次转发,类似于 nginx 的反向代理。springcloud 就有集成了一个路由网关组件 Zuul
Zuul 路由网关的主要用途是转发和过滤,转发请求,对一些请求进行过滤。
使用 Zuul 可以很轻松实现:

创建一个 zuul 服务

1. pom.xml

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.2.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>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</artifactId>
			<version>1.4.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-zuul</artifactId>
			<version>1.4.2.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</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>Finchley.RELEASE</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>

	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

需要加入 zuul 依赖

2. application.properties

eureka.client.serviceUrl.defaultZone=http://localhost:7070/eureka/
server.port=7075
spring.application.name=zuul

zuul.routes.api-100.path=/api-serviceA/**
zuul.routes.api-100.service-id=serviceA
zuul.routes.xiao-c.path=/api-rest/**
zuul.routes.xiao-c.service-id=service-rest
###一行配置搞定,zuul-routes 后面直接接服务名,作用同上面两行,可并存
zuul.routes.service-rest=/xiao-rest/**
zuul.routes.api-a.path 表示在网关输入的路径
zuul.routes.api-a.service-id 表示要转发的目标,这里写的是服务名
path 和 service-id 构成一组
zuul.routes 后面的那个字段可以是任意数字及字母
根据上面的配置,地址 /api-rest/** 与 /xiao-rest/** 都将转发到 service-rest 服务

3. 启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

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

@EnableZuulProxy 启用路由

以上3步就实现了一个可以 转发请求 的服务工程了。

路由网关测试

启动注册中心,启动 serviceA1 服务、 service-rest 服务和 zuul 服务。
输入 localhost:7075/api-rest/getListRest
输入 localhost:7075/xiao-rest/getListRest

图一:api-rest
图二:xiao-rest
说明通过路由网关,请求确实转发到了 service-rest ,对同一个服务可以同时配置多个路由。

加入过滤功能

新建一个 MyFilter 类,继承 ZuulFilter

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 MyFilter extends ZuulFilter {

	private static Logger log = LoggerFactory.getLogger(MyFilter.class);
	// 过滤类型
	@Override
	public String filterType() {
		return "pre";
	}
	// 过滤优先级
	@Override
	public int filterOrder() {
		return 0;
	}
	// 是否过滤
	public boolean shouldFilter() {
		return true;
	}
	// 过滤逻辑
	public Object run() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
		Object accessToken = request.getParameter("token");
		if (accessToken != null) {
			return null;
		}
		log.warn("token is empty");
		ctx.setSendZuulResponse(false);
		ctx.setResponseStatusCode(401);
		try {
			ctx.getResponse().getWriter().write("token is empty");
		} catch (Exception e) {
		}
		return null;

	}
}

使用@Component 把这个 Bean 注入到容器就可以生效了

String filterType()

  • pre:可以在请求被路由之前调用
  • routing: 路由请求时被调用
  • post:在routing和error过滤器之后被调用
  • error:处理请求时发生错误时被调用

int filterOrder(); 数值越小优先级越高

boolean shouldFilter(); 返回一个boolean值来判断该过滤器是否要执行

Object run(); 过滤器的具体逻辑

zuul 过滤详解参考 https://www.jianshu.com/p/ff863d532767

加入过滤器功能后重启 zuul 服务

输入 localhost:7075/xiao-rest/getListRest 效果如下图
输入 localhost:7075/xiao-rest/getListRest?token=xiao123 效果如下图

在这里插入图片描述
本例的 MyFilter 的过滤逻辑需要判断 token 参数
加入token

博主经验尚浅,也暂无微服务相关项目经验,如果理解不到位甚至理解错误,希望评论区讨论,请多指教!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值