6.SpringCloud-zuul

Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能。当然,用Nginx也可以实路由功能以及负载均衡等功能,暂且不说ng,先来看看Zuul+Ribbon怎么做。

1.创建zuul工程

pom文件依赖如下

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
   <groupId>com.netflix.zuul</groupId>
   <artifactId>zuul-core</artifactId>
   <version>1.3.1</version>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <scope>test</scope>
</dependency>

2.在启动类加入注解

@EnableZuulProxy
@EnableEurekaClient

3.修改配置文件

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8888/eureka/
server:
  port: 8009
spring:
  application:
    name: service-zuul
zuul:
  routes:
    api-a:
      path: /api-a/**
      serviceId: service-ribbon
    api-b:
      path: /api-b/**
      serviceId: service-feign

4.启动前几节建好的Eureka server、client、Ribbon工程以及zuul工程
访问http://localhost:8009/api-a/hi?name=forezp可以看到通过Ribbon访问了Eureka client
此时http://localhost:8009/api-b/hi?name=forezp不能访问,需要开启Feign工程,
启动后可以通过Feign访问Eureka client

5.zuul的过滤功能
加入zuul过滤器

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class MyFilter extends ZuulFilter {

    private static Logger log = LoggerFactory.getLogger(MyFilter.class);

    /**
     * pre:路由之前
     * routing:路由之时
     * post: 路由之后
     * error:发送错误调用
     * filterOrder:过滤的顺序
     * shouldFilter:这里可以写逻辑判断,是否要过滤,本文true,永远过滤。
     * run:过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。
     **/

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

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
        Object accessToken = request.getParameter("token");
        if (accessToken == null) {
            log.warn("token is empty");
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            try {
                ctx.getResponse().getWriter().write("token is empty");
            } catch (Exception e) {
            }

            return null;
        }
        log.info("ok");
        return null;
    }
}

再次访问http://localhost:8009/api-a/hi?name=forezp
提示token is empty
加入token后访问http://localhost:8009/api-a/hi?name=forezp&token=abc
可以正常访问

猜你喜欢

转载自blog.csdn.net/gaojingyuan/article/details/79013605