eureka组件服务集群,feign远程调用,生产者服务集群,ribbon组件(负载均衡),hystrix组件(断路器),zuul(网关路由)

一、搭建Eureka服务集群

1、创建和一个父module(用于依赖管理)

a、 配置pom文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gec</groupId>
    <artifactId>springcloudparent</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>eureka-server</module>
        <module>provider-8801</module>
        <module>provider-8802</module>
        <module>provider-8803</module>
        <module>consumer</module>
        <module>consumer-feign</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.14.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!--Springcloud的依赖库文件版本的锁定-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>




</project>

2、创建三个eureka server的module(此处仅详细列出一台服务的配置)

b、 配置pom文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>eureka-parent</artifactId>
        <groupId>com.gec</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-server</artifactId>

    <dependencies>
        <!--配置eureka依赖库组件-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
</project>

c、 配置全局配置文件application.yml

spring:
  application:
    name: eureka-server
server:
  port: 7001
eureka:
  instance:
    hostname: eureka7001.com
  client:
    service-url:
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
        #本身就是注册中心,不需要注册
      register-with-eureka: false
        #本身就是注册中心,不需要获取注册信息
      fetch-registry: false

d、 全局配置文件截图说明

在这里插入图片描述

e、 eureka-server集群后的另外两台配置yml截图,其余部分与第一台server的代码相同

  • 第二台:在这里插入图片描述

f、 第三台

在这里插入图片描述

g、 编写启动类

package com.gec;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class ServerApp7001 {
    public static void main(String[] args) {
        SpringApplication.run(ServerApp7001.class, args);
    }
}

h、 验证集群是否配置成功,在浏览器中输入:http://eureka7001.com:7001或http://eureka7002.com:7002或http://eureka7003.com:7003验证是否成功

* 当eureka服务集群时,未全部启动所有参与集群的服务时,会报以下异常:com.sun.jersey.api.client.ClientHandlerException: org.apache.http.conn.ConnectTimeoutException: Connect to eureka7003.com:7003 timed out……,当集群的全部服务都启动完后即可,也可增长服务连接超时时间,来消除此异常,异常截图如下:
* ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200522000455873.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NjE4MzU2MQ==,size_16,color_FFFFFF,t_70)
* 成功界面截图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200522000832570.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NjE4MzU2MQ==,size_16,color_FFFFFF,t_70)

二、创建公共模块

1、创建公共模块(普通模块,通常就是创建bean,pom文件不用配置)

a、 编写一个user的pojo

package com.gec.user.pojo;

import java.io.Serializable;

public class UserBean implements Serializable {

    private String userName;
    private Integer age;

    public UserBean() {
    }

    public UserBean(String userName, Integer age) {
        this.userName = userName;
        this.age = age;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserBean{" +
                "userName='" + userName + '\'' +
                ", age=" + age +
                '}';
    }
}

三、生产者模块

1、生产者模块(一)

a、 配置pom文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>eureka-parent</artifactId>
        <groupId>com.gec</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>provider-8801</artifactId>

    <dependencies>
        <!--引入公共模块-->
        <dependency>
            <groupId>com.gec</groupId>
            <artifactId>user-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--配置eureka的客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--配置web的starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

b、 编写application.yml配置文件

spring:
  application:
    name: user-service
server:
  port: 8801
  #eureka的基本信息
eureka:
  instance:
    hostname: 127.0.0.1
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    #它本身是一个普通的服务,需要在eureka-server注册
    register-with-eureka: true
    #需要获取注册信息
    fetch-registry: true

c、 配置文件截图说明:

在这里插入图片描述

d、 编写controller

@RestController
public class UserController {
    @RequestMapping("/getUser")
    public User getUser(){
        User user = new User("张三", "123");
        return user;
    }
    @RequestMapping("/addUser")
    public int addUser(@RequestBody User user){
        System.out.println("插入user成功:"+user);
        return 1;
    }
    @RequestMapping("/getUserById/{id}")
    public User alterUser(@PathVariable int id){
        if (id == 1){
            return new User("小泽", "12345");
        }else if (id == 2){
            return new User("小苍", "23456");
        }else if (id == 3){
            return new User("小野", "34567");
        }else {
            return new User("小罗", "45678");
        }
    }
}

e、 编写启动类

package com.gec;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class ProviderApp8801 {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApp8801.class, args);
    }
}

2、生产者模块(二),直接复制生产者模块(一),并按照以下操作步骤进行

a、 导入复制好的模块,删除之前之前模块的idea配置文件和target文件夹,并将其设置为maven项目

