6.网关/服务端负载均衡器/服务过滤器(Zuul)

来源:互联网 发布:java中国天气网api 编辑:程序博客网 时间:2024/06/05 18:02

1.Zuul介绍

zuul是一个网关和负载均衡器,在通过ribbon或者feign实现了客户端负载均衡之后,zuul在服务端实现负载均衡。zuul支持用任何JVM语言来编写规则和过滤条件。zuul充当了一个代理服务器承担内部网络的网关的角色。如图:




2.cmd下启动四个工程(eureka注册工程/ribbon消费者工程/feign消费者工程/服务提供者工程)



3.创建一个Zuul工程(zuul_test)

(1)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.tyf</groupId>  <artifactId>zuul_test</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>jar</packaging>  <name>zuul_test</name>  <url>http://maven.apache.org</url><!-- 1 --><parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.2.RELEASE</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  </properties>   <!-- 2 -->   <dependencies><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>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>  </dependencies>    <!-- 3 -->  <dependencyManagement>        <dependencies>            <dependency>                <groupId>org.springframework.cloud</groupId>                <artifactId>spring-cloud-dependencies</artifactId>                <version>Dalston.RC1</version>                <type>pom</type>                <scope>import</scope>            </dependency>        </dependencies>    </dependencyManagement>   <!-- 4 -->  <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build><!-- 5 -->    <repositories>        <repository>            <id>spring-milestones</id>            <name>Spring Milestones</name>            <url>https://repo.spring.io/milestone</url>            <snapshots>                <enabled>false</enabled>            </snapshots>        </repository>    </repositories>      </project>
(2)resources/application.yml
eureka:  client:    serviceUrl:      defaultZone: http://localhost:8761/eureka/server:  port: 8770spring:  application:    name: zuul-testzuul:  routes:    api-a:      path: /test-a/**      serviceId: feign-consumer-test          api-b:      path: /test-b/**      serviceId: ribbon-consumer-test
这里test-a前缀负责将所有的这类请求路由给feign-consumer-test
所以这里访问feign-consumer-test的控制器不会直接请求feign-consumer-test的地址,而是通过zuul这个网关
不使用zuul访问feign-consumer-test:http://localhost:8766/feignConsumer/test?name=xxx
使用zuul访问feign-consumer-test:http://localhost:8770/test-a/test?name=xxx
(3)启动类
package com.tyf.zuul_test;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;/** * Hello world! * */@EnableZuulProxy@EnableEurekaClient@SpringBootApplicationpublic class App {    public static void main( String[] args )    {    SpringApplication.run(App.class, args);    }}
(4)启动zuul工程
通过zuul访问feign-consumer-test的控制器:http://localhost:8770/test-a/feignConsumer/test?name=xxx
通过zuul访问ribbon-consumer-test的控制器:http://localhost:8770/test-b/modelController/test

4.zuul做过滤器

直接继承zuul的过滤器,四个方法说明见注释(别忘了注入ioc中)

package com.tyf.zuul_test;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Component;import com.netflix.zuul.ZuulFilter;import com.netflix.zuul.context.RequestContext;/* *  * 基础zuul过滤器: * 1.String filterType():返回一个字符串代表这个过滤器在路由的那个阶段进行 * pre:路由之前 * routing:路由之时 * post: 路由之后 * error:发送错误调用 * 2.int filterOrder():返回一个int整数用来排序(从0开始),请求在多个过滤器之间传递,传递的顺序就是这个值 * 3.boolean shouldFilter():获取到请求,如果请求不符合要求可以不让请求通过,这里可以实现很多逻辑: *  * 4.run():具体的过滤逻辑,这里检查请求参数是否有token,这里访问url变成如下形式: * feign-consumer-test的控制器:http://localhost:8770/test-a/feignConsumer/test?name=xxx&token=xxx * ribbon-consumer-test的控制器:http://localhost:8770/test-b/modelController/test?token=xxx *  *  */@Componentpublic class myFiler extends ZuulFilter {@Overridepublic Object run() {RequestContext ctx = RequestContext.getCurrentContext();        HttpServletRequest request = ctx.getRequest();        Object accessToken = request.getParameter("token");        System.out.println(accessToken);        try {if(accessToken == null) {    //ctx设置response,直接在这里进行responsectx.setSendZuulResponse(false);ctx.setResponseStatusCode(401);        ctx.getResponse().getWriter().write("token is empty");        System.out.println("token is null !");    return null;}} catch (Exception e) {e.printStackTrace();}                //如果一切正常,request会被路由到消费者/服务提供者那里由他们做出response        return null;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic int filterOrder() {//filterOrder:过滤的顺序return 0;}@Overridepublic String filterType() {//过滤器在路由之前起作用return "pre";}}

run方法中如果request没有token参数,则zuul服务器直接response告诉浏览器。如果一切正常则request会通过过滤器再通过路由器传播

正确的访问参数:

feign-consumer-test的控制器:http://localhost:8770/test-a/feignConsumer/test?name=xxx&token=xxx
ribbon-consumer-test的控制器:http://localhost:8770/test-b/modelController/test?token=xxx


原创粉丝点击