nginx

一、Web服务基础
1.1 Web服务发展历程

1993年中国首次接入国际互联网专线

1995年马云创建中国黄页

1999年阿里巴巴成立

2003年淘宝网上线

2004年支付宝创立

2009年首次双十一购物节(成交额5000万元)

2022年双十一成交额达5571亿元

1.2 Web服务器类型
Apache服务器
Prefork模型:多进程模式,稳定但并发能力有限(最大1024)

Worker模型:多进程+多线程混合模式,支持更高并发

Event模型:事件驱动模型,解决keepalive资源占用问题

Nginx服务器
由俄罗斯工程师Igor Sysoev开发

2019年被F5以6.7亿美元收购

特点:高性能、高并发、低内存消耗

应用场景:静态资源服务、反向代理、负载均衡等

1.3 用户体验关键指标
1秒最优,1-3秒较优,3-10秒较慢,10秒以上不可接受

Google:慢500ms = 20%用户流失

亚马逊:慢100ms = 1%交易放弃

二、Nginx核心架构
2.1 进程模型

Master进程:管理Worker进程,不处理请求

Worker进程:实际处理请求,数量通常等于CPU核心数

2.2 高性能原理
事件驱动模型(epoll)

非阻塞I/O

多路复用

零拷贝技术

2.3 模块化设计
核心模块

标准HTTP模块

可选HTTP模块

邮件服务模块

第三方模块

三 实战

nginx的安装


[root@Nginx nginx-1.24.0]# useradd -s /sbin/nologin -M nginx
[root@Nginx nginx]# tar zxf nginx-1.24.0.tar.gz
[root@Nginx nginx-1.24.0]# useradd -s /sbin/nologin -M nginx
[root@Nginx nginx]# cd nginx-1.24.0/
[root@Nginx nginx-1.24.0]# ls
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README
[root@Nginx nginx-1.24.0]# ./configure --prefix=/usr/local/nginx \
--user=nginx \ # 指定nginx运行用户
--group=nginx \ # 指定nginx运行组
--with-http_ssl_module \ # 支持https://
--with-http_v2_module \ # 支持http版本2
--with-http_realip_module \ # 支持ip透传
--with-http_stub_status_module \ # 支持状态页面
--with-http_gzip_static_module \ # 支持压缩
--with-pcre \ # 支持正则
--with-stream \ # 支持tcp反向代理
--with-stream_ssl_module \ # 支持tcp的ssl加密
--with-stream_realip_module # 支持tcp的透传ip
[root@Nginx nginx-1.24.0]# make && make install

平滑升级

