Zuul(路由网关)的使用

版权声明:欢迎技术爱好者前来讨论,转载请标明出处.谢谢 https://blog.csdn.net/qq_42875051 https://blog.csdn.net/qq_42875051/article/details/88783210

Zuul是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用。

Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。

Zuul为了实现以上功能必然的它就需要实现一个更为基础的功能:反向代理。

zuul为了能够实现对前端请求的全部代理、拦截、转发,它代理微服框架中的其他服务器。

springcloud对zuul进行了集成: spring-cloud-starter-zuul。

下面开始zuul在springcloud下的整合运用:

1、首先创建一个springboot项目,项目中集成:eureka server  和  zuul  插件

启动类添加注解:@EnableZuulProxy

package com.example.zuul;



import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.zuul.EnableZuulProxy;



@SpringBootApplication

@EnableZuulProxy     zuul作为一个中间介

public class ZuulApplication {



    public static void main(String[] args) {

        SpringApplication.run(ZuulApplication.class, args);

    }

}

配置文件中添加:端口号、开启服务代理

server:

  port: 5200



spring:

  application:

    name: zuulserver

zuul:

  routes:

    user:     这个地方随便写就可以了,不过建议用被代理的名称,便于区分

      path: /user/**     拦截的位置

      serviceId: user    被代理端注册名称

         url: http://localhost:5100/  通过URL地址进行代理

#推荐使用serviceId的映射方式,除了对Zuul维护上更加友好之外,serviceId映射方式还支持了断路器,
对于服务故障的情况下,可以有效的防止故障蔓延到服务网关上而影响整个系统的对外服务  
但是:serviceId方式是依赖Eureka服务发现的。



#forward模式 直接转发至zuul提供的rest服务  这个只能是自己编写的一种处理方式,这个可以用来进行token的解析,解/加密操作

zuul.routes.myDemo.path=/myDemo/**

zuul.routes.myDemo.url=forward:/demo





    user2:

      path: /user2/**

      serviceId: user2

eureka:

  client:

    service-url:

      defaultZone: http://localhost:5001/eureka

这样就可以实现代理服务端了。

下一步就是实现代理过程中的前期、中期、后期的拦截处理。

Zuul 的核心是 Filters,根据执行时期分为以下几类:

PRE:这种过滤器在请求被路由之前调用

ROUTING:这种过滤器将请求路由到微服务

POST:这种过滤器在路由到微服务以后执行

ERROR:在其他阶段发生错误时执行该过滤器

需要编写一个拦截器filter的代码:

package com.example.zuul;



import com.netflix.zuul.ZuulFilter;

import com.netflix.zuul.context.RequestContext;

import com.netflix.zuul.exception.ZuulException;



import javax.servlet.http.HttpServletRequest;



public class ZuulFilterTest extends ZuulFilter {

    /**

     * 这个方法返回过滤器的类型,pre(路由前执行),route(路由中执行),post(路由后执行),error(发生错误后执行)

     *

     * @return

     */

    @Override

    public String filterType() {

        return "pre";

    }



    /**

     * 这个位置是指返回的数字决定执行顺序  多个拦截器的情况下,返回数值越小越靠前执行。

     *

     * @return

     */

    public int filterOrder() {

        return 0;

    }



    /**

     * 返回boolean值来决定过滤器是否执行,true执行,false不执行

     *

     * @return

     */

    @Override

    public boolean shouldFilter() {

        return true;

    }



    /**

     * 过滤器要执行的操作

     *

     * @return

     * @throws ZuulException

     */

    @Override

    public Object run() throws ZuulException {

        RequestContext rtx = RequestContext.getCurrentContext();

        HttpServletRequest request = rtx.getRequest();

        

        Object temp = request.getParameter("temp");

        

        if (temp == null){

            rtx.setSendZuulResponse(false);              是否将请求通过:false 不通过   true  通过(默认)

            //rtx.setResponseStatusCode(404);            返回一个404页面

            rtx.setResponseBody("你的请求被拦截了!");     返回一个message

            System.out.println("你的请求被拦截了!");      这个位置可以是控制台输出

            return null;

        }

        return null;

    }

}

启动类里面需要添加:将写好的filter在初始化的时候进行实例化。

package com.example.zuul;



import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

import org.springframework.context.annotation.Bean;



@SpringBootApplication

@EnableZuulProxy

public class ZuulApplication {



    public static void main(String[] args) {

        SpringApplication.run(ZuulApplication.class, args);

    }



    @Bean

    public ZuulFilterTest zuulFilterTest(){

        return new ZuulFilterTest();

    }

}

路由规则说明

传统路由配置:不依赖服务发现,如nginx

* 单例实例配置:通过zuul.routes.<route>.path和zuul.routes.<route>.url参数对的方式来配置

# 传统路由配置

zuul.routes.server-provide.path=/server-provide/**

zuul.routes.server-provide.url=http://127.0.0.1:1001/

* 多实例配置:通过一组zuul.routes.<route>.path与zuul.routes.<route>.serviceId参数对的方式配置

# 多实例

zuul.routes.server-provide.path=/user-service/**

zuul.routes.server-provide.serviceId=user-service

ribbon.eureka.enabled=false

server-provide.ribbon.listOfServers=http://127.0.0.1:1001/,http://127.0.0.1:1001/

服务路由配置:依赖服务发现,结合Eureka

* 默认规则:http://ZUUL_HOST:ZUUL_PORT/微服务实例名(serverId)/** ,转发至serviceId对应的微服务。

* 自定义路由规则:通过一组zuul.routes.<route>.path与zuul.routes.<route>.serviceId参数对的方式配置

# 自定义路由

zuul.routes.server-provide.path=/server-api/**

zuul.routes.server-provide.serviceId=server-provide

比如:

而且,要注意,这些过滤器是path进行最佳路径匹配的,所以,一般上在一些历史系统上,我们会在最后后面加上一个路径/**的匹配规则,以保证历史api可以使用,做到最大兼容性,避免类似404的异常。

zuul.routes.legacy.path=/**

Zuul实现负载均衡

设置多个服务器,在eureka服务器上注册在一个名称下。zuul通过serviceId代理了端口,eureka实现了注册名称和服务地址的关联。这样就可以实现代理端口的负载均衡了。

但是这个负载均衡是属于客户端的负载均衡。在这我也就简要的说下客户端负载均衡。

客户端负载均衡

基于客户端的负载均衡,简单的说就是在客户端程序里面,自己设定一个调度算法,在向服务器发起请求的时候,先执行调度算法计算出向哪台服务器发起请求,然后再发起请求给服务器。

特点:

1. 由客户端内部程序实现,不需要额外的负载均衡器软硬件投入。

2. 程序内部需要解决业务服务器不可用的问题,服务器故障对应用程序的透明度小。

3. 程序内部需要解决业务服务器压力过载的问题。

使用场景:

1. 可以选择为初期简单的负载均衡方案,和DNS负载均衡一样。

2. 比较适合于客户端具有成熟的调度库函数,算法以及API等

3. 毕竟适合对服务器入流量较大的业务,如HTTP POST文件上传,FTP文件上传,Memcache大流量写入。

4. 可以结合其他负载均衡方案进行架构。

猜你喜欢

转载自blog.csdn.net/qq_42875051/article/details/88783210