在这里插入图片描述
在这里插入图片描述

b、 修改当前模块的pom文件

在这里插入图片描述

c、 修改父模块的pom文件

在这里插入图片描述

d、 修改配置文件application.yml;只需修改端口号不同即可,其余不改,服务名需相同,是服务集群的关键。

3、生产者其他模块操作步骤同上。

四、消费者模块

1、消费者Feign客户端,负载均衡

a、 pom文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>eureka-parent</artifactId>
        <groupId>com.gec</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>consumer-feign</artifactId>

    <dependencies>
        <!--引入自建公共模块-->
        <dependency>
            <groupId>com.gec</groupId>
            <artifactId>user-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--支持feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>
</project>

b、 编写配置文件application.yml

spring:
  application:
    name: user-feign
server:
  port: 9999
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
      #它本身是一个普通的服务,需要在eureka-server注册
      register-with-eureka: true
      #需要获取注册信息
      fetch-registry: true

c、 编写service接口(无需其实现类)

package com.gec.service;


import com.gec.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
//value为指定微服务的应用访问名称(提供方)
// 默认具备负载均衡功能(轮询)
@FeignClient(value = "USER-SERVICE", fallback = UserServiceFallback.class)
public interface UserService {
   //此接口无需实现,由框架帮实现,类似mybatis中的mapper
   //value为提供方的访问方式,method也需要和提供方保持一致
   @GetMapping("/getUser")
   User getUser();
   @RequestMapping("/addUser")
   int addUser(User user);
   @RequestMapping("/getUserById/{id}")
   User getUserById(@PathVariable int id);
   // 测试负载均衡方法
   @GetMapping("/getPort")
   String getPort();
}

e、 编写控制器

package com.gec.controller;

import com.gec.pojo.User;
import com.gec.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @Autowired
    UserService userService;
    @RequestMapping("/getUser")
    public User getUser(){
        return userService.getUser();
    }
    @RequestMapping("/addUser")
    public String addUser(){
        User user = new User("lisi", "123");
        Integer isSuccess = userService.addUser(user);
        if (isSuccess == 1){
            return "添加user成功";
        }else {
            return "添加失败";
        }
    }
    @RequestMapping("/getUserById/{id}")
    public User getUserById(@PathVariable int id){
        User user = userService.getUserById(id);
        return user;
    }
    @GetMapping("/getPort")
    public String getPort(){
        return userService.getPort();
    }
}

f、 编写配置负载均衡的类,可不配,则默认采用轮询负载均衡策略

package com.gec.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 负载均衡配置类,包含七种策略:
 * 1.RoundRobinRule(默认) --轮询策略
 * 2.RandomRule --随机策略
 * 3.AvailabilityFilteringRule  --根据并发数
 * 4.WeightedResponseTimeRule  --根据响应时间
 * 5.RetryRule  --重试效果
 * 6.BestAvailableRule
 * 7.ZoneAvoidanceRule
 */
@Configuration
public class LoadBalanceConfig {
   /* @Bean
    public IRule setLoadBalancer(){
        //轮询策略
        return new RoundRobinRule();
    }*/

    @Bean
    public IRule setLoadBalancer(){
        //随机策略
        return new RandomRule();
    }
}

g、 编写启动类

package com.gec;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients 
public class FeignClientApp {
    public static void main(String[] args) {
        SpringApplication.run(FeignClientApp.class, args);
    }
}

2、启动完所有服务后,查看服务注册列表,并调用消费端的handler访问测试

a、 查看服务注册列表

在这里插入图片描述

b、访问测试

在这里插入图片描述

3、配置hystrix断路器

a、 断路器作用:由于网络原因或者自身服务的原因,导致服务可能会产生故障或者是不可用,如果此服务生产故障,就会导致请求此服务的线程阻塞,如果涉及大量的线程请求阻塞,就进一步导致容器产生瘫痪,也会导致其它服务不可用,就会产生“雪崩效应”。因此需要一种机制处理,此机制就是“断路器”。

a、为什么会有Hystrix组件

  • 由于网络原因或者自身服务的原因,导致服务可能会产生故障或者是不可用,如果此服务生产故障,就会导致请求此服务的线程阻塞,如果涉及大量的线程请求阻塞,就进一步导致容器产生瘫痪,也会导致其它服务不可用,就会产生“雪崩效应”。因此需要一种机制处理,此机制就是“断路器”

