nginx
1. nginx 应用场景
- 静态资源服务
- 反向代理服务
- API 接口服务
2. nginx 的优势
- 高并发高性能
- 可扩展性好
- 高可靠性
- 热部署
- 开源许可证
3. 学习环境
3.1 常用版本四大阵营
3.2 操作系统
- VMware: 新建虚拟机
- CentOS7:镜像
3.3 环境确认
-
启动网卡
vi /etc/sysconfig/network-scripts/ifcfg-ens33 ONBOOT=yes # 是否随网路服务启动,ens33生效 systemctl restart network # 重启网络
-
配置静态 ip 地址:
# vi /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" - BOOTPROTO="dhcp" + BOOTPROTO="static" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="ens33" UUID="5439782d-91b9-43c5-8709-063de676279f" DEVICE="ens33" ONBOOT="yes" + IPADDR="192.168.75.137" # 静态ip地址 + NETMASK="255.255.255.0" # 子网掩码 + GATEWAY="192.168.75.1" # 网关 + DNS1="8.8.8.8" # DNS服务器 # 重启网络 systemctl restart network
-
一些公网 DNS 服务器
-
阿里
223.5.5.5 223.6.6.6
-
腾讯
119.29.29.29 182.254.118.118
-
百度
180.76.76.76
-
114DNS
114.114.114.114 114.114.115.115
-
谷歌
8.8.8.8 8.8.4.4
-
-
-
虚拟机不能上网排除:VMware->编辑->虚拟网络编辑器
/etc/sysconfig/network-scripts/ifcfg-ens33 中网关改为"192.168.75.2"
-
关闭防火墙
systemctl stop firewalld.service
:关闭防火墙systemctl disable firewalld.service
: 禁止开机启动
-
重启防火墙
firewall-cmd --reload
-
确认停用 selinux
-
安全增强型 Linux(Security-Enhanced Linux) 简称 SElinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统
-
SELinux 主要作用就是最大限度地减少系统中服务进程可访问的资源(最小权限原则)
vi /etc/selinux/config SELINUX=disabled
- 强制模式
SELINUX=enforcing
:表示所有违反安全策略的行为都将被禁止。 - 宽容模式
SELINUX=permissive
:表示所有违反安全策略的行为不被禁止,但是会在日志中作记录
修改
config
文件后,需要重启实例,但直接重启实例将会出现系统无法启动的错误。因此在重启之前需要在根目录下新建autorelabel
文件。touch /.autorelabel
重启
shutdown -r now
- 强制模式
-
-
放行端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
-
安装依赖模块
yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake yum -y install wget httpd-tools vim
4. nginx 的架构
4.1 轻量
- 源代码只包含核心模块
- 其他非核心功能都是通过模块实现,可以自由选择
4.2 架构
- Nginx 采用的是多进程(单线程)和多路 IO 复用模型
4.2.1 工作流程
- Nginx 在启动后,会有一个 master 进程和多个互相独立的 worker 进程
- 接收来自外界的信号,向各 worker 进程发送信号,每个进程都有可能处理这个连接
- master 进程能监控 worker 进程的运行状态,当 worker 进程退出(异常情况下),会自动启动新的 worker 进程
- worker 进程数,一般会设置成机器 cpu 核数,因为更多 worker 数,只会导致进程相互竞争 cpu,从而带来不必要的上下文切换
- 使用多进程模式,不仅能提高并发率,而且进程之间相互独立,一个 worker 进程挂了不影响其他 worker 进程
4.2.2 IO 多路复用
- 多个文件描述符的 IO 操作都能在一个线程里并发交替顺序完成,复用线程。多对一,一对多。如:多个客户,对应一个服务员下单,服务员对多个厨师派发任务
4.2.3 CPU 亲和
- 把 CPU 内核和 nginx 的工作进程绑定在一起,让每一个 worker 进程固定在一个 CPU 上执行,从而减少 CPU 的切换并提高缓存命中率,提高性能。
4.2.4 sendfile
- sendfile 零拷贝传输模式
5. nginx 安装及启动
5.1 版本分类
- Mainline version 开发版
- Stable version 稳定版
- Legacy versions 历史版
5.2 下载及安装
-
-
下载
-
上传
-
解压:
tar zxvf nginx-1.24.0.tar.gz # z:gzip属性,x:解压,v:显示所有过程,f:使用文档名
-
安装
cd nginx-1.24.0 ls # auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src # 安装命令 ./configure --prefix=/usr/local/nginx
-
错误提示及解决
checking for OS + Linux 3.10.0-693.el7.x86_64 x86_64 checking for C compiler ... not found ./configure: error: C compiler cc is not found
# 解决 yum install -y gcc
./configure: error: the HTTP rewrite module requires the PCRE library. You can either disable the module by using --without-http_rewrite_module option, or install the PCRE library into the system, or build the PCRE library statically from the source with nginx by using --with-pcre=<path> option.
# 解决 yum install -y pcre pcre-devel
./configure: error: the HTTP gzip module requires the zlib library. You can either disable the module by using --without-http_gzip_module option, or install the zlib library into the system, or build the zlib library statically from the source with nginx by using --with-zlib=<path> option.
# 解决 yum install -y zlib zlib-devel
-
-
执行
make make install
-
-
# 创建文件 vi /etc/yum.repos.d/nginx.repo # 内容 [nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
-
yum 安装
yum install nginx -y nginx -v nginx -V
5.3 启动
进入安装好的目录/usr/local/nginx/sbin
./nginx # 启动
./nginx -s stop # 快速停止
./nginx -s quit # 优雅关闭,在退出前完成已经接收的连接请求
./nginx -s reload # 重新加载配置
5.4 安装成系统服务
创建服务脚本
vi /usr/lib/systemd/system/nginx.service
脚本内容
[Unit]
Description=nginx - web server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
ExecQuit=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
重新加载系统服务
systemctl daemon-reload
启动服务
# 启动服务前需要,先关闭nginx服务,否则有冲突,
systemctl start nginx.service
开机启动
systemctl enable nginx.service
5.5 配置 nginx 全局可用
vi /etc/profile
export PATH=$PATH:/usr/local/nginx/sbin
/etc/profile
6. 目录
6.1 安装目录
查看 nginx 安装的配置文件和目录
rpm -ql nginx
6.2 日志的切割
vi /etc/logrotate.d/nginx
# 文件内容
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
# 查询日志文件
ls /var/log/nginx/*.log
/var/log/nginx/access.log /var/log/nginx/error.log
6.3 主配置文件
路径 | 用途 |
---|---|
/etc/nginx/nginx.conf | 核心配置文件 |
/etc/nginx/conf.d/default.conf | 默认 http 服务器配置文件 |
6.4 cgi 配置
- CGI 是 common gateway interface(通用网关接口)
- Web server 通过 CGI 协议可以把动态的请求传递给如 php/jsp/python/perl 等应用程序
- FastCGI 实际上是增加了一些扩展功能的 CGI,是 CGI 的改进,描述了客户端和 Web 服务器程序之间传输数据的一种标准
- SCGI 协议是一个 CGI 协议的替代品,它是一个应用于 http 服务器的接口标准,类似于 fastCGI,但它设计的更为容易实现
- uwsgi 是一个 web 服务器,它实现了 wsgi 协议、uwsgi、http 等协议
6.5 编码转换映射转化文件
- 这三个文件都是与编码转换映射文件,用于在输出内容到客户端时,将一种编码转换到另一种编码
- koi8-r 是斯拉夫文字 8 位元编码,供俄语及保加利亚语使用,在 Unicode 未流行之前,koi8-r 是最为广泛使用的俄语编码,使用率甚至比 ISO/IEC 8859-5 还高。
路径 | 用途 |
---|---|
/etc/nginx/koi-utf | koi8-r<---> utf-8 |
/etc/nginx/koi-win | koi8-r<---> windows-1251 |
/etc/nginx/win-utf | windows-1251<---> utf-8 |
6.6 扩展名文件
路径 | 用途 |
---|---|
/etc/nginx/mime.types | 设置 http 协议的 Content-Type 与扩展名对应关系 |
6.7 nginx 模块目录
路径 | 用途 |
---|---|
/etc/nginx/modules | 最基本的共享库和内核模块 |
存放用于启动系统和执行 root 文件系统的命令如
/bin
和/sbin
的二进制文件的共享库
6.8 文档
路径 | 用途 |
---|---|
/usr/share/doc/nginx-1.24.0 | 帮助文档 |
/usr/share/doc/nginx-1.24.0/COPYRIGHT | 版权声明 |
/usr/share/man/man8/nginx.8.gz | 手册 |
6.9 缓存目录
路径 | 用途 |
---|---|
/var/cache/nginx | nginx 的缓存目录 |
6.10 日志目录
路径 | 用途 |
---|---|
/var/log/nginx | nginx 的日志目录 |
6.11 可执行命令
路径 | 用途 |
---|---|
/var/sbin/nginx | 可执行命令 |
/var/sbin/nginx-debug | 调试执行可执行命令 |
7. 编译参数
7.1 安装目录和路径
7.2 临时性文件
执行对应模块时 nginx 所保留的临时性文件
7.3 指定用户
用户和用户组权限越少越好
7.4 设置额外参数
- 设置额外的参数将被添加到
CFLAGS
变量 CFLAGS
变量用来存放 C 语言编译时的优化参数
--with-cc-opt='-02 -g -pipe -Wall -Wp, -D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong'
7.5 设置链接文件参数
- 定义要传递到 C 链接器命令行的其他选项
- PCRE 库,需要指定-with-ld-opt="-L /usr/local/lib"
--with-lld-opt="-Wl,-z,relro -Wl,-z,now -pie"
8. 配置文件
路径 | 用途 |
---|---|
/etc/nginx/nginx.conf | 主配置文件 |
/etc/nginx/conf.d/*.conf | conf.d 目录下的所有配置文件 |
/etc/nginx/conf.d/default.conf | 默认配置文件 |
8.1 nginx 配置语法
# 使用#可以添加注释,使用$符号可以使用变量
# 配置文件由指令与指令块组成,指令块以{}将多条指令组织在一起
user nginx; # 设置运行此nginx用户名 (权限可能受限)
worker_processes auto; # 工作进程数
error_log /var/log/nginx/error.log notice; # 指定错误日志的路径 格式为notice
pid /var/run/nginx.pid; # 这是一个文件,放的是当前nginx的进程号
events {
worker_connections 1024; # 单个工作进程的最大连接数
}
http {
# include语句可以将多个文件包含进来
include /etc/nginx/mime.types; # 包含内容和文件名后缀的对应关系
# 每行指令以;分号结尾,指令与参数之间以空格分隔
default_type application/octet-stream; # 默认的文件类型Content-Type 字节流的方式
# 日志格式,日志格式名称main
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 访问日志的日志位置 日志格式
access_log /var/log/nginx/access.log main;
sendfile on; # 零拷贝模式
#tcp_nopush on; # TCP不推,有一定的缓存,攒够一定数量后再返回给客户端
keepalive_timeout 65; # 活动链接的超时时间s
#gzip on; # 是否启用压缩
include /etc/nginx/conf.d/*.conf; # 包含其他配置文件
}
server { # 每个server对应一个网站,vhost 虚拟主机
listen 80; # 监听端口号
server_name localhost; # 监听的域名、主机名 可以是多个
#charset koi8-r # 指定字符集
#access_log /var/log/nginx/host.access.log main; # 指定访问日志位置和格式
location / { # 匹配所有路径
root /usr/share/nginx/html; # 静态文件根目录
index index.html index.htm; # 索引文件
}
#error_page 404 /404.html; # 错误页面,返回的状态码为404时,重定向到/404.html
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html; # 错误,重定向到/50x.html
location = /50x.html { # 精确匹配,当路径为/50x.html时,根目录是/usr/share/nginx/html
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ { # 如果访问的文件名是.php结尾的话,会把此请求转发给http://127.0.0.1
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ { # 如果访问的文件名是.php结尾的话,会把此请求转发给127.0.0.1:9000
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
# 如果路径是/.ht的话, 禁止所有人访问
#location ~ /\.ht {
# deny all;
#}
}
正则匹配
- 正则语法
- = 进行普通字符精确匹配
- ~ 波浪线表示执行一个正则匹配,区分大小写
- ~* 表示执行一个正则匹配,不区分大小写
- ^~ ^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
- @ 定义命名 location 区段,这些区段客户端不能访问,只可以由内部产生的请求来访问,内部跳转,如 try_files 或 error_page 等
- !~ 区分大小写不匹配
- !~* 不区分大小写不匹配
- ^ 以什么开头的匹配
- $ 以什么结尾的匹配
- \ 转义字符。可以转. * ?等
- * 代表任意字符
- 查找顺序和优先级
- 1:带有“=“的精确匹配优先
- 2:没有修饰符的精确匹配
- 3:正则表达式按照他们在配置文件中定义的顺序
- 4:带有“^~”修饰符的,开头匹配
- 5:带有“~” 或“~*” 修饰符的,如果正则表达式与 URI 匹配
- 6:没有修饰符的,如果指定字符串与 URI 开头匹配
日志
日志类型
- 访问日志:
/var/log/nginx/access.log
- 错误日志:
/var/log/nginx/error.log
日志格式
log_format name [escape=default[json] string]
nginx -V: 验证格式是否正确
变量名称(内置) | 用途 |
---|---|
$remote_addr | 客户端地址 |
$remote_user | 客户端用户名 |
$time_local | 访问时间和时区 |
$request | 请求行 |
$body_bytes_sent | 发送给客户端文件内容大小 |
$status | HTTP 请求状态 |
变量名称(http 请求) | 用途 | 例子 |
---|---|---|
arg_PARAMETER | 请求参数 | $arg_name |
http_HEADER | 请求头 | $http_referer $http_host $http_user_agent $http_x_forwarded_for(代理过程) |
sent_http_HEADER | 响应头 | sent_htttp_cookie |
8.2 虚拟主机与域名解析
域名、dns、ip 地址的关系
浏览器发送 http 请求,经过本地 dns 服务器--->根 dns 服务器解析: 如www.baidu.com ,本地如果没有解析出,则向各级网关获取(网关中有缓存),如果各级网关还没有解析出,则向根 dns 服务器(13 台)获取。根服务器返回.com
服务器,如果还没有解析到,则.com
服务器返回.baidu
服务器,此时解析出www.baidu.com的ip地址,本地dns服务器缓存,
http 协议是建立在 TCP/IP 协议之上的协议,TCP/IP 协议(传输层/网络层)没有开始结束标识,http 协议有固定的标准规定,三次握手,四次挥手(服务器需要确定数据传输完成,客户端需要确定数据接收完成)
公网域名配置和泛域名解析
9. 核心模块
9.1 监控 nginx 客户端的状态
模块名
--with-http_stub_status_module
:监控 nginx 客户端的状态
语法
Syntax: stub_status on/off
Default: -
Content: server->location
实战
vi /etc/nginx/conf.d/status.conf
+ location = /status {
+ stub_status on;
+ }
systemctl reload nginx.service
# 浏览器访问http://192.168.75.136/status
# 返回结果:
Active connections: 2
server accepts handled requests
2 2 3
Reading: 0 Writing: 1 Waiting: 1
9.2 随机主页
模块名
--with-http_random_index_module
:在根目录里随机选择一个主页显示
语法
Syntax: random_index on/off
Default: off
Content: location
实战
vi /etc/nginx/conf.d/default.conf
+ location / {
+ root /data/html;
+ random_index on;
+ }
9.3 内容替换
模块名
--with-http_sub_module
:内容替换
语法
Syntax: sub_filter string repalcement;
Default: --
Content: http, service, location
实战
vi /etc/nginx/conf.d/default.conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
+ sub_filter 'word' 'hyf'; # 将word替换成 hyf
+ sub_filter_once off; # 默认替换一次,关闭 全部替换
}
9.4 请求限制
模块名
- --with-limit_conn_module: 连接频率限制
- --with-limit_req_module:请求频率限制
- 一次 TCP 请求至少产生一个 http 请求
- SYN > SYN, ACK > ACK > request > response > FIN > ACK > FIN > ACK
请求限制
语法
# 可以以IP为key zone为空间的名称 size为空间的大小 rate 每秒中发送一次
Syntax: limit_req_zone key zone=name1:size rate=1r/s;
Default: --
Content: http(定义在server以外)
# zone= 上述定义的name1
Syntax: limit_req zone=name1 [burst] [nodelay];
# burst突发的,burst=3 如果有4个请求,1个将被处理,3个将被放到队列中等待处理
# nodelay
Default: --
Content: http,server,location
实例
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
server {
location / {
root /usr/share/nginx/html;
index index.html index.htm;
+ limit_req zone=req_zone;
}
}
- $binary_remote_addr: 远程的 IP 地址
- zone=req_zone:10 表示 一个内存大小为 10M,并设定名称为 req_zone
- rate=1r/s: 速率是每秒钟请求 1 次
- zone=req_zone: 对应 limit_req_zone 中定义的 zone 名称
- burst=3: 请求队列的长度,如果有 4 个请求,1 个将被处理,3 个将被放到队列中等待处理
- nodelay: 表示不延时
连接限制
语法
# 可以以IP为key zone为空间的名称 size为空间的大小
Syntax: limit_conn_zone key zone=name1:size;
Default: --
Content: http(定义在server以外)
# zone= 上述定义的name1 number限制的数量
Syntax: limit_conn zone number;
Default: --
Content: http,server,location
实例
vi /etc/nginx/conf.d/status.conf
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
+ limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
server {
location / {
root /usr/share/nginx/html;
index index.html index.htm;
limit_req zone=req_zone;
+ limit_conn conn_zone 1;
}
}
9.5 访问限制
- 基于 IP 的访问限制 -http_access_module
- 基于用户的信任登录 -http_auth_basic_module
http_access_module
Syntax: allow address|all;
Default: --
Content: http,server,locaion,limit_except
Syntax: deny address|CIDR|all;
Default: --
Content: http,server,locaion,limit_except
server {
+ location ~ ^/admin.html {
+ deny 192.168.66.1
+ allow all
+ }
}
server {
+ location ~ ^/admin.html {
+ if ($http_x_forwarded_for !~* '^8\.8\.8\.8'){
+ return 403
+ }
+ }
}
符号 | 含义 |
---|---|
= | 严格匹配,如果这个查询匹配,那么将停止搜索并立即处理此请求 |
~ | 区分大小写匹配 |
!~ | 区分大小写不匹配 |
~* | 不区分大小写匹配 |
!~* | 不区分大小写不匹配 |
^~ | 如果把这个前缀用于一个常规字符串,那么就是告诉 nginx 如果路径匹配,那么不测试正则表达式 |
http_auth_basic_module
Syntax: auth_basic string|off;
Default: auth_basic off;
Content: http,server,locaion,limit_except
Syntax: auth_basic_user_file file;
Default: --
Content: http,server,locaion,limit_except
server {
+ auth_basic '请登录';
+ auth_basic_user_file /data/users/users.conf;
}
htpasswd -c /data/users/users.conf hyf
10. 跨域
一个域名下的脚步或文档去请求另一个域名下的资源
Syntax: add_header name value;
Default: --;
Content: http,server,locaion
location ~ .*\.json$ {
add_header Access-Control-Allow-Origin http://localhost:8888;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
root /data/json;
}
11. 防盗链
- 防止资源被盗用
- 保证信息安全
- 防止流量过量
- 使用
http_refer
实现
Syntax: valid_referers none | blocked | server_names | string ;
Default: --;
Content: server,locaion
location ~ .*\.(jpg|png|gif)$ {
valid_referers none blocked xx.xx.xx.xx; # 没有referer头,或非正式HTTP请求,或特定的IP地址都是可以访问的
if($invalid_referer) { #允许访问为0,不允许访问为1
return 403
}
root /data/json;
}
12. 建站
13. rewrite
隐藏真正的地址,同一域名下更换请求资源的路径
Syntax: rewrite <regex> <replacement> [flag];
Default: --;
Content: server,location,if
rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1 break;
flag 标记说明
参数名 | 作用 |
---|---|
last | 本条规则匹配完成后,继续向下匹配新的 location URI 规则 |
break | 本条规则匹配完成即终止,不再匹配后面的任何规则 |
redirect | 返回 302 临时重定向,浏览器地址会显示跳转后的 URL 地址 |
permanent | 返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址 |
防火墙设置
开启防火墙
systemctl start firewalld
重启防火墙
systemctl restart firewalld
重载规则
firewall-cmd --reload
查看已配置规则
firewall-cmd --list-all
指定端口和 ip 访问
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.75.137" port protocol="tcp" port="8080" accept"
# --permanent 永久
移除规则
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.75.137" port port="8080" protocol="tcp" accept"
网关配置
upstream httpds {
server 192.168.44.102 weight=8 down;
server 192.168.44.103:8080 weight=2;
server 192.168.44.104:8080 weight=1 backup;
}
location / {
rewrite ^/([0-9]+).html$ /index.jsp?pageNum=$1 redirect;
proxy_pass http://httpds ;
}
14. 高可用配置
- 主机和备用机
- 虚拟 ip:vip
keepalived 安装
-
克隆 nginx01 虚拟机
-
修改 mac 地址-设置--网络适配器--高级--生成--完成
-
编译安装
下载地址: https://www.keepalived.org/download.html#
使用 ./configure 编译安装
如遇报错提示configure: error: !!! OpenSSL is not properly installed on your system. !!! !!! Can not include OpenSSL headers files. !!!
安装依赖
yum install openssl-devel
-
yum 安装
yum install keepalived
keepalived 配置
使用 yum 安装后配置文件在/etc/keepalived/keepalived.conf
global_defs {
router_id LVS_DEVElL # 自定义名称
}
vrrp_instance VI_1 { # 实例名称VI_1
state MASTER # BACKUP备用机
interface eth0 # 网卡名称
virtual_router_id 51
priority 100 # 优先级越高 = master
advert_int 1 # 间隔检测的时间
authentication { # 同一组保持一致
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { # 虚拟ip
192.168.75.200
}
}
15. LNMP、Oneinstack
LNMP: Linux + nginx + mysql + php
Oneinstack:一站式安装
16. 附录
用户空间和内核空间
我们知道操作系统采用的是虚拟地址空间,以 32 位操作系统举例,它的寻址空间为 4G(2 的 32 次方),这里解释二个概念:
- 寻址: 是指操作系统能找到的地址范围,32 位指的是地址总线的位数,你就想象 32 位的二进制数,每一位可以是 0,可以是 1,是不是有 2 的 32 次方种可能,2^32 次方就是可以访问到的最大内存空间,也就是 4G。
- 虚拟地址空间:为什么叫虚拟,因为我们内存一共就 4G,但操作系统为每一个进程都分配了 4G 的内存空间,这个内存空间实际是虚拟的,虚拟内存到真实内存有个映射关系。例如 X86 cpu 采用的段页式地址映射模型。
操作系统将这 4G 可访问的内存空间分为二部分,一部分是内核空间,一部分是用户空间。
内核空间是操作系统内核访问的区域,独立于普通的应用程序,是受保护的内存空间。
用户空间是普通应用程序可访问的内存区域。
以 linux 操作系统为例,将最高的 1G 字节(从虚拟地址 0xC0000000 到 0xFFFFFFFF),供内核使用,称为内核空间,而将较低的 3G 字节(从虚拟地址 0x00000000 到 0xBFFFFFFF),供各个进程使用,称为用户空间。
进程上下文切换
- 保存上下文信息
- 还原上下文信息
进程的阻塞
- 正在执行的进程,由于期待的某些事件未发生,将自己的运行状态变为阻塞状态
- 进程的阻塞是进程自身的一种主动行为,也因为只有处于运行态的进程(获取 CPU),才能将其转为阻塞状态,当进程进入阻塞是不占用 CPU 资源的
文件描述符
- 一个用于表述指向文件引入的抽象概念
- 当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符
I/O 模式
- 对于一次 IO 访问,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的缓存区,最后交给进程。当一个 read 发生时,会经历两个阶段
- 等待数据准备
- 将数据从内核拷贝到进程中
分类
- 同步阻塞 IO
- 同步非阻塞 IO
- 异步阻塞 IO(IO 多路复用)
- 异步非阻塞 IO
事件模型
- 目前支持 IO 多路复用的系统调用有 select,poll 和 epoll
- I/O 多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(读就绪,写就绪)。能够通知程序进行相应的读写操作
- 但 select/poll/epoll 本质上都是同步 IO,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的
进程间通信
-
管道(也称作共享文件)
-
管道中的数据只能单向流动
-
匿名管道只能用于父子进程之间的通信。
-
管道的本质就是内核在内存中开辟了一个缓冲区,这个缓冲区与管道文件相关联,对管道文件的操作,被内核转换成对这块缓冲区的操作
-
管道这种进程通信方式虽然使用简单,但是效率比较低,不适合进程间频繁地交换数据,并且管道只能传输无格式的字节流。
-
-
消息队列(也称作消息传递)
- 消息队列的本质就是存放在内存中的消息的链表,而消息本质上是用户自定义的数据结构
需要注意的是,消息队列对于交换较少数量的数据很有用,因为无需避免冲突。但是,由于用户进程写入数据到内存中的消息队列时,会发生从用户态拷贝数据到内核态的过程;同样的,另一个用户进程读取内存中的消息数据时,会发生从内核态拷贝数据到用户态的过程。因此,如果数据量较大,使用消息队列就会造成频繁的系统调用,也就是需要消耗更多的时间以便内核介入。
-
共享内存(也称作共享存储)
两个不同进程的逻辑地址通过页表映射到物理空间的同一区域,它们所共同指向的这块区域就是共享内存。不同于消息队列频繁的系统调用,对于共享内存机制来说,仅在建立共享内存区域时需要系统调用,一旦建立共享内存,所有的访问都可作为常规内存访问,无需借助内核。这样,数据就不需要在进程之间来回拷贝,所以这是最快的一种进程通信方式。
-
信号量和 PV 操作
为了保证共享内存在任何时刻只有一个进程在访问(互斥),并且使得进程们能够按照某个特定顺序访问共享内存(同步),我们就可以使用进程的同步与互斥机制,常见的比如信号量与 PV 操作。
信号量其实就是一个变量 ,我们可以用一个信号量来表示系统中某种资源的数量,比如:系统中只有一台打印机,就可以设置一个初值为 1 的信号量。
用户进程可以通过使用操作系统提供的一对原语来对信号量进行操作,从而很方便的实现进程互斥或同步。这一对原语就是 PV 操作:
1)P 操作:将信号量值减 1,表示申请占用一个资源。如果结果小于 0,表示已经没有可用资源,则执行 P 操作的进程被阻塞。如果结果大于等于 0,表示现有的资源足够你使用,则执行 P 操作的进程继续执行。
可以这么理解,当信号量的值为 2 的时候,表示有 2 个资源可以使用,当信号量的值为 -2 的时候,表示有两个进程正在等待使用这个资源。不看这句话真的无法理解 V 操作,看完顿时如梦初醒。
2)V 操作:将信号量值加 1,表示释放一个资源,即使用完资源后归还资源。若加完后信号量的值小于等于 0,表示有某些进程正在等待该资源,由于我们已经释放出一个资源了,因此需要唤醒一个等待使用该资源(就绪态)的进程,使之运行下去。
-
信号
信号是进程通信机制中唯一的异步通信机制,它可以在任何时候发送信号给某个进程。通过发送指定信号来通知进程某个异步事件的发送,以迫使进程执行信号处理程序。信号处理完毕后,被中断进程将恢复执行。用户、内核和进程都能生成和发送信号。
比如常见的组合键 Ctrl+C 产生 SIGINT 信号,比如 kill -9 1111 ,表示给 PID 为 1111 的进程发送 SIGKILL 信号,让其立即结束。
-
套接字(Socket)
- 跨网络与不同主机上的进程进行通信
- Socket 套接字是网络通信的基石,是支持 TCP/IP 协议的网络通信的基本操作单元。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)