zuul网关简单使用

zuul主要用于路由和过滤

zuul是一种服务网关,服务网关作用:企业级应用防火墙,节省流量,提高性能,作用于微服务项目,单体项目不需要

网关解决的问题:

统一接入,协议适配,安全防护,流量管控

nginx作为服务层的网关存在,zuul更多是的作为业务层网关存在

zuul的1.x版本是阻塞io,不支持长连接,zuul的2.x版本支持异步

项目中根据url路由

server.port=1002

spring.application.name=zuul-service

logging.level.com.zuul=debug
logging.level.web=debug
spring.devtools.add-properties=false

#路由规则配置
#配置请求url映射路径
zuul.routes.product-service.path=/product-service/**
#映射路径对应的微服务地址
zuul.routes.product-service.url=http://localhost:1001/

 这种路由存在问题,如果服务器地址更换,对应的url地址也要更换,对于服务的迁移不方便

所以使用调用服务的方式代替

server:
  port: 1002
spring:
  application:
    name: zuul-service

zuul:
  routes:
    product-service:
      path: /product-service/**
      serviceId: product-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

  

 

当网关的作用只是路由转发的时候,可以进行如下优化,路由设置的部分注释掉

server:
  port: 1002
spring:
  application:
    name: zuul-service

#zuul:
#  routes:
#    product-service:
#      path: /product-service/**
#      serviceId: product-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

  路径排除

zuul:
  routes:
    product-service:
      path: /product-service/**
      serviceId: product-service
  ignored-patterns: /**/order/**   #排除order路径

  

 

商品服务依旧可以访问

 

服务排除

 

路由前缀配置,隐藏真实的地址

zuul:
  routes:
    product-service:
      path: /product-service/**
      serviceId: product-service
  #ignored-patterns: /**/order/**   #排除order路径
  prefix: /api

  

 

 

网关过滤

package com.zuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * @author yourheart
 * @Description
 * @create 2022-05-09 22:14
 */
@Component
@Slf4j
public class GetwayFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

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

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

    @Override
    public Object run() throws ZuulException {
        //获取请求上下文
        RequestContext rc = RequestContext.getCurrentContext();
        HttpServletRequest request = rc.getRequest();
        log.info("【过滤地址】方法:{},地址:{}",request.getMethod(),request.getRequestURL().toString());
        return null;
    }
}

  

 

 

鉴权处理

package com.zuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author yourheart
 * @Description
 * @create 2022-05-09 21:56
 */
@Component
@Slf4j
public class AccessFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

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

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

    @Override
    public Object run() throws ZuulException {
        //获取请求上下文
        RequestContext rc = RequestContext.getCurrentContext();
        HttpServletRequest request = rc.getRequest();
        String token = request.getParameter("token");
        if (null==token){
            log.warn("【token为空】");
            //请求结束
            rc.setSendZuulResponse(false);
            //状态码,401未授权
            rc.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            rc.getResponse().setContentType("application/jsop; charset=utf-8");
            PrintWriter writer=null;

            try {
                writer=rc.getResponse().getWriter();
                writer.print("401,登录未授权");
            } catch (IOException e) {
                e.printStackTrace();
            }

        }else {
            log.info("【token id ok】");
        }

        return null;
    }
}

  

 

 

 

 

项目层级

 

 

 父级依赖

<?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>org.example</groupId>
    <artifactId>zuul-aprent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>eureka-service</module>
        <module>prodoct-service</module>
        <module>order-service</module>
        <module>zuul-service</module>
    </modules>

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

    <dependencyManagement>

        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>



        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!--编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
            <!--打包插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

  eureka项目

 

<?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">
    <parent>
        <artifactId>zuul-aprent</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.eureka</groupId>
    <artifactId>eureka-service</artifactId>

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


</project>

  

package com.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
 * @author yourheart
 * @Description
 * @create 2022-04-20 21:17
 */
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class,args);
    }
}

server.port=8761
spring.application.name=eureka-service
eureka.instance.hostname=localhost
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

