MariaDB 数据库和Nginx服务器

MariaDB 数据库管理

介绍 MariaDB

MariaDB数据库管理系统是MySQL数据库的一个分支,主要由开源社区维护,采用GPL授权许可。

MariaDB数据库完全兼容MySQL数据库,包括API和命令行,使之能轻松的成为MySQL的代替品。

部署 MariaDB

安装 MariaDB
安装
# 安装服务端
[root@server ~]# yum install -y mariadb-server
# 安装客户端
[root@server ~]# yum install -y mariadb
启用并启动服务
[root@server ~]# systemctl enable --now mariadb
配置防火墙
[root@server ~]# firewall-cmd --permanent --add-service=mysql
[root@server ~]# firewall-cmd --reload
加固 MariaDB
[root@server ~]# mysql_secure_installation
连接 MariaDB
[root@server ~ ]# mysql -u root
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and
others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input
statement.
MariaDB [(none)]>
# 数据库服务器本机创建连接用户
[root@server ~ ]# mysql -u root -p
MariaDB [(none)]> create user han@'%' identified by 'redhat';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# 客户端测试
[root@client ~]# mysql -u han -predhat -h server
配置 MariaDB

在 CentOS 7 中, MariaDB 的配置文件采用 “主配置文件 + 细分配置文件” 的分层结构,核心文件集中在 /etc/my.cnf 和 /etc/my.cnf.d/ 目录下

主配置文件

etc/my.cnf, MariaDB 的全局主配置文件,是服务启动时优先读取的配置入口

细分配置文件

/etc/my.cnf.d/ 目录下文件是细分配置文件

MariaDB 中 SQL

连接数据库

mariadb软件包提供了命令mysql,该命令支持对MariaDB数据库的交互式和非交互式访问。

  • 交互式执行时,结果以ASCII表的格式显示。
  • 非交互执行时,结果以制表符分隔的格式显示。

示例:

[root@server ~]# mysql -u root -h localhost -p

首次安装时, MariaDB默认设置root用户帐户无需密码即可进行访问

[root@server ~]# mysql -u root
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.3.17-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input
statement.
# 查看当前登录用户
MariaDB [(none)]> SELECT USER();
+------------------+
| USER() |
+------------------+
| root@localhost |
+------------------+
1 row in set (0.003 sec)
数据库操作
查询数据库列表
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
3 rows in set (0.019 sec)
使用数据库
MariaDB [(none)]> USE mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [mysql]>
创建数据库
MariaDB [mysql]> CREATE DATABASE han;
Query OK, 1 row affected (0.010 sec)
MariaDB [mysql]> USE han;
Database changed
删除数据库
MariaDB [inventory]> DROP DATABASE han;
Query OK, 0 rows affected (0.006 sec)
表操作
环境准备
# 导入备份
[root@server ~]# mysql -uroot -predhat -e 'create database inventory;'
[root@server ~]# mysql -uroot -predhat inventory < inventory.dump
查询表
查询表列表
# 查询表列表
MariaDB [(none)]> USE inventory;
MariaDB [inventory]> SHOW TABLES;
+---------------------+
| Tables_in_inventory |
+---------------------+
| category |
| manufacturer |
| product |
+---------------------+
3 rows in set (0.001 sec)
查询表结构
MariaDB [inventory]> DESCRIBE product;
+-----------------+--------------+------+-----+---------+--------------
--+
| Field | Type | Null | Key | Default | Extra
| +
-----------------+--------------+------+-----+---------+--------------
--+
| id | int(11) | NO | PRI | NULL |
auto_increment |
| name | varchar(100) | NO | | NULL |
|
| price | double | NO | | NULL |
|
| stock | int(11) | NO | | NULL |
|
| id_category | int(11) | NO | | NULL |
|
| id_manufacturer | int(11) | NO | | NULL |
| +
-----------------+--------------+------+-----+---------+--------------
--+
6 rows in set (0.008 sec)
MariaDB [inventory]>
查询表中数据

查询表中所有记录所有字段

MariaDB [inventory]> SELECT * FROM product;
+----+-------------------+---------+-------+-------------+-------------
----+
| id | name | price | stock | id_category |
id_manufacturer |
+----+-------------------+---------+-------+-------------+-------------
----+
| 1 | ThinkServer TS140 | 539.88 | 20 | 2 |
4 |
| 2 | ThinkServer RD630 | 2379.14 | 20 | 2 |
4 |
| 3 | RT-AC68U | 219.99 | 10 | 1 |
3 |
| 4 | X110 64GB | 73.84 | 100 | 3 |
1 |
+----+-------------------+---------+-------+-------------+-------------
----+
4 rows in set (0.004 sec)
MariaDB [inventory]> SELECT * FROM category;
+----+------------+
| id | name |
+----+------------+
| 1 | Networking |
| 2 | Servers |
| 3 | Ssd |
+----+------------+
3 rows in set (0.001 sec)
MariaDB [inventory]> SELECT * FROM manufacturer;
+----+----------+----------------+-------------------+
| id | name | seller | phone_number |
+----+----------+----------------+-------------------+
| 1 | SanDisk | John Miller | +1 (941) 329-8855 |
| 2 | Kingston | Mike Taylor | +1 (341) 375-9999 |
| 3 | Asus | Wilson Jackson | +1 (432) 367-8899 |
| 4 | Lenovo | Allen Scott | +1 (876) 213-4439 |
+----+----------+----------------+-------------------+
4 rows in set (0.001 sec)
MariaDB [inventory]>

