微服务网关

1 什么是网关

在这里插入图片描述

如果让客户端直接和各个微服务通信,可能会有很多问题:

(1)客户端会多次请求不同的微服务,增加了客户端的复杂性;

(2)存在跨域请求,在一定场景下处理相对复杂;

(3)认证复杂,每个微服务需要独立认证。

为了解决以上问题,需要在客户端和服务器端之间加一层(网关层),让所有的请求先经过网关,再打到微服务上。

在这里插入图片描述

网关实现方式:

Nginx+lua 一般为企业级的网关,zuul和spring cloud gateway 是业务级的网关,用于聚合微服务。

网关在服务架构中的作用:

2 zuul

(1)什么是Zuul
Zuul是Netflix开源的微服务网关。可以完成以下功能:身份认证与安全,审查与监控,动态路由,压力测试,负载分配,静态响应处理等。

zuul 目前有两个大的版本:Zuul1 和 Zuul2
Zuul1 是基于 Servlet 框架构建,采用的是阻塞和多线程方式,即一个线程处理一次连接请求,这种方式在内部延迟严重、设备故障较多情况下会引起存活的连接增多和线程增加的情况发生。

Zuul2 运行在异步和无阻塞框架上,每个 CPU 核一个线程,处理所有的请求和响应,请求和响应的生命周期是通过事件和回调来处理的,这种方式减少了线程数量,因此开销较小。

zuul GitHub:https://github.com/Netflix/zuul, 中文文档:https://www.springcloud.cc/spring-cloud-netflix.html

zuul包含了对请求的路由和过滤两个核心功能。其中路由负责将外部请求转发到具体的微服务上,是实现外部访问统一入口的基础。

而过滤功能则负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能的基础。

(2)路由
2.1 开启zuul

启动类上加上@EnableZuulProxy

2.2 配置路由规则

zuul:
    routes:
        provider-service:                 #路由id自定义
            path: /provider-service/**    #配置请求url的映射路径
            #url: http://localhost:9090/   #映射路径对应的微服务地址
            serviceId: provider-service   #根据serviceId自动从注册中心获取地址并转发请求
            #默认路由规则,路由id和微服务名称一致,path默认对应:微服务名称/**,以上可以简化不写。

zuul:
    #路由排除
    ignored-patterns: /**/provider/** #URL地址排除,排除所有包含/provider/的路径
    #ignored-services: provider-service  #服务名称排除
    #路由前缀
    prefix: /api

(3)过滤

默认类型:pre , routing, post, error

执行顺序:见上图;对于同类型,可以自定义执行顺序。

pre: 请求被路由到源服务器之前执行的过滤器;身份认证,选路由,请求日志

routing:处理将请求发送到源服务器的过滤器

post: 响应从源服务器返回时执行的过滤器;对响应增加HTTP头,收集统计和度量指标,将响应以流的方式发送给回客户端。

error: 上述阶段中出现错误时执行的过滤器。

自定义过滤器

案例:


@Component
public class CustomFilter extends ZuulFilter {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(AccessFilter.class);
    @Override
    public String filterType() {
        return "pre";
    }
 
    @Override
    public int filterOrder() {
        return 1;
    }
 
    @Override
    public boolean shouldFilter() {
        return true;
    }
 
    @Override
    public Object run() throws ZuulException {
        //获取请求上下文
        RequestContext rc = RequestContext.getCurrentContext();
        HttpServletRequest request = rc.getRequest();
        //获取表单中的token
        String token = request.getParameter("token");
        //业务逻辑处理
        if (token==null){
            LOGGER.warn("token is null");
            //请求结束,不再继续向下请求
            rc.setSendZuulResponse(false);
            //响应状态码,401,没有权限
            rc.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
            //响应类型
            rc.getResponse().setContentType("application/json;charset=utf-8");
            PrintWriter writer = null;
            try {
                writer = rc.getResponse().getWriter();
                //响应内容
                writer.print("{\"message\":\"" + org.springframework.http.HttpStatus.UNAUTHORIZED.getReasonPhrase() + "\"}");
 
            }catch (IOException e){
                LOGGER.error("异常");
            }finally {
                if (null != writer){
                    writer.close();
                }
            }
        }else {
            LOGGER.info("token is ok");
        }
        return null;
    }
}

(4)限流
文档: https://github.com/marcosbarbero/spring-cloud-zuul-ratelimit

令牌桶算法:

参考:https://segmentfault.com/a/1190000020745218

3 spring cloud gateway

Spring Cloud Gateway 是Spring Cloud的一个全新的API网关项目,目的是为了替换掉Zuul1。Gateway可以与Spring Cloud Discovery Client(如Eureka)、Ribbon、Hystrix等组件配合使用,

实现路由转发、负载均衡、熔断等功能,并且Gateway还内置了限流过滤器,实现了限流的功能。

spring cloud gateway 官方文档:https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html/

参考文献:

https://www.cnblogs.com/xuweiweiwoaini/p/13814388.html
https://zhuanlan.zhihu.com/p/101341556
https://zhuanlan.zhihu.com/p/91865256

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值