spring cloud zuul简单用法(负载均衡、熔断、限流)

前言

看这篇文章之前,我建议还是先看一下我之前写的两篇文章(feign服务调用;负载均衡与熔断)。
spring cloud zuul是一个网关相关技术,它统一代理所有服务的访问路径。并且还可以在访问过程中拦截请求,做一些过滤操作。zuul自带了负载均衡和熔断依赖,那么这些依赖会对原先feign的负载均衡、熔断产生什么影响呢?以及限流操作是怎么实现的,下述文章将会通过例子的方式来讲述。

zuul的负载均衡(不通过消费者调用,直接访问提供者)

准备两个服务
yml配置
provider

server:
  port: 8081
spring:
  application:
    name: provider
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

provider2

server:
  port: 8091
spring:
  application:
    name: provider
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

接口
provider

@RestController
public class TestController {
	@RequestMapping(value = "/test3")
    public String thirdCloud(){
        return "test3";
    }

provider2

@RestController
public class TestController {
	@RequestMapping(value = "/test3")
    public String thirdCloud(){ //空参
        return "test33332222";
    }

以上两个服务为了达到负载均衡的效果。包名,路径映射,eureka注册路径等都一样。
启动服务后可以看到eureka的变化
在这里插入图片描述
zuul配置
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.qiu</groupId>
        <artifactId>boot2cloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.qiu</groupId>
    <artifactId>zuul</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>zuul</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

yml配置

server:
  port: 9999
spring:
  application:
    name: zuul
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

启动类上开启zuul代理功能

@SpringBootApplication
@EnableZuulProxy //开启zuul代理
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
    }
}

以上,zuul的初步配置就完成了
传统访问
在这里插入图片描述
通过zuul网关访问提供者(添加服务名就可以访问到)
在这里插入图片描述
zuul访问方式刷新,发现调用的接口是另一个提供者的,说明负载均衡的作用出来了,不需要任何配置,只要有两个服务是集群关系即可自行起效。
在这里插入图片描述
自定义zuul访问规则
如果仅仅是上述配置,那么zuul的访问规则是:ip:port /服务名/接口路径
但是如果想改变这个规则,可以在yml文件中进行如下配置

zuul:
  routes:
    customer: /cus/**    #服务名: 代理的路径
    provider: /pro/**    #服务名: 代理的路径
  ignored-services: "*" #规定原来的路径无法访问,必须通过zuul的路由才能访问。

以上配置后重启服务
用http://localhost:9999/provider/test3去访问的时候会出现如下结果。
在这里插入图片描述
用http://localhost:9999/pro/test3访问才可以访问的到。
在这里插入图片描述

zuul的熔断

我以前的文章介绍过feign它是整合了熔断的,当访问的服务宕掉的时候会返回指定的内容。但是feign的熔断在zuul好像失效了。
在这里插入图片描述
所以,只好再配置zuul的熔断了
配置十分简单,不用添加依赖、不用改yml,也不用在启动类添加什么注解,只需要添加一个java代码。

package com.qiu.zuul.mybreak;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @Author VULCAN
 * @create 2020/1/13 1:30
 */
@Component
public class ZuulFallBack implements FallbackProvider {
    //熔断配置
    @Override
    public String getRoute() {
        //作用于所有被zuul代理的服务
        return "*";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpHeaders getHeaders() {
            //添加头信息,必须要添加,不添加则熔断失败
                HttpHeaders httpHeaders=new HttpHeaders();
                httpHeaders.add("reason","theboom");
                return httpHeaders;
            }

            @Override
            public InputStream getBody() throws IOException {
                //如果熔断了展现出什么信息
                byte[] bytes = "your serve has boom".getBytes("UTF-8");
                return new ByteArrayInputStream(bytes);
            }

            @Override
            public HttpStatus getStatusCode() throws IOException {
            	//报错类型400
                return HttpStatus.BAD_REQUEST;
            }

            @Override
            public int getRawStatusCode() throws IOException {
            	//错误代码,和上述HttpStatus一致就行
                return 400;
            }

            @Override
            public String getStatusText() throws IOException {
                return null;
            }

            @Override
            public void close() {

            }
        };
    }
}

配置完成后,我们重启所有服务,然后在宕掉消费者调用的所有提供者。‘
访问消费者路径http://localhost:9999/cus/feignRibbonTest
出现指定内容,为了更好的展现信息,我这一回使用postman来测试接口
在这里插入图片描述
在这里插入图片描述

zuul的限流

在一些高并发的项目中,为了保护网站不被恶意攻击(疯狂刷新导致服务器压力过高),限流的作用就体现出来了,它能指定一个规则,哪个ip在多少分钟内能访问多少次,访问次数超过限制后会报错。
zuul本身没有限流的功能,所以我们需要借助另外的依赖。
github地址:https://github.com/marcosbarbero/spring-cloud-zuul-ratelimit
在这里插入图片描述
点开他,在下方有说明书
在这里插入图片描述
那么根据这个说明书的内容引入这两个maven坐标

<!-- 用于zuul限流-->
        <dependency>
            <groupId>com.marcosbarbero.cloud</groupId>
            <artifactId>spring-cloud-zuul-ratelimit</artifactId>
            <version>LATEST</version>
        </dependency>
<!-- 基于redis来计数-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

说明书也有yml配置说明
在这里插入图片描述
删除里面多余的内容,并启动redis服务,添加进yml
在这里插入图片描述

  redis: #计数操作在redis里面执行
    port: 6379
    host: localhost
zuul:
  ratelimit:
    enabled: true
    repository: redis
    behind-proxy: true
    add-response-headers: true
    default-policy-list:  #所有服务都有效
      - limit: 10    #限制次数,每刷新一次次数+1
        quota: 1000  #窗口对应的请求时间限制
        refresh-interval: 60 #多少秒后刷新计数
        type: #optional #限制类型
          - origin  #url  包括ip+接口

重新启动服务后,我们对一个服务疯狂刷新。
起初是正常的
在这里插入图片描述
但是达到十次之后
在这里插入图片描述
用图形化工具打开redis。里面的计数情况:value则是刷新的次数,TTL则是这个String的生命周期,14代表的是还剩下14秒这个key就会被删除。
在这里插入图片描述

zuul的过滤

zuul的过滤在这篇文章中暂时不讲,今后会和oauth2整合的时候再讲述。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值