《SpringCloud微服务 六》之 Zuul 网关路由

本文介绍了SpringCloud的Zuul组件作为微服务网关的作用,包括动态路由、过滤器等功能。Zuul通过URL路径或服务ID匹配进行路由,并可自定义过滤器进行权限校验等操作。示例中展示了如何配置服务路由,以及创建自定义的权限token校验过滤器,确保只有携带正确token的请求才能通过。
摘要由CSDN通过智能技术生成

《SpringCloud微服务 六》之 Zuul 网关路由



六、Zuul网关路由


Zuul是netflix组的一个子项目

之前学习了spring cloud提供给微服务系统的服务注册与发现、配置中心统一管理、断路器、负载均衡、服务间通信工具等,而Netflix提供了一个组件Zuul,它的作用有微服务网关,提供动态路由,访问过滤等服务


Zuul组件的核心就是一系列的过滤器,这些过滤器有:

1.身份认证和安全: 识别每一个资源的验证要求,并拒绝那些不符的请求
2.审查与监控:指标健康监控
3.动态路由:动态将请求路由到不同后端集群
4.压力测试:逐渐增加指向集群的流量,以了解性能
5.负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求
6.静态响应处理:边缘位置进行响应,避免转发到内部集群


没有网关路由之前:

没有网关时


比如目前有两个服务:books-service、user-service

分别对应的有个资源请求需要对外提供的,比如:/books、/users

若是没有网关路由的话,需要请求:http://books-service/books、http://users-service/users

服务消费者方需要维护两个服务的地址,若是现在需要加上认证,服务生产方需要对每个服务都需要添加认证的代码块,双方都比较头疼麻烦


若是现在有了网关路由,则统一对外管理API

使用网关后


比如 :

请求网关服务:http://zuul-server/books-service/books zuul服务就转发请求到 books-service 服务进行查询

请求网关服务:http://zuul-server/user-service/users zuul服务就转发请求到 user-service 服务进行查询

若是需要统一添加认证,则在zuul服务中拦截一切请求,通过认证的进行转发,没有通过认证的,则直接返回,这样减少了多个微服务直接的服务IP暴露,并且外部是不需要知道内部微服务间通信的


6.1 配置服务路由


1.添加依赖

<!-- Netflix Zuul网关-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>


2.启动类上添加开启路由代理注解 @EnableZuulProxy

// 开启网关路由代理
@EnableZuulProxy
@SpringBootApplication
public class LearnZuulApplication {

	public static void main(String[] args) {
		SpringApplication.run(LearnZuulApplication.class, args);
	}

}


6.1.1 URL路径匹配方式

URL路径匹配方式设置路由

server:
  port: 5050
  servlet:
    context-path: /

spring:
  application:
    name: zuul-server


