使用idea從零編寫SpringCloud項目-zuul


  帶着問題學習是最好的,什么是網關?使用網關的好處是什么?怎么使用網關

  網關:是系統對外的唯一入口,是介於客戶端和服務端的中間層,處理非業務功能,提供路由的請求,鑒權,監控,緩存,限流等

  網關的好處:可以將很多非業務功能集中在網關處理,例如鑒權,限流等,並且只提供了一個入口,那么也可以將業務服務很好的保護起來。

    網關的使用:

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM