微服务网关Zuul

一、简介

网关是系统唯一对外的入口,介于客户端与服务器端之间,用于对请求进行鉴权、限流、路由、监控等功能。

二、官网

https://github.com/Netflix/zuul/wiki

【原文】Zuul is the front door for all requests from devices and web sites(设备和web站点) to the backend of the Netflix streaming application(Netflix流应用后端). As an edge service application(边界服务应用), Zuul is built to enable dynamic routing, monitoring, resiliency and security. It also has the ability to route requests to multiple Amazon Auto Scaling Groups(亚马逊自动缩放组,亚马逊的一种云计算方式)as appropriate(视情况而定, 酌情).


【翻译】ZUUL是从设备和web站点到Netflix流应用后端的所有请求的前门。作为边界服务应用,ZUUL是为了实现动态路由、监视、弹性和安全性而构建的。它还具有根据情况将请求路由到多个Amazon Auto Scaling Groups(亚马逊自动缩放组,亚马逊的一种云计算方式)的能力

 

抽象可以这样理解

 

三、基本环境搭建

  • 一个EurekaServer
  • 一个zuul网关
  • 两个消费者

四、创建项目05-zuul-consumer--8080

(1)创建工程

(2)依赖

<?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.abc</groupId>
    <artifactId>05-zuul-consumer-8080</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

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

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <!--hystrix依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <!--feign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <!--actuator依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--eureka客户端依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>


    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

(3)application.yml配置

spring:
  application:  # 指定微服务对外暴露的名称
      name: abcmsc-consumer-depart-8080

eureka:
  client:
    service-url: # 指定Eureka服务注册中心
      defaultZone: http://localhost:8000/eureka

(4)实体类

package com.abc.consumer.bean;

import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class Depart {
    private Integer id;
    private String name;

    public Depart(String name) {
        this.name = name;
    }
}

(5)接口类

package com.abc.consumer.service;


import com.abc.consumer.bean.Depart;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Service
// 指定当前Service所绑定的提供者微服务名称
@FeignClient("abcmsc-provider-depart")
@RequestMapping("/provider/depart")
public interface DepartService {

    @GetMapping("/get/{id}")
    Depart getDepartById(@PathVariable("id") int id);

    @GetMapping("/list")
    List<Depart> listAllDeparts();
}

(6)RestTemplate类

