介绍
今天的高流量Web应用程序由流畅的快速响应Web服务器,可扩展的企业级数据库和由功能丰富的脚本语言提供的动态内容提供支持。 典型的Linux Web应用程序栈遵循LAMP架构(Linux,Apache,MySQL和PHP / Python)。 广泛的教程向我们展示了如何在单个服务器中安装和配置这些组件。
这在现实生活中很少见。 在专业的三层架构中,数据库后端将在其自己的服务器中被隔离; web服务器将其请求发送到作为数据库和网站之间的中间件的应用层。
尽管Apache仍是迄今为止最广泛使用的Web服务器,但Nginx已经因其小占地面积和快速响应时间而迅速获得普及。 MySQL的社区版仍然是数据库的常用选择,但许多网站也使用另一个称为PostgreSQL的开源数据库平台。
目标
在本教程中,我们将在两层架构中创建一个简单的Web应用程序。 我们的两个节点的基本操作系统将是CentOS 7.该站点将由一个Nginx Web服务器运行PHP代码与一个PostgreSQL数据库。
我们将使用“从头开始”的方法,而不是采用在其他LAMP或LEMP教程中看到的“自上而下”方法:我们将首先创建数据库层,然后创建Web服务器,然后查看Web服务器如何连接到数据库。
我们将这个配置称为LEPP(Linux,Nginx,PHP,PostgreSQL)。
先决条件
要遵循本教程,您需要以下内容:
- 两个CentOS 7 Droplet,至少有2GB RAM和2个CPU内核,每个内核用于数据库服务器和Web服务器。
我们将把这些机器的IP地址your_db_server_ip
和your_web_server_ip
分别; 您可以在DigitalOcean控制面板上找到这些机器的实际IP地址。
- Sudo非root用户在两个Droplets。 要这样设置,请按照本教程 。
第一步 - 安装PostgreSQL
在这一步中,我们将在数据库服务器上安装PostgreSQL。
连接到空的,刚安装的CentOS 7盒,你想要安装PostgreSQL。 它的存储库默认没有CentOS 7,所以我们需要首先下载yum存储库RPM。
sudo wget http://yum.postgresql.org/9.4/redhat/rhel-7Server-x86_64/pgdg-centos94-9.4-1.noarch.rpm
保存RPM后,安装存储库。
sudo yum install pgdg-centos94-9.4-1.noarch.rpm -y
最后,安装PostgreSQL 9.4服务器及其contrib模块。
sudo yum install postgresql94-server postgresql94-contrib -y
第二步 - 配置PostgreSQL
在这一步中,我们将为PostgreSQL定制一些安装后配置。
在CentOS 7,PostgreSQL的9.4数据和配置文件的默认位置是/var/lib/pgsql/9.4/data/
和程序二进制的位置/usr/pgsql-9.4/bin/
。 数据目录在开始时为空。 我们将需要运行initdb
程序初始化数据库集群和创造必要的文件吧:
sudo /usr/pgsql-9.4/bin/postgresql94-setup initdb
一旦数据库集群已初始化,将有一个名为postgresql.conf
的数据文件夹,这是PostgreSQL的主配置文件。 我们将更改此文件中的两个参数。 使用vi
或你喜欢的文本编辑器,打开文件进行编辑。
sudo vi /var/lib/pgsql/9.4/data/postgresql.conf
并更改以下行:
- 更改
# listen_addresses = ' localhost '
来listen_addresses = '*'
- 更改
# port = 5432
到port = 5432
第一个参数指定数据库服务器将侦听的IP地址。 作为安全措施,开箱即用的Postgres安装仅允许本地主机连接。 将此更改为“*”意味着Postgres将监听来自任何来源的流量。 第二个参数已通过取消注释标记(#)启用; 它指定Postgres的默认端口。
保存并退出文件。
接下来,我们将编辑pg_hba.conf
,这是PostgreSQL的基于主机的访问(HBA)配置文件。 它指定哪些主机和IP范围可以连接到数据库服务器。 每个条目指定连接是可以在本地还是远程(主机),它可以连接到哪个数据库,它可以连接到哪个用户,请求可以来自哪个IP块,以及应该使用什么认证模式。 与任何这些条目不匹配的任何连接请求都将被拒绝。
开放pg_hba.conf
进行编辑。
sudo vi /var/lib/pgsql/9.4/data/pg_hba.conf
滚动到文件的底部,并添加以下行:
host all all your_web_server_ip/32 md5
这行告诉PostgreSQL的接受来自IP地址只有到来的数据库连接your_web_server_ip
使用密码认证标准MD5校验。 可以作为任何用户对任何数据库进行连接。
保存并退出文件。
接下来,启动Postgres服务:
sudo systemctl start postgresql-9.4.service
然后启用它:
sudo systemctl enable postgresql-9.4.service
要检查数据库服务器是否正在接受连接,我们可以查看最新的Postgres日志文件的最后几行。 数据库错误日志保存在/var/lib/pgsql/9.4/data/pg_log
目录。 运行以下命令查看此目录中的文件。
sudo ls -l /var/lib/pgsql/9.4/data/pg_log
日志文件名的模式postgresql- day_of_week .log
(例如, postgresql-Wed.log
)。 查找对应于当天的日志文件,并查看最新日志文件的最后几行。
sudo tail -f -n 20 /var/lib/pgsql/9.4/data/pg_log/postgresql-day_of_week.log
输出应该显示类似以下内容:
...
< 2015-02-26 21:32:24.159 EST >LOG: database system is ready to accept connections
< 2015-02-26 21:32:24.159 EST >LOG: autovacuum launcher started
按CTRL + C停止从输出tail
命令。
第三步 - 更新数据库服务器防火墙
我们还需要允许Postgres数据库流量通过防火墙。 CentOS 7实现了通过一个动态防火墙firewalld
守护进程; 该服务不需要重新启动才能使更改生效。 该firewalld
服务应该在系统启动时自动启动,但它总是好的检查。
sudo firewall-cmd --state
默认状态应该是running
,但如果not running
启动它:
sudo systemctl start firewalld
接下来,添加端口5432的规则。这是PostgreSQL数据库流量的端口。
sudo firewall-cmd --permanent --zone=public --add-port=5432/tcp
然后重新加载防火墙。
sudo firewall-cmd --reload
第四步 - 创建和填充数据库
在这一步中,我们将创建一个数据库并向其中添加一些数据。 这是我们的Web应用程序将动态提取和显示的数据。
第一步就是要改变Postgres超级用户,被称为Postgres的 ,第一次安装的PostgreSQL时创建的密码。 最好的用户密码从Postgres而不是操作系统提示更改。 要做到这一点,切换到postgres用户:
sudo su - postgres
这将改变命令提示符-bash-4.2$
。 接下来,启动内置的客户端工具。
psql
默认情况下,这会将postgres用户记录到Postgres数据库。 您提示将变为postgres=#
,psql的提示,而不是一个操作系统提示。 发出\password
现在命令将导致提示要求更改密码。
\password
为Postgres用户提供安全的密码。
接下来,创建一个数据库,称为产品 :
CREATE DATABASE product;
然后连接到产品数据库:
\connect product;
接下来,在数据库中创建名为所属类别表:
CREATE TABLE product_list (id int, product_name varchar(50));
每次运行以下命令之一。 每个命令将一个记录添加到product_list
表。
INSERT INTO product_list VALUES (1, 'Book');
INSERT INTO product_list VALUES (2, 'Computer');
INSERT INTO product_list VALUES (3, 'Desk');
最后,检查数据是否正确添加。
SELECT * FROM product_list;
输出应如下所示:
id | product_name
----+--------------
1 | Book
2 | Computer
3 | Desk
(3 rows)
这就是我们在数据库服务器上需要做的; 您现在可以断开它。
第五步 - 安装Nginx
接下来,我们将在其他Droplet中安装和配置一个Nginx Web服务器。 连接到另一个空的,刚安装的CentOS 7盒。
像PosgreSQL一样,Nginx存储库默认不随CentOS 7一起提供。 我们将需要首先下载yum存储库RPM。
sudo wget http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
保存RPM后,安装存储库。
sudo yum install nginx-release-centos-7-0.el7.ngx.noarch.rpm -y
最后,安装Nginx Web服务器。
sudo yum install nginx -y
第六步 - 更新Web服务器防火墙
在此步骤中,我们将配置防火墙以允许Nginx流量,并自定义一些Nginx配置。
我们需要允许HTTP / HTTPS流量通过防火墙。 和以前一样,检查firewalld
服务正在运行。
sudo firewall-cmd --state
默认状态应该是running
,但如果它not running
,启动它:
sudo systemctl start firewalld
现在为端口80(HTTP)添加防火墙规则:
sudo firewall-cmd --permanent --zone=public --add-port=80/tcp
为端口443(HTTPS)添加另一个:
sudo firewall-cmd --permanent --zone=public --add-port=443/tcp
然后,重新加载防火墙。
sudo firewall-cmd --reload
接下来,启动Nginx。
sudo systemctl start nginx.service
并启用它。
sudo systemctl enable nginx.service
将浏览器指向服务器的IP地址应该显示默认网页:
第七步 - 配置Nginx
在此步骤中有两个相关的Nginx配置文件。 第一个是主配置文件,第二个是特定于站点的配置文件。
通用配置文件控制整个服务器的特性。 Nginx可以服务于许多网站,每个网站被称为服务器块(Apache称为虚拟主机或虚拟主机)。 每个站点的配置由服务器块配置文件控制。
让我们编辑主服务器配置文件。
sudo vi /etc/nginx/nginx.conf
在文件的第二行,改变worker_processes
1参数2。这告诉nginx的工作线程使用所有可用的CPU核心。 保存并退出文件。
我们不会在这里创建服务块。 相反,我们将在默认服务器块中创建Web应用程序,所以让我们编辑默认的服务器块配置文件。
sudo vi /etc/nginx/conf.d/default.conf
内容看起来像这样。 将编辑的零件突出显示。
server {
listen 80;
server_name localhost;
...
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
...
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
...
}
进行以下编辑:
设置
server_name
从localhost
到your_web_server_ip
。添加
index.php
到index
的指令,所以它读取index.php index.html index.htm
。删除
location / {
和}
包含线root
和index
指令。 没有这个变化你会发现你的网页浏览器和Nginx的错误日志记录的消息一样不显示"Unable to open primary script: /etc/nginx/html/index.php (No such file or directory)"
取消对
location ~ \.php$
下, 通过PHP脚本块(包括最后的大括号), 以FastCGI的服务器注释。删除同一下根指令
location ~ \.php$
块。更改fastcgi_pass指令值从
127.0.0.1:9000
到unix:/var/run/php-fpm/php5-fpm.sock
。 这是为了确保PHP FastCGI进程管理器(我们将在下一步中安装)将侦听Unix套接字。更改TE
fastcgi_param
指令值SCRIPT_FILENAME $document_root$fastcgi_script_name
。 这告诉Web服务器PHP脚本文件将保存在文档根目录下。
完成编辑后,文件应如下所示:
server {
listen 80;
server_name your_web_server_ip;
...
root /usr/share/nginx/html;
index index.php index.html index.htm;
...
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
...
保存并退出文件,然后启动Web服务器。
sudo systemctl restart nginx.service
第八步 - 安装PHP
我们现在将在Web服务器中安装PHP的三个组件:PHP引擎本身,FastCGI进程管理器(FPM)和PostgreSQL的PHP模块。
首先,安装PHP。
sudo yum install php -y
接下来我们将安装FastCGI过程管理器(FPM),这是PHP自己的FastCGI实现。 FastCGI就像一个加载项在你的web服务器的顶部。 它独立运行,并通过将它们合并在一个进程中来加速用户请求,从而加快响应时间。
sudo yum install php-fpm -y
最后,安装PHP Postgres模块:
sudo yum install php-pgsql -y
第九步 - 配置PHP
在这一步,我们将配置PHP。
打开PHP配置文件。
sudo vi /etc/php.ini
进行以下更改:
更改
expose_php = On
到expose_php = Off
。 将此参数设置为Off
只是意味着PHP不其签名添加到Web服务器的标题和不公开该服务器正在运行PHP的事实。改变
;cgi.fix_pathinfo=0
到;cgi.fix_pathinfo=1
。
保存并退出文件。 接下来,编辑FPM配置文件。
sudo vi /etc/php-fpm.d/www.conf
进行以下更改:
更改
user = apache
给user = nginx
。同样,改变
group = apache
到group = nginx
。更改
listen = 127.0.0.1:9000
来listen = /var/run/php-fpm/php5-fpm.sock
。 我们在Nginx默认服务器块的配置文件中设置相同的值。
保存并退出vi。 下一步启动PHP-FPM。
sudo systemctl start php-fpm.service
然后启用它。
sudo systemctl enable php-fpm.service
第十步 - 创建Web应用程序
我们有所有的服务器组件准备在两个节点。 现在是我们创建我们的PHP应用程序。 创建一个文件名为index.php
中/usr/share/nginx/html
。
sudo vi /usr/share/nginx/html/index.php
粘贴以下内容。 确保您分别用数据库服务器IP地址和Postgres密码替换突出显示的变量。
<html>
<head>
<title>LEPP Stack Example</title>
</head>
<body>
<h4>LEPP (Linux, Nginx, PHP, PostgreSQL) Sample Page</h4>
<hr/>
<p>Hello and welcome. This web page is dynamically showing a product list from a PostgreSQL database</p>
<?php
$host = "your_db_server_ip";
$user = "postgres";
$password = "your_postgres_password";
$dbname = "product";
$con = pg_connect("host=$host dbname=$dbname user=$user password=$password")
or die ("Could not connect to server\n");
$query = "SELECT * FROM product_list";
$resultset = pg_query($con, $query) or die("Cannot execute query: $query\n");
$rowcount = pg_numrows($resultset);
for($index = 0; $index < $rowcount; $index++) {
$row = pg_fetch_array($resultset, $index);
echo $row["id"], "-", $row["product_name"];
echo "<br>";
}
?>
</body>
</html>
这是一个嵌入PHP代码的简单网页。 首先,它为数据库连接字符串定义了多个参数。 接下来,一个连接(通过指定$con
)对数据库服务器进行。 查询是指定的,它再对所属类别表执行。 它遍历返回的结果,并在新行中打印每行的内容。
一旦文件被写入并保存,打开浏览器窗口,并指出它your_web_server_ip
。 内容应该如下所示:
结论
我们从头开始构建了两个框,安装和配置了所有必要的软件,然后在其中部署了我们的Web应用程序。 生产会有额外的复杂性,例如添加外部防火墙和负载平衡器,但这是一个坚实的基本配置,您可以使用它来开始。 请享用!