Spring Cloud 之 Zuul的学习

服务网关 Zuul

一.微服务架构存在的问题(需求分析)

在前端如何来访问内部各种各样的微服务呢?如果还用nginx做一个反向代理的话那么需要在nginx.conf中配置的太麻烦了,而且在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务。当我们使用Spring Cloud Zuul作为API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信,它不仅可以对请求做一个反向代理和负载均衡, 还能通过内置的过滤器进行请求的过滤或拦截,当请求一个服务器超时时,也能够对服务进行降级处理,防止服务因为压力过大造成雪崩。

二.API网关名词解释

API Gateway(API GW / API 网关),顾名思义,是出现在系统边界上的一个面向API的、串行集中式的强管控服务,这里的边界是企业IT系统的边界。
在微服务流行之前,API GW的实体就已经诞生了,这时的主要应用场景是OpenAPI,也就是开放平台,面向的是企业外部合作伙伴,对于这个应用场景,相信接触的人会比较多。当在微服务概念流行起来之后,API网关似乎成了在上层应用层集成的标配组件。

三.Spring Cloud Zuul 简介

Zuul 是Netflix 提供的一个开源组件,致力于在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。也有很多公司使用它来作为网关的重要组成部分。Spring Cloud 体系收录的该模块,主要用于提供动态路由、监控、安全控制、限流配额等,可以将内部微服务API统一暴露。

四.Spring Cloud Zuul的使用

4.1 Zuul通过ribbon负载均衡到目标服务器

zuul内置了ribbon,当客户端请求过来的时候会从eureka上拉取到服务可用列表,通过ribbon做一个负载均衡的转发。

创建zuul项目用来对外提供访问:http:ip:zuul端口:想要访问服务的service-id/对应的mapper接口,然后添加依赖.

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

启动类上加@EnableZuulProxy,配置上还需要加
zuul:
sensitive-headers:
#解决zuul无法获取cookie

将Zuul注册到eureka server上去发现其他服务,就可以实现对serviceId的映射。
测试

4.2 Zuul作为过滤器入门

zuul内置filer可以对所有请求做一个控制。

创建POJO类,继承ZuulFilter抽象类,重写zuulfilter里面的四个方法

@Component
public class TestZuulFilter extends ZuulFilter {}

指定当前过滤器的类型

@Override
public String filterType() {
    return FilterConstants.PRE_TYPE;
}

指定过滤器的执行顺序

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

配置是否启用

@Override
public boolean shouldFilter() {
    // 开启当前过滤器,为true是拦截所有请求,为false是放行(过滤)所有请求。
    return true;
}

指定过滤器中的具体业务代码

@Override
public Object run() throws ZuulException {
    //1. 获取Request对象
    RequestContext requestContext = RequestContext.getCurrentContext();
    HttpServletRequest request = requestContext.getRequest();
    //2. 获取token参数
    String token = request.getParameter("token");
    //3. 对比token
    if(token == null || !"123".equalsIgnoreCase(token)) {
        //4. token校验失败,直接响应数据
             baseResp.setMessage("验证失败");
             currentContext.getResponse().setContentType("text/html;charset=UTF-8");        
             currentContext.setResponseBody(baseResp.toString());
    }
    return null;
}

4.3 Zuul的降级

zuul内置了Hystrix,可以对不可用的服务做一个降级处理,防止发生服务雪崩。

创建POJO类,实现接口FallbackProvider

@Component
public class ZuulFallBack implements FallbackProvider {}

重写两个方法

@Override
public String getRoute() {
    return "*";   // 代表指定全部出现问题的服务,都走这个降级方法
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
    System.out.println("降级的服务:" + route);
    cause.printStackTrace();
    return new ClientHttpResponse() {
        @Override
        public HttpStatus getStatusCode() throws IOException {
            // 指定具体的HttpStatus
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        @Override
        public int getRawStatusCode() throws IOException {
            // 返回的状态码
            return HttpStatus.INTERNAL_SERVER_ERROR.value();
        }
        @Override
        public String getStatusText() throws IOException {
            // 指定错误信息
            return HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase();
        }
        @Override
        public void close() {
        }
        @Override
        public InputStream getBody() throws IOException {
            // 给用户响应的信息
            String msg = "当前服务:" + route + "出现问题!!!";
            return new ByteArrayInputStream(msg.getBytes());
        }
        @Override
        public HttpHeaders getHeaders() {
            // 指定响应头信息
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            return headers;
        }
    };
}

说明:

zuul主要的作用就是将用户发来的所有的请求进行一个转发,像对请求的过滤处理和不可用服务的降级处理会导致zuul转发所有请求的工作效率变慢,所以我们一般是不会再zuul中处理除转发外的业务逻辑.让它真正成为一个轻量级的服务框架.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值