如何在EC2实例上用单端口443运行多Java服务并优化IP与安全
最优解决方案
方案1:使用AWS Application Load Balancer(ALB)
这是AWS生态下最省心的托管式方案,完美匹配你的需求:
- 减少EIP数量:只需要给ALB绑定一个公网IP(或直接使用ALB提供的域名,无需手动分配EIP),所有Java服务通过ALB对外提供访问。
- 关闭非标准端口:
- 给EC2实例的安全组配置规则:仅允许ALB的安全组访问内部端口1234(无需开放到公网)。
- ALB的安全组仅开放443端口给公网,彻底屏蔽1234端口的外部访问。
- 流量转发配置:
- 创建多个目标组,每个目标组对应一个Java服务(如果服务绑定不同ENI,目标组指定对应ENI的1234端口;如果是同一网卡不同端口,调整目标端口即可)。
- 在ALB的443监听规则中,通过主机头(Host)或路径前缀区分不同服务:
- 比如
service1.yourdomain.com转发到服务1的目标组,service2.yourdomain.com转发到服务2的目标组; - 或者
yourdomain.com/service1/*转发到服务1,yourdomain.com/service2/*转发到服务2。
- 比如
- 给ALB配置SSL证书(可使用AWS Certificate Manager免费生成),实现HTTPS终止。
方案2:使用Nginx作为反向代理(自托管)
如果不想依赖AWS托管服务,可在EC2实例上部署Nginx做反向代理:
- EIP简化:仅给EC2绑定一个EIP,安全组仅开放443端口给公网。
- 端口安全:EC2内部仅允许Nginx访问Java服务的1234端口(可通过
iptables或安全组限制localhost访问),1234完全不暴露给公网。 - Nginx配置示例:
server { listen 443 ssl; server_name service1.yourdomain.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://127.0.0.1:1234; # 若服务绑定不同ENI,替换为对应ENI的内网IP:1234 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } server { listen 443 ssl; server_name service2.yourdomain.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://127.0.0.1:1235; # 若服务用不同端口,替换对应端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } - 注意:如果多个Java服务都绑定同一端口1234,需确保它们分别绑定不同的内网IP(比如EC2的多个ENI),否则会出现端口冲突,此时Nginx的
proxy_pass要指向对应ENI的IP而非127.0.0.1。
方案对比
- ALB优势:无需维护服务器,自动扩容,集成AWS Certificate Manager、WAF等安全工具,适合长期稳定运行的生产环境。
- Nginx优势:配置灵活,可自定义转发规则、缓存策略,适合需要高度定制化的场景,无额外AWS服务费用(仅EC2成本)。
内容的提问来源于stack exchange,提问作者Khaled Hussein
相关产品推荐
相关产品推荐

