带着问题学习是最好的,什么是网关?使用网关的好处是什么?怎么使用网关

  网关:是系统对外的唯一入口,是介于客户端和服务端的中间层,处理非业务功能,提供路由的请求,鉴权,监控,缓存,限流等

  网关的好处:可以将很多非业务功能集中在网关处理,例如鉴权,限流等,并且只提供了一个入口,那么也可以将业务服务很好的保护起来。

    网关的使用:

  1.使用idea创建zuul工程

  

 

 

 2.zuul也是一个注册中心的客户端,并且要导入你使用的网关类型,我这里使用的是zuul,如果选不了,就是spring-boot版本过高,要调整一下spring-boot版本

 

 

 3.在启动类上增加注解 @EnableZuulProxy

package com.xdclass.apigateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {

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

}

4.修改配置文件application.yml(我是将.properties修改 成yml的)

server:
  port: 9000

#服务名称
spring:
  application:
    name: api-gateway

#指定注册中心
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

5.启动项目,访问试一试,拿到结果了

使用网关前的链接:ip:server port/controller Request mapping/method mapping
http://localhost:8781/api/v1/order/save?user_id=1&product_id=1

 

使用网关后的链接:ip:gateway port/server name/controller Request mapping/method mapping

http://localhost:9000/order-service/api/v1/order/save?user_id=1&product_id=1

 

 

 

6.yml增加配置

#自定义路径规则
zuul:
  routes:
    #自定义路由转发:
    order-service: /apigateway-order/**
    product-service: /apigateway-product/**
    #环境隔离配置:不想让默认的服务对外暴露接口
  ignored-patterns: /*-service/**

再次使用链接:http://localhost:9000/order-service/api/v1/order/save?user_id=1&product_id=1,发现不能访问数据了,更改链接成:http://localhost:9000/apigateway-order/api/v1/order/save?user_id=1&product_id=1

在配置文件中将order-service 替换成了apigateway-order,不暴露原路径

 

7.自定义拦截器,创建一个类,增加注解@Component,继承ZuulFilter,然后实现里面的方法‘

package com.xdclass.apigateway.filter;

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

import javax.servlet.http.HttpServletRequest;


@Component
public class LoginFilter extends ZuulFilter {

    @Override
    public String filterType() {
        //这个类里面记录了很多拦截器的类型,PRE表示前置,表示你这个拦截器是要在什么时候执行
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        //这里表示拦截器执行的先后顺序,数字越小越在前面执行
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
        String uri = request.getRequestURI();
        System.out.println("uri--:::"+uri);

        if(!StringUtils.isEmpty(uri) && uri.toLowerCase().contains("order")){
        //true表示拦截
return true; } return false; } @Override
  //拦截时调用的方法
public Object run() throws ZuulException {
   RequestContext requestContext
= RequestContext.getCurrentContext(); HttpServletRequest request = requestContext.getRequest(); System.out.println("拦截了--"+request.getRequestURI()); String tokenStr = "token"; //进行逻辑处理 String token = request.getHeader(tokenStr); if(StringUtils.isEmpty(token)){ token = request.getParameter(tokenStr); } //根据token 进行登录校验逻辑的处理,根据公司的情况来自定义 JWT if(StringUtils.isEmpty(token)){ requestContext.setSendZuulResponse(false); requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); } return null; } }

7.zuul默认拦截三种请求信息,要么使用token,要么就在配置文件中增加一个配置

 

#增加配置,等于空就行
zuul
 sensitiveHeaders=

 8.使用zuul进行限流,使用令牌算法

 

 代码如下:

package com.xdclass.apigateway.filter;

import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

/**
 * 订单限流
 * @author chengcheng123
 * @date 2021/6/9 0:35
 */
//@Component
public class OrderRateLimiterFilter extends ZuulFilter {


    //每秒创建一千个令牌
    private static final RateLimiter RATE_LIMITER = RateLimiter.create(1000);


    @Override
    public String filterType() {
        //这个类里面记录了很多拦截器的类型,PRE表示前置
        return FilterConstants.PRE_TYPE;
    }

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

    @Override
    public boolean shouldFilter() {
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        //如果请求的接口是订单接口的话,那么就进行拦截
        String requestURI = request.getRequestURI();

        if(!StringUtils.isEmpty(requestURI) && requestURI.toLowerCase().contains("order")){
            return true;
        }
        return false;
    }

    @Override
    public Object run() throws ZuulException {
        //进行限流的处理
        RequestContext currentContext = RequestContext.getCurrentContext();
        if(!RATE_LIMITER.tryAcquire()){
            //如果没有拿到令牌,则返回一个错误码
            currentContext.setSendZuulResponse(false);
            currentContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
        }

        return null;
    }
}

 

posted on 2021-06-09 12:13  程英俊  阅读(578)  评论(0编辑  收藏  举报