Spring Cloud +Gateway + Nginx +Docker 实现高可用网关集群_docker nginx gateway-程序员宅基地

技术标签: # docker  nginx  spring cloud  # Nginx  # Spring Cloud  gateway  

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


前言

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

代码地址: Spring-Cloud-Demo

一、项目搭建

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

1、parent

该目录下只有一个 pom.xml 文件,作为所有微服务的 父级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 https://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.6.8</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.study</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <!--    版本控制-->
    <properties>
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-cloud.version>2021.0.3</spring-cloud.version>
        <packaging.type>jar</packaging.type>
        <lombok.version>1.18.24</lombok.version>
        <feign-httpClienr.version>10.7.4</feign-httpClienr.version>
        <ribbon.version>2.7.18</ribbon.version>
    </properties>
    <!--maven 仓库-->
    <repositories>
        <repository>
            <id>central</id>
            <name>Nexus aliyun</name>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>
    </repositories>
    <!--版本统一控制-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--        Feign 使用 httpClient -->
            <dependency>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-httpclient</artifactId>
                <version>${feign-httpClienr.version}</version>
            </dependency>
            <!--        ribbon 点对点直连 和 局部负载均衡 不可用-->
            <dependency>
                <groupId>com.netflix.ribbon</groupId>
                <artifactId>ribbon-loadbalancer</artifactId>
                <version>${ribbon.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <!--    打包时按不同环境进行打包-->
    <profiles>
        <profile>
            <id>docker</id>
            <properties>
                <!--                用于配置文件 属性的统一管理-->
                <activated.profile>docker</activated.profile>
                <!-- redis连接 -->
                <redis.host>cloud-redis</redis.host>
                <redis.port>6379</redis.port>
            </properties>
            <build>
                <resources>
                    <resource>
                        <filtering>true</filtering>
                        <directory>src/main/resources</directory>
                    </resource>
                </resources>
            </build>
        </profile>
        <profile>
            <id>dev</id>
            <properties>
                <activated.profile>dev</activated.profile>
                <!-- redis连接 -->
                <redis.host>localhost</redis.host>
                <redis.port>6379</redis.port>
            </properties>
            <build>
                <resources>
                    <resource>
                        <filtering>true</filtering>
                        <directory>src/main/resources</directory>
                        <excludes>
                            <exclude>application-docker.*</exclude>
                        </excludes>
                    </resource>
                </resources>
            </build>
        </profile>
    </profiles>
</project>

2、Eureka

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

2.1 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.study</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../parent</relativePath> <!-- lookup parent from repository -->
    </parent>

    <artifactId>eureka01</artifactId>
    <packaging>${packaging.type}</packaging>

    <dependencies>
        <!--        security-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!--        eureka service-->
        <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-actuator</artifactId>
        </dependency>

        <!--        单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </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 目录结构

在这里插入图片描述

3.2 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.study</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../parent</relativePath> <!-- lookup parent from repository -->
    </parent>

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

    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--        eureka client-->
        <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-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </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

<?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.study</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../parent</relativePath> <!-- lookup parent from repository -->
    </parent>

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

    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--        eureka client-->
        <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-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--        负载均衡策略-->
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-loadbalancer</artifactId>
            <scope>compile</scope>
        </dependency>
        <!--        openFeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--        Feign 使用 httpClient -->
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </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

<?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.study</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../parent</relativePath> <!-- lookup parent from repository -->
    </parent>

    <artifactId>gateway01</artifactId>
    <packaging>${packaging.type}</packaging>

    <dependencies>
    	<!--        gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>3.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--        redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </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>/?.*),$\{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、项目结构

请添加图片描述

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 		
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42151956/article/details/125533954

智能推荐

spring rest案例-程序员宅基地

文章浏览阅读180次。spring rest

6个月计算机专硕408备考经验_408备考6个月-程序员宅基地

文章浏览阅读9k次,点赞23次,收藏177次。考研情况一志愿:华东师范大学计算科学与技术学院计算机专硕。初试成绩:总分332,政治:70,英语二:67,数学二:95,408计算机综合:100。初试排名37。复试400分,总分=初试x0.7 +复试x0.3 = 352 ,最终排名43。招生人数:37 + 13 + 2 = 52人,考前统招37,复试前一次扩13人,拟录取后二次扩2人。2019年9月,专业课从839自命题改408全国统考。个人情况本科北京某双非一本大学,信息与计算科学专业(408四门课全都学过,但不是很精通)。班级排名_408备考6个月

转:涉足机器视觉_idiap全称-程序员宅基地

文章浏览阅读1.5k次。作机器视觉和图像处理方面的研究工作,最重要的两个问题:其一是要把握住国际上最前沿的内容;其二是所作工作要具备很高的实用背景。解决第一个问题的办法就是找出这个方向公认最高成就的几个超级专家(看看他们都在作什么)和最权威的出版物(阅读上面最新的文献),解决第二个问题的办法是你最好能够找到一个实际应用的项目,边做边写文章。 做好这几点的途径之一就是利用网络资源,利用权威网站和专家们的个人主页_idiap全称

bcm56150_i2c驱动分析-程序员宅基地

文章浏览阅读95次。本文主要关注bsp中,关于smbus(系统管理总线,是i2c的子集)的配置过程,了解如如何配置i2c寄存器。所有发送的数据都会写在FIFO中,使能之后就发送出去。接收数据就从接收寄存器中读取。读取和发送的数据都保存在iproc_xact_info结构体中。结合smbus数据帧的格式,分析下面代码。struct iproc_xact_info { bool cmd_valid; /* t..._bcm56150手册

2023最新版Nessus10.5+Awvs15.2+Routersploit+Kali_awvs最新版-程序员宅基地

文章浏览阅读148次。从时代发展的角度看,网络安全的知识是学不完的,而且以后要学的会更多,同学们要摆正心态,既然选择入门网络安全,就不能仅仅只是入门程度而已,能力越强机会才越多。因为入门学习阶段知识点比较杂,所以我讲得比较笼统,大家如果有不懂的地方可以找我咨询,我保证知无不言言无不尽,需要相关资料也可以找我要,我的网盘里一大堆资料都在吃灰呢。干货主要有:①1000+CTF历届题库(主流和经典的应该都有了)②CTF技术文档(最全中文版)③项目源码(四五十个有趣且经典的练手项目及源码)_awvs最新版

vue多tab页面全部关闭后自动退出登录_vue 关闭页面 触发退出-程序员宅基地

文章浏览阅读758次,点赞9次,收藏10次。业务场景:主项目是用vue写的单页面应用,但是有多开页面的需求,现在需要在用户关闭了所有的浏览器标签页面后,自动退出登录。思路:因为是不同的tab页面,我只能用localStorage来通信,新打开一个标签页(页面初次装载时),我就往数组中加一个页面,在(页面关闭或刷新等)页面卸载时移除它。这样就只需要在页面装载时(load事件)判断当前是不是刷新页面就可以了,只要是其他来源就直接登出。_vue 关闭页面 触发退出

随便推点

服务器项目前端调用摄像头失败,浏览器调用摄像头失败:NotSupportedError Only secure origins are allowed...-程序员宅基地

文章浏览阅读5.4k次。通过浏览器调用摄像头失败:NotSupportedError Only secure origins are allowed错误报告NotSupportedError Only secure origins are allowed (see: https://goo.gl/Y0ZkNV).[Deprecation] getUserMedia() no longer works on insecur...

vue中v-bind绑定属性后,双引号和花括号的结合用法_vue双花括号拼接字符串-程序员宅基地

文章浏览阅读3.2k次。vue中v-bind绑定属性后,双引号和花括号的结合用法v-bind绑定属性后,如果是对象写法,属性名要加单引号,以示和vue实例变量属性的区别,属性值可以是布尔值或者vue实例的变量属性或者计算属性或者js表达式如果是数组写法,则每个元素可以是单引号字符串的写法,也可以是js表达式,不过不能使用 ‘mardown’ + checked === 0 ? ‘s’ : ‘’ 这种字符串拼接表达式..._vue双花括号拼接字符串

systemui start time out导致的黑屏问题_process dtart timeout-程序员宅基地

文章浏览阅读1.9k次。一. 问题描述1.1 现象 手机黑屏,长按power键能出现关机界面1.2 JIRA xxx1.3 结论 systemui 的service没有重启,导致黑屏。这是一个原生bug,因为systemui启动的方式比较特别,他是通过service来将界面画出来的,如果service没有起来那就会导致黑屏。1.4 修复链接: xxx..._process dtart timeout

python+numpy中矩阵的逆和伪逆的区别_numpy pinv误差-程序员宅基地

文章浏览阅读3.7k次。python+numpy中矩阵的逆和伪逆的区别_numpy pinv误差

计算机网络技术及其应用规范论文,计算机网络技术专业论文写作规范.doc-程序员宅基地

文章浏览阅读136次。计算机网络技术专业论文写作规范计算机网络技术专业论文写作规范毕业设计论文是毕业设计工作的总结和提高,应有一定的实际应用价值,能反映出作者所具有的专业基础知识和分析解决问题的能力。在毕业设计期间,尽可能多的阅读文献资料是很重要的,一方面是为毕业设计做理论准备,另一方面是学习论文的写作方法。一篇优秀的论文对启发我们的思维,掌握论文的写作规范很有帮助。下面仅对工科论文中的几个主要部分的写作规范和写作方法..._计算机网络行业规范论文

基于STM32单片机智能家居无线315M门铃叮咚门铃系统毕业设计DIY89_stm32 315m 编码-程序员宅基地

文章浏览阅读350次,点赞8次,收藏8次。基于STM32单片机无线超再生模块315M门铃叮咚门铃系统设计315M超再生无线收发/DIY开发板套件89。_stm32 315m 编码