Spring Cloud +Gateway + Nginx +Docker 实现高可用网关集群

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、项目搭建
    • 1、parent
    • 2、Eureka
      • 2.1 pom.xml
      • 2.2 SecurityConfig
      • 2.3 启动类
      • 2.4 application.yml
      • 2.5 application-docker.yml
    • 3、Provider
      • 3.1 目录结构
      • 3.2 pom.xml
      • 3.3 application.yml
      • 3.4 application-docker.yml
    • 4、Consumer
      • 4.1 pom.xml
      • 4.2 启动类
      • 4.3 application.yml
      • 4.4 application-docker.yml
    • 5、Gateway
      • 5.1 pom.xml
      • 5.2 application.yml
      • 5.3 application-docker.yml
  • 二、项目部署
    • 1、项目结构
    • 2、配置文件
      • 2.1 nginx.conf
      • 2.2 dockerFile
      • 2.3 docker-compose.yml
    • 3、docker 部署
      • 3.1 Maven 打包
      • 3.2 docker部署


前言

本文主要介绍实现在 docker 中部署 高可用的网关集群微服务,涉及到的技术栈如下:
 SpringCloud、Eureka、Gateway、Nginx 、Docker 

代码地址: Spring-Cloud-Demo

一、项目搭建

Spring Cloud 中的业务不做展示,这里只展示相关的配置

1、parent

该目录下只有一个 pom.xml 文件,作为所有微服务的 父级pom,便于项目依赖的版本控制,以及不同环境的打包配置等


<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.6.8version>
        <relativePath/> 
    parent>
    <groupId>com.studygroupId>
    <artifactId>parentartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <packaging>pompackaging>

    
    <properties>
        <java.version>11java.version>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <spring-cloud.version>2021.0.3spring-cloud.version>
        <packaging.type>jarpackaging.type>
        <lombok.version>1.18.24lombok.version>
        <feign-httpClienr.version>10.7.4feign-httpClienr.version>
        <ribbon.version>2.7.18ribbon.version>
    properties>
    
    <repositories>
        <repository>
            <id>centralid>
            <name>Nexus aliyunname>
            <url>https://maven.aliyun.com/repository/publicurl>
        repository>
    repositories>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <version>${lombok.version}version>
                <optional>trueoptional>
            dependency>

            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            
            <dependency>
                <groupId>io.github.openfeigngroupId>
                <artifactId>feign-httpclientartifactId>
                <version>${feign-httpClienr.version}version>
            dependency>
            
            <dependency>
                <groupId>com.netflix.ribbongroupId>
                <artifactId>ribbon-loadbalancerartifactId>
                <version>${ribbon.version}version>
            dependency>
        dependencies>
    dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombokgroupId>
                            <artifactId>lombokartifactId>
                        exclude>
                    excludes>
                configuration>
            plugin>
        plugins>
    build>

    
    <profiles>
        <profile>
            <id>dockerid>
            <properties>
                
                <activated.profile>dockeractivated.profile>
                
                <redis.host>cloud-redisredis.host>
                <redis.port>6379redis.port>
            properties>
            <build>
                <resources>
                    <resource>
                        <filtering>truefiltering>
                        <directory>src/main/resourcesdirectory>
                    resource>
                resources>
            build>
        profile>
        <profile>
            <id>devid>
            <properties>
                <activated.profile>devactivated.profile>
                
                <redis.host>localhostredis.host>
                <redis.port>6379redis.port>
            properties>
            <build>
                <resources>
                    <resource>
                        <filtering>truefiltering>
                        <directory>src/main/resourcesdirectory>
                        <excludes>
                            <exclude>application-docker.*exclude>
                        excludes>
                    resource>
                resources>
            build>
        profile>
    profiles>
project>

2、Eureka

这里 Eureka 注册中心服务启用两个作为示例,相互注册,并进行数据同步,启用 security 安全验证
注意:
两个 Eureka 相互注册,yml 配置文件中,服务端口号不可重复,注册地址为对方地址,应用名称保持一直

2.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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <parent>
        <groupId>com.studygroupId>
        <artifactId>parentartifactId>
        <version>0.0.1-SNAPSHOTversion>
        <relativePath>../parentrelativePath> 
    parent>

    <artifactId>eureka01artifactId>
    <packaging>${packaging.type}packaging>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-securityartifactId>
        dependency>

        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
        dependency>

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintagegroupId>
                    <artifactId>junit-vintage-engineartifactId>
                exclusion>
            exclusions>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>
project>

