【问题标题】:How can I run a Spring Boot application on port 80如何在端口 80 上运行 Spring Boot 应用程序
【发布时间】:2016-02-15 16:43:49
【问题描述】:

我无法在端口 80 上启动应用程序。

我已经在本地计算机上尝试过(使用我的 IDE 和本地服务器),但没有成功。

我检查了其他类似的帖子,并确保我在服务器上使用 root 运行 jar。

这是错误:

 till here all ok
...
java.net.SocketException: Permission denied
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:338)
at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:760)
at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:472)
at org.apache.catalina.connector.Connector.startInternal(Connector.java:986)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardService.addConnector(StandardService.java:237)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.addPreviouslyRemovedConnectors(TomcatEmbeddedServletContainer.java:186)
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:149)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:288)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at com.andirod.StartApplication.main(StartApplication.java:20)
...
...
...
Exception in thread "main" java.lang.IllegalStateException: Tomcat connector in failed state
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:157)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:288)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at com.andirod.StartApplication.main(StartApplication.java:20)

【问题讨论】:

标签: java spring spring-boot


【解决方案1】:

linux上1024以下的端口只有root才能打开,所以默认限制80端口

如果你想在 80 端口上发布你的应用,你需要将请求从 80 端口重定向到你将运行你的 springapp 的端口(例如 8080)端口

方案一:HTTP 代理服务器

您可以使用默认允许在 80 端口上工作的 Apache2 服务器,并且可以将请求转发给 Tomcat

Debian 配置示例

sudo apt-get install apache2

a2enmod proxy
a2enmod proxy_http   

cd /etc/apache2/sites-enabled
sudo nano 000-default.conf

编辑文件:

<VIRTUALHOST *:80>

    ProxyPreserveHost On

    # ...

    ProxyPass / http://localhost:8080/
</VIRTUALHOST>

保存文件:Ctrl+O, ENTER, Ctrl+X

注意:要了解有关虚拟主机配置的更多信息,您可以通过单击here 查看有关该主题的详细 Apache 手册。

重启 Apache2 以应用更改:

sudo service apache2 restart

sudo systemctl restart apache2

解决方案 2:端口转发

使用 iptables 进行重定向

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

如果你需要使用 localhost 也添加这个

iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080

【讨论】:

  • 感谢 iptables 解决方案。
  • 对于 mac,以下命令将起作用: echo "rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080" | sudo pfctl -ef -
  • 感谢 Apache2 解决方案!我已经编辑了您的答案,以便为此解决方案添加更多详细信息。
  • 以 root 身份运行该过程,然后我可以使用 80 和 443。谢谢您
  • 如果apache能做到,我为什么不能呢?他们所有的文件都归 apahe/http 用户所有,但他们打开端口 80 就好了。为什么我不能?
【解决方案2】:

在 Linux 上使用 sudo

我在 Ubuntu 上运行 Spring Boot 应用程序,java -jar app.jar --server.port=80 给了我同样的错误。由于1024以下的端口只能通过root权限打开,所以使用“sudo”:sudo java -jar app.jar --server.port=80

出于安全考虑,仅建议将这种部署方式用于本地测试。详情见 cmets。

【讨论】:

  • 从安全的角度来看,这不是一个好主意:现在您的 java 应用程序以超级用户权限运行。 iptables 解决方案巧妙地避免了这种情况。
  • @dirkjot 是的,感谢您指出这一点。在我编写解决方案时,已接受答案中的iptables 部分不存在,因此我只是将其作为本地测试的快速解决方案。这绝对不适合生产部署。
  • 虽然不适合prd,但这是用于测试和调查目的的快速解决方案...
【解决方案3】:

这是我在 centos 上遵循的步骤。

第 1 步(可选):设置端口

默认情况下,spring boot 应用程序在端口 8080 上运行,如果您想更改此设置,可以在 src/main/resources/application.properties 文件中进行更改

server.port = 8082 // any port above than 1024

第 2 步:如果尚未安装,请安装 apache

在 Centos 7 上

sudo yum install httpd

第 3 步:编辑您的虚拟主机

/etc/httpd/conf.d/vhost.conf

你的配置应该是这样的

<VirtualHost *:80>
   ServerName yourdomin.com
   #DocumentRoot /var/www/html

   ProxyPreserveHost On
   ProxyPass / http://localhost:8082/
   ProxyPassReverse / http://localhost:8082/
</VirtualHost>

然后重启apache

sudo service httpd restart

【讨论】:

    【解决方案4】:

    在使用 ma​​cOs 的情况下,现在可以在端口 80 上运行,而无需对 ma​​cOs Mojave 版本 10.14 进行任何更改。

    【讨论】:

      【解决方案5】:

      如果你使用 docker 运行 spring boot。

      Dockerfile:

      FROM adoptopenjdk/openjdk13 AS server
      ADD /target/AppServer-1.0.jar AppServer-1.0.jar
      ENTRYPOINT ["java", "-jar" , "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:9000", "-Dcom.sun.management.jmxremote", "-Dcom.sun.management.jmxremote.authenticate=false", "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.local.only=false", "-Dcom.sun.management.jmxremote.port=1099", "-Dcom.sun.management.jmxremote.rmi.port=1099", "-Djava.rmi.server.hostname=127.0.0.1", "-Dlog4j.configurationFile=log4j2-docker.xml", "AppServer-1.0.jar", "--server.port=80"]
      

      (*) 向右滚动到最后,在 jar 名称后面看到 --server.port=80

      构建镜像并运行:

      docker run -it -p 8080:80 --cap-drop all --cap-add net_bind_service <image-name>:<tag>
      

      (!) 请注意,我删除了此进程/容器的所有功能,只添加了相关的功能 - net_bind_service,它将套接字绑定到特权端口(端口号小于 1024)。

      【讨论】:

        【解决方案6】:

        -Djava.net.preferIPv4Stack=true 添加到虚拟机选项

        JavaMail API to iMail -- java.net.SocketException: Permission denied: connect

        【讨论】:

          猜你喜欢
          • 2023-04-06
          • 2018-03-27
          • 2015-12-02
          • 1970-01-01
          • 2013-03-02
          • 2019-06-23
          • 1970-01-01
          • 2013-01-27
          • 1970-01-01
          相关资源
          最近更新 更多