2、Hystrix的特征

  • 触发熔断条件
    • 当请求服务失败的次数超过一定的比例(默认50%),熔断就会生效
    • 熔断默认持续时间5秒,5秒之后它就会从(开路状态—》半开路状态)
    • 处于半开路状态,判断下一次请求,是否成功,如果成功,则切回到闭路状态
  • 降级服务
    • 当熔断机制启动,此服务不可用,直接返回失败,它会有一个响应机制处理:调用降级服务的响应方法实现

3、如何实现熔断降级机制

a、原pom文件中新增依赖

 <!--支持断路器-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

b、application.yml文件中开启支持断路器

#开启支持熔断
feign:
  hystrix:
    enabled: true

c、 编写回退类UserServiceFallback,用于访问服务出现异常时的降级处理

package com.gec.service;

import com.gec.pojo.User;
import org.springframework.stereotype.Component;

@Component
public class UserServiceFallback implements UserService {
    @Override
    public User getUser() {
        return new User("熔断啦", "111111111");
    }

    @Override
    public int addUser(User user) {
        return 0;
    }

    @Override
    public User getUserById(int id) {
        return new User("熔断啦", "888888888");
    }

    @Override
    public String getPort() {
        return "发生了熔断";
    }
}

c、 在原service接口中指定降级的处理类(回退类)

// fallback指定一个回退类(熔断机制),
@FeignClient(value = "USER-SERVICE", fallback = UserServiceFallback.class)
public interface UserService {
……
}

d、启动类中新增使能hystrix注解

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix 
public class FeignClientApp {
    public static void main(String[] args) {
        SpringApplication.run(FeignClientApp.class, args);
    }
}

4、依赖隔离

a、简介

  • 可以根据服务划分出多个线程池处理,一般情况下,多个服务应用同一个线程池,如果一个服务不可用或者是阻塞,导致线程池的连接资源不足,这样子也会导致其它的服务不可用,因此可以使用依赖隔离解决此问题,根据服务划分多个线程池处理。举例:一个应用服务器中部署了服务A和服务B,默认情况下,此两服务共享同一容器中的线程池,当服务A出现了异常后,会导致出现线程阻塞,没有任何处理的情况下,阻塞线程会随着请求服务A的数量递增而递增,最终耗尽该容器的线程池中的线程,致使发送给正常的服务B也会无响应。

b、代码实现(给服务中,根据id查找用户的服务为例)

  • 创建实现线程池的类
package com.gec.pool;

import com.gec.pojo.User;
import com.gec.service.UserService;
import com.netflix.hystrix.*;
// HystrixCommand<User>此处的泛型类型与,自定义的UserService中根据id查找用户的返回值类型相同,因为此类的作用就是要给UserService中根据id查找用户的那个方法划分一个独立的线程池运行
public class PoolCommandA extends HystrixCommand<User> {
    private UserService userService;
    private Integer id;

    public PoolCommandA(UserService userService) {

        super(
                Setter.withGroupKey(
                        //服务分组
                        HystrixCommandGroupKey.Factory.asKey("PoolCommandAGroup")
                ).andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("PoolCommandAPool"))
                        //线程池配置
                        //withCoreSize:线程池大小为10
                        //withKeepAliveTimeMinutes:线程存活时间15秒
                        //withQueueSizeRejectionThreshold:队列等待的阈值为100,超过100执行拒绝策略
                        .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
                                .withCoreSize(10)
                                .withKeepAliveTimeMinutes(3)
                                .withMaxQueueSize(10)
                                .withQueueSizeRejectionThreshold(10000))
                        //线程池隔离
                        .andCommandPropertiesDefaults(
                                HystrixCommandProperties.Setter()
                                        .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
                        )
        );
        this.userService=userService;
    }

    public void setUserService(UserService userService) {
        this.userService=userService;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    /*
    线程池的任务方法执行
    */
    @Override
    protected User run() {
        System.out.println("PoolCommandAPool thread id="+Thread.currentThread().getId());
        //执行UserService中根据id查找用户的那个方法
        User user=this.userService.getUserById(id);
        return user;
    }
}
  • 创建一个service接口PoolCommandAUserService
package com.gec.service;

import com.gec.pojo.User;

public interface PoolCommandAUserService {
    //根据id查找用户,方法名不一定要与UserService中的方法名相同
    User getUserById(int id);
}
  • 创建一个类实现PoolCommandAUserService接口
package com.gec.service.impl;

import com.gec.pojo.User;
import com.gec.pool.PoolCommandA;
import com.gec.service.PoolCommandAUserService;
import com.gec.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * 此类用于体现hystrix依赖隔离
 */