2.2 SecurityConfig

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * Date: 2022-06-16 星期四
 * Time: 17:11
 * Author: Dily_Su
 * Remark: 两种方式任选其一
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // 方式一: 弹窗登录
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http // 直接disable 会把安全验证也禁用,
//                .csrf().disable().authorizeRequests()
//                .anyRequest()
//                .authenticated()
//                .and()
//                .httpBasic();
//    }

    // 方式二:页内登录
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http); // 访问eureka 的控制台和/actuator 是可以做安全控制
        http.csrf().ignoringAntMatchers("/eureka/**"); //忽略eureka/**的所有请求
    }
}

2.3 启动类

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

@EnableEurekaServer  // 启用注册中心服务
@SpringBootApplication
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }

}

2.4 application.yml

该文件用可用于本地 Dev 环境,Docker 环境时使用 application-docker.yml

spring:
  application:
    name: eureka                 # 应用名称
  profiles:
    active:
      - "@activated.profile@" # 从 maven parent 的配置中 获取值 # 从 maven parent 的配置中 获取值
  # 安全认证
  security:
    user:
      name: root       # 用户名
      password: 123456 # 密码

server:
  port: 8761                     # 端口
# port: 8762                     # 第二个 Eureka 的端口号

# 注册中心
eureka:
  instance:
    hostname: eureka          # 主机名
    prefer-ip-address: true   # 使用 IP 地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port}

  client:
    register-with-eureka: true  # 是否将自己注册到注册中心,默认 true ,集群时要为 true,相互注册
    fetch-registry: false        # 是否从注册中线获取注册信息,默认为 true
    service-url:                 # 注册中心对外暴露的注册地址
      defaultZone: http://root:123456@localhost:8762/eureka/
    # defaultZone: http://root:123456@localhost:8761/eureka/	# 第二个 Eureka 的注册地址

#  server:
#    enable-self-preservation: false # true 开启自我保护, false 关闭自我保护
#    eviction-interval-timer-in-ms: 60000 # 清除隔离(单位:毫秒) 默认 60 * 1000

# 度量指标监控与健康检查
management:
  endpoints:
    web:
      exposure:
        include: shutdown   # 开启 shutdown 端点访问
  endpoint:
    shutdown:
      enabled: true # 开启 shutdown 实现优雅停服

2.5 application-docker.yml

该配置只用于 docker 环境,用于覆盖 application.yml 中的配置

# 注册中心
eureka:
  client:
    register-with-eureka: true  # 是否将自己注册到注册中心,默认 true ,集群时要为 true,相互注册
    fetch-registry: false        # 是否从注册中线获取注册信息,默认为 true
    service-url:                 # 注册中心对外暴露的注册地址,这里的 erueka-02 是 docker 中微服务容器名
      defaultZone: http://root:123456@eureka-02:8762/eureka/
    # defaultZone: http://root:123456@eureka-02:8762/eureka/	# 第二个 Eureka 的注册地址				

3、Provider

这里创建两个 Provider 服务,用于提供服务
注意:
两个 Provider 服务,端口号不能重复,应用名称必须一直,用于网关做负载均衡

3.1 目录结构

Spring Cloud +Gateway + Nginx +Docker 实现高可用网关集群_第1张图片

3.2 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <parent>
        <groupId>com.studygroupId>
        <artifactId>parentartifactId>
        <version>0.0.1-SNAPSHOTversion>
        <relativePath>../parentrelativePath> 
    parent>

    <artifactId>provider-eureka-01artifactId>
    <packaging>${packaging.type}packaging>

    <properties>
        <java.version>11java.version>
    properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

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

project>

3.3 application.yml

spring:
  application:
    name: provider                # 应用名称
  profiles:
    active:
      - "@activated.profile@" # 从 maven parent 的配置中 获取值
  # 安全认证
  security:
    user:
      name: root       # 用户名
      password: 123456 # 密码

server:
  port: 7070                  # 端口

# 注册中心
eureka:
  instance:
    hostname: provider          # 主机名
    prefer-ip-address: true   # 使用 IP 地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port}

  client:
    register-with-eureka: true  # 是否将自己注册到注册中心,默认 true ,集群时要为 true,相互注册
    fetch-registry: true        # 是否从注册中线获取注册信息,默认为 true
    service-url:                 # 注册中心对外暴露的注册地址, 向两个注册中心注册
      defaultZone: http://root:123456@localhost:8762/eureka/,http://root:123456@localhost:8761/eureka/

#  server:
#    enable-self-preservation: false # true 开启自我保护, false 关闭自我保护
#    eviction-interval-timer-in-ms: 60000 # 清除隔离(单位:毫秒) 默认 60 * 1000