logging.level.com.eureka=info
logging.level.web=info
spring.devtools.add-properties=false

  order项目

 

<?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">
    <parent>
        <artifactId>zuul-aprent</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.order</groupId>
    <artifactId>order-service</artifactId>

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--添加fastjson依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.7</version>
        </dependency>

        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

    </dependencies>


</project>

  

package com.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @author yourheart
 * @Description
 * @create 2022-04-20 21:38
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
}

  

package com.order;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author yourheart
 * @Description
 * @create 2022-04-20 21:46
 */
@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {


    @Autowired
    private ProductService productService;

    @GetMapping("/getOrder/{id}")
    public String getProduct(@PathVariable  String id){
        log.info("【调用消费者入参】:{}",id);
        String selectProduct = productService.selectProduct(id);
        return selectProduct;
    }
}

  

package com.order;


import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(value = "product-service")
public interface ProductService {

    @GetMapping("/product/getProduct/{id}")
    String selectProduct(@PathVariable String id);
}

  

server.port=1001

spring.application.name=order-service
#注册到eureka注册中心,如果是注册到集群就用逗号连接多个,单实例写上一个就好
eureka.client.service-url.defaultZone=http://localhost:8761/eureka


logging.level.com.order=debug
logging.level.web=debug
spring.devtools.add-properties=false

  product项目

 

package com.product;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * @author yourheart
 * @Description
 * @create 2022-04-20 21:28
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class,args);
    }
}

  

 

package com.product;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author yourheart
 * @Description
 * @create 2022-04-20 21:30
 */
@RestController
@RequestMapping("/product")
@Slf4j
public class ProductController {

    @GetMapping("/getProduct/{id}")
    public String selectProduct(@PathVariable String id){
        log.info("【调用服务者入参】:{}",id);
        return "查询到的主键返回"+id;
    }
}

  

server.port=1000

spring.application.name=product-service
#注册到eureka注册中心,如果是注册到集群就用逗号连接多个,单实例写上一个就好
eureka.client.service-url.defaultZone=http://localhost:8761/eureka


logging.level.com.product=debug
logging.level.web=debug
spring.devtools.add-properties=false

  zuul网关项目

 

package com.zuul;

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

/**
 * @author yourheart
 * @Description
 * @create 2022-04-20 22:05
 */
@SpringBootApplication
//开启zuul注解
@EnableZuulProxy
@EnableDiscoveryClient
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class,args);
    }
}

  

package com.zuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author yourheart
 * @Description
 * @create 2022-05-09 21:56
 */
@Component
@Slf4j
public class AccessFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

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

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

    @Override
    public Object run() throws ZuulException {
        //获取请求上下文
        RequestContext rc = RequestContext.getCurrentContext();
        HttpServletRequest request = rc.getRequest();
        String token = request.getParameter("token");
        if (null==token){
            log.warn("【token为空】");
            //请求结束
            rc.setSendZuulResponse(false);
            //状态码,401未授权
            rc.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            rc.getResponse().setContentType("application/jsop; charset=utf-8");
            PrintWriter writer=null;

            try {
                writer=rc.getResponse().getWriter();
                writer.print("401,登录未授权");
            } catch (IOException e) {
                e.printStackTrace();
            }

        }else {
            log.info("【token id ok】");
        }

        return null;
    }
}

  

package com.zuul.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * @author yourheart
 * @Description
 * @create 2022-05-09 22:14
 */
@Component
@Slf4j
public class GetwayFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

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

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

    @Override
    public Object run() throws ZuulException {
        //获取请求上下文
        RequestContext rc = RequestContext.getCurrentContext();
        HttpServletRequest request = rc.getRequest();
        log.info("【过滤地址】方法:{},地址:{}",request.getMethod(),request.getRequestURL().toString());
        return null;
    }
}

  

server:
  port: 1002
spring:
  application:
    name: zuul-service

zuul:
  routes:
    product-service:
      path: /product-service/**
      serviceId: product-service
  prefix: /api

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

  

 

posted @ 2022-05-09 22:35  不忘初心2021  阅读(296)  评论(0编辑  收藏  举报