[root@Nginx nginx]# tar zxf nginx-1.26.1.tar.gz
[root@Nginx nginx]# cd nginx-1.26.1/
#开始编译新版本
[root@Nginx nginx-1.26.1]# ./configure --with-http_ssl_module --withhttp_v2_module --with-http_realip_module --with-http_stub_status_module --withhttp_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --
with-stream_realip_module
#只要make无需要make install
[root@Nginx nginx-1.26.1]# make
#查看两个版本
[root@Nginx nginx-1.26.1]# ll objs/nginx /usr/local/nginx/sbin/nginx
-rwxr-xr-x 1 root root 1239416 Jul 18 15:08 objs/nginx
-rwxr-xr-x 1 root root 5671488 Jul 18 11:41 /usr/local/nginx/sbin/nginx
#把之前的旧版的nginx命令备份
[root@Nginx ~]# cd /usr/local/nginx/sbin/
[root@Nginx sbin]# cp nginx nginx.24
#把新版本的nginx命令复制过去
[root@Nginx sbin]# \cp -f /root/nginx/nginx-1.26.1/objs/nginx
/usr/local/nginx/sbin
#检测一下有没有问题
[root@Nginx sbin]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@Nginx sbin]# kill -USR2 48732 #nginx worker ID
#USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的
nginx
#此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80
#此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进
程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。
[root@Nginx sbin]# ps aux | grep nginx
root 48732 0.0 0.1 9868 2436 ? Ss 14:17 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
nobody 48733 0.0 0.2 14200 4868 ? S 14:17 0:00 nginx: worker
process
root 52075 0.0 0.3 9876 6528 ? S 15:41 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
nobody 52076 0.0 0.2 14208 4868 ? S 15:41 0:00 nginx: worker
process
[root@Nginx sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.24.0 ##依旧是旧版本生生效
Date: Thu, 18 Jul 2024 07:45:58 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 18 Jul 2024 03:41:13 GMT
Connection: keep-alive
ETag: "66988ed9-267"
Accept-Ranges: bytes
#回收旧版本
[root@Nginx sbin]# kill -WINCH 48732
[root@Nginx sbin]# ps aux | grep nginx
root 48732 0.0 0.1 9868 2436 ? Ss 14:17 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
root 52075 0.0 0.3 9876 6528 ? S 15:41 0:00 nginx: master
process /usr/local/nginx/sbin/nginx
nobody 52076 0.0 0.2 14208 4868 ? S 15:41 0:00 nginx: worker
process
#检测版本信息
[root@Nginx ~]# nginx -V
nginx version: nginx/1.24.0

编写启动脚本

[root@Nginx ~]# vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root@Nginx ~]# nginx -s stop
[root@Nginx ~]# systemctl start nginx

解决高并发

[root@Nginx ~]# ulimit -n 102400
[root@Nginx ~]# ab -c 5000 -n 10000 http://10.0.0.8/
#默认配置不支持高并发,会出现以下错误日志
[root@Nginx ~]# tail /apps/nginx/logs/error.log
2020/09/24 21:19:33 [crit] 41006#0: *1105860 open() "/apps/nginx/html/50x.html"
failed (24: Too many open files), client: 10.0.0.7, server: localhost, request:
"GET / HTTP/1.0", host: "10.0.0.8"
2020/09/24 21:19:33 [crit] 41006#0: accept4() failed (24: Too many open files)
2020/09/24 21:19:33 [crit] 41006#0: *1114177 open()
"/apps/nginx/html/index.html" failed (24: Too many open files), client: 10.0.0.7,
server: localhost, request: "GET / HTTP/1.0", host: "10.0.0.8"
#修改配置
[root@Nginx ~]# vim /etc/security/limits.conf
* - nproc 100000
[root@Nginx ~]# vim /apps/nginx/conf/nginx.conf
worker_rlimit_nofile 100000;
[root@Nginx ~]# systemctl restart nginx

建立站点

root 与 alias

server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
location /dirtest { #必须建立/mnt/dirtest才能访问
root /mnt;
}
}
alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于
location上下文,此指令使用较少
alias示例:
Note
location中使用root指令和alias指令的意义不同
[root@Nginx ~]# mkdir /mnt/dirtest/
[root@Nginx ~]# echo dirtest page > /mnt/dirtest/index.html
[root@Nginx ~]# nginx -s reload
#重启Nginx并访问测试
[root@node100 ~]# curl lee.timinglee.org/dirtest/
dirtest page
server {
listen 80;
server_name lee.timinglee.org;
location / {
root /webdata/nginx/timinglee.org/lee/html;
}
location /dirtest {
root /mnt;
}
location /alias { #注意about后不要加/
#使用alias的时候uri后面如果加了斜杠,则下面的路径配置
必须加斜杠,否则403
alias /mnt/dirtest; #当访问alias的时候,会显示alias定义的/mnt/dirtest
里面的内容
}
}
#重启Nginx并访问测试
[root@node100 ~]# curl lee.timinglee.org/alias/
dirtest page

账号认证:

[root@Nginx ~]# htpasswd -cmb /usr/local/nginx/conf/.htpasswd admin lee #-b 表
示非交互建立用户认证
Adding password for user admin
[root@Nginx ~]# htpasswd -mb /usr/local/nginx/conf/.htpasswd lee lee
Adding password for user lee
[root@Nginx ~]# cat /usr/local/nginx/conf/.htpasswd
admin:$apr1$haGCKgCT$myogggALmqNecTyNupsWQ/
lee:$apr1$H97AyQPF$kGU.Tc4zn1E4Zkp/M4R6G.
[root@Nginx ~]# mkdir /webdata/nginx/timinglee.org/lee/login
[root@Nginx ~]# echo login > /webdata/nginx/timinglee.org/lee/login/index.html
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
location /login {
root /webdata/nginx/timinglee.org/lee;
index index.html;
auth_basic "login password";
auth_basic_user_file "/usr/local/nginx/conf/.htpasswd";
}
}
#重启Nginx并访问测试
[root@node100 ~]# curl lee.timinglee.org/login/ -u lee:lee
login
[root@node100 ~]# curl lee.timinglee.org/login/ -u admin:lee
login

自定义错误页面

[root@Nginx ~]# mkdir /webdata/nginx/timinglee/lee/errors -p
[root@Nginx ~]# echo error page > /webdata/nginx/timinglee/lee/errors/40x.html
server {
listen 80;
server_name lee.timinglee.org;
error_page 404 /40x.html
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}
}
测试:
[root@node100 ~]# curl lee.timinglee.org/haha
error page

自定义错误日志

[root@Nginx ~]# mkdir "/var/log/nginx" -p
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
error_page 404 /40x.html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}
}
#重启nginx并访问不存在的页面进行测试并验证是在指定目录生成新的日志文件

nginx长链接控制


keepalive_requests 3;
keepalive_timeout 65 60;
#开启长连接后,返回客户端的会话保持时间为60s,单次长连接累计请求达到指定次数请求或65秒就会被断
开,第二个数字60为发送给客户端应答报文头部中显示的超时时间设置为60s:如不设置客户端将不显示超时时
间。
Keep-Alive:timeout=60 #浏览器收到的服务器返回的报文
#如果设置为0表示关闭会话保持功能,将如下显示:
#Connection:close 浏览器收到的服务器返回的报文
#使用命令测试:
[root@node100 ~]# telnet lee.timinglee.org 80

nginx下载服务器

