SpringCloud实战6-Zuul网关服务

API网关主要为了服务本身对外的调用该怎么调用来解决的,还有解决权限校验的问题,你可以在这里整合调用一系列过滤器的,例如整合shiro,springsecurity之类的东西。

Zuul可以通过加载动态过滤机制,从而实现以下各项功能:

1.验证与安全保障:识别面向各类资源的验证要求并拒绝与要求不符的那些请求。

2.审查与监控:在边缘位置监控有意义数据及统计结果,从而给我们带来准确的生产状态结论。

3.动态路由:以动态方式根据需求将请求路由到不同后台集群处。

4.压力测试:逐渐增加指向集群的负载流量,从而计算性能水平。

5.负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求。

6.静态响应处理:在边缘位置直接建立部分响应,从而避免其流入内部集群。

7.多区域弹性: 跨越AWS区域进行请求路由,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。

接着下来进行实战小Demo

第一步,在原来的工程下,新建一个Zuul模块,引入依赖,代码如下:

    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

 

接着在启动类上打上@EnableZuulProxy注解,代码如下:

 

server:
  port: 5000
spring:
  application:
    name: api-geteway
zuul:
  routes:
#标识你服务的名字,这里可以自己定义,一般方便和规范来讲还是跟自己服务的名字一样
    hello-service:
#服务映射的路径,通过这路径就可以从外部访问你的服务了,目的是为了不爆露你机器的IP,面向服务的路由了,给你选一个可用的出来,
#这里zuul是自动依赖hystrix,ribbon的,不是面向单机
      path: /hello-service/**
#这里一定要是你Eureka注册中心的服务的名称,是所以这里配置serviceId因为跟eureka结合了,如果单独使用zuul,那么就必须写自己机器的IP了,
#如url:http://localhost:8080/  这样的不好就是写死IP了,万一这IP挂了,这高可用性,服务注册那套东西就用不起来了
      serviceId: hello-service

eureka:
#客户端
  client:
#注册中心地址
    service-url:
      defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/

 

接着启动先前文章中的注册中心和两个hello-service服务提供者,接着我们运行,看一下它的请求转发功能,看他有没有轮询进入两个服务,

输入localhost:5000/hello-service/hello,如下:

 

接着再刷新一遍:

 

 

 可以看到zuul进行了请求分发了。它是根据你的服务名字hello-servie来映射到具体的机器上,这不就是一个反向代理的功能吗?

zuul还能进行请求过滤,那么我们进行一下token校验来演示一下,首先我们需要先新建一个TokenFilter类来继承ZuulFilter这个类,实现它的四个接口,代码如下:

package hjc.zuul;

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

import javax.servlet.http.HttpServletRequest;

/**
 * Created by cong on 2018/5/18.
 */
public class TokenFilter extends ZuulFilter {
    //四种类型:pre,routing,error,post
    //pre:主要用在路由映射的阶段是寻找路由映射表的
    //routing:具体的路由转发过滤器是在routing路由器,具体的请求转发的时候会调用
    //error:一旦前面的过滤器出错了,会调用error过滤器。
    //post:当routing,error运行完后才会调用该过滤器,是在最后阶段的
    @Override
    public String filterType() {
        return "pre";
    }

    //自定义过滤器执行的顺序,数值越大越靠后执行,越小就越先执行
    @Override
    public int filterOrder() {
        return 0;
    }

    //控制过滤器生效不生效,可以在里面写一串逻辑来控制
    @Override
    public boolean shouldFilter() {
        return true;
    }

    //执行过滤逻辑
    @Override
    public Object run() {

        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        String token = request.getParameter("token");
        if (token == null){
            context.setSendZuulResponse(false);
            context.setResponseStatusCode(401);
            context.setResponseBody("unAuthrized");


            return null;
        }
        return null;
    }
}

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

  1.pre:可以在请求被路由之前调用,用在路由映射的阶段是寻找路由映射表的

  2.route:在路由请求时候被调用,具体的路由转发过滤器是在routing路由器具体的请求转发的时候会调用

  3.error:处理请求时发生错误时被调用

  4.post:当routing,error运行完后才会调用该过滤器,是在最后阶段的

这里声明一下zuul过滤器执行网络请求发生的异常,过滤器里面是不能直接将try-catch捕捉的异常抛出给页面的。应用程序抛出的异常是可以返回出的需解决办法就是在catch里面用context.set()方法返回给页面。如下:
try{
    业务逻辑......
}catch(Exception e){
        RequestContext context = RequestContext.getCurrentContext();
          context.set("error.status_code",401);
            context.set("error.exception",e);
            context.set("error.message","sfdfsdf");
}

接着,你还需要把这个过滤器加入spring中,让spring管理,代码如下:

package hjc;

import hjc.zuul.TokenFilter;
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);
    }

  //将过滤器交给Spring管理
    @Bean
    public TokenFilter tokenFilter(){
        return new TokenFilter();
    }

}

接着,让我们启动启动类,先进行不带token的访问,如下:

可以看到,返回一个没权限的信息,这里要说一下,Token一般都是放在请求头中的,这里我们只是为了演示才没那么干,

接着将token带上再去访问,如下:

可以看到这是已经将我们的请求放过去了。

这里我还要讲一下什么是默认路由,将zuul的配置删除路由配置,如下:

复制代码

server:
  port: 5000
spring:
  application:
    name: api-geteway


eureka:
#客户端
  client:
#注册中心地址
    service-url:
      defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/

复制代码

接着,重启继续访问,如下:

 

 

 

可以看到,还是能继续访问,我们什么都没配,居然还能访问,那是因为,这里默认用你的服务名字hello-service自动声明了。

那么,如果说我不想让它帮我自动声明,我要我自己定义,那么可以在yml配置文件中使用zuu.ignored-services就可以把自己像过滤的过滤,如下:”

zuul:
#如果ignored-services:*  表示所有的默认路由都失效了,要自己一个个配,没人会那么操蛋,除非遇到奇葩业务

  ignored-services: 

zuul官方已经放弃维护了,用gateway吧,或者Kong替代

原文转自:https://www.cnblogs.com/huangjuncong/p/9060984.html

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值