在Linux上完整搭建Apache HTTP服务器的详细步骤
作者:知远漫谈
引言
Apache HTTP Server(简称 Apache)是世界上最流行的 Web 服务器软件之一。它开源、稳定、功能强大,支持模块化扩展,适用于从小型个人网站到大型企业级应用的各种场景。本文将带你从零开始在 Linux 系统上完整搭建 Apache 服务器,并结合 Java Web 应用进行实战部署。
为什么选择 Apache?
在开始动手之前,我们先来了解下 Apache 的优势:
- ✅ 成熟稳定:自1995年发布以来,Apache 已经经历了近30年的考验。
- ✅ 高度可配置:支持 .htaccess 文件、虚拟主机、URL重写等高级功能。
- ✅ 模块丰富:通过加载不同模块(如 mod_ssl、mod_rewrite)实现功能扩展。
- ✅ 社区活跃:拥有庞大的开发者社区和详尽的官方文档。
- ✅ 跨平台兼容:不仅支持 Linux,也支持 Windows、macOS 等系统。
小贴士:虽然 Nginx 在静态资源处理和高并发方面表现更优,但 Apache 在动态内容处理、.htaccess 控制、与 PHP/Python 集成等方面依然具有不可替代的优势。
环境准备
本文以 Ubuntu 22.04 LTS 为例进行演示,其他主流发行版(如 CentOS、Debian)操作类似,仅包管理命令略有不同。
检查系统版本
lsb_release -a
输出示例:
No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy
更新系统包
sudo apt update && sudo apt upgrade -y
确保你的系统是最新的,避免因依赖问题导致安装失败。
安装 Apache HTTP Server
Ubuntu 默认仓库中包含 Apache,我们可以直接使用 apt 安装:
sudo apt install apache2 -y
安装完成后,Apache 服务会自动启动。你可以通过以下命令检查状态:
sudo systemctl status apache2
你应该看到类似如下输出:
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2024-06-10 10:00:00 UTC; 2min ago
验证安装是否成功
打开浏览器,访问你的服务器 IP 地址或域名:
http://your-server-ip
如果看到 “Apache2 Ubuntu Default Page” 页面,说明安装成功!
你也可以在命令行中使用 curl 测试:
curl http://localhost
Apache 目录结构详解
理解 Apache 的目录结构对后续配置至关重要:
# 主配置文件目录 /etc/apache2/ # 站点配置(启用的站点) /etc/apache2/sites-enabled/ # 可用站点配置模板 /etc/apache2/sites-available/ # 模块配置 /etc/apache2/mods-enabled/ /etc/apache2/mods-available/ # Apache 主配置文件 /etc/apache2/apache2.conf # 端口配置 /etc/apache2/ports.conf # 默认网页根目录 /var/www/html/ # 日志目录 /var/log/apache2/
提示:Ubuntu 使用 a2ensite 和 a2enmod 命令来启用站点和模块,这些命令本质是在 sites-enabled 和 mods-enabled 中创建符号链接。
基础配置优化
修改默认监听端口(可选)
编辑 /etc/apache2/ports.conf:
sudo nano /etc/apache2/ports.conf
默认监听 80 端口:
Listen 80
如果你想改为 8080:
Listen 8080
然后重启 Apache:
sudo systemctl restart apache2
注意:修改端口后需确保防火墙允许新端口访问。
配置防火墙(UFW)
如果你启用了 UFW 防火墙,需要放行 HTTP 端口:
sudo ufw allow 'Apache Full' # 或者指定端口 sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw reload
查看状态:
sudo ufw status
配置虚拟主机(Virtual Host)
虚拟主机允许你在同一台服务器上托管多个网站。
创建网站目录
假设我们要部署一个名为 example.com 的网站:
sudo mkdir -p /var/www/example.com/public_html sudo chown -R $USER:$USER /var/www/example.com/public_html sudo chmod -R 755 /var/www/example.com
创建测试页面
nano /var/www/example.com/public_html/index.html
内容如下:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Example.com!</title>
</head>
<body>
<h1>Success! The example.com virtual host is working!</h1>
</body>
</html>创建虚拟主机配置文件
sudo nano /etc/apache2/sites-available/example.com.conf
添加以下内容:
<VirtualHost *:80>
ServerAdmin admin@example.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html
ErrorLog ${APACHE_LOG_DIR}/example_error.log
CustomLog ${APACHE_LOG_DIR}/example_access.log combined
<Directory /var/www/example.com/public_html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>启用站点并重启 Apache
sudo a2ensite example.com.conf sudo systemctl reload apache2
提示:a2ensite 是 “Apache2 Enable Site” 的缩写。
启用重要模块
Apache 的强大之处在于其模块化架构。以下是几个常用模块:
启用 rewrite 模块(用于 URL 重写)
sudo a2enmod rewrite sudo systemctl restart apache2
启用 SSL 模块(HTTPS 支持)
sudo a2enmod ssl sudo systemctl restart apache2
启用 headers 和 expires(性能优化)
sudo a2enmod headers sudo a2enmod expires sudo systemctl restart apache2
性能调优配置
编辑主配置文件:
sudo nano /etc/apache2/apache2.conf
在文件末尾添加以下优化配置:
# 启用 KeepAlive 以复用 TCP 连接
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
# MPM Prefork 配置(适用于 PHP 等非线程安全应用)
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
# 启用压缩
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
</IfModule>
# 缓存静态资源
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresDefault "access plus 2 days"
</IfModule>
重启服务使配置生效:
sudo systemctl restart apache2
使用 Mermaid 图表展示请求处理流程
Apache 处理 HTTP 请求的过程可以用以下流程图表示:

这个流程图展示了 Apache 如何接收请求、匹配虚拟主机、应用重写规则,最后返回响应的全过程。
部署 Java Web 应用
虽然 Apache 本身不直接运行 Java 应用,但我们可以通过反向代理的方式,将请求转发给后端的 Tomcat 或 Spring Boot 应用。
方案一:Apache + Tomcat(推荐传统项目)
1. 安装 Tomcat
sudo apt install tomcat9 tomcat9-admin -y sudo systemctl start tomcat9 sudo systemctl enable tomcat9
2. 部署 WAR 包
将你的 Java Web 应用打包为 .war 文件,放入:
sudo cp your-app.war /var/lib/tomcat9/webapps/
Tomcat 会自动解压并部署。
3. 配置 Apache 反向代理
启用 proxy 模块:
sudo a2enmod proxy sudo a2enmod proxy_http sudo systemctl restart apache2
编辑虚拟主机配置:
sudo nano /etc/apache2/sites-available/java-app.conf
<VirtualHost *:80>
ServerName javaapp.yourdomain.com
ProxyPreserveHost On
ProxyPass / http://localhost:8080/your-app/
ProxyPassReverse / http://localhost:8080/your-app/
ErrorLog ${APACHE_LOG_DIR}/javaapp_error.log
CustomLog ${APACHE_LOG_DIR}/javaapp_access.log combined
</VirtualHost>启用站点:
sudo a2ensite java-app.conf sudo systemctl reload apache2
现在访问 http://javaapp.yourdomain.com 就能看到你的 Java 应用了!
方案二:Apache + Spring Boot(现代微服务架构)
Spring Boot 内嵌 Tomcat,可独立运行。我们只需配置 Apache 作为前端代理。
示例 Java 代码:Spring Boot Controller
// 📄 DemoController.java
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("/api/hello")
public ApiResponse hello() {
return new ApiResponse("Hello from Spring Boot via Apache!", System.currentTimeMillis());
}
@GetMapping("/health")
public HealthCheck health() {
return new HealthCheck(true, "UP", "All systems operational");
}
}
// 📄 ApiResponse.java
package com.example.demo.model;
public class ApiResponse {
private String message;
private long timestamp;
public ApiResponse(String message, long timestamp) {
this.message = message;
this.timestamp = timestamp;
}
// Getters and Setters
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
public long getTimestamp() { return timestamp; }
public void setTimestamp(long timestamp) { this.timestamp = timestamp; }
}
// 📄 HealthCheck.java
package com.example.demo.model;
public class HealthCheck {
private boolean success;
private String status;
private String details;
public HealthCheck(boolean success, String status, String details) {
this.success = success;
this.status = status;
this.details = details;
}
// Getters and Setters
public boolean isSuccess() { return success; }
public void setSuccess(boolean success) { this.success = success; }
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public String getDetails() { return details; }
public void setDetails(String details) { this.details = details; }
}启动 Spring Boot 应用
java -jar your-springboot-app.jar --server.port=8081
配置 Apache 代理
<VirtualHost *:80>
ServerName api.yourdomain.com
# 代理 API 请求
ProxyPass /api http://localhost:8081/api
ProxyPassReverse /api http://localhost:8081/api
# 代理健康检查
ProxyPass /health http://localhost:8081/health
ProxyPassReverse /health http://localhost:8081/health
# 静态资源由 Apache 直接提供(可选)
Alias /static /var/www/api.yourdomain.com/static
<Directory /var/www/api.yourdomain.com/static>
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/api_error.log
CustomLog ${APACHE_LOG_DIR}/api_access.log combined
# 启用 CORS(如需)
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
</VirtualHost>这样,Apache 负责静态资源和负载均衡,Spring Boot 专注业务逻辑,架构清晰高效。
启用 HTTPS(SSL/TLS)
安全是现代 Web 的基本要求。我们可以使用免费的 Let’s Encrypt 证书。
安装 Certbot
sudo apt install certbot python3-certbot-apache -y
获取并安装证书
sudo certbot --apache -d example.com -d www.example.com
Certbot 会自动修改 Apache 配置并重启服务。
自动续期
Let’s Encrypt 证书有效期为 90 天,设置自动续期:
sudo crontab -e
添加一行:
0 12 * * * /usr/bin/certbot renew --quiet
这将在每天中午检查并自动续期即将过期的证书。
安全加固建议
1. 隐藏 Apache 版本信息
编辑 /etc/apache2/conf-available/security.conf:
ServerTokens Prod ServerSignature Off
2. 禁用目录浏览
确保所有 <Directory> 块中没有 Indexes 选项:
Options -Indexes +FollowSymLinks
3. 限制 HTTP 方法
<LimitExcept GET POST HEAD>
Require all denied
</LimitExcept>4. 设置安全头
在虚拟主机配置中添加:
Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';"
监控与日志分析
查看实时访问日志
sudo tail -f /var/log/apache2/access.log
使用 GoAccess 分析日志(推荐)
安装 GoAccess:
sudo apt install goaccess -y
生成 HTML 报告:
goaccess /var/log/apache2/access.log -o report.html --log-format=COMBINED
你也可以配置定时任务自动生成日报:
# 每天凌晨 2 点生成报告 0 2 * * * goaccess /var/log/apache2/access.log -o /var/www/html/stats/report-$(date +\%Y-\%m-\%d).html --log-format=COMBINED
自动化部署脚本示例
下面是一个 Bash 脚本,用于自动化部署 Java Web 应用:
#!/bin/bash
# deploy-java-app.sh
APP_NAME="my-java-app"
APP_VERSION="1.0.0"
TOMCAT_HOME="/var/lib/tomcat9"
WEBAPPS_DIR="$TOMCAT_HOME/webapps"
WAR_FILE="$APP_NAME-$APP_VERSION.war"
echo "🚀 开始部署 $APP_NAME v$APP_VERSION"
# 1. 停止 Tomcat
echo "🛑 停止 Tomcat 服务..."
sudo systemctl stop tomcat9
# 2. 删除旧版本
echo "🗑️ 清理旧版本..."
sudo rm -rf "$WEBAPPS_DIR/$APP_NAME"
sudo rm -f "$WEBAPPS_DIR/$APP_NAME.war"
# 3. 复制新 WAR 包
echo "📦 部署新版本..."
sudo cp "./build/libs/$WAR_FILE" "$WEBAPPS_DIR/"
# 4. 设置权限
echo "🔐 设置权限..."
sudo chown tomcat:tomcat "$WEBAPPS_DIR/$WAR_FILE"
sudo chmod 644 "$WEBAPPS_DIR/$WAR_FILE"
# 5. 启动 Tomcat
echo "✅ 启动 Tomcat 服务..."
sudo systemctl start tomcat9
# 6. 等待部署完成
echo "⏳ 等待应用部署完成 (最多 60 秒)..."
for i in {1..12}; do
if [ -d "$WEBAPPS_DIR/$APP_NAME" ]; then
echo "🎉 应用部署成功!"
break
fi
sleep 5
done
# 7. 检查应用状态
echo "🔍 检查应用健康状态..."
sleep 10
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/$APP_NAME/health)
if [ "$STATUS_CODE" == "200" ]; then
echo "💚 应用健康检查通过!状态码: $STATUS_CODE"
else
echo "💔 应用健康检查失败!状态码: $STATUS_CODE"
exit 1
fi
echo "✅ 部署完成!访问地址: http://your-domain.com/$APP_NAME"
保存为 deploy.sh,赋予执行权限:
chmod +x deploy.sh ./deploy.sh
Java 客户端测试代码
编写一个简单的 Java 客户端来测试部署的应用:
// 📄 ApacheIntegrationTest.java
package com.example.test;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
public class ApacheIntegrationTest {
private static final String BASE_URL = "http://your-domain.com/api";
public static void main(String[] args) {
ApacheIntegrationTest test = new ApacheIntegrationTest();
System.out.println("🧪 开始测试 Apache + Spring Boot 集成...");
// 测试健康检查
test.testHealthEndpoint();
// 测试 Hello 接口
test.testHelloEndpoint();
// 测试错误处理
test.testNotFoundEndpoint();
System.out.println("✅ 所有测试完成!");
}
private void testHealthEndpoint() {
System.out.println("\n=== 测试健康检查接口 ===");
try {
String response = sendGetRequest(BASE_URL + "/health");
Gson gson = new Gson();
JsonObject json = gson.fromJson(response, JsonObject.class);
boolean success = json.get("success").getAsBoolean();
String status = json.get("status").getAsString();
if (success && "UP".equals(status)) {
System.out.println("💚 健康检查通过!状态: " + status);
System.out.println("📊 详细信息: " + json.get("details").getAsString());
} else {
System.out.println("💔 健康检查失败!状态: " + status);
}
} catch (Exception e) {
System.out.println("❌ 健康检查异常: " + e.getMessage());
}
}
private void testHelloEndpoint() {
System.out.println("\n=== 测试 Hello 接口 ===");
try {
String response = sendGetRequest(BASE_URL + "/hello");
Gson gson = new Gson();
JsonObject json = gson.fromJson(response, JsonObject.class);
String message = json.get("message").getAsString();
long timestamp = json.get("timestamp").getAsLong();
System.out.println("💬 收到消息: " + message);
System.out.println("⏱️ 时间戳: " + timestamp);
System.out.println("✅ Hello 接口测试通过!");
} catch (Exception e) {
System.out.println("❌ Hello 接口测试失败: " + e.getMessage());
}
}
private void testNotFoundEndpoint() {
System.out.println("\n=== 测试 404 错误处理 ===");
try {
String response = sendGetRequest(BASE_URL + "/nonexistent-endpoint");
System.out.println("⚠️ 意外成功!应该返回 404");
} catch (Exception e) {
System.out.println("✅ 正确捕获 404 错误: " + e.getMessage());
}
}
private String sendGetRequest(String urlString) throws Exception {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("User-Agent", "Java Apache Integration Test Client");
conn.setRequestProperty("Accept", "application/json");
int responseCode = conn.getResponseCode();
System.out.println("🌐 请求 URL: " + urlString);
System.out.println("🔢 响应码: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
StringBuilder response = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
response.append(line);
}
in.close();
return response.toString();
} else {
throw new RuntimeException("HTTP Error: " + responseCode);
}
}
}要运行此测试,你需要添加 Gson 依赖:
<!-- pom.xml -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>使用 Mermaid 展示架构拓扑
以下是 Apache + Java 应用的典型生产架构:

这种架构提供了高可用性、负载均衡和横向扩展能力。
故障排查技巧
1. 检查 Apache 配置语法
sudo apache2ctl configtest
2. 查看错误日志
sudo tail -50 /var/log/apache2/error.log
3. 检查端口占用
sudo netstat -tlnp | grep :80
4. 测试本地连接
curl -I http://localhost
5. 检查 SELinux(CentOS/RHEL)
getenforce # 如果是 Enforcing,可能需要调整策略 sudo setsebool -P httpd_can_network_connect 1
最佳实践总结
- 使用虚拟主机:每个网站独立配置,便于管理和维护。
- 启用 HTTPS:保护用户数据安全,提升 SEO 排名。
- 定期备份配置:
cp -r /etc/apache2 /backup/apache2-$(date +%Y%m%d) - 监控日志:设置日志轮转,避免磁盘空间耗尽。
- 性能测试:使用
ab(Apache Bench)或wrk进行压力测试。 - 安全更新:定期更新系统和 Apache 版本。
结语
通过本文,你已经掌握了在 Linux 上搭建 Apache HTTP 服务器的完整流程,包括基础安装、虚拟主机配置、性能优化、安全加固,以及与 Java Web 应用的集成部署。Apache 作为久经考验的 Web 服务器,配合现代 Java 框架,依然能够构建高性能、高可用的 Web 应用系统。
记住,技术选型没有绝对的对错,关键是根据项目需求选择合适的工具。Apache + Java 的组合在企业级应用、内容管理系统、API 网关等场景中仍然具有强大的生命力。
现在,轮到你动手实践了!部署你的第一个 Java Web 应用,让它运行在自己搭建的 Apache 服务器上吧!💪
提示:技术之路永无止境,保持好奇心,持续学习,你将成为更优秀的开发者!
常见问题解答(FAQ)
Q1: Apache 和 Nginx 哪个更好?
A: 没有绝对答案。Nginx 在静态文件处理和高并发方面表现优异;Apache 在动态内容处理、.htaccess 控制、模块生态方面更强大。很多生产环境采用 Nginx 做前端 + Apache 做后端的混合架构。
Q2: 如何提高 Apache 性能?
A: 主要方法包括:
- 启用压缩(mod_deflate)
- 设置缓存头(mod_expires)
- 使用 MPM 事件模式(mpm_event_module)
- 启用 KeepAlive
- 限制不必要的模块
- 使用 CDN 加速静态资源
Q3: Apache 能直接运行 Java 吗?
A: 不能。Apache 是 Web 服务器,不是应用服务器。Java 应用需要运行在 Tomcat、Jetty、Undertow 等 Servlet 容器中,Apache 通过反向代理将请求转发给它们。
Q4: 如何监控 Apache 性能?
A: 可以使用:
mod_status模块查看实时状态apachetop工具监控实时请求- Prometheus + Grafana 构建可视化监控
- ELK Stack(Elasticsearch+Logstash+Kibana)分析日志
Q5: Apache 支持 HTTP/2 吗?
A: 支持!需要启用 mod_http2 模块,并在虚拟主机配置中添加:
Protocols h2 http/1.1
同时需要 HTTPS 支持,因为主流浏览器只支持 HTTP/2 over TLS。
希望这篇详细的指南能帮助你在 Linux 上成功搭建 Apache HTTP 服务器,并顺利部署 Java Web 应用!
以上就是在Linux上完整搭建Apache HTTP服务器的详细步骤的详细内容,更多关于Linux搭建Apache HTTP服务器的资料请关注脚本之家其它相关文章!
