如何在 AWS 上托管 nanohttpd java 应用程序?

Posted

技术标签:

【中文标题】如何在 AWS 上托管 nanohttpd java 应用程序?【英文标题】:How to host nanohttpd java app on AWS? 【发布时间】:2018-11-16 14:59:09 【问题描述】:

我已经用 nanohttpd 编写了简单的 hello-world http 服务器应用程序:

package name.antonsmirnov.apptogether.service.http;

import fi.iki.elonen.NanoHTTPD;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * HTTP server
 */
public class HttpSample 

    private static Logger logger = LoggerFactory.getLogger(HttpSample.class);

    private NanoHTTPD server;
    private int port;
    private String host;

    public int getPort() 
        return port;
    

    public void setPort(int port) 
        this.port = port;
    

    public String getHost() 
        return host;
    

    public void setHost(String host) 
        this.host = host;
    

    private AtomicInteger counter = new AtomicInteger(0);

    private void initHttp() 
        server = new NanoHTTPD(host, port) 
            @Override
            public Response serve(IHTTPSession session) 
                String ip = session.getHeaders().get("http-client-ip");
                logger.info("Request from " + ip);
                String message = "hello " + ip + " " + counter.incrementAndGet();
                return newFixedLengthResponse(Response.Status.OK, MIME_PLAINTEXT, message);
            
        ;
    

    /**
     * Start HTTP server
     * @throws Exception
     */
    public void start() throws Exception 
        if (started)
            return;

        initHttp();
        started = true;

        doStart();
    

    private void doStart() throws IOException 
        logger.info("Starting at port  ...", port);
        server.start();
        logger.debug("Started");
    

    /**
     * Stop HTTP server
     * @throws Exception
     */
    public void stop() throws Exception 
        if (!started)
            return;
        started = false;

        doStop();
    

    private void doStop() 
        logger.info("Stopping ...");
        server.stop();
        logger.debug("Stopped");
    

    private boolean started;

    public boolean isStarted() 
        return started;
    

    public static void main(String[] args) 
        HttpSample httpSample = new HttpSample();
        httpSample.setPort(5555);
        httpSample.setHost("0.0.0.0");

        try 
            httpSample.start();
         catch (Exception e) 
            logger.error("Failed to start", e);
            return;
        

        try 
            Thread.sleep(Long.MAX_VALUE);
         catch (InterruptedException e) 
            logger.error("Interrupted");
        
    

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>name.antonsmirnov.apptogether</groupId>
    <artifactId>http-sample</artifactId>
    <version>1.0</version>
    <description>HTTP server</description>

    <dependencies>

        <!-- http server -->
        <dependency>
            <groupId>org.nanohttpd</groupId>
            <artifactId>nanohttpd</artifactId>
            <version>2.2.0</version>
        </dependency>

        <!-- logging -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
        </dependency>

        <!-- logging -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.0.13</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <archive>
                                <manifest>
                                    <mainClass>name.antonsmirnov.apptogether.service.http.HttpSample</mainClass>
                                </manifest>
                            </archive>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

maven clean package 之后,我可以使用java -jar ...-with-dependencies.jar 在本地运行它,我可以导航到 127.0.0.1:5555 并查看响应。

当我将它作为“网络层”托管在 AWS Elastic Beanstalk 上时

我可以在日志中看到它已启动:

-------------------------------------
/var/log/nginx/error.log
-------------------------------------
2018/06/06 19:34:57 [error] 3230#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 5.189.7.39, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5000/", host: "http.us-east-2.elasticbeanstalk.com"
2018/06/06 19:34:58 [error] 3230#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 5.189.7.39, server: , request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:5000/favicon.ico", host: "http.us-east-2.elasticbeanstalk.com", referrer: "http://http.us-east-2.elasticbeanstalk.com/"



-------------------------------------
/var/log/web-1.log
-------------------------------------
19:32:58.043 [main] INFO  HttpSample - Starting at port 5555 ...
19:32:58.062 [main] DEBUG HttpSample - Started



-------------------------------------
/var/log/web-1.error.log
-------------------------------------

但在http://http.us-east-2.elasticbeanstalk.com:5555中无法访问

我在日志中看不到请求(我应该能够在 localhost 上看到像 00:59:25.864 [NanoHttpd Request Processor (#1)] INFO HttpSample$1 - Request from x.y.z.k 这样的东西)。相反,我看到 ERR_CONNECTION_TIMED_OUT 错误。

怎么了?我应该以某种方式为 VPC 配置端口吗?和nginx冲突吗?

【问题讨论】:

【参考方案1】:

我刚刚允许安全组中端口 5555 上的传入请求:

如果我决定使用端口 80,不确定它是否与 nginx 冲突。

【讨论】:

以上是关于如何在 AWS 上托管 nanohttpd java 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何在支持ssl的aws ec2单实例上托管多个网站?

如何使用 Cloudfront 设置 AWS Elastic Beanstalk 以在 PHP 堆栈上托管图像和视频

Ubuntu 上托管的 LAMP 应用程序的 AWS SSL 证书

在 AWS 上托管多个网站 - Amazon Linux EC2

AWS Elastic Beanstalk 使用 Django 在部署的 EC2 服务器上托管 PostgreSQL

在 AWS 上托管时,拒绝为目标域生成登录提示的权限