LAMP 架构: 传统 Web 开发的基石
在早期的 Web 开发领域
随着移动互联网的迅猛发展
以一个简单的聊天室系统为例
LAMP 架构之所以在早期广受欢迎
然而
在如今多终端设备共存的时代
前后端分离的诞生: 解耦与协作的必然
在移动互联网时代
前后端分离模式正是为了解决这些问题而应运而生
这种模式还实现了技术栈的独立
以电商平台为例
引入 Node.js 中间层进一步优化了整个架构
前后端分离的实践要点
接口规范与协作模式
在前后端分离的架构中
在开发过程中
为了确保前后端对接口的理解一致
技术架构设计
前端架构在前后端分离模式下
后端架构则趋向于微服务化
在部署方案上
性能优化
性能优化是前后端分离架构中不可忽视的重要环节
CDN
懒加载技术则是针对页面中的图片
后端优化同样至关重要
随着数据量的不断增加
Node.js 中间层在性能优化方面也有着独特的作用
从 LAMP 到分离架构的演进示例
为了更直观地理解从 LAMP 到前后端分离架构的演进
在 LAMP 架构中
<?php
// 连接数据库
$conn = mysqli_connect("localhost", "username", "password", "chat_database");
// 查询聊天记录
$messages = mysqli_query($conn, "SELECT * FROM chat");
// 循环输出聊天记录
while ($row = mysqli_fetch_array($messages)) {
echo "<div>{$row['content']}</div>";
}
// 关闭数据库连接
mysqli_close($conn);
?>
在这段代码中
而在前后端分离架构下
<template>
<div>
<div v-for="message in messages" :key="message.id">{{ message.content }}</div>
<form @submit.prevent="sendMessage">
<input v-model="newMessage" placeholder="输入消息">
<button type="submit">发送</button>
</form>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return { messages: [], newMessage: '' };
},
mounted() { this.fetchMessages(); },
methods: {
async fetchMessages() {
try {
const response = await axios.get('/api/messages');
this.messages = response.data;
} catch (error) {
console.error('获取聊天记录失败', error);
}
},
async sendMessage() {
try {
await axios.post('/api/messages', { content: this.newMessage });
this.newMessage = '';
this.fetchMessages();
} catch (error) {
console.error('发送消息失败', error);
}
}
}
};
</script>
在后端
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api")
public class ChatController {
private final ChatService chatService;
public ChatController(ChatService chatService) {
this.chatService = chatService;
}
@GetMapping("/messages")
public List<Message> getMessages() {
return chatService.getMessages();
}
@PostMapping("/messages")
public Message sendMessage(@RequestBody Message message) {
return chatService.sendMessage(message);
}
}
在前后端分离架构中
const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
// 模拟聊天消息存储
let messages = [];
io.on('connection', (socket) => {
console.log('用户已连接');
// 发送历史消息给新连接的用户
socket.emit('history-messages', messages);
socket.on('send-message', (message) => {
messages.push(message);
io.emit('receive-message', message);
});
socket.on('disconnect', () => {
console.log('用户已断开连接');
});
});
const port = 3000;
http.listen(port, () => {
console.log(`服务器正在运行<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>端口号: ${port}`);
});
从 LAMP 架构演进到前后端分离架构
挑战与解决方案
在从 LAMP 架构向前后端分离架构演进的过程中
跨域问题是前后端分离架构中常见的挑战之一
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600);
}
};
}
}```
也可以通过 Nginx 代理来解决跨域问题<span class="bd-box"><h-char class="bd bd-beg"><h-inner>。</h-inner></h-char></span>Nginx 作为反向代理服务器<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>可以将前端的请求转发到后端服务器<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>并在转发过程中对请求和响应进行处理<span class="bd-box"><h-char class="bd bd-beg"><h-inner>。</h-inner></h-char></span>在 Nginx 的配置文件中<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>通过proxy_pass指令将前端的请求代理到后端的真实地址<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>同时可以添加add_header指令来设置响应头<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>允许跨域请求<span class="bd-box"><h-char class="bd bd-beg"><h-inner>。</h-inner></h-char></span>这样<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>前端通过访问 Nginx 的地址<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>就可以间接访问后端接口<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>避免了跨域问题<span class="bd-box"><h-char class="bd bd-beg"><h-inner>。</h-inner></h-char></span>
```java
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://backend_server;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
}
}
在前后端分离的开发模式下
前后端分离架构还带来了学习成本的挑战
总结
从 LAMP 到前后端分离
解耦作为前后端分离架构的核心价值之一
前后端分离模式极大地提高了开发效率
前后端分离架构还为系统的扩展性提供了有力支持
展望未来
拓展: CentOS快速部署LAMP
CentOS 快速部署 LAMP 环境
以下是为 CentOS 7/8/Stream 系统设计的快速部署步骤
1. 更新系统组件
# 更新系统软件包
sudo yum update -y
# 安装常用工具<span class="bd-box"><h-char class="bd bd-end"><h-inner>(</h-inner></h-char></span>可选<span class="bd-box"><h-char class="bd bd-beg"><h-inner>)</h-inner></h-char></span>
sudo yum install -y wget vim net-tools
2. 安装 Apache
# 安装 Apache
sudo yum install -y httpd
# 启动 Apache 并设置开机自启
sudo systemctl start httpd
sudo systemctl enable httpd
# 验证 Apache 状态
systemctl status httpd
配置防火墙( 若开启)
# 允许 HTTP/HTTPS 流量
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
3. 安装 MySQL/MariaDB
方案 1: 安装 MariaDB( 推荐)
# CentOS 默认仓库包含 MariaDB
sudo yum install -y mariadb-server mariadb
# 启动并设置开机自启
sudo systemctl start mariadb
sudo systemctl enable mariadb
# 运行安全配置脚本
sudo mysql_secure_installation
提示
按需设置 root 密码 : 移除匿名用户 、 禁止远程 root 登录等 、 。
方案 2: 安装 MySQL 8.0( 需添加官方仓库)
# 下载 MySQL Yum 仓库
wget https://dev.mysql.com/get/mysql80-community-release-el7-6.noarch.rpm
# 安装仓库
sudo rpm -ivh mysql80-community-release-el7-6.noarch.rpm
# 安装 MySQL
sudo yum install -y mysql-community-server
# 启动并配置
sudo systemctl start mysqld
sudo systemctl enable mysqld
# 获取临时 root 密码
grep 'temporary password' /var/log/mysqld.log
# 运行安全配置
sudo mysql_secure_installation
4. 安装 PHP
安装基础 PHP 版本
# CentOS 7 默认仓库提供 PHP 5.4<span class="bd-box"><h-char class="bd bd-end"><h-inner>(</h-inner></h-char></span>旧<span class="bd-box"><h-char class="bd bd-beg"><h-inner>)</h-inner></h-char><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>建议升级到新版
# 安装 EPEL 和 Remi 仓库<span class="bd-box"><h-char class="bd bd-end"><h-inner>(</h-inner></h-char></span>PHP 7.4/8.0+<span class="bd-box"><h-char class="bd bd-beg"><h-inner>)</h-inner></h-char></span>
sudo yum install -y epel-release
sudo yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm
# 启用指定 PHP 版本<span class="bd-box"><h-char class="bd bd-end"><h-inner>(</h-inner></h-char></span>例如 PHP 7.4<span class="bd-box"><h-char class="bd bd-beg"><h-inner>)</h-inner></h-char></span>
sudo yum-config-manager --enable remi-php74
# 安装 PHP 及扩展
sudo yum install -y php php-mysqlnd php-gd php-opcache php-mbstring php-json php-xml
验证 PHP
# 创建测试文件
echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php
# 重启 Apache
sudo systemctl restart httpd
访问 http://服务器IP/info.php
5. 验证 LAMP 环境
测试数据库连接
创建 PHP 文件测试 MySQL 连接
<?php
$servername = "localhost";
$username = "root";
$password = "你的MySQL密码";
// 创建连接
$conn = new mysqli($servername, $username, $password);
// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
}
echo "MySQL 连接成功<span class="bd-box"><h-char class="bd bd-beg"><h-inner>!</h-inner></h-char></span>";
?>
保存为 /var/www/html/db_test.php
6. 可选优化
配置虚拟主机
# 创建网站目录
sudo mkdir /var/www/mywebsite
# 编辑 Apache 配置
sudo vim /etc/httpd/conf.d/mywebsite.conf
添加以下内容
<VirtualHost *:80>
ServerAdmin admin@example.com
DocumentRoot "/var/www/mywebsite"
ServerName mywebsite.com
ErrorLog "/var/log/httpd/mywebsite_error.log"
CustomLog "/var/log/httpd/mywebsite_access.log" combined
<Directory "/var/www/mywebsite">
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
重启 Apache
sudo systemctl restart httpd
常见问题解决
访问被拒绝
- 检查防火墙和 SELinux
临时关闭 SELinux: setenforce 0
或配置规则, 。 - 确认文件权限
: sudo chown -R apache:apache /var/www/html
。
- 检查防火墙和 SELinux
PHP 无法连接 MySQL
- 确认安装
php-mysqlnd
扩展。 - 检查 MySQL 用户权限
: GRANT ALL PRIVILEGES ON *.* TO '用户名'@'localhost' IDENTIFIED BY '密码';
- 确认安装
总结
通过上述步骤
- 将网站文件放入
/var/www/html
或自定义目录。 - 配置 HTTPS
使用 Certbot 获取免费 SSL 证书( ) 。 - 安装 phpMyAdmin 管理数据库
: sudo yum install -y phpmyadmin
。
此架构适合传统 PHP 应用