Zuul网关

zuul官网:https://github.com/Netflix/zuul

zuul加入微服务后的架构

V1XJI0.md.png

  • 不管是来自于客户端(PC或移动端)的请求,还是服务内部调用。一切对服务的请求都会经过Zuul这个网关,然后再由网关来实现 鉴权、动态路由等等操作。Zuul就是我们服务的统一入口。

zuul功能:

一、路由功能

  • 0、新建模块module,gateway
  • 1、引入pom依赖
<!--引入zuul依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
  • 2、添加启用Zuul代理注解@EnableZuulProxy
@EnableZuulProxy
@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class);
    }
}
  • 3、配置application.yml信息

配置端口:

server:
      port: 10010

第一种配置:

zuul:
  routes:
    hehe:
      path: /user-service/**
      url: http://127.0.0.1:8081

所有符合/user-service/**(path)规则的请求都会被转发到http://127.0.0.1:8081/**(url)中

启动gateway,访问:http://localhost:10010/user-service/user/333

V1j51U.png

第二种配置:面向服务的路由

pom文件添加依赖

<!--eureka-client 注册中心 客户端-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

yml配置文件添加配置:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka
spring:
  application:
    name: gateway

zuul:
  routes:
    hehe:
      path: /user-service/**
      serviceId: user-service

请求转发+负载均衡

重启gateway服务,访问:http://localhost:10010/user-service/user/222

V1xpGV.md.png

第三种配置:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka
spring:
  application:
    name: gateway
zuul:
  routes:
    user-service: /user-service/**

重启gateway服务,访问:http://localhost:10010/user-service/user/111

V1xiMF.md.png

此时,我们只配置了user-service,但我们可以试着访问:http://localhost:10010/consumer-service/consumer/111

V1x8Zd.md.png

也能访问得到,由此可知,zuul帮我们所有服务都默认配置了此规则:

zuul:
      routes:
        xxx-service: /xxx-service/**

注:xxx-service 代表服务在eureka中注册的服务名字

第四种配置:不用配置zuul.routes规则

所以我们可以什么都不用配置,即可访问

第五种配置:不忽略前缀

zuul:
  routes:
    user-service:
      path: /user/**
      serviceId: user-service
      strip-prefix: false

不忽略前缀,可通过
http://localhost:10010/user-service/user/111访问到(默认配置)

V1zr6O.md.png

也可通过
http://localhost:10010/user/111访问到

V1zD1K.md.png

将某个服务不对外提供 zuul.ignored-services 值是一个集合

zuul:
  ignored-services:
    - consumer-service

访问:http://localhost:10010/consumer-service/consumer/111

V1zWtI.md.png

二、过滤器

编写过滤器继承ZuulFilter

package cn.itcast.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class LoginFilter extends ZuulFilter {
    @Override
    public String filterType() {//过滤器类型  前置过滤器  xx过滤器  后置过滤器
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {//过滤器顺序   在处理请求头 之前
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }

    @Override
    public boolean shouldFilter() {//要不要过滤
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        //获取请求上下文
        RequestContext ctx = RequestContext.getCurrentContext();
        //获取request
        HttpServletRequest request = ctx.getRequest();
        //获取请求参数
        String token = request.getParameter("access-token");
        //判断是否存在
        if(StringUtils.isBlank(token)){
            //不存在 则登录拦击拦截
            ctx.setSendZuulResponse(false);
            //返回403
            ctx.setResponseStatusCode(HttpStatus.SC_FORBIDDEN);
        }
        return null;
    }
}

访问

http://localhost:10010/user-service/user/111:

V3t8gI.md.png

http://localhost:10010/user-service/user/111?access-token=asdf:

V3tVjx.md.png

三、zuul的负载均衡和熔断

Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
zuul:
retryable: true
ribbon:
ConnectTimeout: 250 # 连接超时时间(ms)
ReadTimeout: 2000 # 通信超时时间(ms) (ConnectTimeout+ReadTimeout)*2 不能超过 熔断超时时长 6000ms
OkToRetryOnAllOperations: true # 是否对所有操作重试
MaxAutoRetriesNextServer: 2 # 同一服务不同实例的重试次数
MaxAutoRetries: 1 # 同一实例的重试次数
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMillisecond: 6000 # 熔断超时时长:6000ms

番外

<!--StringUtils工具包-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
</dependency>

查看字符串是否为空(空返回true) StringUtils.isBlank(“asd”);

insist,on the road
-------------本文结束感谢您的阅读-------------