查询表中所有记录特定字段

MariaDB [inventory]> SELECT name,price,stock FROM product;
+-------------------+---------+-------+
| name | price | stock |
+-------------------+---------+-------+
| ThinkServer TS140 | 539.88 | 20 |
| ThinkServer RD630 | 2379.14 | 20 |
| RT-AC68U | 219.99 | 10 |
| X110 64GB | 73.84 | 100 |
+-------------------+---------+-------+
4 rows in set (0.001 sec)
WHERE 子句
MariaDB [inventory]> SELECT * FROM product WHERE price > 100;
+----+-------------------+---------+-------+-------------+--------------
---+
| id | name | price | stock | id_category |
id_manufacturer |
+----+-------------------+---------+-------+-------------+--------------
---+
| 1 | ThinkServer TS140 | 539.88 | 20 | 2 |
4 |
| 2 | ThinkServer RD630 | 2379.14 | 20 | 2 |
4 |
| 3 | RT-AC68U | 219.99 | 10 | 1 |
3 |
+----+-------------------+---------+-------+-------------+--------------
---+
3 rows in set (0.020 sec)

条件操作数

# 条件操作符包括: =、 <>、 >、 <、 >=、 <=
MariaDB [inventory]> SELECT * FROM product WHERE price > 100;
# BETWEEN,匹配2个数字之间(包括数字本身 )的记录。
MariaDB [inventory]> SELECT * FROM product WHERE id BETWEEN 1 AND 3;
# IN,匹配列表中记录。
MariaDB [inventory]> SELECT * FROM product WHERE id IN (1,3);
MariaDB [inventory]> SELECT * FROM category WHERE name IN
('Servers','Ssd');
# LIKE,用于匹配字符串。 %表示一个或多个字符, _表示一个字符, [charlist]表示字
符列中的任何单一字符, [^charlist]或者[!charlist]不在字符列中的任何单一字
符。
MariaDB [inventory]> SELECT * FROM product WHERE name like '%Server%';
# 逻辑与AND
MariaDB [inventory]> SELECT * FROM product WHERE name like '%RD%' AND
price>1000;
# 逻辑或or
MariaDB [inventory]> SELECT * FROM product WHERE name like '%RD%' OR
price>500;
# ORDER BY 关键字用于对结果集进行排序。
MariaDB [inventory]> SELECT * FROM product ORDER BY price;
MariaDB [inventory]> SELECT * FROM product ORDER BY price desc;
创建表
MariaDB [inventory]> CREATE TABLE staff(
id INT(11) NOT NULL,
name VARCHAR(100) NOT NULL,
age INT(11) DEFAULT 10,
id_department INT(11)
);
Query OK, 0 rows affected (0.017 sec)
MariaDB [inventory]> SHOW TABLES;
插入记录
MariaDB [inventory]> INSERT INTO staff (id,name,age,id_department)
VALUES (1,'han1',28,10);
MariaDB [inventory]> INSERT INTO staff (id,name,age) VALUES
(2,'han2',20);
MariaDB [inventory]> INSERT INTO staff (id,name) VALUES (3,'han3');
更新记录
MariaDB [inventory]> UPDATE staff SET age=30 WHERE id=3;
MariaDB [inventory]> UPDATE staff SET age=30
删除记录
MariaDB [inventory]> DELETE FROM staff WHERE id=3 ;
MariaDB [inventory]> DELETE FROM staff;
删除表
MariaDB [inventory]> DROP TABLE staff;

管理 MariaDB 用户

创建用户账户
MariaDB [(none)]> CREATE USER han@'localhost' IDENTIFIED BY 'redhat';
控制用户权限
1.全局范围

常用权限: CREATE USER (创建用户)、 DROP USER (删除用户)、CREATE DATABASE (创建数据库)、 ALL PRIVILEGES (全权限)、RELOAD (重载配置)、 GRANT OPTION (给其他用户授权)等