# 度量指标监控与健康检查
management:
  endpoints:
    web:
      exposure:
        include: shutdown   # 开启 shutdown 端点访问
  endpoint:
    shutdown:
      enabled: true # 开启 shutdown 实现优雅停服

3.4 application-docker.yml

# 注册中心
eureka:
  client:
    register-with-eureka: true  # 是否将自己注册到注册中心,默认 true ,集群时要为 true,相互注册
    fetch-registry: true        # 是否从注册中线获取注册信息,默认为 true
    service-url:                 # 注册中心对外暴露的注册地址, 地址为 docker 中 eureka 微服务容器名
      defaultZone: http://root:123456@eureka-02:8762/eureka/,http://root:123456@eureka-01:8761/eureka/

4、Consumer

这里使用OpenFeign 进行服务内调用

4.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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <parent>
        <groupId>com.studygroupId>
        <artifactId>parentartifactId>
        <version>0.0.1-SNAPSHOTversion>
        <relativePath>../parentrelativePath> 
    parent>

    <artifactId>consumer-eureka-feignartifactId>
    <packaging>${packaging.type}packaging>

    <properties>
        <java.version>11java.version>
    properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        
        <dependency>
            <groupId>com.netflix.ribbongroupId>
            <artifactId>ribbon-loadbalancerartifactId>
            <scope>compilescope>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-openfeignartifactId>
        dependency>
        
        <dependency>
            <groupId>io.github.openfeigngroupId>
            <artifactId>feign-httpclientartifactId>
        dependency>
    dependencies>

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

project>

4.2 启动类

import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

//@EnableEurekaClient //如果配置了注册中心,则会默认开启,无需使用该注解
@SpringBootApplication
public class ConsumerApplication {

    @Bean
    @LoadBalanced  // 这个开启后,默认使用 轮询策略,用于服务内部调用
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    // 全局负载均衡采用 随机策略
//    @Bean
//    public RandomRule randomRule() {
//        return new RandomRule();
//    }


    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

}

4.3 application.yml

spring:
  application:
    name: consumer                 # 应用名称
  profiles:
    active:
      - "@activated.profile@" # 从 maven parent 的配置中 获取值
  # 安全认证
  security:
    user:
      name: root       # 用户名
      password: 123456 # 密码

# 注册中心
eureka:
  instance:
    hostname: consumer          # 主机名
    prefer-ip-address: true   # 使用 IP 地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port}

  client:
    register-with-eureka: true  # 是否将自己注册到注册中心,默认 true ,集群时要为 true,相互注册
    fetch-registry: true        # 是否从注册中线获取注册信息,默认为 true
    service-url: # 注册中心对外暴露的注册地址
      defaultZone: http://root:123456@localhost:8762/eureka/,http://root:123456@localhost:8761/eureka/
  #
  server:
    enable-self-preservation: false # true 开启自我保护, false 关闭自我保护
    eviction-interval-timer-in-ms: 60000 # 清除隔离(单位:毫秒) 默认 60 * 1000

# 度量指标监控与健康检查
management:
  endpoints:
    web:
      exposure:
        include: shutdown   # 开启 shutdown 端点访问
  endpoint:
    shutdown:
      enabled: true # 开启 shutdown 实现优雅停服

server:
  port: 6061                  # 端口
  # 全局开启压缩
  compression:
    enabled: true
    # 配置压缩支持的 MIME TYPE
    mime-types: application/json,application/xml,text/html,text/xml,text/plain

# 局部 通过 Feign 到 Provider 的请求 进行 Gzip 压缩
feign:
  compression:
    request:
      min-request-size: 512  # 配置压缩数据大小的最小阈值,默认 2048
      mime-types: text/xml,application/xml,application/json  # 配置压缩文件支持的 MIME TYPE
      enabled: true                # 请求是否开启 Gzip 压缩
    response:
      enabled: true                # 响应是否开启 Gzip 压缩
  httpclient:
    enabled: true    # 开始 httpClient
  #  服务内部调用
  client:
    config:
      # 全局 配置请求超时时间
      default:
        connectTimeout: 1000  # 请求连接超时时间 默认为 1s
        readTimeout: 1000     # 请求处理的超时时间
      # 局部 配置 请求请求超时
