天天看點

Web開發——部署

對一個Web應用程式來說,除了Servlet、Filter這些邏輯元件,還需要JSP這樣的視圖檔案,外加一堆靜态資源檔案,如CSS、JS等。

合理組織檔案結構非常重要。我們以一個具體的Web應用程式為例:

Web開發——部署

我們把所有的靜态資源檔案放入/static/目錄,在開發階段,有些Web伺服器會自動為我們加一個專門負責處理靜态檔案的Servlet,但如果IndexServlet映射路徑為/,會屏蔽掉處理靜态檔案的Servlet映射。是以,我們需要自己編寫一個處理靜态檔案的FileServlet:

@WebServlet(urlPatterns = "/static/*")
public class FileServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext ctx = req.getServletContext();
        // RequestURI包含ContextPath,需要去掉:
        String urlPath = req.getRequestURI().substring(ctx.getContextPath().length());
        // 擷取真實檔案路徑:
        String filepath = ctx.getRealPath(urlPath);
        if (filepath == null) {
            // 無法擷取到路徑:
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        Path path = Paths.get(filepath);
        if (!path.toFile().isFile()) {
            // 檔案不存在:
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        // 根據檔案名猜測Content-Type:
        String mime = Files.probeContentType(path);
        if (mime == null) {
            mime = "application/octet-stream";
        }
        resp.setContentType(mime);
        // 讀取檔案并寫入Response:
        OutputStream output = resp.getOutputStream();
        try (InputStream input = new BufferedInputStream(new FileInputStream(filepath))) {
            input.transferTo(output);
        }
        output.flush();
    }
}
           

這樣一來,在開發階段,我們就可以友善地高效開發。

類似Tomcat這樣的Web伺服器,運作的Web應用程式通常都是業務系統,是以,這類伺服器也被稱為應用伺服器。應用伺服器并不擅長處理靜态檔案,也不适合直接暴露給使用者。通常,我們在生産環境部署時,總是使用類似Nginx這樣的伺服器充當反向代理和靜态伺服器,隻有動态請求才會放行給應用伺服器,是以,部署架構如下:

Web開發——部署

實作上述功能的Nginx配置檔案如下:

server {
    listen 80;

    server_name www.local.liaoxuefeng.com;

    # 靜态檔案根目錄:
    root /path/to/src/main/webapp;

    access_log /var/log/nginx/webapp_access_log;
    error_log  /var/log/nginx/webapp_error_log;

    # 處理靜态檔案請求:
    location /static {
    }

    # 處理靜态檔案請求:
    location /favicon.ico {
    }

    # 不允許請求/WEB-INF:
    location /WEB-INF {
        return 404;
    }

    # 其他請求轉發給Tomcat:
    location / {
        proxy_pass       http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
           

使用Nginx配合Tomcat伺服器,可以充分發揮Nginx作為網關的優勢,既可以高效處理靜态檔案,也可以把https、防火牆、限速、反爬蟲等功能放到Nginx中,使得我們自己的WebApp能專注于業務邏輯。

小結

部署Web應用程式時,要設計合理的目錄結構,同時考慮開發模式需要便捷性,生産模式需要高性能。

繼續閱讀