-- 示例1:授予 han 全局创建/删除用户权限(管理员级 ) + 给其他用户授权的权限
GRANT CREATE USER, DROP USER, GRANT OPTION ON *.* TO 'han'@'%';
-- 示例2:授予 han 全局创建/删除数据库权限(管理员级 ) + 给其他用户授权的权
限
GRANT CREATE DATABASE, DROP DATABASE, GRANT OPTION ON *.* TO
'han'@'%';
-- 示例3:授予 admin 超级管理员全权限(谨慎!生产环境避免 )
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;
-- 示例4:授予只读管理员全局查询权限(监控/报表 )
GRANT SELECT ON *.* TO 'monitor'@'%';
2.数据库范围

常用权限: CREATE (建表)、 ALTER (改表)、 DROP (删表)、SELECT/INSERT/UPDATE/DELETE (增删改查)等

-- 示例1:授予 dev_shop 仅操作 `shop_db` 电商库的全权限(开发人员 )
GRANT CREATE, ALTER, DROP, SELECT, INSERT, UPDATE, DELETE ON shop_db.*
TO 'dev_shop'@'%';
-- 示例2:授予 read_shop 仅读取 `shop_db` 数据(运营/报表 )
GRANT SELECT ON shop_db.* TO 'read_shop'@'%';
-- 示例3:授予 dba_shop 仅管理 `shop_db` 结构(表创建/修改 )
GRANT CREATE, ALTER, DROP ON shop_db.* TO 'dba_shop'@'%';
3.表范围

常用权限:针对单表的增删改查、索引操作等

-- 示例1:授予 order_op 仅操作 `shop_db.order` 订单表的增删改查权限
GRANT SELECT, INSERT, UPDATE, DELETE ON shop_db.`order` TO
'order_op'@'%';
-- 示例2:授予 index_admin 仅对 `shop_db.user` 表创建/删除索引
GRANT CREATE INDEX, DROP INDEX ON shop_db.user TO 'index_admin'@'%';
-- 示例3:仅允许统计用户查询 `shop_db.goods` 商品表(只读 )
GRANT SELECT ON shop_db.goods TO 'stat_user'@'%';
4.列范围

注意:列级授权需显式指定列名,且仅支持SELECT/INSERT/UPDATE/REFERENCES 权限

-- 示例1:授予 user_op 仅能查询 `shop_db.user` 表的 `id``name` 列(隐藏手
机号/密码 )
CREATE USER IF NOT EXISTS 'user_op'@'%' IDENTIFIED BY 'UserOp@123';
GRANT SELECT (id, name) ON shop_db.user TO 'user_op'@'%';
-- 示例2:授予 user_admin 仅能修改 `shop_db.user` 表的 `status` 列(账号状
态 )
GRANT UPDATE (status) ON shop_db.user TO 'user_admin'@'%';
-- 示例3:组合授权:查询基础列 + 修改手机号列
GRANT SELECT (id, name), UPDATE (phone) ON shop_db.user TO
'user_mgr'@'%';
查询用户权限
MariaDB [(none)]> SHOW GRANTS FOR root@localhost;
+-----------------------------------------------------------------------
-----------------------------------------------------------------+
| Grants for root@localhost
|
+-----------------------------------------------------------------------
-----------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY
PASSWORD '*84BB5DF4823DA319BBF86C99624479A198E6EEE9' WITH GRANT OPTION |
| GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION
|
+-----------------------------------------------------------------------
-----------------------------------------------------------------+
2 rows in set (0.006 sec)
查看权限

验证授权结果,避免配置错误:

-- 查看指定用户的所有权限
SHOW GRANTS FOR 'han'@'%';
-- 查看当前登录用户的权限
SHOW GRANTS;
权限回收

如需撤销权限,格式与授权对应(替换 GRANT 为 REVOKE ):

-- 撤销 han 的全局创建用户权限
REVOKE CREATE USER ON *.* FROM 'han'@'%';
回收用户权限

REVOKE语句从帐户中删除特权。 连接的用户必须具有GRANT OPTION特权,并且必须具有被撤消的特定特权

MariaDB [(none)]> REVOKE SELECT, UPDATE, DELETE, INSERT
-> ON inventory.category FROM han@localhost;
Query OK, 0 rows affected (0.011 sec)
删除用户
MariaDB [(none)]> DROP USER han@localhost;
Query OK, 0 rows affected (0.001 sec)
更改用户密码
# root用户修改普通用户账户密码
MariaDB [(none)]> USE mysql;
MariaDB [(mysql)]> UPDATE user SET password=PASSWORD('mypass') WHERE
user='han' and host=’localhost’;
# 或者
MariaDB [(none)]> SET PASSWORD FOR 'han'@'localhost' =
PASSWORD('mypass');
# 普通用户修改自己账户密码
MariaDB [(none)]> SET PASSWORD = PASSWORD('mypass');
MariaDB [(none)]> FLUSH PRIVILEGES;

备份和恢复