[root@Nginx ~]# mkdir -p /webdata/nginx/timinglee.org/lee/download
[root@Nginx ~]# cp /root/anaconda-ks.cfg
/webdata/nginx/timinglee.org/lee/download
[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
server {
listen 80;
server_name lee.timinglee.org;
root /webdata/nginx/timinglee.org/lee;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
try_files $uri $uri.html $uri/index.html /error/default.html;
location = /40x.html {
root /webdata/nginx/timinglee/lee/errors;
}
location /download {
autoindex on; #自动索引功能
autoindex_exact_size on; #计算文件确切大小(单位bytes),此为默认值,off只显示
大概大小(单位kb、mb、gb)

防盗链

[root@client ~]# yum install httpd -y
[root@client html]# vim /var/www/html/index.html
#准备盗链web页面:
<html>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>盗链</title>
</head>
<body>
<img src="http://www.timinglee.org/images/lee.png" >
<h1 style="color:red">欢迎大家</h1>
<p><a href=http://www.timinglee.org>狂点老李</a>出门见喜</p>
</body>
</html>
~
#重启apache并访问ip
#验证两个域名的日志,是否会在被盗连的web站点的日志中出现以下盗链日志信息:
[root@Nginx ~]# cat /usr/local/nginx/logs/access.log

nginx 反向代理和动静分离

测试

负载均衡

[root@apache20 ~]# yum install httpd -y
[root@apache20 ~]# echo "web1 172.25.254.20" > /var/www/html/index.html
[root@apache20 ~]# systemctl enable --now httpd
[root@apache30 ~]# yum install httpd -y
[root@apache30 ~]# echo "web2 172.25.254.30" >> /var/www/html/index.html
[root@apache30 ~]# systemctl enable --now httpd

nginx -s reload
yum install httpd -y
 echo "web1 172.25.254.10" > /var/www/html/index.html
systemctl enable --now httpd
yum install httpd -y
 echo "web2 172.25.254.20" >> /var/www/html/index.html
 systemctl enable --now httpd

PHP源码安装

tomcat

 一、WEB 技术基础与演进

1.1 网络通信与编程模式演变

计算机硬件资源的充分利用催生了多进程与多线程技术,使得单台主机可作为服务器为多个客户端提供服务。跨主机进程间通信依赖网络编程,其中Socket(套接字) 是最核心的接口,形成了经典的C/S(Client/Server)编程模式。这种模式基于传输层协议(TCP/UDP),典型应用如 QQ、迅雷等,需在客户端和服务器端分别安装专用程序。

1990 年,HTTP 协议与浏览器的诞生标志着 WEB 时代的开启。与 C/S 模式不同,B/S(Browser/Server)模式通过应用层的 HTTP 协议传输文本数据,浏览器负责渲染服务器返回的 HTML 内容,无需安装专用客户端。早期 WEB 技术以静态内容为主,随着用户需求升级,动态网页技术应运而生:

CGI(通用网关接口):首次实现通过 URL 映射执行服务器端脚本,动态生成内容。ASP、PHP、JSP:后续出现的服务器端编程技术,进一步完善动态网页开发能力,形成 “前端(HTML/CSS/JS)+ 后端” 的 B/S 架构分工。

1.2 前端核心技术详解

1.2.1 HTML:网页的骨架

HTML(超文本标记语言)并非编程语言,而是通过标签描述网页结构与内容的标记语言。其 “超文本” 特性突破纯文本限制,可包含图片、音频、视频等非文本元素,以及字体样式、布局等格式信息。

示例基础 HTML 结构:

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <h1>核心内容标题</h1>
</body>
</html>

浏览器作为 HTML 的解析器,负责将标签定义的格式转化为可视化页面。HTTP 协议的制定则解决了超文本内容的网络传输问题。

1.2.2 CSS:网页的样式

随着网页设计需求复杂化,HTML 内置的样式功能导致代码臃肿,CSS(层叠样式表) 应运而生。1994 年 W3C(万维网联盟)成立后主导 CSS 标准制定:

1996 年发布 CSS 1.0,奠定基础样式体系;

1998 年发布 CSS 2.0,增强布局与定位能力;

CSS 3 采用模块化设计,各模块独立扩展功能(如动画、圆角等)。

由于不同浏览器引擎对 CSS 的支持存在差异(如早期 IE 与其他浏览器的兼容性问题),实现跨浏览器一致的页面效果曾是前端开发的主要挑战。

1.2.3 JavaScript:网页的交互灵魂

JavaScript(JS)是唯一被主流浏览器支持的前端动态脚本语言,与 HTML、CSS 并称 WEB 三大核心技术。其发展历程关键节点包括:

1995 年:网景公司为 Netscape Navigator 浏览器推出 LiveScript,后更名为 JavaScript(借 Java 名气推广);

1997 年:ECMA(欧洲计算机制造商协会)制定ECMAScript 标准,统一 JS 语法(微软 JScript 等均为其实现);

2008 年:Chrome 浏览器的V8 引擎发布,采用本地编译而非解释执行,大幅提升 JS 运行效率;

2009 年:基于 V8 引擎的Node.js诞生,使 JS 可用于服务器端编程,成为唯一前后端通用语言,并催生 npm 包管理生态。

1.3 同步与异步交互技术

同步交互:用户请求后需等待服务器响应,页面整体刷新(即使仅修改局部内容),存在带宽浪费、体验差等问题(如早期注册表单因验证失败需重新填写)。异步交互:通过Ajax(异步 JavaScript 和 XML) 技术实现局部更新,无需重载整个页面。其核心是浏览器内置的XMLHttpRequest对象,可在后台与服务器交换少量数据。Ajax 虽非新技术发明,而是多种技术的组合(JS、XML/JSON、DOM 等),但彻底改变了 WEB 交互模式,推动前后端分离架构发展。

二、WEB 应用架构与框架

2.1 资源访问与架构模式

WEB 应用的资源访问流程可分为:

静态资源(HTML、CSS、JS、图片):由静态服务器直接返回给浏览器;

动态内容:浏览器 / 移动端 App 向业务服务器请求,业务服务器访问数据库后生成动态数据返回。

现代前端开发中,移动端 App 常内置 HTML 和 JS 文件以减少网络传输,仅动态数据从业务服务器获取。

2.2 主流应用架构对比

架构类型 核心特点 优势 劣势 适用场景
单体架构 所有功能模块集成于单一工程,统一部署为一个进程 开发、测试、部署简单;初期维护成本低 耦合度高,某模块故障可能导致全站不可用;扩展需整体复制 小型应用、快速迭代原型
微服务架构 按业务拆分独立服务,松耦合,可独立部署与扩展 服务内聚性高,开发效率高;支持多语言;故障影响范围小 增加开发、测试、运维复杂度;需解决分布式事务与服务治理 大型复杂系统、高并发场景
2.2.1 微服务框架代表

Dubbo:阿里开源的高性能 Java RPC 框架,依赖 Zookeeper 实现服务注册与发现,适用于 Java 生态的微服务通信。

Spring Cloud:基于 HTTP 协议的 REST 风格微服务解决方案,提供服务注册、配置中心、熔断等完整组件,兼容性更强。

三. 实战

tomcat安装

压缩包下载到虚拟机

[root@tomcatA ~]# tar zxf apache-tomcat-9.0.107.tar.gz -C /usr/local/
[root@tomcatA ~]# cd /usr/local/
[root@tomcatA local]# ls
apache-tomcat-9.0.107 bin etc games include lib lib64 libexec sbin share
src
[root@tomcatA local]# mv apache-tomcat-9.0.107/ tomcat
[root@tomcatA local]# ls

1.生成tomcat的主配置文件
[root@web1 ~]# vim /usr/local/tomcat/conf/tomcat.conf
 
JAVA_HOME=/etc/alternatives/jre_openjdk
.生成启动文件
[root@tomcat ~]# vim /lib/systemd/system/tomcat.service
[Unit]
Description=Tomcat
#After=syslog.target network.target remote-fs.target nss-lookup.target
After=syslog.target network.target
[Service]
Type=forking
EnvironmentFile=/usr/local/tomcat/conf/tomcat.conf
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
PrivateTmp=true
User=tomcat
Group=tomcat
[Install]
WantedBy=multi-user.target

[root@tomcatB bin]# useradd -s /sbin/nologin -M tomcat
[root@tomcatB bin]# chown tomcat.tomcat /usr/local/tomcat/ -R

反向代理

web1和web2

nginx

[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
location ~ \.jsp$ {
proxy_pass http://172.25.254.10:8080;
}

实现负载均衡

[root@Nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf
upstream tomcat {
#ip_bash;
#hash $cookie_JSESSIONID;
server 172.25.254.10:8080;
server 172.25.254.20:8080;
}
server {
listen 80;
server_name lee.timinglee.org;
root /webdataw/nginx/timinglee.org/lee;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
try_files $uri $uri.html $uri/index.html /error/default.html;
location ~ \.jsp$ {
proxy_pass http://tomcat;
}
}

Memcached

[root@tomcat ~]# vim /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 0.0.0.0,::1"

配置 session 共享服务器
安装如下插件
kryo-3.0.3.jar
asm-5.2.jar
objenesis-2.6.jar
reflectasm-1.11.9.jar
minlog-1.3.1.jar
kryo-serializers-0.45.jar
msm-kryo-serializer-2.3.2.jar
memcached-session-manager-tc9-2.3.2.jar
spymemcached-2.12.3.jar
memcached-session-manager-2.3.2.jar

[root@tomcat-node1 lib]# vim /usr/local/tomcat/conf/context.xml

web2和web1操作相同

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