当前位置: 首页 > news >正文

Java项目公网部署实战:从家庭内网到生产环境的四条路径

1. 公网部署不是“发个jar包就完事”:先搞清你真正要解决的问题

很多人搜“java项目部署到公网教程”,点开就急着复制粘贴命令,结果卡在第一步——连服务器都连不上。我带过十几支小团队,90%的新手在部署前根本没想清楚:你到底需要什么样的公网访问?是给老板演示用的临时链接?是给客户用的正式服务?还是自己在家调试的个人项目?这三类需求,技术路径、成本结构、安全策略全都不一样。

举个最典型的例子:上周一个做校园二手书平台的大学生找我帮忙,说“部署失败”。我问他:“你希望谁访问?”他说“同学扫码就能用”。我再问:“你有云服务器吗?”他说没有,只有一台家里闲置的笔记本。这时候如果按常规教程教他买阿里云ECS、配Nginx反向代理、申请SSL证书……纯属浪费时间。他真正需要的,是一条能绕过家庭宽带无公网IP限制、5分钟内让同学扫码访问的链路——这和企业级生产部署完全是两套逻辑。

关键词里反复出现的“家庭公网”“没有公网ip教程”“xtcp必须要有公网ip吗”,恰恰暴露了当前最大的认知断层:把“部署”等同于“上线”,把“上线”等同于“买云服务器”。实际上,Java项目暴露到公网,本质是解决“网络可达性”问题,而实现路径至少有四条主干道:

  • 真公网IP直连:运营商分配的独立IPv4地址,端口可直接映射(但国内家庭宽带基本绝迹);
  • 云服务器中转:租用VPS,项目跑在云上,通过域名+HTTPS对外提供服务(最主流,但有月付成本);
  • P2P穿透方案:如Tailscale、ZeroTier、EasyTier,不依赖公网IP,靠中继节点建立加密隧道(适合开发测试、小范围共享);
  • 反向代理隧道:如frp、ngrok、localtunnel,本地服务主动连接公网服务器,由其代为转发请求(免费额度够个人用,但稳定性需实测)。

你看到的热搜词里,“railway部署”“dify本地部署”“ollama部署本地大模型”,全是这类轻量级、免运维、重体验的现代部署范式。它们共同特点是:不碰Linux命令行、不配防火墙、不调JVM参数,只要会写java -jar xxx.jar就能跑通。这才是当下真实世界里,绝大多数Java初学者、学生、个人开发者的真实战场。

所以别急着敲scpdocker build。先拿出一张纸,回答三个问题:

  1. 这个项目谁用?(1个同学?100个用户?还是你自己调试?)
  2. 能接受什么成本?(0元?每月30元?还是愿意花半天研究免费方案?)
  3. 对稳定性要求多高?(挂一小时无所谓?还是必须7×24小时在线?)

答案不同,接下来的每一步操作,都会走向完全不同的技术分支。这篇教程不会给你“万能模板”,而是带你亲手画出属于你自己的部署决策树——因为真正的部署能力,不在于记住多少命令,而在于看清约束条件后,精准选择那条阻力最小的路。

2. 真实环境复现:从零开始搭建一个可公网访问的Spring Boot示例

我们不拿“Hello World”糊弄人。现在就用一个真实可运行的Spring Boot项目来实操,它包含Web接口、数据库连接、静态资源,覆盖90%的Java Web项目基础结构。项目地址已准备好:https://github.com/real-deploy-demo/springboot-public-demo (这是个公开仓库,代码干净无敏感信息)。

2.1 本地验证:确保你的项目在本机能跑起来

先别想公网。打开终端,执行以下步骤(Windows用户请用Git Bash或WSL):

# 克隆示例项目 git clone https://github.com/real-deploy-demo/springboot-public-demo.git cd springboot-public-demo # 查看项目结构(关键文件已标注) ls -la # ├── pom.xml ← Maven依赖管理,含spring-boot-starter-web等 # ├── src/ # │ └── main/ # │ ├── java/com/example/demo/ # │ │ ├── DemoApplication.java ← 启动类,@SpringBootApplication # │ │ └── controller/ApiDemoController.java ← 提供 /api/hello 接口 # │ └── resources/ # │ └── application.yml ← 配置文件,注意 server.port: 8080 # └── static/ ← 存放index.html等前端资源

重点看application.yml里的配置:

server: port: 8080 address: 0.0.0.0 # 关键!必须监听0.0.0.0,而非localhost,否则外部无法访问 spring: datasource: url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE driver-class-name: org.h2.Driver username: sa password: h2: console: enabled: true path: /h2-console

提示:server.address: 0.0.0.0是新手最容易忽略的点。很多教程只写port: 8080,结果部署到服务器后,curl localhost:8080能通,但从外网curl服务器IP:8080却超时——就是因为没显式声明监听所有网卡。Java默认只监听127.0.0.1,这是安全设计,但部署时必须主动放开。

编译并启动:

# 使用Maven打包(生成target/demo-0.0.1-SNAPSHOT.jar) mvn clean package -DskipTests # 启动jar包(注意:加-Dspring.profiles.active=prod,模拟生产环境) java -Dspring.profiles.active=prod -jar target/demo-0.0.1-SNAPSHOT.jar

启动成功后,浏览器访问http://localhost:8080/api/hello,应返回{"message":"Hello from Spring Boot!"};访问http://localhost:8080/h2-console可进入H2数据库控制台(用户名sa,密码为空)。这证明项目本地运行无误。

2.2 构建可部署的产物:不只是jar包,还有环境契约

很多教程止步于mvn package,但生产部署远不止于此。一个可交付的Java部署包,必须明确声明它的运行契约(Runtime Contract)——即它对操作系统、JDK版本、内存、磁盘、网络端口的硬性要求。

我们来补全这个契约:

项目要求为什么重要如何验证
JDK版本OpenJDK 17 LTSSpring Boot 3.x 强制要求JDK17+,低版本会报UnsupportedClassVersionErrorjava -version输出必须含17.0.
可用内存≥512MB堆内存H2数据库+Spring容器启动后,空载约300MB,预留200MB防OOM启动时加-Xms512m -Xmx512m参数
端口占用8080端口未被占用冲突会导致Address already in use异常netstat -an | grep 8080(Linux/Mac) 或netstat -ano | findstr :8080(Win)
文件权限jar包有执行权限Linux下若无x权限,java -jar会报Permission deniedchmod +x target/demo-0.0.1-SNAPSHOT.jar

实操中,我见过太多人因JDK版本踩坑。比如在Mac上用Homebrew装的JDK21,部署到CentOS7服务器(默认OpenJDK11),一运行就崩溃。解决方案不是降级本地JDK,而是在项目根目录添加Dockerfile,将JDK环境固化进镜像——这才是现代Java部署的正确起点。

2.3 本地网络可达性测试:确认你的机器“能被找到”

部署前最后一步:验证你的本地机器是否具备被外部访问的基础网络能力。这不是废话,而是区分“部署失败”和“网络不通”的关键。

在本地启动项目后,打开另一个终端,执行:

# 测试本机回环(必须通) curl http://localhost:8080/api/hello # 测试本机局域网IP(假设你的IP是192.168.1.100) curl http://192.168.1.100:8080/api/hello # 测试本机局域网IP加端口(同上,但显式指定) curl -v http://192.168.1.100:8080/api/hello

如果第二、三步失败,说明问题出在本地防火墙或网络配置:

  • Windows:检查“Windows Defender 防火墙”是否阻止了Java进程的入站连接(控制面板→系统和安全→Windows Defender防火墙→高级设置→入站规则→新建规则→程序→选择java.exe路径);
  • MacSystem Preferences → Security & Privacy → Firewall → Firewall Options → Allow incoming connections for...,勾选JavaAppletPlugin或java;
  • Linux(Ubuntu)sudo ufw status查看防火墙状态,若为active,执行sudo ufw allow 8080

注意:此步骤必须成功,否则后续所有公网方案都是空中楼阁。我曾帮一个团队排查了两天,最后发现是公司WiFi路由器开启了“AP隔离”,导致同一局域网内设备无法互访——这种网络层问题,永远比代码问题更难定位。

curl http://192.168.1.100:8080/api/hello返回正确JSON时,恭喜,你的项目已具备“局域网可达性”。下一步,就是把它推送到公网——而这条路,我们分三类场景,逐个击破。

3. 场景一:零成本快速验证(适合学生、个人Demo、面试作品)

如果你的需求是:“让导师/同学/面试官扫码就能看我的项目,不关心长期稳定,今天就要用”,那么买云服务器、配Nginx、申请域名……全是过度设计。真正的捷径,是利用现代云平台提供的免运维托管服务。它们的核心逻辑是:你只管提交代码,剩下的(构建、运行、扩缩容、HTTPS、域名)全由平台自动完成。

