一、简介
网关是系统唯一对外的入口,介于客户端与服务器端之间,用于对请求进行鉴权、限流、路由、监控等功能。
二、官网
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