nginx部署前端工程替代方案gateway

有市场要求部署的前端vue工程不使用nginx中间件。想弄国产替代的东方通之类的,公司没有购买该产品,我参考了网上的一些java网关框架,springcloud组件:gateway实现代替。

  • 注意后台都是用java编写的,因此也使用java实现前端静态文件的部署。
  • 至于市场为什么要替换nginx?客户可能有他们的考量,比如预计5万亿元的设备更新款。我们提供解决方案即可。

依赖

创建一个Maven项目 frontend-gateway

<?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.18.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>top.lingkang</groupId>
    <artifactId>frontend-gateway</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!--Spring Cloud Gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>2.1.5.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>central</id>
            <name>huaweicloud</name>
            <url>https://mirrors.huaweicloud.com/repository/maven/</url>
            <layout>default</layout>
            <!-- 是否开启发布版构件下载 -->
            <releases>
                <enabled>true</enabled>
            </releases>
            <!-- 是否开启快照版构件下载 -->
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

为什么使用springboot低版本?
公司产品是基于jdk8、springboot2.1.x的

编写配置 application.yml

server:
  port: 8080


# 配置 dist,其中 C:\Users\Administrator\Desktop\temp\dist\index.xml 索引文件
dist:
  path: C:\Users\Administrator\Desktop\temp\dist

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "*"
            allowedMethods:
              - GET
              - POST
              - PUT
              - DELETE
      routes:
        - id: auth
          uri: http://127.0.0.1:8070
          # 转发重写 /auth-center/** → /**
          filters:
            - RewritePath=/auth-center/(?<segment>.*), /$\{segment}
          predicates:
            # 匹配路径转发
            - Path=/auth-center/**
        - id: pro
          uri: http://10.8.6.125:8080/pro-5.0
          # 转发重写 /pro/** → /pro-5.0/**
          filters:
            - RewritePath=/pro/(?<segment>.*), /pro-5.0/$\{segment}
          predicates:
            # 匹配路径转发
            - Path=/pro/**



配置

启动类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author lingkang
 * @create by 2024/3/7 16:25
 */
@SpringBootApplication
public class FrontendGatewayApplication implements ApplicationRunner {
    private static final Logger log = LoggerFactory.getLogger(FrontendGatewayApplication.class);

    @Value("${server.port:8080}")
    private String port;

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

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("启动完成, access to http://localhost:{}", port);
    }
}

配置类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.config.ResourceHandlerRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;

import java.io.File;

/**
 * @author lingkang
 * @create by 2024/3/7 16:29
 */
@Configuration
public class AppConfig implements WebFluxConfigurer {
    private static final Logger log = LoggerFactory.getLogger(AppConfig.class);
    @Value("${dist.path}")
    private String path;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if (StringUtils.isEmpty(path))
            throw new RuntimeException("dist目录路径配置不能为空: dist.path, 请在application.yml中配置");
        if (!path.endsWith("/") && !path.endsWith("\\\\")) {
            path += File.separator;
        }
        log.info("dist目录路径: {}", path);
        registry.addResourceHandler("/**").addResourceLocations("file:" + path);
    }
}

重定向类

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.reactive.result.view.Rendering;

/**
 * @author lingkang
 * @create by 2024/3/7 16:30
 */
@Controller
public class WebController {
    @GetMapping("/")
    public Rendering index() {
        return Rendering.redirectTo("/index.html").build();
    }
}

启动访问

http://localhost:8080

image-1709803619285

登录后能正常访问产品

image-1709803734028

生产部署

frontend-gateway-1.0.0.jarapplication.yml 配置文件放于同一目录

Window下执行启动命令:

java -jar -Dspring.config.location=application.yml frontend-gateway-1.0.0.jar

Linux下执行:

nohup java -jar -Dspring.config.location=application.yml frontend-gateway-1.0.0.jar > nohup.out 2>&1 &