# 配置服务路由
zuul:
  routes:
  	# 服务名称(可以自定义 可以配置多个服务,名称不能相同)
    books-service:
      path: /book-server/** #接口前缀
      url: http://localhost:9090/ #实际服务地址
      
    # 用户服务
    users-service:
      path: /users-server/**
      url: http://localhost:9091/
      

zuul-server服务启动后,充当微服务门户,当所有访问请求URL以 /book-server/** 开头的,都会被zuul路由到 http://localhost:9090/ 服务去实际访问

比如:

启动 books-service 服务,有个接口 /book,返回值

{"id":1002,"name":"疯狂Java","author":"李刚"}

当访问:http://localhost:5050/book-server/book 时,会被zuul重定向到books-service服务,请求 /book 接口


其实会发现,books-service服务的地址 http://localhost:9090 在eureka服务注册中心里面已经有了,所以可以结合 eureka服务注册中心更加方便的获取到服务地址


6.1.2 服务ID匹配方式

结合eureka服务注册中心使用

首先 books-service服务 要注册到eureka服务中心里,serviceID= books-service


zuul路由项目注册eureka服务注册中心上:

1.添加eureka客户端依赖

<!-- eureka客户端-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.启动类上添加服务注册注解

// 开启网关路由代理
@EnableZuulProxy
// 启动eureka客户端
@EnableEurekaClient
@SpringBootApplication
public class LearnZuulApplication {

	public static void main(String[] args) {
		SpringApplication.run(LearnZuulApplication.class, args);
	}
}


3.添加路由配置

server:
  port: 5050
  servlet:
    context-path: /

spring:
  application:
    name: zuul-server

# eureka服务中心配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka


# 配置服务路由
zuul:
  routes:
  	# 书籍服务(名称可自定义)
    books-service:
      #请求前缀
      path: /book-server/**
      #eureka服务中心中的服务ID,zuul可以根据eureka中的服务地址路由到具体服务
      serviceId: books-service
    

当访问:http://localhost:5050/book-server/book 时,zuul网关会根据serviceId去找eureka服务中心,然后拿到 books-service服务的具体地址,然后执行 /book 接口

{"id":1002,"name":"疯狂Java","author":"李刚"}

其实会发现,books-service服务的serviceId也在eureka服务注册中心里面配置,所以 zuul网关路由默认支持直接去eureka配置中心获取服务,进行路由


6.1.3 默认读取eureka进行路由

比如:什么都没有配置路由规则的前提下

默认路由规则:http://zuulIP:zuulPort/serviceId/path

访问:http://localhost:5050/books-service/book 时,zuul会根据规则 http://zuulIP:zuulPort/serviceId/path 获取到serviceID,然后去eureka注册中心获取到服务的地址,进行访问


zuul和eureka注册中心联用


6.2 自定义过滤器


zuul网关允许用户自定义过滤器进行统一的配置,比如:用户认证token、日志记录、权限校验等

zuul提供了一个过滤器抽象类 com.netflix.zuul.ZuulFilter

只要继承此类,自定义实现四个方法即可:

1.public boolean shouldFilter() 是否执行此过滤器

2.public String filterType() 过滤器类型

3.public int filterOrder() 过滤器顺序(过滤器执行顺序,数字越小,优先级越高)

4.Object run() throws ZuulException 过滤器执行体


filterType:过滤器类型有四种

1.pre - 前置过滤器,在请求被zuul路由到真正服务前执行,通常用于处理身份认证,日志记录等

2.route - 在路由执行后,服务调用前被调用,通常用于特定服务调用前添加参数等

3.error - 任意一个filter发生异常的时候执行或远程服务调用没有反馈的时候执行(超时),通常用于处理异常

4.post - 在route或error执行后被调用,一般用于收集服务信息,统计服务性能指标等,也可以对response结果做特殊处理


6.2.1 自定义权限token校验过滤器

自定义权限校验token的过滤器

package com.tianya.springcloud.zuul.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;

import lombok.extern.slf4j.Slf4j;

/**
 * @author TianwYam
 * @description 自定义filter 拦截网关服务
 * @date 2022年3月2日下午6:40:19
 */
@Slf4j
@Component
public class AuthFilter extends ZuulFilter {

    @Override
    public boolean shouldFilter() {
        // 是否执行该过滤器
        return true;
    }

    /**
     * 具体执行方法
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {

       	// 获取请求
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        log.info("当前执行方法:{},{}", request.getMethod(),
                request.getRequestURL().toString());

        // 获取 token header(简单校验,具体业务具体分析)
        String token = request.getHeader("token");
        if (StringUtils.hasText(token)) {
            // 对请求放行 继续路由
            ctx.setSendZuulResponse(true);
            ctx.setResponseStatusCode(200);
            return null;
        }

        // 不对其路由
        ctx.setSendZuulResponse(false);
        ctx.setResponseStatusCode(403);
        ctx.setResponseBody("权限不对,token不能为空");

        // 取response 设置返回格式
        HttpServletResponse response = ctx.getResponse();
        // 防止界面展示乱码
        response.setContentType("text/html;charset=UTF-8");

        return null;
    }

    @Override
    public String filterType() {
        // 过滤器类型(路由前执行)
        return "pre";
    }

    @Override
    public int filterOrder() {
        // 过滤器执行顺序,数字越小,优先级越高
        return 0;
    }

}


启动网关服务后,直接访问:http://localhost:5050/book-server/book 界面展示:权限不对,token不能为空(因为我们header里面没有token)


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯共明月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值