SpringCloud入门教学|第五篇:路由网关(zuul)

本文介绍了Zuul作为微服务架构中的路由器和负载均衡器的功能,包括如何配置路由和服务发现,以及如何实现服务过滤进行安全验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Zuul简介

路由在微服务体系结构的一个组成部分。例如,/可以映射到您的Web应用程序,/api/users映射到用户服务,并将/api/shop映射到商店服务。Zuul是Netflix的基于JVM的路由器和服务器端负载均衡器。
Zuul有以下功能

  • 认证(Authentication)
  • 洞察(Insights)
  • 压力测试(Stress Testing)
  • 金丝雀测试(Canary Testing)
  • 动态路由(Dynamic Routing)
  • 服务迁移(Service Migration)
  • 负载脱落(Load Shedding)
  • 安全(Security)
  • 静态响应处理(Static Response handling)
  • 主动/主动流量管理(Active/Active traffic management)

创建zuul工程

创建service-zuul的Modules 依赖如前几篇一样:

<?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.example</groupId>
    <artifactId>service-zuul</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>service-zuul</name>
    <description>Demo project for Spring Boot</description>
    <!-- 指定父pom -->
    <parent>
        <groupId>com.example</groupId>
        <artifactId>springcloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <kotlin.version>1.2.20</kotlin.version>
        <spring-cloud.version>Edgware.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </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>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <artifactId>kotlin-maven-plugin</artifactId>
                <groupId>org.jetbrains.kotlin</groupId>
                <version>${kotlin.version}</version>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                    </compilerPlugins>
                    <jvmTarget>1.8</jvmTarget>
                </configuration>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <phase>test-compile</phase>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>


</project>

  • 在入口类中增加@EnableZuulProxy,进行开启zuul功能
@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
class ServiceZuulApplication

fun main(args: Array<String>) {
    SpringApplication.run(ServiceZuulApplication::class.java, *args)
}
  • 在配置文件中进行配置如下:
eureka.client.service-url.defaultZone=  http://localhost:8761/eureka/

server.port=8770

spring.application.name=service-zuul

zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=service-ribbon

zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.serviceId=service-feign

配置文件解析如下:
1. 首先指定服务注册中心 http://localhost:8761/eureka/
2. 服务端口号8770
3. 服务名为service-zuul
4. /api-a/ 开头的请求都转发给service-ribbon服务
5. /api-b/ 开头的请求都转发给service-feign服务

接下来 启动所有项目 :

服务过滤

zuul不仅仅只是路由,而且还能进行过滤,做一些安全验证。


@Component
class MyFilter: ZuulFilter() {

    companion object {
        private val log =LoggerFactory.getLogger(MyFilter::class.java)
    }

    override fun run(): Any? {
        val currentContext = RequestContext.getCurrentContext()
        val request = currentContext.request
        log.info("${request.method} >>> ${request.requestURL}")
        val accessToken  = request.getParameter("token")
        if (accessToken == null) {
            log.warn("token is empty")
            currentContext.setSendZuulResponse(false)
            currentContext.responseStatusCode = 401
            try {
                currentContext.response.writer.write("token is empty")
            } catch (e: Exception) {

            }
            return null
        }
        log.info("ok")
        return null
    }

    override fun shouldFilter(): Boolean {
        return true
    }

    override fun filterType(): String {
        return "pre"
    }

    override fun filterOrder(): Int {
        return 0
    }


}
  • filterType:返回一个字符串代表过滤器的类型。因此不同类型的过滤器代表不同的生命周期的一环。

    • pre: 路由之前
    • routing:路由之时
    • post: 路由之后
    • error: 发送错误调用

  • filterOrder:过滤顺序


  • shouldFilter:这里可以写判断逻辑,是否过滤。为true代表永远过滤。


  • run: 过滤器的具体逻辑,可以很复杂的操作。

示例代码
https://github.com/houshuai0816/SpringCloudDemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值