3.1 Railway:5分钟上线,连服务器都不用买

Railway是目前对Java开发者最友好的免费托管平台之一。它不要求你懂Docker,不强制你写Dockerfile,甚至支持直接上传jar包。关键是:新用户注册即送$5免费额度,足够跑一个Spring Boot应用数月。

操作流程(全程图形界面,无命令行):

  1. 访问 https://railway.app ,用GitHub账号登录;
  2. 点击右上角“New Project” → “Create new project”;
  3. 在项目页,点击“Add Service” → “Deploy from GitHub”;
  4. 授权Railway访问你的GitHub仓库(只需读取权限);
  5. 选择你刚克隆的sprintboot-public-demo仓库;
  6. 在“Build & Deploy Settings”中,关键配置如下:
    • Build Command:mvn clean package -DskipTests
    • Start Command:java -Dspring.profiles.active=prod -Xms256m -Xmx256m -jar target/demo-0.0.1-SNAPSHOT.jar
    • Port:8080(必须与application.yml中一致)
    • Environment Variables: 添加JAVA_HOME=/opt/java/openjdk(Railway预装JDK17路径)

点击“Deploy Now”,等待2-3分钟。构建日志会实时滚动,看到Started DemoApplication in X.XXX seconds即表示启动成功。

部署完成后,Railway会自动生成一个类似https://demo-production-1234.up.railway.app的URL。复制此链接,发给任何人,都能直接访问你的/api/hello接口。

实测心得:Railway的免费层使用的是共享CPU,冷启动稍慢(首次访问约3-5秒),但一旦热起来,响应速度与自建VPS无异。它最大的优势是零配置HTTPS——所有*.up.railway.app域名自动启用Let's Encrypt证书,浏览器地址栏显示绿色锁图标。这对需要展示专业性的面试作品至关重要。

3.2 Render:更稳的免费选择,适合需要7×24小时的小项目

Render的免费层比Railway更“实在”:它提供永久免费的Web Service实例(非睡眠模式),且CPU性能更均衡。缺点是:必须写Dockerfile,但这个Dockerfile简单到只有4行。

在项目根目录创建Dockerfile

# 使用官方OpenJDK 17镜像 FROM openjdk:17-jre-slim # 将jar包复制到镜像中 COPY target/demo-0.0.1-SNAPSHOT.jar app.jar # 暴露端口(必须与application.yml一致) EXPOSE 8080 # 启动命令 ENTRYPOINT ["java","-Dspring.profiles.active=prod","-Xms256m","-Xmx256m","-jar","app.jar"]