#      provider: # 服务名
#        OkToRetryOnAllOperations: true   # 对所有请求都进行重试
#        MaxAutoRetries: 2                # 对当前实例的重复次数
#        MaxAutoRetriesNextServer: 0      # 切换实例的重复次数
#        ConnectTimeOut: 3000             # 请求连接超时时间 默认为 1s
#        ReadTimeOut: 3000                # 请求处理的超时时间

4.4 application-docker.yml

# 注册中心
eureka:
  client:
    register-with-eureka: true  # 是否将自己注册到注册中心,默认 true ,集群时要为 true,相互注册
    fetch-registry: true        # 是否从注册中线获取注册信息,默认为 true
    service-url: # 注册中心对外暴露的注册地址
      defaultZone: http://root:123456@eureka-02:8762/eureka/,http://root:123456@eureka-01:8761/eureka/

5、Gateway

使用 令牌桶的模式进行网关流量限制,该策略使用redis,spring 官网使用 spring-boot-starter-data-redis-reactive 作为 redis 连接依赖,不可更改
这里使用两个网关微服务做网关集群模拟,两个微服务端口不可重复,应用名相同

5.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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <parent>
        <groupId>com.studygroupId>
        <artifactId>parentartifactId>
        <version>0.0.1-SNAPSHOTversion>
        <relativePath>../parentrelativePath> 
    parent>

    <artifactId>gateway01artifactId>
    <packaging>${packaging.type}packaging>

    <dependencies>
    	
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-gatewayartifactId>
            <version>3.1.3version>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-redis-reactiveartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

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

project>

5.2 application.yml

server:
  port: 9000  
# port: 9001 # 第二个网关服务端口
# 注册中心
eureka:
  instance:
    hostname: gateway          # 主机名
    prefer-ip-address: true   # 使用 IP 地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port}

  client:
    register-with-eureka: true  # 是否将自己注册到注册中心,默认 true ,集群时要为 true,相互注册
    fetch-registry: true        # 是否从注册中线获取注册信息,默认为 true
    service-url:                 # 注册中心对外暴露的注册地址
      defaultZone: http://root:123456@localhost:8762/eureka/,http://root:123456@localhost:8761/eureka/

spring:
  application:
    name: gateway # 应用名称
  profiles:
    active:
      - "@activated.profile@" # 从 maven parent 的配置中 获取值
  cloud:
      # 路由规则
    gateway:
      discovery:
        locator:
          # 是否与服务发现组件进行结合,通过 serviceId 转发到具体服务
          enabled: true                      # 是否开启基于服务发现的路由规则
          lower-case-service-id: true        # 是否将服务名称转小写
#      default-filters:
#        - PrefixPath=/product
      routes:
        - id: provider                                            # 路由 ID,唯一
          uri: lb://provider                                      # 根据注册中心动态路由
