Spring Cloud配置动态路由Zuul

Zuul是什么?

  • front door. API Gateway.Zuul is a JVM based router and server side load balancer by Netflix.
  • 所有请求的入口。
  • As an edge service application, Zuul is built to enable dynamic routing, monitoring, resiliency and security. 作为边界应用服务,zuul能实现动态路由、监控、弹性与安全性。
  • 用groovy编写。


官网说明 Netflix uses Zuul for the following:

Authentication 认证
Insights 洞察力
Stress Testing 压力测试
Canary Testing 金丝雀测试
Dynamic Routing 动态路由
Service Migration 服务迁移
Load Shedding 减载
Security 安全
Static Response handling 静态响应处理
Active/Active traffic management


Zuul可以实现好些功能,路由功能是微服务的一部分,这里主要记录下使用zuul做负载均衡。

使用注意事项

  1. If you need your routes to have their order preserved you need to use a YAML file as the ordering will be lost using a properties file.如果你希望按照书写顺序来执行路由规则,则必须使用YAML文件,不能使用properties

具体配置如下:

在根目录spring_cloud中创建Maven Moudle模块:zuul-server

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-cloud</artifactId>
        <groupId>com.sam</groupId>
        <version>0.0.1</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
 
    <artifactId>zuul-server</artifactId>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>
    </dependencies>
 
</project>


创建消费者服务启动类:ZuulApplication

package com.sam.zuul.server;
 
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
 
/**
 * @ClassName: ZuulApplication 
 * @Description: Zuul路由服务
 * Zuul的主要功能是路由和过滤器。路由功能是微服务的一部分,zuul实现了负载均衡。
 * @author sam 
 * @date 2018年8月10日 上午11:38:24
 */
@SpringCloudApplication //这个注解整合了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreake
@EnableZuulProxy
public class ZuulApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
    }
 
    @Bean
    public MyZuulFilter getZuulFilter(){
        return new MyZuulFilter();
    }
}


创建过滤器:MyZuulFilter

package com.sam.zuul.server;
 
import javax.servlet.http.HttpServletRequest;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
 
/**
 * @ClassName: MyZuulFilter
 * @Description: 自定义过滤器
 * @author sam
 * @date 2018年8月10日 上午11:23:11
 */
public class MyZuulFilter extends ZuulFilter {
 
    private static Logger log = LoggerFactory.getLogger(MyZuulFilter.class);
 
    /**
     * 返回过滤器类型
     * 
     * @return pre:可以在请求被路由之前调用 routing:在路由请求时候被调用 post:在routing和error过滤器之后被调用
     *         error:处理请求时发生错误时被调用
     */
    @Override
    public String filterType() {
        return "pre";
    }
 
    /**
     * 通过int值来定义过滤器的执行顺序
     */
    @Override
    public int filterOrder() {
        return 0;
    }
 
    /**
     * 判断过滤器是否执行
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }
 
    /**
     * 过滤器的具体逻辑 ctx.setSendZuulResponse(false)令zuul不允许请求,
     * ctx.setResponseStatusCode(401)设置了其返回的错误码
     * ctx.setResponseBody(body)编辑返回body内容
     * 
     * @return
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
 
        HttpServletRequest request = ctx.getRequest();
 
        log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
        Object id = request.getParameter("id");
        if (id == null) {
            log.warn("id is null");
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            return null;
        }
 
        log.info("pass!");
        return null;
    }
 
}


创建配置文件:application.yml

spring:
  application:
    name: zuul
 
server:
  port: 8020
 
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8010/eureka/
 
zuul:
  routes:
    api-a:
      path: /service-producer/**
      serviceId: service-producer
    api-b:
      path: /service-producer-c/**
      serviceId: service-producer-c
  sensitive-headers:  #设置忽略的头信息,设置为空能解决会话保持问题
  add-host-header: true #设为true才能保持Host头信息处理正确


上面配置说明

扫描二维码关注公众号,回复: 6176750 查看本文章

把/service-producer/开头的所有请求都转发给service-producer服务执行,

把/service-producer-c/开头的所有请求都转发给service-producer-c服务执行,

PS: 由于用到新的一个生产者服务,于是创建一个新的生产者服务service-producer-c,直接从service-producer-A拷贝一份,修改端口名称,及服务名,其它的一致,其中配置文件application.yml如下:

spring:
  application:
    name: service-producer-c
 
server:
  port: 8813
 
eureka:
  client:
    serviceUrl:
          defaultZone: http://localhost:8010/eureka/ #eureka服务注册地址


注意名称是 service-producer-c 。

以上配置完成后,启动 zuul-server 等服务,如下图:

访问Zuul服务,
分别打开

http://localhost:8020/service-producer/hi?id=zuul

hi, zuul, service-producer:8811


http://localhost:8020/service-producer-c/hi?id=zuul

hi, zuul, service-producer-c:8813

可以看到Zuul已经实现了相应的路由规则,根据不同的访问路径进行动态 分发!

猜你喜欢

转载自blog.csdn.net/yuyecsdn/article/details/90017395
今日推荐