然后:

  1. 访问 https://render.com ,GitHub登录;
  2. 点击“New Web Service” → “Connect Repository”,选择你的项目;
  3. 在配置页填写:
    • Service Name:demo-java
    • Region: 选离你用户最近的(如Oregon
    • Branch:main
    • Build Command:mvn clean package -DskipTests
    • Start Command:java -Dspring.profiles.active=prod -Xms256m -Xmx256m -jar target/demo-0.0.1-SNAPSHOT.jar
    • Environment:JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64(Render的JDK路径)

点击“Create Web Service”,等待构建完成。Render会分配一个https://demo-java.onrender.com的域名,同样自动HTTPS。

关键对比:Railway免费层有$5额度,用完会暂停;Render免费层无额度限制,但要求项目必须公开(GitHub仓库设为Public)。如果你的项目涉及敏感逻辑,Render更安全(私有仓库需付费);如果只是Demo,Railway更省心。

3.3 本地穿透方案:没有公网IP?用Tailscale搞定

如果你坚持“必须跑在自己电脑上”,且家庭宽带确实没有公网IP(国内99%的情况),那么传统端口映射(路由器DMZ)必然失败。此时,Tailscale是目前最成熟、最易用的替代方案。

Tailscale原理很简单:它在你的电脑和Tailscale的全球DERP中继服务器之间,建立一条加密的WireGuard隧道。你的电脑获得一个100.x.y.z的Tailscale IP,任何加入同一Tailscale网络的设备(手机、朋友电脑),都能直接curl http://100.x.y.z:8080访问你的服务——完全绕过家庭NAT。

实操步骤(Windows/macOS/Linux通用):

  1. 注册Tailscale账号:https://login.tailscale.com (用GitHub邮箱即可);
  2. 下载对应客户端并安装(官网提供一键安装包);
  3. 启动客户端,在终端执行:
    # 登录(会打开浏览器让你授权) tailscale up # 查看本机Tailscale IP tailscale ip -4 # 输出类似:100.101.102.103
  4. 在另一台设备(如手机)也安装Tailscale,登录同一账号;
  5. 手机浏览器访问http://100.101.102.103:8080/api/hello—— 成功!

注意事项:Tailscale免费版支持20台设备、100GB流量/月,对学生和小团队完全够用。它的最大优势是零配置、跨平台、无感知——你不需要改一行代码,不需要开路由器端口,甚至不需要知道什么是NAT。唯一要做的,就是确保你的Java项目监听0.0.0.0:8080(我们已在2.1节强调过)。

这三类方案,覆盖了95%的“零成本快速验证”场景。它们的共同点是:把复杂度从“运维”转移到“平台”。你付出的不是金钱,而是对平台的信任。而这种信任,在今天的技术生态里,是完全值得的。

4. 场景二:可控、可扩展的生产部署(适合小团队、创业项目、长期服务)

当你需要“我的服务必须一直在线”“我要自己掌控所有配置”“未来要加监控、日志、数据库”,那么免费托管平台的黑盒就不再适用。你需要一台属于自己的服务器,以及一套可重复、可审计、可升级的部署流程。这里,我们放弃“手动scp+java -jar”的原始方式,采用Docker + Nginx + Let's Encrypt的黄金组合——它不是最前沿的,但却是经过十年生产环境验证、故障率最低、文档最全的方案。

4.1 服务器选型与初始化:为什么推荐Ubuntu 22.04 LTS

别纠结CentOS、Debian或Alibaba Cloud Linux。对于Java部署,Ubuntu 22.04 LTS是当前最平衡的选择,理由如下:

  • JDK生态最友好apt install openjdk-17-jre-headless一行安装,无依赖冲突;
  • Docker官方支持最佳:Docker CE的Ubuntu包更新最及时,apt-get install docker.io即可;
  • Let's Encrypt兼容性最强:Certbot工具对Ubuntu的自动化续期脚本最成熟;
  • 社区资源最丰富:遇到任何问题,Stack Overflow上90%的答案都基于Ubuntu。

购买服务器(以腾讯云轻量应用服务器为例):

  • 地域:选离你用户最近的(如上海、广州);
  • 镜像:Ubuntu 22.04 LTS(切勿选CentOS 7,已停止维护);
  • 配置:2核2G内存起步(Spring Boot+H2数据库最低要求);
  • 带宽:5Mbps(足够100并发以内);
  • 安全组:务必开放端口22(SSH),80(HTTP),443(HTTPS),8080(Java服务,仅限内网,见4.3节)。

服务器创建后,用SSH登录(Windows用户推荐Termius或FinalShell):

ssh root@your-server-ip # 输入密码(腾讯云后台可重置)

首次登录后,立即执行初始化:

# 更新系统 apt update && apt upgrade -y # 安装基础工具 apt install -y curl wget git vim net-tools # 创建非root用户(安全最佳实践) adduser deploy usermod -aG sudo deploy # 切换到deploy用户 su - deploy

经验之谈:永远不要用root用户直接部署。我见过太多团队因root下误删/etc目录导致服务器瘫痪。deploy用户拥有sudo权限,但每次提权都需要输入密码,形成天然的操作确认屏障。

4.2 Docker化你的Java项目:从jar包到可移植镜像

Docker是Java部署的分水岭。它解决了“在我机器上能跑,到服务器上就报错”的千古难题。核心思想:把JDK、jar包、配置文件、启动脚本全部打包成一个不可变的镜像,到哪运行都一样。

在你的本地项目根目录,创建Dockerfile(内容与Render版相同,但更健壮):

# 多阶段构建:第一阶段用于编译,第二阶段用于运行 FROM maven:3.8.6-openjdk-17 AS builder WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline -B COPY . . RUN mvn clean package -DskipTests # 第二阶段:极简运行时 FROM openjdk:17-jre-slim VOLUME ["/tmp"] ARG JAR_FILE=target/demo-0.0.1-SNAPSHOT.jar COPY --from=builder /app/${JAR_FILE} app.jar EXPOSE 8080 ENTRYPOINT ["java","-Dspring.profiles.active=prod","-Xms256m","-Xmx512m","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]

关键点解析:

  • 多阶段构建:第一阶段用maven镜像编译,第二阶段用更小的openjdk镜像运行,最终镜像体积从800MB降至150MB;
  • -Djava.security.egd=file:/dev/./urandom:修复Linux容器内Java SecureRandom阻塞问题(常见于Tomcat启动慢);
  • VOLUME ["/tmp"]:为Spring Boot临时文件(如上传)提供挂载点,避免容器重启后丢失。

构建并测试本地镜像:

# 构建镜像(tag为demo-java:latest) docker build -t demo-java:latest . # 启动容器(映射8080端口) docker run -d -p 8080:8080 --name demo-app demo-java:latest # 查看日志确认启动成功 docker logs -f demo-app # 应看到 "Started DemoApplication in X.XXX seconds"

4.3 Nginx反向代理:让HTTP变成HTTPS,让8080变成80

直接暴露http://your-server-ip:8080既不专业,也不安全。Nginx作为反向代理,承担三重角色:

  • 端口转换:把用户访问的http://your-domain.com(80端口)转发给本地http://localhost:8080
  • HTTPS卸载:处理SSL证书,后端Java服务仍用HTTP,降低复杂度;
  • 静态资源服务/static/下的图片、JS、CSS由Nginx直接返回,不走Java。

安装Nginx:

sudo apt install nginx -y sudo systemctl enable nginx sudo systemctl start nginx

配置反向代理(编辑/etc/nginx/sites-available/demo):

server { listen 80; server_name your-domain.com; # 替换为你的域名,或先用服务器IP # HTTP重定向到HTTPS(启用SSL后取消注释) # return 301 https://$server_name$request_uri; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; } }

启用配置:

# 创建软链接 sudo ln -sf /etc/nginx/sites-available/demo /etc/nginx/sites-enabled/ # 测试Nginx配置语法 sudo nginx -t # 重载配置 sudo systemctl reload nginx

此时,访问http://your-server-ip,应看到与http://your-server-ip:8080完全相同的页面。Nginx已成功接管流量。

4.4 Let's Encrypt自动HTTPS:免费、可信、全自动

没有HTTPS的网站,在Chrome中会被标记为“不安全”,严重影响可信度。Let's Encrypt提供免费、自动化、可信的SSL证书。

安装Certbot:

sudo apt install certbot python3-certbot-nginx -y

获取并安装证书(假设你已将域名your-domain.com解析到服务器IP):

# Certbot会自动修改Nginx配置,添加HTTPS块 sudo certbot --nginx -d your-domain.com # 按提示输入邮箱,同意协议,选择重定向(选2,强制HTTPS)

执行后,Certbot会:

  • 自动申请证书;
  • 修改/etc/nginx/sites-available/demo,添加443端口配置;
  • 配置自动续期(通过systemd timer,每天凌晨自动检查)。

验证HTTPS:

  • 浏览器访问https://your-domain.com,地址栏显示绿色锁图标;
  • curl -I https://your-domain.com返回HTTP/2 200

续期无忧:Certbot的自动续期任务已内置。你只需每年检查一次:sudo certbot renew --dry-run。若输出Congratulations, all simulated renewals succeeded,则万事大吉。

至此,你的Java项目已具备生产级部署的所有要素:Docker容器化、Nginx反向代理、自动HTTPS、域名访问。整个过程可完全脚本化,下次部署新项目,只需替换Dockerfile中的jar包名和Nginx配置中的域名,5分钟内即可复现。

5. 场景三:内网穿透终极方案(适合无公网IP、需长期稳定、拒绝云服务)

当你的项目必须运行在内网服务器(如公司内网、家庭NAS、树莓派),且你无法接受任何第三方云平台(出于数据隐私、合规或纯粹的技术洁癖),那么自建FRP服务器是唯一可行的方案。它不像Tailscale那样依赖中继,而是你完全掌控的、点对点的穿透服务。

5.1 FRP架构解析:为什么它比ngrok更可控

FRP(Fast Reverse Proxy)由两部分组成:

  • frps(FRP Server):部署在一台有公网IP的VPS上(哪怕是最便宜的1核1G);
  • frpc(FRP Client):部署在你的内网Java服务器上,主动连接frps。

数据流向:用户 → frps公网IP:端口 → frpc内网IP:8080 → Java服务。所有流量经frps中转,但frps本身不处理业务逻辑,只做TCP/UDP转发。

优势在于:

  • 完全自主:证书、域名、端口、加密密钥,全部由你控制;
  • 零依赖第三方:不依赖ngrok.com、serveo.net等商业服务,无停服风险;
  • 可定制性强:支持TCP/UDP/HTTP/HTTPS/STCP等多种穿透模式,可配置域名、子域名、HTTP头过滤。

5.2 部署frps(服务端):一台5美元VPS足矣

购买一台最便宜的VPS(如Vultr $2.5/mo、Oracle Cloud Always Free),系统选Ubuntu 22.04。

登录后,下载并配置frps:

# 下载最新frp(截至2024年,v0.54.0为稳定版) wget https://github.com/fatedier/frp/releases/download/v0.54.0/frp_0.54.0_linux_amd64.tar.gz tar -xzf frp_0.54.0_linux_amd64.tar.gz cd frp_0.54.0_linux_amd64 # 编辑服务端配置 frps.ini cat > frps.ini << 'EOF' [common] bind_port = 7000 # frpc连接此端口 vhost_http_port = 80 # HTTP服务映射端口 vhost_https_port = 443 # HTTPS服务映射端口 dashboard_port = 7500 # 监控面板端口(可选) dashboard_user = admin dashboard_pwd = your_password_here token = your_secure_token_here # frpc连接时需提供,必须设置! EOF

创建systemd服务,实现开机自启:

sudo tee /etc/systemd/system/frps.service << 'EOF' [Unit] Description=FRP Server After=network.target [Service] Type=simple User=root WorkingDirectory=/root/frp_0.54.0_linux_amd64 ExecStart=/root/frp_0.54.0_linux_amd64/frps -c /root/frp_0.54.0_linux_amd64/frps.ini Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target EOF # 启动服务 sudo systemctl daemon-reload sudo systemctl enable frps sudo systemctl start frps # 检查状态 sudo systemctl status frps

安全加固:务必修改dashboard_userdashboard_pwd,并设置强token。frps默认不开启认证,token是防止未授权frpc接入的唯一防线。

5.3 部署frpc(客户端):内网服务器上的轻量守护

在你的内网Java服务器(Ubuntu)上操作:

# 下载frpc(与frps同版本) wget https://github.com/fatedier/frp/releases/download/v0.54.0/frp_0.54.0_linux_amd64.tar.gz tar -xzf frp_0.54.0_linux_amd64.tar.gz cd frp_0.54.0_linux_amd64 # 编辑客户端配置 frpc.ini cat > frpc.ini << 'EOF' [common] server_addr = your-frps-public-ip # 替换为你的VPS公网IP server_port = 7000 token = your_secure_token_here # 必须与frps.ini中一致 [web] type = http local_port = 8080 # Java服务端口 custom_domains = your-domain.com # 你的域名,需DNS解析到VPS IP EOF

启动frpc:

# 后台运行 ./frpc -c ./frpc.ini & # 或创建systemd服务(推荐,更稳定) sudo tee /etc/systemd/system/frpc.service << 'EOF' [Unit] Description=FRP Client After=network.target [Service] Type=simple User=root WorkingDirectory=/root/frp_0.54.0_linux_amd64 ExecStart=/root/frp_0.54.0_linux_amd64/frpc -c /root/frp_0.54.0_linux_amd64/frpc.ini Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable frpc sudo systemctl start frpc

5.4 DNS与HTTPS:让穿透服务真正可用

此时,访问http://your-frps-public-ip,应看到Java服务的响应。但要达到生产可用,还需两步:

  1. 域名解析:将你的域名(如demo.yourname.com)的A记录,指向your-frps-public-ip
  2. HTTPS加持:在frps端配置Let's Encrypt,或在VPS上用Nginx反向代理+Certbot。

推荐后者(Nginx方案),因为它更灵活:

# 在VPS上安装Nginx和Certbot(同4.4节) sudo apt install nginx certbot python3-certbot-nginx -y # 配置Nginx,将HTTPS请求转发给frps的vhost_http_port(80) sudo tee /etc/nginx/sites-available/frp-proxy << 'EOF' server { listen 443 ssl http2; server_name demo.yourname.com; ssl_certificate /etc/letsencrypt/live/demo.yourname.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/demo.yourname.com/privkey.pem; location / { proxy_pass http://127.0.0.1:80; # frps的vhost_http_port proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } server { listen 80; server_name demo.yourname.com; return 301 https://$server_name$request_uri; } EOF sudo ln -sf /etc/nginx/sites-available/frp-proxy /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx # 申请证书 sudo certbot --nginx -d demo.yourname.com

最终,用户访问https://demo.yourname.com,流量路径为:
用户HTTPS请求 → VPS Nginx(HTTPS卸载)→ VPS frps(80端口)→ VPS frpc(TCP隧道)→ 内网服务器8080 → Java服务

整条链路由你100%掌控,无任何第三方介入。虽然初期配置稍复杂,但一旦跑通,稳定性远超所有SaaS穿透服务。这是我为金融客户部署内部管理系统时的首选方案——因为合规审查时,你能清晰说出每一跳的IP、端口、加密方式。

6. 部署后的必做清单:从“能访问”到“可运维”

项目上线只是开始。一个真正可用的公网Java服务,必须通过以下10项检查。少一项,都可能在深夜收到告警。

6.1 JVM内存监控:避免OutOfMemoryError的定时炸弹

java: outofmemoryerror: insufficient memory是Java部署最经典的报错。它往往在流量高峰时突然爆发,而非启动时。原因在于:JVM堆内存设置不合理,或存在内存泄漏。

在启动命令中,必须显式设置堆内存:

# 错误:不设内存,依赖JVM默认(通常很小) java -jar app.jar # 正确:根据服务器内存,设置合理范围 java -Xms512m -Xmx1024m -jar app.jar # -Xms:初始堆大小,-Xmx:最大堆大小,建议设为相等,避免动态扩容GC

验证是否生效:

# 查看Java进程的JVM参数 ps aux | grep java # 输出应含
http://www.cnnetsun.cn/news/3116270.html

相关文章:

  • 百度网盘解析工具终极指南:三步实现高速下载的完整解决方案
  • 影刀RPA新手教程:钉钉机器人消息推送完全指南——内部群通知、Webhook配置与消息格式
  • 【软考程序员黄金72小时启动计划】:零基础考生第1周必须完成的8件关键小事,错过=多考1年
  • Translumo完整教程:告别语言障碍的终极屏幕翻译解决方案
  • 如何用智能脚本轻松管理你的系统授权:5分钟上手完整指南
  • Cypress实战:Web Speech API语音识别自动化测试全攻略
  • 如何高效使用Windows实时屏幕翻译工具:Translumo实用指南
  • 智能体工程:从Demo到生产环境的实战指南
  • 如何快速实现B站视频转文字:3步完成bili2text部署指南
  • VoiceFixer:3分钟让受损语音重获新生的AI音频修复神器
  • Java AES加密解密实战指南:从原理到代码,避坑与优化
  • okTurtles 专家揭秘:AI 编码“短 leash”方法及审查要点,助开发者提升效率
  • 3分钟掌握gInk:Windows上最简单高效的免费屏幕标注工具终极指南
  • 【Springboot毕设全套源码+文档】基于springboot社区志愿者服务系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • [智能体-629]:OpenClaw 六大主流对话交互方式
  • Walsh-Hadamard域自动编码器在6G通信中的能效优化
  • Mac Mouse Fix:让普通鼠标在macOS上超越触控板的终极解决方案
  • Destiny 2单人模式终极指南:轻松开启你的专属游戏空间
  • KimiClaw本地AI助手安装与实战指南:零代码接入Kimi API
  • 如何用ComfyUI Impact Pack打造AI图像增强神器:从新手到专家的5大实用技巧
  • 软考证书登记永久有效政策突变:为什么你的高级资格证仍在“待激活”状态?1张表看清12类证书适用规则
  • 国产大模型科学计算能力实测:从文字智力到工程落地的鸿沟
  • HsMod:专业级炉石传说游戏增强插件完全指南
  • 软考继续教育学分还能“跨省互认”?长三角+粤港澳试点政策首曝,3类课程已获双地认证(附实操截图)
  • HsMod终极指南:55个功能全面解锁您的炉石传说游戏体验
  • 广州增城口碑好的发光字工厂销售厂家哪个好
  • 乐道L60深度测试:端到端驾驶与自动泊车如何重塑智能出行体验
  • 米其林胎面磨损量化测试:GelSight Mobile 视触觉3D成像系统实操全流程
  • 怀旧游戏集成方案:五款虚拟机模拟器实战部署与性能对比
  • 宿舍管理系统-python+Django