【Spring Cloud】Spring Cloud服务网关Spring Cloud Zuul

Zuul作为微服务系统的网关组件,用于构建边界服务(Edge Service),致力于动态路由、过滤、监控、弹性伸缩和安全。其在微服务架构中有着重要的作用,主要体现在以下六个方面:

  • Zull、Ribbon以及Eureka相结合可以实现智能路由和负载均衡的功能,Zull可以按照某种策略将请求分发到不同的实例上;
  • 网关作为边界服务,将内部服务的API接口进行聚合并统一对外暴露接口。保护内部服务的API接口,防止内部服务被外界调用泄露敏感信息;
  • 网关可以对用户的身份权限进行认证,防止非法请求API接口;
  • 网关可以实现监控功能,实时日志输出,对请求进行记录;
  • 网关可以用来实现流量监控,在高流量的情况下,对服务进行降级;
  • API接口从内部服务分离出来,便于测试

springBoot使用的是2.0.2.RELEASE版本 springCloud使用的是Finchley.RELEASE版本。


                <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<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-netflix-zuul</artifactId>
		</dependency>

配置文件

zuul:
  routes:
  # /myProduct/product/list -> /product/product/list
  #aaaaa 表示这个名字可以随便写,下面是简洁的写法
    aaaaa: 
      path: /myProduct/**
      serviceId: product
      
  #简洁写法
#    product: /myProduct/**

启动类

@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {

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

面向服务的路由 

Spring Cloud Zuul 与 Spring Cloud Eureka 可以实现无缝对接实现面向服务的路由。我们让路由的path映射到具体的服务上,而具体的url交由Eureka的服务发现机制去自动维护。面向服务的路由默认实现了负载均衡。

商品服务原来的访问地址是:http://localhost:8080/product/list

使用zuul网关也可以实现路由功能:http://localhost:8002/product/product/list或者http://localhost:8002/myProduct/product/list

都可以进行服务的访问。

其中productmyProduct(自定义)为微服务的名称,可以任意定义。根据配置从注册中心拿到真实的路由地址。

/product/list 表示的是服务的真实的请求地址。

由于默认情况下所有Eureka上的服务都会被Zuul自动创建映射关系进行路由,这会使得一些我们不希望对外开放的服务也被外部访问到。这个时候我们可以配置zuul.ignored-services参数来设置一个服务名匹配表达式进行判断,如果服务名匹配表达式,那么Zull将跳过这个服务,不为其创建路由规则。例如:zuul.ignored-services=*表示对所有的服务不自动创建路由规则,这样我们就需要为每个服配置路由规则。

#排除某些路由
#  ignored-patterns:
#    - /**/product/listForOrder 

Zuul的过滤器

Zull有请求过滤的功能,其过滤器可以在Http请求的发起和响应返回期间执行一系列的过滤器。Zuul包扩以下四种过滤器:

  • PRE: 该类型的filters在Request routing到源web-service之前执行。可以进行一些权限认证,日志记录,或者额外给Request增加一些属性供后续的filter使用;
  • ROUTING:该类型的filters用于把Request routing到源web-service,源web-service是实现业务逻辑的服务。这里使用HttpClient请求web-service;
  • POST:该类型的filters在ROUTING返回Response后执行。用来实现对Response结果进行修改,收集统计数据以及把Response传输会客户端;
  • ERROR:上面三个过程中任何一个出现错误都交由ERROR类型的filters进行处理。

Zuul过滤器具有以下关键特性:

  • Type(类型):Zuul过滤器的类型,这个类型决定过滤器在哪个阶段执行,例如:pre,post等阶段;
  • Execution Order(执行顺序):规定了过滤器的执行顺序,Order的值越小,越先执行;
  • Criteria(标准):Filters执行所需条件
  • Action(行动):如果符合执行条件,则执行Action(具体逻辑代码)

Zuul请求的生命周期如图所示:

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

@Component
public class TokenFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

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

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

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

        //这里从url参数里获取, 也可以从header里获取
        String token = request.getParameter("token");
        if (StringUtils.isEmpty(token)) {
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            requestContext.setResponseBody("token is undefined...");
        }
        return null;
    }
}

发布了110 篇原创文章 · 获赞 36 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/wjx_jasin/article/details/103289663