执行逻辑备份与恢复
备份
[root@server ~]# mysqldump -u root -p inventory > /backup/inventory.dump
[root@server ~]# mysqldump -u root -p --all-databases >
/backup/mariadb.dump
恢复
[root@server ~]# mysql -u root -p inventory < /backup/mariadb.dump
执行物理备份与恢复
备份
# 先停止
[root@server ~]# systemctl stop mariadb
# 再执行备份
[root@server ~]# cp -a /var/lib/mysql /backup/mysql
恢复
# 停止mariadb服务
[root@server ~]# systemctl stop mariadb
# 模拟删除原数据
[root@server ~]# rm -fr /var/lib/mysql
# 恢复数据
[root@server ~]# cp -a /backup/mysql /var/lib/mysql
[root@server ~]# chown -R mysql:mysql /var/lib/mysql/
#确认目录中内容
[root@server ~]# ls /var/lib/mysql
# 启动服务
[root@server ~]# systemctl start mariadb

Nginx 服务器

安装 nginx

# 安装 nginx
[root@www ~]# yum -y install nginx
# 启动 nginx
[root@www ~]# systemctl enable nginx --now
# 准备主页
[root@www ~]# mv /usr/share/nginx/html/index.html{,.ori}
[root@www ~]# echo Hello World From Nginx >
/usr/share/nginx/html/index.html
# 防火墙
[root@www ~]# firewall-cmd --add-service=http --permanent
[root@www ~]# firewall-cmd --reload
[root@client ~]# curl http://www.han.cloud
# windows客户端修改C:\Windows\System32\drivers\etc\hosts
# Linux或Unix修改 /etc/hosts
# 添加如下记录
10.1.8.10 www.han.cloud
根据名称
# 参考主配置文件/etc/nginx/nginx.conf中server块配置
[root@www ~]# vim /etc/nginx/conf.d/vhost-name.conf
server {
server_name web1.han.cloud;
root /usr/share/nginx/web1;
}
server {
server_name web2.han.cloud;
root /usr/share/nginx/web2;
}
[root@www ~]# mkdir /usr/share/nginx/web{1,2}
[root@www ~]# echo web1.han.cloud > /usr/share/nginx/web1/index.html
[root@www ~]# echo web2.han.cloud > /usr/share/nginx/web2/index.html
[root@www ~]# systemctl restart nginx

客户端测试

# 配置名称解析,假设web服务器ip地址为10.1.8.10
10.1.8.10 web1.han.cloud
10.1.8.10 web2.han.cloud
[root@client ~]# curl http://www1.han.cloud/
www1.han.cloud
[root@client ~]# curl http://www2.han.cloud/
www2.han.cloud

清理环境

[root@www ~]# mkdir /etc/nginx/conf.d/vhosts
[root@www ~]# mv /etc/nginx/conf.d/vhost-name.conf /etc/nginx/conf.d/vhosts
根据 port
[root@www ~]# vim /etc/nginx/conf.d/vhost-port.conf

server {
    listen       8081;
    server_name  www.han.cloud;
    root         /usr/share/nginx/8081;
}
server {
    listen       8082;
    server_name  www.han.cloud;
    root         /usr/share/nginx/8082;
}
[root@www ~]# mkdir /usr/share/nginx/808{1,2}
[root@www ~]# echo 8081 > /usr/share/nginx/8081/index.html
[root@www ~]# echo 8082 > /usr/share/nginx/8082/index.html
[root@www ~]# systemctl restart nginx

客户端测试

# 配置名称解析,假设web服务器ip地址为10.1.8.10
10.1.8.10 www.han.cloud
[root@client ~]# curl http://www.han.cloud:8081
8081
[root@client ~]# curl http://www.han.cloud:8082
8082

配置 SSL/TLS

生成证书
#--1--生成私钥
[root@www ~]# mkdir certs && cd certs
[root@www certs]# openssl genrsa -out www.key 2048
#--2--生成请求文件csr
[root@www certs]# openssl req -new -key www.key -out www.csr -subj
"/C=CN/ST=JS/L=NJ/O=LM/OU=DEVOPS/CN=www.han.cloud/emailAddress=webadmin@
han.cloud"
#CN的值必须是网站域名
#--3--使用自己的私钥对请求文件签名,以生成证书
[root@www certs]# openssl x509 -req -days 3650 -in www.csr -signkey
www.key -out www.crt
配置站点
[root@www certs]# mkdir /etc/ssl/certs/www.han.cloud
[root@www certs]# mv www* /etc/ssl/certs/www.han.cloud
# 参照默认配置修改
[root@www ~]# cp /etc/nginx/nginx.conf /etc/nginx/conf.d/vhostwww.han.cloud-ssl.conf
[root@www ~]# vim /etc/nginx/conf.d/vhost-www.han.cloud-ssl.conf
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.han.cloud;
root /usr/share/nginx/html;
# 证书
ssl_certificate "/etc/ssl/certs/www.han.cloud/www.crt";
# 私钥
ssl_certificate_key "/etc/ssl/certs/www.han.cloud/www.key";
}
[root@www ~]# systemctl restart nginx