#          uri: http://localhost:7070/                            # 目标 URI,路由到微服务的地址
          predicates:                                             # 断言(判断条件)
            # Path
            - Path=/product/**                                           # 匹配对应的 URL 请求,并追加到 URI 后
            # Query
#            - Query=name                                         # 匹配请求参数中包含 name 的请求
#            - Query=name,abc.+                                   # 匹配请求参数中包含 name 且满足正则表达式 abc. 的请求
            # Method
#            - Method=GET                                         # 匹配 GET 请求
            # Datetime
#            - After=2022-06-27T16:00:00.000+08:00[Asia/Shanghai] # 匹配中国上海 2022-06-27 16:00:00 后的请求
            # RemoteAddr
#            - RemoteAddr=172.16.10.82/0                          # 匹配请求中地址是 172.16.10.82 的请求,/0为子网掩码
            # Header
#            - Header=X-Request-Id, \d+                            # 匹配请求头中包含 X-Request-Id 并且其值匹配正则表达式 \d+ 的请求

          # Filters
          filters:
            # 将 /gateway/product/list 重写为 /product/list
#            - RewritePath=/gateway(?/?.*),$\{segment}
            # 请求增加前缀
#            - PrefixPath=/product
            # 分割前缀 /api/gateway/product/list
#            - StripPrefix=2
            # 将 /gateway/product/list 重写为 /product/list
#            - SetPath=/product/{segment}
            # 在下游请求中增加 参数 id = 1
#            - AddRequestParameter=id,1
            # 在任何情况下,响应状态码设置为888
#            - SetStatus=888
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 1  # 令牌每秒填充数量
                redis-rate-limiter.burstCapacity: 2  # 令牌桶总容量
                key-resolver: "#{@ipKeyResolver}"  # 使用 SpEL 表达式按名称引用 bean

  redis:
    host: localhost
    port: 6379
    database: 1

5.3 application-docker.yml

# 注册中心
eureka:
  client:
    register-with-eureka: true  # 是否将自己注册到注册中心,默认 true ,集群时要为 true,相互注册
    fetch-registry: true        # 是否从注册中线获取注册信息,默认为 true
    service-url:                 # 注册中心对外暴露的注册地址
      defaultZone: http://root:123456@eureka-02:8762/eureka/,http://root:123456@eureka-01:8761/eureka/
spring:
  redis:
    #    从 maven parent 中 获取属性值
    host: '@redis.host@'
    port: '@redis.port@'
    database: 1

二、项目部署

1、项目结构

Spring Cloud +Gateway + Nginx +Docker 实现高可用网关集群_第2张图片

2、配置文件

2.1 nginx.conf

# nginx 配置文件:负载均衡默认为轮询
worker_processes 1;

events { worker_connections 1024; }

http {
    include    /etc/nginx/mime.types;
    sendfile   on;

    proxy_buffer_size   128k;
    proxy_buffers   4 256k;
    proxy_busy_buffers_size   256k;

    client_max_body_size   100m;

    # 网关集群
    upstream gateway {
        # docker 中 localhost 为 镜像容器名
        server gateway-01:9000;
        server gateway-02:9001;
    }

    server {
        listen 8080;

        location / {
            # 将所有请求指向 网关集群
            proxy_pass http://gateway;
        }
    }
}

2.2 dockerFile

# 每个微服务根目录下都要放置一个,用于将打包好的 jar 整理为 docker image
# jdk 版本不能低于自己编译时的版本,否则 docker 启动会报错
FROM openjdk:11.0.15-jre
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
WORKDIR /
ENTRYPOINT ["java","-jar","/app.jar"]

2.3 docker-compose.yml

version: "3.7"
services:
  redis:
    image: redis:latest  # 从 docker hub 中 pull 最新的 redis image
    container_name: cloud-redis # docker 中的容器名称
    ports:               # 对外映射的端口,占用容器内的 6379,本机的26379,不想对外暴漏时,可以省略
      - "26379:6379"
    networks:            # 容器内网关,用于容器内镜像互相调用
      - backend
    environment:         # 设置时区
      - TZ=Asia/Shanghai

  erurka-01:
    build: ./eureka01    # build 存在时,表示从该目录下获取镜像名称
    image: cloud/eureka01:latest # 镜像名称
    container_name: eureka-01 # 容器名称
    ports:
      - "28761:8761"
    networks:
      - backend
    environment:
      - TZ=Asia/Shanghai

  erurka-02:
    build: ./eureka02
    image: cloud/eureka02:latest
    container_name: eureka-02
    ports:
      - "28762:8762"
    networks:
      - backend
    environment:
      - TZ=Asia/Shanghai

  gateway-01:
    build: ./gateway01
    image: cloud/gateway01:latest
    container_name: gateway-01
    networks:
      - backend
    environment:
      - TZ=Asia/Shanghai

  gateway-02:
    build: ./gateway02
    image: cloud/gateway02:latest
    container_name: gateway-02
    networks:
      - backend
    environment:
      - TZ=Asia/Shanghai

  provider-01:
    build: ./provider01
    image: cloud/provider01:latest
    container_name: provider-01
    networks:
      - backend
    environment:
      - TZ=Asia/Shanghai

  provider-02:
    build: ./provider02
    image: cloud/provider02:latest
    container_name: provider-02
    networks:
      - backend
    environment:
      - TZ=Asia/Shanghai

  consumer-eureka:
    build: ./consumer-eureka
    image: cloud/consumer-eureka:latest
    container_name: consumer-eureka
    networks:
      - backend
    environment:
      - TZ=Asia/Shanghai

  consumer-eureka-feign:
    build: ./consumer-eureka-feign
    image: cloud/consumer-eureka-feign:latest
    container_name: consumer-eureka-feign
    networks:
      - backend
    environment:
      - TZ=Asia/Shanghai

  nginx:
    image: nginx
    container_name: cloud-demo-nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 28080:8080
    restart: unless-stopped
    networks:
      - backend

networks: # 该微服务项目在容器中的网关
  backend: 
    name: cloud-demo 

3、docker 部署

3.1 Maven 打包

# 清理 targer 文件,并按照 按照 docker 配置 打包
 mvn clean package -P docker -DskipTests

ker -DskipTests

3.2 docker部署

# build image 并 生成容器,启动 image
docker compose up -d 		

你可能感兴趣的:(#,Spring,Cloud,#,Nginx,#,docker,spring,cloud,gateway,nginx)