欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring Cloud_22_网关Zuul/介绍与使用(一)

程序员文章站 2022-03-23 12:30:36
...

网关Zuul/介绍与使用(一)

  • 在之前的例子中,都是通过浏览器或者HttpClient模拟浏览器向服务发送请求
  • 在实际环境中,一个集群肯定是多个服务提供者的,如何统一起来对外使用呢?
  • 外部服务不能知道每一个服务提供者在哪, 只需要记住统一提供的出口遍可以

1、Zuul介绍

  • Zuul是Netflix的一个子项目
  • Zuul提供代理、过滤、路由等功能
  • 如果集群中提供API/Web服务需要与外部进行通信,比较好的方式就是添加网关,将集群的服务均隐藏至网关后面,这样做有如下好处
    1. 对于外部客户端而言,无需关心集群内部结构,只需关心网关在哪
    2. 对于SpringCloud集群而言,不会过多暴露服务,间接提升了集群的安全性

2、编写第一个Zuul程序

  • 建立服务项目:atm_zuul_server
  • 建立网关项目(接收外部请求,然后转发至服务项目中):atm_zuul_router
  • 我们先简单地将Zuul整合到web应用中,实现一个简单的转发功能

Spring Cloud_22_网关Zuul/介绍与使用(一)

2.1、atm_zuul_server

2.1.1、引入依赖

<!-- Spring Boot Web-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.5.4.RELEASE</version>
</dependency>

2.1.2、启动类/服务提供

package com.atm.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class ZuulServerApp {

    // 默认使用8080端口
    public static void main(String[] args) {
        SpringApplication.run(ZuulServerApp.class, args);
    }

    @RequestMapping(value = "/hello/{name}", method = RequestMethod.GET)
    public String hello(@PathVariable String name) {
        return "hello, " + name;
    }
}

2.2、atm_zuul_router

2.2.1、引入依赖

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.atm.cloud</groupId>
    <artifactId>atm_zuul_router</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>atm_zuul_router Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <!-- Spring Cloud -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- Zuul -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>
        <!-- HttpClient -->
        <!-- 为什么还需要引入HttpClient?因为Zuul底层是使用httpclient来请求发送的 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>atm_zuul_router</finalName>
    </build>
</project>

2.2.2、启动类

package com.atm.cloud;

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

@SpringBootApplication
@EnableZuulProxy//打开Zuul客户端功能,开启Zuul代理
public class ZuulRouterApp {

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

2.2.3、配置application.yml

server:
  port: 8085
##Zuul配置转发规则
zuul:
  routes:
  ##路由名称
    myServer:
      url: http://localhost:8080

2.2.4、访问测试

Spring Cloud_22_网关Zuul/介绍与使用(一)

3、Zuul过滤器运行机制

Spring Cloud_22_网关Zuul/介绍与使用(一)

  • 这是一个Http请求的生命周期
  • 用户或外部应用会发送一个请求到Zuul(虚线框内则是Zuul处理的一个过程)
  • Zuul提供了四种过滤器(4个阶段,并不是具体的过滤器,每个阶段都包含若干个过滤器)

    1. ”pre”阶段过滤器:对请求尽心预处理(如:对参数进行设置),然后由routing过滤器处理
    2. “routing”阶段过滤器:进行转发和获取响应,调用源服务
    3. “post”阶段过滤器:最后会通过“post”阶段过滤器进行处理,响应给用户
    4. “error”阶段过滤器:出现异常,则由该阶段过滤器处理
  • 每一个阶段都内置许多过滤器,当然,还可以添加自定义过滤器

  • 看看ZuulServlet的一段源码
 @Override
    public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
        try {
            init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);

            // Marks this request as having passed through the "Zuul engine", as opposed to servlets
            // explicitly bound in web.xml, for which requests will not have the same data attached
            RequestContext context = RequestContext.getCurrentContext();
            context.setZuulEngineRan();

            try {
                preRoute();
            } catch (ZuulException e) {
                error(e);
                postRoute();
                return;
            }
            try {
                route();
            } catch (ZuulException e) {
                error(e);
                postRoute();
                return;
            }
            try {
                postRoute();
            } catch (ZuulException e) {
                error(e);
                return;
            }

        } catch (Throwable e) {
            error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));
        } finally {
            RequestContext.getCurrentContext().unset();
        }
    }