Spring Cloud 入门 (八): 路由网关 zuul

本贴最后更新于 2191 天前,其中的信息可能已经事过景迁

在微服务架构中,需要几个关键的组件,服务注册与发现、服务消费、负载均衡、断路器、智能路由、配置管理等,由这几个组件可以组建一个简单的微服务架构。客户端的请求首先经过负载均衡(zuul、Ngnix),再到达服务网关(zuul 集群),然后再到具体的服务,服务统一注册到高可用的服务注册中心集群,服务的所有的配置文件由配置服务管理,配置服务的配置文件放在 Git 仓库,方便开发人员随时改配置。

imagepng

1. Zuul 介绍

Zuul 的主要功能是路由和过滤器。路由功能是微服务的一部分,比如/api/user 映射到 user 服务,/api/shop 映射到 shop 服务。zuul 实现了负载均衡。以下是微服务结构中,Zuul 的基本流程。在接下来的步骤中,我们来创建一个 zuul 服务, 将/api-feign/**映射到我们之前创建 feign-service, 将/api-ribbon/**映射到之前的 ribbon-service 服务。

2. 创建 Zuul 的 Maven 工程

关于 zuul 的依赖是

<dependency>
     <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-zuulartifactId>
<dependency>

完整 pom.xml 如下:

<?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>cm.chry</groupId>
    <artifactId>spring.helloworld.zuul.service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring.helloworld.zuul.service</name>
    <description>zuul service demo</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.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>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</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>Dalston.RC1</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>
</project>

3. 创建启动类: 使用 @EnableZuulProxy 注解

package spring.helloworld.zuul.service;

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

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

4. 编写 zuul 服务配置:

简单配置两个路由, 一个路由到 ribbon,一个路由到 feign; 由于都注册到 eureka 服务中心,所以都用通过 serviceId 来发现服务具体地址, path 是路由的地址映射关系

eureka:
    client:
        serviceUrl:
            defaultZone: http://localhost:8761/eureka/
server:
    port: 8904
spring:
    application:
        name: service-zuul
zuul:
  routes:
    ribbo:
      path: /api-ribbon/**
      serviceId: service-ribbon
    feign:
      path: /api-feign/**
      serviceId: service-feign

这时启动 zuul 服务, 然后访问 http://localhost:8904/api-ribbon 可直接路由到 http://localhost:8901/.

http://localhost:8904/api-feign/hello 可路由到 http://localhost:8902/hello

5. Zuul 过滤器

zuul 还提供了过滤功能, 只要实现接口 ZuulFilter 即可对请求先进行筛选和过滤之后再路由到具体服务。

package spring.helloworld.zuul.service;

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 DemoFilter extends ZuulFilter {
    private static Logger log = LoggerFactory.getLogger(DemoFilter.class);
    @Override
    public String filterType() {
        return "pre";
    }

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

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String s = String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString());
        log.info(s);
        return null;
    }
}

filterType:返回一个字符串代表过滤器的类型,在 zuul 中定义了四种不同生命周期的过滤器类型,具体如下:

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

filterOrder:过滤的顺序

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

shouldFilter:这里可以写逻辑判断,是否要过滤,本文 true,永远过滤。

run:过滤器的具体逻辑,这里只是将请求的 URL 简单些到日志中

  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    942 引用 • 1459 回帖 • 31 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...