部署 Feat Core 应用
Feat Cloud 的部署与交付覆盖了注解式应用的完整交付链路。这一页聚焦 Feat Core:不依赖编译期生成的纯代码式应用,怎么从 main 方法走到生产环境。
用 maven-shade-plugin 打可执行 jar。Core 应用没有 CloudService 服务发现文件需要合并,配置比 Cloud 应用更简单:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.example.Application</mainClass> </transformer> </transformers> </configuration> <executions> <execution> <phase>package</phase> <goals><goal>shade</goal></goals> </execution> </executions></plugin>mvn clean packagejava -jar target/app.jar开发期直接在 IDE 运行 main 方法即可。也可以用 mvn dependency:copy-dependencies 把依赖拷出来,用 java -cp 启动,适合不想打 Fat Jar 的场景:
mvn dependency:copy-dependencies -DoutputDirectory=libjava -cp "target/classes:lib/*" com.example.ApplicationDocker 交付
Section titled “Docker 交付”Feat 应用是普通 Java 进程,容器化没有任何特殊要求:
FROM eclipse-temurin:8-jre-alpine
WORKDIR /appCOPY target/app.jar app.jar
EXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]几个与 Feat 相关的容器实践:
- 监听地址保持默认
0.0.0.0,改成127.0.0.1会容器网络不通 - 端口参数化:端口默认 8080,代码里用
System.getenv("SERVER_PORT")之类的环境变量读取后传给listen(port),即可同一镜像多环境复用 - 日志走 stdout:内置日志输出到控制台,容器运行时自动收集,见日志与可观测性
- 不需要 JRE 之外的基础镜像层:Feat 只依赖 JDK 标准 API 和少量第三方库(如 fastjson2)
基镜像选择 JRE 8 还是更高版本都可以,Feat 主线以 Java 8 编译目标运行,见系统要求。
HttpServer.shutdown() 的执行顺序是固定的,理解它才能写出正确的关闭逻辑:
- 先执行
shutdownHook里注册的清理动作 - 然后关闭监听端口、断开连接
- 最后释放缓冲区池
import tech.smartboot.feat.Feat;import tech.smartboot.feat.core.server.HttpServer;
public class GracefulShutdownDemo { public static void main(String[] args) { HttpServer server = Feat.httpServer(options -> { // 进程收到 SIGTERM(如 docker stop)后,JVM shutdown 钩子触发这里 options.shutdownHook(() -> { System.out.println("flush pending tasks, release resources..."); // 在这里完成:停止接收新任务、刷写缓冲、关闭连接池等 }); }).httpHandler(ctx -> ctx.write("ok"));
server.listen(8080);
Runtime.getRuntime().addShutdownHook(new Thread(server::shutdown)); }}使用要点:
- 业务清理放
shutdownHook,不要放 JVM 钩子里重复写;shutdownHook在连接关闭前执行,还能访问正在处理的请求上下文 - 容器场景下记得把 JVM 钩子挂上
server::shutdown,docker stop默认给 10 秒宽限期 shutdown()可重入,多次调用安全(内部会防止重复关闭)
生产检查清单
Section titled “生产检查清单”- 监听地址
0.0.0.0,端口未与其他服务冲突 -
debug(true)已关闭,feat.log.level按环境设置 -
maxRequestSize、headerLimiter、setIdleTimeout按业务压过默认值(见安全实践) - 优雅关闭链路验证过:
docker stop后日志里能看到 hook 执行 - 健康检查接口就位(最简实现:一个返回 200 的路由)
- 配置通过环境变量或启动参数注入,镜像内不含环境敏感信息