端口80之外:一个Java小白和HTTP、DNS、FTP、SSH的“隐秘”交手

张开发
2026/4/20 17:05:43 15 分钟阅读

分享文章

端口80之外:一个Java小白和HTTP、DNS、FTP、SSH的“隐秘”交手
计网课本里应用层一口气列了十几种协议。我学了两年Java以为只有HTTP/HTTPS是“常客”其余都是“路人”。直到线上域名解析失败导致整个微服务挂掉、对接老旧系统被迫翻出FTP文档、用SSH端口转发救火……我才发现它们一直在我的代码和运维里默默出镜只是我从未认真打过招呼。这篇文章我从一个Java后端学习者的真实经历出发重新认识应用层这五位“老熟人”——HTTP/HTTPS、DNS、FTP、SSH。不讲八股只讲它们什么时候出现在我的项目里、出了什么bug、以及我现在怎么和它们相处。 一、HTTP/HTTPS一日三餐但你真的嚼透了吗1.1 我在项目里和HTTP打了多少照面RestController返回 JSON → 客户端用 HTTP 拿到数据Feign 调另一个微服务 → HTTP 请求RestTemplate 调支付宝/微信/高德地图 API → HTTPNginx 反向代理 → 转发的也是 HTTP可以说没有 HTTP现代 Java Web 开发直接瘫痪。1.2 一个让我改了一晚上bug的报文细节有次在“知识汇”教育平台里前端同事说“登录接口偶尔返回 400”。我抓包看到请求报文POST /login HTTP/1.1 Host: api.zhihui.com Content-Type: application/x-www-form-urlencoded usernameadminpassword123456而我后端期待的是 JSON。错误码 400 Bad Request就是客户端发的东西服务端看不懂。从那以后我死死记住了HTTP 报文的结构 Content-Type 必须匹配。请求报文简化版方法 路径 版本 头部: 值 主体可选响应报文版本 状态码 短语 头部: 值 主体状态码我排错时最常用200 OK → 一切正常301/302 → 重定向比如支付成功后跳转400 → 客户端请求格式有误401 → 没登录403 → 没权限404 → 接口地址写错了429 → 被限流了秒杀场景常见500 → 后端代码异常空指针之类的503 → 服务熔断或不可用1.3 HTTPS HTTP 一件防弹衣HTTPS 就是在 HTTP 外面套了一层TLS/SSL。它在 Java 开发里的体现用RestTemplate调https://接口默认会自动验证证书。本地自签名证书要跳过校验写测试代码时常用但生产环境绝对不能干。一句话HTTP 是裸奔HTTPS 是穿了防弹衣。1.4 关于 HTTP/2 和 HTTP/3我只在配置 Nginx 时打开过http2发现多个请求可以复用同一个连接速度快了不少。至于 HTTP/3底层用 UDP目前还是前沿玩具但面试官喜欢问知道它“解决了队头阻塞”就够了。 二、FTP那个我以为灭绝了结果项目里真遇到了的协议2.1 它居然还在用大二做课设的时候老师说“用 FTP 上传文件”。我心想这什么上古技术后来实习时对接某银行的对账系统对方接口文档写着通过 FTP 下载对账单。我懵了——FTP 还活着。2.2 主动模式 vs 被动模式我踩过的坑第一次用FTPClient连接对方服务器一直超时。查了半天原来是防火墙拦截了主动模式。解决方案在 Java 代码里开启被动模式。FTPClient ftp new FTPClient(); ftp.connect(host, port); ftp.login(user, pass); ftp.enterLocalPassiveMode(); // ← 这一行救了我后来我理解了主动模式服务器主动连客户端的一个随机端口容易被防火墙拦被动模式客户端去连服务器打开的一个随机端口更通用给 Java 学生的建议如果对接 FTP上来就开被动模式省去 90% 的排错时间。 三、DNS互联网的电话本崩一次你就知道它多重要3.1 它每天都在为你工作你却几乎忘了它浏览器输入www.baidu.com能打开全靠 DNS 把这个名字翻译成 IP 地址。Java 里解析域名就是一行InetAddress ip InetAddress.getByName(www.baidu.com); System.out.println(ip.getHostAddress()); // 打印 110.242.68.663.2 一次 DNS 故障让我通宵排查在“智答知识库”项目里我用 Docker Compose 启动 Java Python 两个容器。Java 容器里通过python-api:8000访问 Python 服务有时候突然连不上。重启容器又好了随机复现。查了两小时发现是Docker 内置 DNS 偶尔解析失败。解决方案把两个容器放进同一个自定义网络并加上--link或者用depends_on。从那以后我记住了DNS 解析是有缓存、有超时、有失败可能的。微服务架构里不要频繁做域名解析最好用 IP 或长连接。开发中常见 DNS 问题DNS 污染/劫持 → 换公共 DNS114.114.114.114或8.8.8.8DNS 解析延迟 → 启用缓存或用 IP 直连内网 DNS → 公司内部.local域名需要自建 DNS 或改 hosts 四、SSH不只是ssh rootserver4.1 你以为 SSH 只用来登录服务器我最早用 SSH 就是ssh userhost连服务器部署 Jar 包。后来学到它还能执行远程命令ssh rootserver systemctl restart java-app端口转发把远程服务器的 8080 端口映射到本地直接localhost:8080就能访问远程 SpringBoot 应用Git over SSHgitgithub.com:xxx/xxx.git用的就是 SSHSFTP安全的文件传输比 FTP 安全得多4.2 一个让我觉得“SSH 太强了”的场景有一次线上服务器只开了 22 端口SSH但我想访问它上面的一个 Web 服务8080。用了这条命令ssh -L 8080:localhost:8080 rootserver然后我打开本地浏览器输入http://localhost:8080就看到了远程服务器的网页。这就是 SSH 本地端口转发——开发调试神器。4.3 Java 里调用 SSH可以用 JSch 库执行远程命令JSch jsch new JSch(); Session session jsch.getSession(user, host, 22); session.setPassword(pass); session.connect(); ChannelExec channel (ChannelExec) session.openChannel(exec); channel.setCommand(ls -la); channel.connect(); // 读取输出...不过日常开发中我们更多是用 Git over SSH配密钥或者 Gradle/Maven 插件通过 SSH 部署。 五、一张表总结这些协议到底什么时候会出现在我的 Java 项目里我的感悟HTTP 是主角但配角一个都不能少。面试官问“应用层有哪些协议”别只背名字像我一样说出来“我在知识汇项目里用 Feign 调 HTTP 接口对接银行时用 FTPClient 被动模式拉账单线上 DNS 崩过一次后来加了缓存我用 SSH 端口转发调试过远程服务……”这比任何八股答案都值钱。

更多文章