spring cloud -- 4.路由网关(zuul)

此文章是看了方志朋老师的教材自己写的框架demo:

学习spring cloud推荐大家看下方志朋老师的史上最简单的 SpringCloud 教程 | 终章,地址如下:

   https://blog.****.net/forezp/article/details/70148833 

1.简介与作用

微服务架构中,需要几个基础的服务治理组件,包括服务注册与发现、服务消费、负载均衡、断路器、智能路由、配置管理等,由这几个基础组件相互协作,共同组建了一个简单的微服务系统。一个简答的微服务系统如下图:

spring cloud -- 4.路由网关(zuul)

spring Cloud微服务系统中,一种常见的负载均衡方式是,客户端的请求首先经过负载均衡(zuul、Ngnix),再到达服务网关(zuul集群),然后再到具体的服务,服务统一注册到高可用的服务注册中心集群,服务的所有的配置文件由配置服务管理,配置服务的配置文件放在Gitsvn仓库,方便开发人员随时改配置

 

Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能。

2.代码实现(路由)

2.1 创建maven项目

spring cloud -- 4.路由网关(zuul)
spring cloud -- 4.路由网关(zuul)
spring cloud -- 4.路由网关(zuul)

2.2 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">

  <modelVersion>4.0.0</modelVersion>

  <groupId>com.immo</groupId>

  <artifactId>immo-zuul</artifactId>

  <version>0.0.1-SNAPSHOT</version>

   <!-- spring boot 依赖包 -->

  <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>1.5.2.RELEASE</version>

        <relativePath/> 

   </parent>

   

   <!-- 编码和java版本 -->

   <properties>

        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <java.version>1.7</java.version>

    </properties>

    

    <dependencies>

    <!-- spring cloud -->

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

            <version>1.3.4.RELEASE</version>

        </dependency>

        

        <!-- zuul -->

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-zuul</artifactId>

            <version>1.3.4.RELEASE</version>

        </dependency>

        

        <!-- spring mvc -->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

 

    </dependencies>

</project>

 

2.3 添加启动类

src/main/java 下新建包 com.immo  创建 ZuulApplication.java

src/main/resources 下新建 application.properties

spring cloud -- 4.路由网关(zuul)

编写ZuulApplication.java

@EnableZuulProxy,开启zuul的功能

package com.immo;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

 

@EnableZuulProxy

@EnableEurekaClient

@SpringBootApplication

public class ZuulApplication {

 public static void main(String[] args) {

        SpringApplication.run(ZuulApplication.class,args);

 }

}

 

 

编写application.properties

#发布到的eureka地址

eureka.client.serviceUrl.defaultZone=http://localhost:9000/eureka/

#端口

server.port=8080

#此项目的服务名称

spring.application.name=immo-zuul

#路由配置

zuul.routes.api-a.path= /api-a/**

zuul.routes.api-a.serviceId: immo-feign

#路由配置

zuul.routes.api-b.path: /api-b/**

zuul.routes.api-b.serviceId: immo-client

 

注:如果没有设置路由配置也可以通过 localhost:8080/服务名/** 来访问

2.4测试(路由)

先后启动immo-eurekaimmo-clientimmo-feignimmo-zuul这四个项目:

spring cloud -- 4.路由网关(zuul)

证明路由起作用了

注:如果没有设置路由配置也可以通过 localhost:8080/服务名/** 来访问

spring cloud -- 4.路由网关(zuul)
spring cloud -- 4.路由网关(zuul)

3.代码实现(过滤)

zuul不仅只是路由,并且还能过滤,做一些安全验证。继续改造工程创建包com.immo.filter,在包下创建MyFilter.java

spring cloud -- 4.路由网关(zuul)

编写MyFilter.java

filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:

· pre:路由之前

· routing:路由之时

· post: 路由之后

· error:发送错误调用

· filterOrder:过滤的顺序

· shouldFilter:这里可以写逻辑判断,是否要过滤,本文true,永远过滤。

· run:过滤器的具体逻辑。可用很复杂,包括查sqlnosql去判断该请求到底有没有权限访问

package com.immo.filter;

 

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;

import com.netflix.zuul.context.RequestContext;

 

@Component

public class MyFilter extends ZuulFilter{

 

    @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();

        Object accessToken = request.getParameter("param");

        if(accessToken == null) {

            ctx.setSendZuulResponse(false);

            ctx.setResponseStatusCode(401);

            try {

            HttpServletResponse response = ctx.getResponse();

            response.setCharacterEncoding("utf-8");

            response.getWriter().write("沒有携带参数,拦截!");

            }catch (Exception e){

            e.printStackTrace();

            }

            return null;

        }

        return null;

    }

}

 

 

 

 

测试,先后启动immo-eurekaimmo-clientimmo-feignimmo-zuul这四个项目:

访问刚刚访问过的接口,因为没有携带param接口给我们返回了提示信息,证明过滤了:

spring cloud -- 4.路由网关(zuul)

再次访问,携带param参数,正常获得数据:

spring cloud -- 4.路由网关(zuul)