Spring Cloud 之 Spring Cloud Zuul(七)

一、简介

      Zuul是Netfliex公司开源的为微服务提供服务路由和过滤的一个组件,作为网关的一种选择方案。Spring Cloud 团队将其集成进来形成Spring Cloud zuul组件。
   Spring Cloud Zuul 内置 zuul proxy 代理服务器

二、路由

     在application配置文件中,如果serviceId和route名称相同 配置可以如下 
 zuul:
  ignoredServices: '*'
  routes:
    users: /myusers/**
或者
 zuul:
  routes:
    users:
      path: /myusers/**
      serviceId: users_service

或者 提供一个具体的物理地址
 zuul:
  routes:
    users:
      path: /myusers/**
      url: http://example.com/users_service
匹配规则要符合ant风格。我们可以通过代码自定义匹配规则

@Bean
public PatternServiceRouteMapper serviceRouteMapper() {
    return new PatternServiceRouteMapper(
        "(?<name>^.+)-(?<version>v.+$)",
        "${version}/${name}");
}

我们可以通过zuul.prefix 增加路径前缀,在路由前改前缀会被删除,如果个别服务需要不删除则需要在route 下 设置zuul.stripPrefix=false

 zuul:
  routes:
    users:
      path: /myusers/**
      stripPrefix: false


三、过滤

zuul过滤器有四种类型分别非 pre,route ,post,error ,代表路由前,路由时,路由完毕,发生错误时的过滤器。

自定义ZuulFilter需要继承ZuulFilter ,

public class AddResponseHeaderFilter extends ZuulFilter {
	@Override
	public String filterType() {
		return POST_TYPE;
	}

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

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

	@Override
	public Object run() {
		RequestContext context = RequestContext.getCurrentContext();
    	HttpServletResponse servletResponse = context.getResponse();
		servletResponse.addHeader("X-Foo", UUID.randomUUID().toString());
		return null;
	}
}

该过滤器在路由结束后会调用,增加了一个响应头。

四、使用

创建spring boot 项目 添加依赖spring-cloud-starter-zuul ,我们使用eureka 作为服务注册中心。添加eureka依赖
spring-cloud-starter-eureka
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

创建程序入口类,在这个类中注入了一个zuulFilter
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class ZuulApplication {

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

   @Bean
   MyZuulFilter zuulFilter(){
      return new MyZuulFilter();
   }
}



创建一个zuul过滤器类MyZuulFilter 

public class MyZuulFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return POST_TYPE; //过滤器类型 有pre route post error
    }

    @Override
    public int filterOrder() {
        return 1;  //过滤器顺序 越小越优先
    }

    @Override
    public boolean shouldFilter() {
        return true; //是否过滤
    }

    @Override
    public Object run() {
        RequestContext currentContext = RequestContext.getCurrentContext();
	HttpServletRequest request = currentContext.getRequest();

	String servletPath = request.getServletPath();
	//zuul 对所有 /** forward转发 到本地的 的请求进行重定向 到百度
	if (servletPath.lastIndexOf("/")==0){
    	HttpServletResponse response = currentContext.getResponse();

    	try {
        	response.sendRedirect("http://www.baidu.com");
    	} catch (IOException e) {
        	e.printStackTrace();
    	}
    	return null;
}
HttpServletResponse response = currentContext.getResponse(); Cookie cookie = new Cookie("time-respose", "nowtamstamp" + System.currentTimeMillis()); response.addCookie(cookie); return null; }}

在这个类中,我们给响应头增加了一个cookie。

配置文件 application.yml 

spring:
  application:
    name: zuul
server:
  port: 2000

zuul:
  ignoredPatterns: /**/admin/** #忽略路径含有admin的请求
  sensitiveHeaders: Cookie,Set-Cookie,Authorization #对于外部消费者 忽律这些敏感头
  #ignoredHeaders:      #忽略的头部
  routes:
    hello:
      path: /hello/**
      serviceId: eureka-client-consumer   #serviceId 在虚拟地址 ribbon 通过serviceId查找服务列表 这里重eureka中获取
#      url: http://localhost:8001  #物理地址
    r:
      path: /**
      url: forward:/    ## /** 转发到本地 / 服务
prefix: /api #增加前缀eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ instance: lease-renewal-interval-in-seconds: 3 #3秒钟一次心跳 lease-expiration-duration-in-seconds: 5 #5秒超时

在这个配置文件中定义了一个route. 将/hello/** 路由到eureka-client-consumer服务。
/** 转发到 zuul 的/服务下。

zuul 对本地服务/** 过滤进行重定向:  
@Override
public Object run() {
    RequestContext currentContext = RequestContext.getCurrentContext();
    HttpServletRequest request = currentContext.getRequest();

    String servletPath = request.getServletPath();
    //zuul 对所有 /** forward转发 到本地的 的请求进行重定向 到百度
    if (servletPath.lastIndexOf("/")==0){
        HttpServletResponse response = currentContext.getResponse();

        try {
            response.sendRedirect("http://www.baidu.com");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    return null;
}


启动服务。 访问localhost:2000/api/hello/hello 成功返回。 并且响应头中增加了一个cookie .













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值