配置HTTP重定向到https

[root@www ~]# vim /etc/nginx/conf.d/vhost-www.han.cloud-ssl.conf
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.han.cloud;
root /usr/share/nginx/html;
# 证书
ssl_certificate "/etc/ssl/certs/www.han.cloud/www.crt";
# 私钥
ssl_certificate_key "/etc/ssl/certs/www.han.cloud/www.key";
}
# 配置HTTP重定向到https
server {
listen 80;
listen [::]:80;
server_name www.han.cloud;
root /usr/share/nginx/html;
# 添加重定向
return 301 https://$host$request_uri;
}
[root@www ~]# systemctl restart nginx
# 防火墙设置
[root@www ~]# firewall-cmd --add-service=https --permanent
[root@www ~]# firewall-cmd --reload
# 测试
[root@client ~]# curl http://www.han.cloud/
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>
# 使用-k指明目标站点不是一个安全站点
[root@client ~]# curl -k https://www.han.cloud/

配置基本认证

#安装工具
[root@www ~]# yum -y install httpd-tools
[root@www ~]# vim /etc/nginx/conf.d/vhost-www.han.cloud-ssl.conf
# add into the [server] section
server {
.....
location /auth-basic/ {
auth_basic "Basic Auth";
auth_basic_user_file "/etc/nginx/.htpasswd";
}
}
[root@www ~]# systemctl restart nginx
# add user for Basic authentication
[root@www ~]# yum install -y httpd-tools
[root@www ~]# htpasswd -b -c /etc/nginx/.htpasswd han 123456
# create a test page
[root@www ~]# mkdir /usr/share/nginx/html/auth-basic
[root@www ~]# vim /usr/share/nginx/html/auth-basic/index.html
<html>
<body>
<div style="width: 100%; font-size: 40px; font-weight: bold; text-align:
haner;">
Test Page for Basic Authentication
</div>
</body>
</html>
# 测试,通过-u选项指定用户名和密码
[root@client ~]# curl -ku han:123456 https://www.han.cloud/auth-basic/

支持动态脚本

使用 PHP
# 安装PHP和php-fpm,建议把其他的扩展包一起安装
[root@www ~]# yum install -y php php-fpm
# php-fpm: 负责接收web程序发来的php代码
# php:负责解析和执行php代码,并将结果返回给php-fpm
# 当客户端访问 php 站点时, web站点接收用户请求
# 并转发 php 代码给php-fpm服务
# php-fpm 服务调用php解析php网页,然后将结果返回给web程序
# web 程序将结果返回给客户端
# 建议把其他的扩展包一起安装
[root@www ~]# yum install -y php-gd php-common php-pear php-mbstring phpmcrypt
# 查看 php 版本
[root@www ~]# php -v
# 测试 php 是否正常
[root@www ~]# echo "<?php echo 'PHP Test Page'.\"\n\"; ?>" > php_test.php
[root@www ~]# php php_test.php
PHP Test Page
# 准备测试页,使用phpinfo查看详细信息
[root@www ~]# echo "<?php phpinfo(); ?>" > /usr/share/nginx/html/info.php

配置虚拟机主机支持php

# 修改配置文件
[root@www ~]# vim /etc/nginx/conf.d/vhost-www.han.cloud-ssl.conf
# add into the [server] section
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.han.cloud;
root /usr/share/nginx/html;
ssl_certificate "/etc/ssl/certs/www.han.cloud/www.crt";
ssl_certificate_key "/etc/ssl/certs/www.han.cloud/www.key";
# 添加代理
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
# 配置HTTP重定向到https
server {
listen 80;
listen [::]:80;
server_name www.han.cloud;
root /usr/share/nginx/html;
# 添加重定向
return 301 https://$host$request_uri;
}

客户端测试

[root@client ~]# curl -k https://www.han.cloud/info.php

反向代理

反向代理介绍

反向代理(reverse proxy),指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户。 客户端不直接与后端服务器进行通信,而是与反向代理服务器进行通信,隐藏了后端服务器的IP 地址

