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

5 篇文章 0 订阅
2 篇文章 0 订阅

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


前言

本文主要介绍实现在 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 		
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值