@Service
public class PoolCommandAUserServiceImpl implements PoolCommandAUserService {
    @Autowired
    UserService userService;
    @Override
    public User getUserById(int id) {
        // 启动线程池
        PoolCommandA poolCommandA = new PoolCommandA(userService);
        poolCommandA.setId(id);
        // 执行线程池
        Future<User> future = poolCommandA.queue();
        try {
            User user=future.get();
            return user;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }
}
  • 在原来的控制器中调用此方法
@RestController
public class UserController {
    @Autowired
    UserService userService;
    @Autowired
    PoolCommandAUserService poolCommandAUserService;
    
       ……
   
    @RequestMapping("/getUserByIdPool/{id}")
    public User getUserByIdPoolCommand(@PathVariable int id){
        User user = poolCommandAUserService.getUserById(id);
        return user;
    }
}
  • 重启消费者服务,并测试
    在这里插入图片描述

五、Zuul网关模块

1、简介

  • 在分布式系统系统中,有商品、订单、用户、广告、支付等等一大批的服务,前端怎么调用呢?和每个服务一个个打 交道?这显然是不可能的,这就需要有一个角色充当所有请求的入口,这个角色就是服务网关(API gateway)

2、优点

  • 监控各个微服务
  • 统一认证处理
  • 减少客户端与各个微服务的交互次数

3、什么是ZUUL

  • 它就是一个网关
  • 它其实就是微服务一道门
    • 服务路由
    • 负载均衡
    • 权限控制
  • 它是Netflix的组件

4、配置使用ZUUL

a、配置pom文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>eureka-parent</artifactId>
        <groupId>com.gec</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>zuul</artifactId>

    <dependencies>
        <!--配置eureka的客户端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--支持zuui组件网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

    </dependencies>

</project>

b、配置全局配置文件application.yml

spring:
  application:
    name: zuul-demo
server:
  port: 10000
eureka:
  instance:
    hostname: 127.0.0.1
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    register-with-eureka: true
    fetch-registry: true

# 配置服务路由
zuul:
  routes:
    api-user-provider:   # 自定义的路由
      path: /api-user-provider/**   # 自定义的路由的访问路径
      serviceId: user-service   # 自定义的路由的访问路径所访问的真实服务
    api-user-consumer:
      path: /api-user-consumer/**
      serviceId: user-feign

c、编写启动类

package com.gec;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy
public class ZuulApp {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApp.class, args);
    }
}

d、启动服务测试

在这里插入图片描述

e、网关的过滤器类型

  • pre
    • 可以在请求被路由之前调用。适用于身份认证的场景,认证通过后再继续执行下面的流程
  • route
    • 在路由请求时被调用。适用于灰度发布场景,在将要路由的时候可以做一些自定义的逻辑。
  • post
    • 在 route 和 error 过滤器之后被调用。这种过滤器将请求路由到达具体的服务之后执行。适用于需要添加响应头,记录响应日志等应用场景。
  • error
    • 处理请求时发生错误时被调用。在执行过程中发送错误时会进入 error 过滤器,可以用来统一记录错误信息

f、网关的过滤器配置

  • 创建一个过滤器类
package com.gec.filter;

import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
@Component
public class ZuulFilter extends com.netflix.zuul.ZuulFilter {
    /*
     * 指明过滤器类型
     * 它是一个PRE过滤器
     * */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }
    /*
     * 同一个过滤器类型的执行顺序(例如可能会有两个前置过滤器)
     * */
    @Override
    public int filterOrder() {
        return 1;
    }
    /*
     * 是否作拦截处理
     * */
    @Override
    public boolean shouldFilter() {
        return true;
    }
    /*
     * 编写过滤器的业务逻辑处理
     * */
    @Override
    public Object run() throws ZuulException {
        RequestContext context= RequestContext.getCurrentContext();
        //获取http的request对象
        HttpServletRequest request=context.getRequest();
        //获取请求参数:token
        String token=request.getParameter("token");

        System.out.println("zuul filter token="+token);

        //token如果有数据,并且等于1234,则允许访问,否则拦截处理
        if(token!=null && token.equals("1234"))
        {
            return null;
        }else {

            //如何实现拦截处理
            RequestContext ctx = RequestContext.getCurrentContext();
            //设置为false:不再转发请求到目标服务
            ctx.setSendZuulResponse(false);
            ctx.set("sendForwardFilter.ran", true);
            ctx.setResponseBody("token error");
            return null;
        }
    }
}
  • 重启服务,并测试
    在这里插入图片描述
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值