Spring Cloud(四)服务网关Zuul

Spring Cloud Zuul

Spring Cloud Zuul路由是微服务架构的不可或缺的一部分,提供动态路由,监控,弹性,安全等的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。

使用微服务来构建整个API服务时,系统会有不同职责的应用在运行着,没有统一的访问路径就会造成访问混乱难以维护,这就迫切需要zuul来提供统一的访问接口。

  • zuul的存在的意义就是将“1对N”的问题转化为“1对1”问题,即进行请求转发,将用户的请求根据模块内定好的协议转发到响应的服务模块.在zuul的配置文件定义了路由转发协议。
  • 在用户的请求真正达到微服务之前,可以进行一些预处理,如来源合法性的校验、权限校验、错误拦截等。

Zuul的实现

继续上篇文章的注册发现工程

添加依赖

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

启动类添加路由启动注解和允许跨域访问

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@SpringBootApplication
@EnableZuulProxy //开启路由
public class ZuulApplication {

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


	//实现前后端分离里,所有的服务接口调用都会经过zuul,所以使用CorsFilter来实现前端的跨域访问
    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();

        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.setMaxAge(18000L);
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

配置文件

#服务端口
server.port=8888
#服务名
spring.application.name=cloud-zuul

#多次请求的时候,会把这些header再带过来,然后请求zuul转发的接口又在写入一次,造成重复了,方案就是zuul转发的时候,过滤掉这些header
zuul.ssl-hostname-validation-enabled=false
#防止header出现双重Access-Control-Allow-Origin,Access-Control-Allow-Methods,进行过滤
zuul.routes.user.sensitiveHeaders=Access-Control-Allow-Origin,Access-Control-Allow-Methods

#通过注册发现路径映射
#Zuul的路由规则如下:http://ZUUL_HOST:ZUUL_PORT/微服务在Eureka上的serviceId/**会被转发到serviceId对应的微服务
eureka.client.service-url.defaultZone=http://localhost:8000/eureka/
ribbon.ReadTimeout=60000
ribbon.ConnectTimeout=60000
#开启Ribbon的饥饿加载模式
ribbon.eager-load.enabled=true
#指定需要饥饿加载的服务名
ribbon.eager-load.clients=cloud-consumer

#请求的url规则
zuul.routes.user.path=/api/user/**
#转发到的服务名(负载均衡),user可随意写
zuul.routes.user.serviceId=cloud-consumer
#转发后url是否去掉前缀,即去掉/api/user/
zuul.routes.user.stripPrefix=true

进行安全验证时可以添加filter判断是否进行转发请求

  • filterType:该函数需要返回一个字符串来代表过滤器的类型,而这个类型就是在HTTP请求过程中定义的各个阶段。在Zuul中默认定义了四种不同生命周期的过滤器类型,具体如下:
    • pre:可以在请求被路由之前调用。
    • routing:在路由请求时候被调用。
    • post:在routing和error过滤器之后被调用。
    • error:处理请求时发生错误时被调用。
  • filterOrder:通过int值来定义过滤器的执行顺序,数值越小优先级越高。
  • shouldFilter:返回一个boolean类型来判断该过滤器是否要执行。我们可以通过此方法来指定过滤器的有效范围。
  • run:过滤器的具体逻辑。在该函数中,我们可以实现自定义的过滤逻辑,来确定是否要拦截当前的请求,不对其进行后续的路由,或是在请求路由返回结果之后,对处理结果做一些加工等。
/*
 * @author uv
 * @date 2018/10/9 11:06
 * 过滤
 */

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

@Component
public class Filter extends ZuulFilter {

    @Override
    public String filterType() {
        return "pre";
    }

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

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

    //进行验证,例如token的合法性、参数的合法性验证等确定是否进行转发
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        HttpServletResponse response = ctx.getResponse();

        ctx.setSendZuulResponse(true); //进行路由

        return null;
    }
}

 测试

依次启动eureka,provider,sonsumer,zuul服务,http://localhost:8000/ ,如下

测试url:http://localhost:8888/api/user/test ,测试结果如下,调用成功。

github实例代码:https://github.com/UVliuwei/springcloud-demo  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值