Location 配置语法
http {
# 后端服务可配置 upstream 集群(推荐,支持负载均衡 )
upstream backend_server {
server 192.168.1.100:8080; # 后端服务1
server 192.168.1.101:8080; # 后端服务2(多节点自动轮询负载均衡 )
}
server {
listen 80; # Nginx 监听端口
server_name localhost; # 访问域名/IP
# 1. 匹配所有请求(兜底规则 )
location / {
proxy_pass http://backend_server; # 转发至 upstream 集群
# 必加的反向代理核心参数(传递客户端真实信息、适配后端服务 )
proxy_set_header Host $host; # 传递客户端访问的域
名
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #
传递IP链路
proxy_set_header X-Forwarded-Proto $scheme; # 传递请求协议
( http/https)
}
# 2. 匹配特定路径(如 /api 开头的请求,单独转发 )
location /api/ {
proxy_pass http://192.168.1.102:9090/; # 后端地址末尾带 /,会剔
除匹配的 /api/
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
Location 匹配规则
1.精确匹配(=)
  • 语法: location = /path { … }
  • 逻辑:仅当请求 URL 与 /path 完全一致时命中,优先级最高。
# 仅匹配 http://localhost/login,不匹配 /login?a=1、 /login/
location = /login {
proxy_pass http://backend_login:8080;
}
2.前缀匹配(^~)
  • 语法: location ^~ /path { … }
  • 逻辑: URL 以 /path 开头即命中,优先级仅次于精确匹配, 会跳过正则匹配
# 仅匹配 http://localhost/login,不匹配 /login?a=1、 /login/
location = /login {
proxy_pass http://backend_login:8080;
}
3.正则匹配(~ / ~*)
  • 语法:
    • 区分大小写: location ~ /regex { … } (如 /API 不匹配 /api 规则)
    • 不区分大小写: location ~* /regex { … } (如 /API、 /api 均匹配)
  • 逻辑: URL 符合正则表达式即命中,优先级低于前缀匹配(^~), 多个正则规则按定义顺序匹配,先命中先生效。
# 匹配所有 .jpg、 .png、 .gif 结尾的图片请求(不区分大小写 )
location ~* \.(jpg|png|gif)$ {
proxy_pass http://backend_img:80;
}
4.普通前缀匹配(无符号)
  • 语法: location /path { … }
  • 逻辑: URL 以 /path 开头即命中,优先级低于正则匹配, 多个普通前缀规则按 “路径最长” 优先命中。
# 规则1:匹配 /api/xxx(路径长度3)
location /api/ {
proxy_pass http://backend_api:9090;
}
# 规则2:匹配 /api/user/xxx(路径长度7,比规则1长,优先命中 )
location /api/user/ {
proxy_pass http://backend_user:9090;
}
5.通用匹配(/)
  • 语法: location / { … }
  • 逻辑:所有未被上述规则命中的请求,都会匹配此规则(兜底),优先级最低。
  • 用途:通常作为全局反向代理,转发所有默认请求到主后端服务。
综合示例
http {
    upstream backend_main { nginx 192.168.1.200:8080; }
    upstream backend_api { nginx 192.168.1.201:9090; }
    upstream backend_static { nginx 192.168.1.202:80; }
    upstream backend_login { nginx 192.168.1.203:8080; }

    server {
        listen 80;
        server_name localhost;

        # 1. 精确匹配:仅 /login → 后端 login 服务
        location = /login {
            proxy_pass http://backend_login;
            proxy_set_header Host $host;
        }

        # 2. 前缀匹配:/static/ 开头 → 后端静态服务(跳过正则)
        location ^~ /static/ {
            proxy_pass http://backend_static;
            proxy_set_header Host $host;
        }

        # 3. 正则匹配:图片后缀 → 后端静态服务
        location ~* \.(jpg|png|gif)$ {
            proxy_pass http://backend_static;
            proxy_set_header Host $host;
        }

        # 4. 普通前缀:/api/ 开头 → 后端 api 服务
        location /api/ {
            proxy_pass http://backend_api/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

        # 5. 兜底匹配:所有未命中的请求 → 主后端服务
        location / {
            proxy_pass http://backend_main;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}
反向代理实践环境
环境架构

/etc/hosts

# 所有节点
[root@nginx ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

############ proxy ##################
10.1.8.11 client.han.cloud client
10.1.8.20 www.han.cloud www
10.1.8.20 proxy.han.cloud proxy
10.1.8.21 nginx1.han.cloud nginx1
10.1.8.22 nginx2.han.cloud nginx2
10.1.8.23 nginx3.han.cloud nginx3
后端 nginx 服务器配置
# 除了客户端,所有节点安装nginx并启动nginx服务。
# 以nginx1为例
[root@nginx1 ~]# yum -y install nginx

# 启动并启用服务
[root@nginx1 ~]# systemctl enable nginx --now

# 防火墙设置
[root@nginx1 ~]# firewall-cmd --add-service=http --permanent
[root@nginx1 ~]# firewall-cmd --add-service=http

# 准备主页-其他节点
[root@nginx1 ~]# echo Welcome to $(hostname) > /usr/share/nginx/html/index.html
[root@nginx2 ~]# echo Welcome to $(hostname) > /usr/share/nginx/html/index.html
[root@nginx3 ~]# echo Welcome to $(hostname) > /usr/share/nginx/html/index.html

# 客户端测试
[root@client ~]# curl http://www.han.cloud/
Welcome to www.han.cloud
[root@client ~]# curl http://nginx1.han.cloud/
Welcome to nginx1.han.cloud
[root@client ~]# curl http://nginx2.han.cloud/
Welcome to nginx2.han.cloud
[root@client ~]# curl http://nginx3.han.cloud/
Welcome to nginx3.han.cloud
前端 proxy 服务器配置
# 准备主页-代理节点
[root@proxy ~]# yum -y install nginx
[root@proxy ~]# echo Welcome to www.han.cloud > /usr/share/nginx/html/index.html

[root@proxy ~]# mkdir /var/nginx
[root@proxy ~]# echo "Hello, Nginx" > /var/nginx/index.html
[root@proxy ~]# echo "Hello, han" > /var/nginx/test.txt
[root@proxy ~]# cp /usr/share/nginx/html/nginx-logo.png /var/nginx/
[root@proxy ~]# ls /var/nginx/
index.html  nginx-logo.png  test.txt

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
	listen  80;
	server_name www.han.cloud;

    # 匹配根位置
    location / {
      root /var/nginx;
      index index.html;
    }
}
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload
# 或
[root@proxy ~]# systemctl restart nginx
测试
[root@client ~]# curl http://www.han.cloud/
Hello, Nginx

[root@client ~]# curl http://www.han.cloud/test.txt
Hello, han
反向代理基础实践-代理本地
环境准备
[root@proxy ~]# mkdir /var/nginx/nginx{1,2}
[root@proxy ~]# echo "Hello, I'm here /var/nginx/nginx1" > /var/nginx/nginx1/index.html
[root@proxy ~]# echo "Hello, I'm here /var/nginx/nginx2" > /var/nginx/nginx2/index.html

[root@proxy ~]# mkdir /var/nginx{1,2}
[root@proxy ~]# echo "Hello, Nginx1" > /var/nginx1/index.html
[root@proxy ~]# echo "Hello, Nginx2" > /var/nginx2/index.html
[root@proxy ~]# tree /var/nginx*
/var/nginx
├── index.html
├── nginx1
│   └── index.html
├── nginx2
│   └── index.html
├── nginx-logo.png
└── test.txt
/var/nginx1
└── index.htmlcat 
/var/nginx2
└── index.html

2 directories, 7 files

[root@proxy ~]# \
for path1 in www{1..2}
do
  for path2 in nginx{1..2}
  do
    mkdir -p /var/$path1/$path2
	echo "Hello, I'm here /var/$path1/$path2" > /var/$path1/$path2/index.html
  done
done

[root@proxy ~]# tree /var/www*
/var/www1
├── nginx1
│   └── index.html
└── nginx2
    └── index.html
/var/www2
├── nginx1
│   └── index.html
└── nginx2cat 
    └── index.html

4 directories, 4 files
基本测试
[root@client ~]# curl http://www.han.cloud/
Hello, Nginx

# 显示结果是目录/var/nginx/nginx1中内容
[root@client ~]# curl http://www.han.cloud/nginx1/
Hello, I'm here /var/nginx/nginx1

# 显示结果是目录/var/nginx/nginx2中内容
[root@client ~]# curl http://www.han.cloud/nginx2/
Hello, I'm here /var/nginx/nginx2
实践1:无符号匹配
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
	listen  80;
	server_name www.han.cloud;

    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配/nginx1时,/var目录下找nginx1,完整路径是/var/nginx1
    location /nginx1 {
        root /var;
        # 等效于下面的 alias 语句,必须使用绝对路径
        # alias /var/nginx1;
        index index.html;
    }
}
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload
# 或
[root@proxy ~]# systemctl restart nginx

访问测试

# nginx1 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx1/
Hello, Nginx1
# 显示结果是目录/var/nginx1中内容

# nginx2 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx2/
Hello, I'm here /var/nginx/nginx2
# 显示结果是目录/var/nginx/nginx2中内容
实践2:正则表达式匹配
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
	listen  80;
	server_name www.han.cloud;

    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配/nginx1时,/var目录下找nginx1,完整路径是/var/nginx1
    location /nginx1 {
        root /var;
        # 等效于下面的 alias 语句,必须使用绝对路径
        # alias /var/nginx1;
        index index.html;
    }

    # 正则表达式匹配 /nginx.*
    location ~ /nginx.* {
        root /var/www1;
        index index.html;
    }
}
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload
# 或
[root@proxy ~]# systemctl restart nginx

访问测试

# nginx1 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx1/
Hello, I'm here /var/www1/nginx1
# 显示结果是目录/var/www1/nginx1中内容

# nginx2 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx2/
Hello, I'm here /var/www1/nginx2
# 显示结果是目录/var/www1/nginx2中内容
实践3:精确匹配
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
	listen  80;
	server_name www.han.cloud;

    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配/nginx1时,/var目录下找nginx1,完整路径是/var/nginx1
    location /nginx1 {
        root /var;
        # 等效于下面的 alias 语句,必须使用绝对路径
        # alias /var/nginx1;
        index index.html;
    }

    # 正则表达式匹配 /nginx.*
    location ~ /nginx.* {
        root /var/www1;
        index index.html;
    }

    # 精确匹配
    location = /nginx2/index.html {
        root /var/www2;
        index index.html;
    }

}
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

访问测试

# nginx1 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx1/
Hello, I'm here /var/www1/nginx1
# 显示结果是目录/var/www1/nginx1中内容

# nginx2 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx2/
Hello, I'm here /var/www2/nginx2
# 显示结果是目录/var/www2/nginx2中内容
反向代理基础实践-代理远端
实践1:无符号匹配
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
    listen  80;
    server_name www.han.cloud;
    
    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配 /nginx1/ 开头,代理到nginx1.han.cloud,/nginx1/不组合到后端服务器
    # 访问 /nginx1/ 开头,相当于直接访问http://nginx1.han.cloud/
    location /nginx1/ {
        # 后端服务
        proxy_pass http://nginx1.han.cloud/; # 注意:代理后端后面有 /。
        index index.html;
    }
}
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

访问测试

# nginx1 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/	nginx1/
Welcome to nginx1.han.cloud
# 显示结果是服务器 nginx1.han.cloud 内容

# nginx2 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx2/
Hello, I'm here /var/nginx/nginx2
# 显示结果是目录/var/nginx/nginx2中内容
实践2:正则表达式匹配
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
    listen  80;
    server_name www.han.cloud;
    
    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配 /nginx1/ 开头,代理到nginx1.han.cloud,/nginx1/不组合到后端服务器
    # 访问 /nginx1/ 开头,相当于直接访问http://nginx1.han.cloud/
    location /nginx1/ {
        # 后端服务
        proxy_pass http://nginx1.han.cloud/; # 注意:代理后端后面有 /。
        index index.html;
    }
 
    # 正则表达式匹配 /nginx.*
    location ~ /nginx[12].* {
        # 手动重写路径:去掉 /nginx 前缀,转发到目标服务器
        # ^/nginx[12](.*)$ 匹配 /nginx[12] 开头的完整路径,$1表示 /nginx[12] 后的所有内容
        # break 表示重写后不再匹配其他 rewrite 规则
        rewrite ^/nginx[12](.*)$ $1 break;
         
        # proxy_pass 不带 URI(无末尾的 /),配合 rewrite 实现路径替换
        proxy_pass http://nginx2.han.cloud;  
        index index.html;
    }
}
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

访问测试

# nginx 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx1/
Welcome to nginx2.han.cloud
# 显示结果是服务器 nginx2.han.cloud 内容

# nginx 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx2/
Welcome to nginx2.han.cloud
# 显示结果是服务器 nginx2.han.cloud 内容
实践3:精确匹配
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
    listen  80;
    server_name www.han.cloud;
    
    # 匹配根位置
    location / {
        root /var/nginx;
        index index.html;
    }

    # 匹配 /nginx1/ 开头,代理到nginx1.han.cloud,/nginx1/不组合到后端服务器
    # 访问 /nginx1/ 开头,相当于直接访问http://nginx1.han.cloud/
    location /nginx1/ {
        # 后端服务
        proxy_pass http://nginx1.han.cloud/; # 注意:代理后端后面有 /。
        index index.html;
    }
 
    # 正则表达式匹配 /nginx.*
    location ~ /nginx[12].* {
        # 手动重写路径:去掉 /nginx 前缀,转发到目标服务器
        # ^/nginx[12](.*)$ 匹配 /nginx[12] 开头的完整路径,$1表示 /nginx[12] 后的所有内容
        # break 表示重写后不再匹配其他 rewrite 规则
        rewrite ^/nginx[12](.*)$ $1 break;
         
        # proxy_pass 不带 URI(无末尾的 /),配合 rewrite 实现路径替换
        proxy_pass http://nginx2.han.cloud;  
        index index.html;
    }

    # 精确匹配
    location = /nginx1/ {
        proxy_pass http://nginx1.han.cloud/;  
        index index.html;
    }

}
# 重新加载nginx配置
[root@proxy ~]# nginx -s reload

访问测试

# nginx1 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx1/
Welcome to nginx1.han.cloud
# 显示结果是服务器 nginx1.han.cloud 内容

# nginx2 后面必须添加 / 符号
[root@client ~]# curl http://www.han.cloud/nginx2/
Welcome to nginx2.han.cloud
# 显示结果是服务器 nginx2.han.cloud 内容
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