服务网关zuul

微服务网关

在微服务环境下,不同的服务有其不同的网络地址,若让客户端直接与各个微服务通信,客户端会多次请求不同微服务,存在跨域请求,处理相对复杂。此时我们就需要使用微服务网关。微服务网关介于服务端与客户端的中间层,所有外部服务请求都会先经过微服务网关,客户只能跟微服务网关进行交互,无需调用特定微服务接口,使得开发得到简化。服务网关是在微服务前边设置一道屏障,请求先到服务网关,网关会对请求进行过虑、校验、路由等处理。有了服务网关可以提高微服务的安全性,网关校验请求的合法性,请求不合法将被拦截,拒绝访问。


Zuul简介

Spring Cloud Zuul是整合Netflix公司的Zuul开源项目实现的微服务网关,它的核心是一组过滤器,它实现了请求路由、负载均衡、校验过虑等 功能。

 

 

 

zuul与nginx整合使用 

nginx: 负载均衡,反向代理

zuul:  拦截非法请求,保证请求的合法性,负载均衡

 

下面是网上找的一张图

 

 

 

搭建网关工程

 

pom依赖

    <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>

 

因为zuul网关需要获取微服务地址,所以添加了eureka-client的依赖

 

在application启动类上添加注解,标记此服务是一个网关

@EnableZuulProxy//此工程是一个zuul网关

 

 

 

在   application.yml 文件中配置 eureka

eureka:
  client:
    registerWithEureka: true #服务注册开关
    fetchRegistry: true #服务发现开关
    serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔
      defaultZone: http://localhost:50101/eureka/
  instance:
    prefer-ip-address:  true  #将自己的ip地址注册到Eureka服务中
    ip-address: 127.0.0.1
    instance-id: zuul50201 #指定实例id
ribbon:
  MaxAutoRetries: 2 #最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试,如果eureka中找不到服务则直接走断路器
  MaxAutoRetriesNextServer: 3 #切换实例的重试次数
  OkToRetryOnAllOperations: false  #对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为false
  ConnectTimeout: 5000  #请求连接的超时时间
  ReadTimeout: 6000 #请求处理的超时时间

 

 

zuul具有代理的功能,将请求转发给服务

 

配置路由:           application.yml配置

配置zuul网关根路径   /api  和端口

server:
  port: 50201
  servlet:
    context-path: /api

 

配置路由

zuul:
  routes:
    manager-test1:                        #路由名称,名称任意,保持所有路由名称唯
      path: /test1/**                         #路径匹配规则,如果不匹配,不会转发请求
      serviceId:  xc-service-manage-test1    #服务id,从Eureka中找到服务的ip和端口
      #url: http://localhost:31200 #也可指定url,不用 serviceId
      strip-prefix: false   #true:代理转发时去掉前缀,false:代理转发时不去掉前缀 /test/是前缀,
      sensitiveHeaders:  #默认zuul会屏蔽cookie,cookie不会传到下游服务,这里设置为空则取消默认的黑名单,如果设置了具体的头信息则不会传到下游服务
      ignoredHeaders:  #可以设置过虑的头信息,默认为空表示不过虑任何头

测试 

服务端创建俩个方法请求路径分别为带前缀,跟不带前缀

 

 

 

请求http://localhost:50201/api/test1/hello

访问结果

 

请求被转发到        http://ip:port/test1/hello        因为 strip-prefix为false,所以请求有携带  test1

 

把strip-prefix 改为true,再测试

 

过滤器:

Zuul的核心就是过虑器,通过过虑器实现请求过虑,身份校验等

自定义过虑器需要继承 ZuulFilter,ZuulFilter是一个抽象类,需要覆盖它的四个方法,

1、 shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true表示要执行此过虑器,否则不执行。

2、 run:过滤器的业务逻辑。

3、 filterType:返回字符串代表过滤器的类型,如下

pre:请求在被路由之执行

routing:在路由请求时调用

post:在routing和errror过滤器之后调用

error:处理请求时发生错误调用

4、 filterOrder:此方法返回整型数值,通过此数值来定义过滤器的执行顺序,数字越小优先级越高。

 


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.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class LoginFilterTest extends ZuulFilter {

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

    @Override
    public int filterOrder() {
        return 2;   //返回值越小,优先级越高
    }

    @Override
    public boolean shouldFilter() {
        return true;        //是否执行该过滤器
    }

    @Override
    public Object run() throws ZuulException {

        //zuul 提供的   requestcontext类,可以用此类获取request,response
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        HttpServletResponse response = currentContext.getResponse();

        //取出头部信息Authorization
        String authorization = request.getHeader("Authorization");

        if (StringUtils.isBlank(authorization)){
            //没有携带信息
//            拒绝访问
            currentContext.setSendZuulResponse(false);
            currentContext.setResponseStatusCode(200);  //设置响应码

            //设置响应信息
            currentContext.setResponseBody("不是登陆请求啊");
            response.setContentType("text/plain;charset=UTF-8");
        }

        return null;
    }
}

 

 

测试

然后我使用 postman 发送请求 

 

一切顺利,嘿嘿

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值