SpringCloud之网关Zuul的使用以及简介

说明:

Spring Cloud Zuul是SpringClud的网关,我们知道,网关一般是应用的入口,做一些公共的和业务无关的校验工作,例如加验签、加解密等一些操作,而zuul作为微服务的网关,有如下原因:

1、作为系统的统一入口,屏蔽了微服务内部的实现细节;

2、与服务治理框架相结合(例如:Eureka),实现自动化的实例维护、以及负载均衡的路由转发;

3、实现接口的校验与微服务业务逻辑的解耦;

4、通过zuul中的各种过滤器,在各生命周期去校验请求内容,将原本对外服务层做的校验前移,保证了微服务的无状态性,同时降低了微服务的测试难度,让微服务更加关注本身的业务逻辑的处理;

好了,接下来我们开始一个zuul网关服务:

一、引入zuul的pom以来:

<?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.ck.springcloud</groupId>
    <artifactId>hello-service-api</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.7.RELEASE</version>
        <relativePath/>
    </parent>

  <dependencies>
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-zuul</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-eureka-server</artifactId>
      </dependency>
  </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Brixton.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


</project>

因为Zuul要结合Eureka使用,所以也要引入Eureka的依赖,下面会讲解Zuul怎么和Eureka的结合使用;

二、增加启动类,增加Zuul的启动配置注解@EnableZuulProxy:

package controller;

import com.netflix.zuul.FilterLoader;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableZuulProxy
@EnableConfigurationProperties(FilterConfiguration.class)
public class Application {
    FilterConfiguration filterConfiguration;

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).run(args);

    }

    @Bean
    public AccessFilter getAccessFilter(){
        return new AccessFilter();
    }


    @Bean
    public FilterConfiguration filterLoader(FilterConfiguration filterConfiguration){
        this.filterConfiguration = filterConfiguration;
        System.out.println(filterConfiguration.getInterval()+filterConfiguration.getRoot());
        return filterConfiguration;
    }
}

三、增加配置文件application.yml文件:

spring:
  application:
    name: api-gateway
server:
  port: 5555
eureka:
  client:
    serviceUrl:
        defaultZone: http://localhost:1111/eureka/
zuul:
  routes:
    api-a:
      path: /api-a/**
      url: http://localhost:8080
    api-b:
      path: /api-b/**
      serviceId: feign-consumer
  AccessFilter:
    pre:
      disable:  true
zuuls:
  filter:
     root: filter
     interval: 5

在上面的配置中,我们配置了2个路由规则:

1、是/api-a/**的请求都会转发到http://localhost:8080

2、/api-b/**的请求都会通过Ribbon负载均衡随机转发到微服务名feign-consumer(通过与Eureka注册中心结合,动态的获取所有微服务实例)的实例上;

通过简单的配置,现在一个简单的Spring Cloud Zuul网关就实现了!

Zuul中还可以增加过滤器,在转发请求到微服务之前做拦截过滤,实现过滤器很简单,只要集成ZuulFilter父类;

例子:

package controller;

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

import javax.servlet.http.HttpServletRequest;

public class AccessFilter extends ZuulFilter {

    //表明这是一个前置过滤器,在转发到微服务之前执行
    @Override
    public String filterType() {
        return "pre";
    }

    //多个过滤器之前,通过返回的order判断过滤器的执行顺序
    @Override
    public int filterOrder() {
        return 0;
    }

   //这个过滤器是否执行,true表示执行
    @Override
    public boolean shouldFilter() {
        return true;
    }


    //具体的拦截执行逻辑,过去逻辑是如果请求参数中没有accessToken就拦截此次请求
   //否则通过
    @Override
    public Object run() {
        System.out.println("access token start");
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest httpServletRequest = requestContext.getRequest();
        Object accessToken = httpServletRequest.getParameter("accessToken");
        if(accessToken == null){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(401);
            return null;
        }
        System.out.println("access token ok");
        return null;
    }
}

最后别忘记了,在Application启动类中将AccessFilter注册成bean:

    @Bean
    public AccessFilter getAccessFilter(){
        return new AccessFilter();
    }

禁用过滤器的方法,一种是修改过滤器的shouldFilter方法,这种方法缺乏灵活性,需要修改程序,第二种方式是增加配置:

zuul.<SimpleClassName>.<filterType>.disable=true

其中SimpleClassName代表过滤器的类名,filterType代表过滤器的类型;

猜你喜欢

转载自blog.csdn.net/chengkui1990/article/details/83117331