package com.abc.consumer.codeconfig;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class DepartCodeConfig {

    @LoadBalanced    // 开启消息者端的负载均衡功能,默认是轮询策略
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

(7)Controller类

package com.abc.consumer.controller;

import com.abc.consumer.bean.Depart;
import com.abc.consumer.service.DepartService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/consumer/depart")
public class DepartController {
    @Autowired
    private DepartService service;

    @HystrixCommand(fallbackMethod = "getHystrixHandle")
    @GetMapping("/get/{id}")
    public Depart getHandle(@PathVariable("id") int id, HttpServletRequest request) {
        return service.getDepartById(id);
    }

    public Depart getHystrixHandle(@PathVariable("id") int id, HttpServletRequest request) {
        //自定义
        System.out.println("token = " + request.getHeader("token"));
        //默认屏蔽
        System.out.println("Set-Cookie = " + request.getHeader("Set-Cookie"));
        System.out.println("Authorization = " + request.getHeader("Authorization"));

        Depart depart = new Depart();
        depart.setId(id);
        depart.setName("no this depart-8080");
        return depart;
    }

    @HystrixCommand(fallbackMethod = "listHandleHystrix")
    @GetMapping("/list")
    public List<Depart> listHandle() {
        return service.listAllDeparts();
    }

    public List<Depart> listHandleHystrix() {
        ArrayList<Depart> departs = new ArrayList<>();
        departs.add(new Depart("no this depart-8080"));
        return departs;
    }

}

五、创建项目05-zuul-consumer-8090

(1)创建项目

复制项目05-zuul-consumer--8080,命名05-zuul-consumer-8090

(2)修改配置

只需修改项目端口,其它不需要修改

server:
  port: 8090

spring:
  application:  # 指定微服务对外暴露的名称
    name: abcmsc-consumer-depart-8090

eureka:
  client:
    service-url: # 指定Eureka服务注册中心
      defaultZone: http://localhost:8000/eureka

#feign:
#  client:
#    config:
#      default:
#        connectTimeout: 5000  # 指定Feign连接提供者的超时时限
#        readTimeout: 5000    # 指定Feign从请求到获取提供者响应的超时时限

(3)Controller类

package com.abc.consumer.controller;

import com.abc.consumer.bean.Depart;
import com.abc.consumer.service.DepartService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/consumer/depart")
public class DepartController {
    @Autowired
    private DepartService service;

    @HystrixCommand(fallbackMethod = "getHystrixHandle")
    @GetMapping("/get/{id}")
    public Depart getHandle(@PathVariable("id") int id) {
        return service.getDepartById(id);
    }

    public Depart getHystrixHandle(@PathVariable("id") int id) {
        Depart depart = new Depart();
        depart.setId(id);
        depart.setName("no this depart-8090");
        return depart;
    }

    @HystrixCommand(fallbackMethod = "listHandleHystrix")
    @GetMapping("/list")
    public List<Depart> listHandle() {
        return service.listAllDeparts();
    }

    public List<Depart> listHandleHystrix() {
        ArrayList<Depart> departs = new ArrayList<>();
        departs.add(new Depart("no this depart-8090"));
        return departs;
    }

}

六、创建网关zuul项目

(1)创建00-zuul-9000项目

(2)依赖

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.abc</groupId>
    <artifactId>00-zuul-9000</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>00-zuul-9000</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--zuul依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>

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

        <!--hystrix依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

    </dependencies>




    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

(3)application.yml配置

server:
  port: 9000

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8000/eureka

spring:
  application:
    name: abcmsc-zuul-depart



ribbon:        #设置ribbon的超时时间小于zuul的超时时间
  ReadTimeout: 10000
  ConnectTimeout: 10000

zuul:
  host:
    connect-timeout-millis: 10000
    socket-timeout-millis: 60000
    #指定统一的前辍
  #prefix: /abc
  routes:
    # 指定路由规则
    abcmsc-consumer-depart-8080: /abc8080/**
    abcmsc-consumer-depart-8090: /abc8090/**
    #abcmsc-consumer-depart: /abc012/**
    # /**:匹配任意多级路径   /abc8080/aaa/bbb/ccc
    # /* :仅匹配一级路径      /abc8080/aaa
    # /? :匹配仅包含一个字符的一级路径  /abc8080/a

  # 屏蔽指定微服务
  #ignored-services: abcmsc-consumer-depart-8090
  # 屏蔽所有微服务
  #ignored-services: "*"

  # 屏蔽指定URI
  # ignored-patterns: /**/list/**

  # 指定要屏蔽的敏感头信息
  #sensitive-headers: ["token","Set-Cookie"]


七、创建eureka项目

(1)创建00-eurekaserver-8000

(2)依赖

<?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.abc</groupId>
    <artifactId>00-eurekaserver-8000</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

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

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

(3)application.yml配置

server:
  port: 8000

eureka:
  instance:
    hostname: localhost  # 指定Eureka主机
  client:
    register-with-eureka: false   # 指定当前主机是否向Eureka服务器进行注册
    fetch-registry: false    # 指定当前主机是否要从Eurka服务器下载服务注册列表
    service-url:   # 服务暴露地址
     defaultZone: http://localhost:8000/eureka
#     defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka

#  server:
#    enable-self-preservation: false    # 关闭自我保护

八、测试

(1) 启动eureka

(2)启动网关

(3) 启动消费者05-zuul-consumer-8080

(4) 启动消费者05-zuul-consumer-8090

(4) 效果

因为网关配置

所以分别请求

http://localhost:9000/abc8080/consumer/depart/get/1

 

http://localhost:9000/abc8090/consumer/depart/get/1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2014Team

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值