欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

springboot~zuul实现网关

程序员文章站 2022-03-26 09:21:44
网关在微服务里的角色 在微服务架构体系里,网关是非常重要的一个环节,它主要实现了一些功能的统一处理,包括了: 1. 统一授权 2. 统一异常处理 3. 路由导向 4. 跨域处理 5. 限流 实践一下 1 添加依赖 2 添加yml 3 添加实现代码 http拦截器,获取用户ID,为子服务进行传递 在主 ......

网关在微服务里的角色

在微服务架构体系里,网关是非常重要的一个环节,它主要实现了一些功能的统一处理,包括了:

  1. 统一授权
  2. 统一异常处理
  3. 路由导向
  4. 跨域处理
  5. 限流

实践一下

1 添加依赖

dependencies {
    implementation('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
    implementation('org.springframework.cloud:spring-cloud-starter-netflix-zuul')
    testimplementation('org.springframework.boot:spring-boot-starter-test')
    implementation('com.marcosbarbero.cloud:spring-cloud-zuul-ratelimit:1.3.2.release')
}

2 添加yml

server:
  port: 8300
spring:
  application:
    name: microservice-gateway-zuul
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultzone: http://localhost:6761/eureka
  instance:
    ip-address: true

zuul:
 routes:
    users:
       path: /lind/** #以lind开头的路径被重定向到lind服务
       serviceid: lind
 add-host-header: true #显示真实的http头
 retryable: false #关闭hystrix的重试功能
 ratelimit:
    enabled: true
   #  repository: redis
    behind-proxy: true
    policies:
       users:
         limit: 5 #限流,每分钟请求5次
         refresh-interval: 60
         type:
           - user
           - origin
           - url
         #       url类型的限流就是通过请求路径区分
         #       origin是通过客户端ip地址区分
         #       user是通过授权用户进行区分,也包括匿名用户

3 添加实现代码
http拦截器,获取用户id,为子服务进行传递

public class prerequestlogfilter extends zuulfilter {
  private static final logger logger = loggerfactory.getlogger(prerequestlogfilter.class);
  private final ratelimiter ratelimiter = ratelimiter.create(1000.0);

  @override
  public object run() {

    try {
      requestcontext currentcontext = requestcontext.getcurrentcontext();
      httpservletresponse response = currentcontext.getresponse();
      httpservletrequest reqeust = currentcontext.getrequest();

      currentcontext.addzuulrequestheader("userid","123");//向子系统http头写数据
      currentcontext.addzuulrequestheader("username","test");

      prerequestlogfilter.logger.info(
          string.format("send %s request to %s",
              reqeust.getmethod(),
              reqeust.getrequesturl().tostring()));

      if (!ratelimiter.tryacquire()) {
        httpstatus httpstatus = httpstatus.too_many_requests;
        response.setcontenttype(mediatype.text_plain_value);
        response.setstatus(httpstatus.value());
        response.getwriter().append(httpstatus.getreasonphrase());
        currentcontext.setsendzuulresponse(false);
        throw new zuulexception(
            httpstatus.getreasonphrase(),
            httpstatus.value(),
            httpstatus.getreasonphrase()
        );
      }
    } catch (java.lang.exception e) {
      reflectionutils.rethrowruntimeexception(e);
    }
    return null;

  }

  @override
  public boolean shouldfilter() {

    // 判断是否需要过滤
    return true;

  }


  @override

  public string filtertype() {

    return filterconstants.pre_type;

  }


  @override

  public int filterorder() {

    return ordered.highest_precedence;

  }


}

在主程中注入这个过滤器

  @bean
  public prerequestlogfilter prerequestlogfilter() {
    return new prerequestlogfilter();
  }

4 使用它
在url上通过localhost:8300/users/home 将进行lind服务里的home控制器下,并在http头上写入了userid和username这个键值对!