1. Nginx简介
Nginx是一款轻量级的Web 服务器/反向代理服务器
http://nginx.org/en/download.html
占有内存少,并发能力强
官方测试nginx能够支撑5万并发链接,并且CPU、内存等资源消耗却非常低,运行非常稳定。
Tengine淘宝基于Nginx研发的web服务器
http://tengine.taobao.org/book/
2. 使用场景
2.1. 高并发场景
- 高并发通常是指通过设计保证系统能够同时并行处理很多请求。通俗来讲,高并发是指在同一个时间点,有很多用户同时的访问同一 API 接口或者 Url 地址。它经常会发生在有大活跃用户量,用户高聚集的业务场景中。
- 会给服务器和硬件环境带来很大的压力
- 大学选体育课:
- 很卡,挤不进去
- 池:
- 刚开始的时候创建多个请求等待使用
- 使用完毕后并不会销毁,而是重新归还到池
- 如果业务量比较大,我们通过池控制最大连接的数
- 负载均衡(load Balance )
- 将请求/数据【均匀】分摊到多个操作单元上执行,负载均衡的关键在于【均匀】
2.2. 正向代理
- 代理人明确买家的目标是谁,代理人帮我们去联系目标
- 小明
- 王妈妈
- 金莲
- 金莲
- 王妈妈
2.3. 反向代理
- 客户只需要发送请求到代理服务器,代理服务器会将请求转发给内部的服务器去处理,处理完毕之后会将结果返回给客户
- 但整个过程中客户和实际处理服务器是不会直接建立连接的
3. Nginx源码安装
3.1. 解编安启
- 将安装包上传到Linux虚拟机
- 解压,并把Nginx存放到指定目录
tar -zxf nginx-1.8.1.tar.gz
- 需要安装nginx依赖的软件
yum install gcc pcre-devel zlib-devel openssl-devel -y
- 配置安装路径
./configure --prefix=/opt/lzj/nginx-1.8.1
- 开始编译并安装nginx
make && make install
- 开启Ngxin
cd /opt/lzj/nginx-1.8.1/sbin
./nginx
3.2. 常用命令
关闭nginx服务
kill `cat /usr/local/nginx/logs/nginx.pid`
nginx -s reload :修改配置后重新加载生效
nginx -s reopen :重新打开日志文件
nginx -t -c /path/to/nginx.conf 测试nginx配置文件是否正确
关闭nginx:
nginx -s stop :快速停止nginx
quit :完整有序的停止nginx
其他的停止nginx 方式:
ps -ef | grep nginx
kill -QUIT 主进程号 :从容停止Nginx
kill -TERM 主进程号 :快速停止Nginx
pkill -9 nginx :强制停止Nginx
启动nginx:
nginx -c /path/to/nginx.conf
平滑重启nginx:
kill -HUP 主进程号
3.3. 安装目录
conf
配置文件
html
静态资源文件
sbin
可执行文件
logs
日志文件
3.4. 配置文件
Nginx中文文档
https://www.nginx.cn/doc/index.html
# user 指定运行 nginx 的用户和组(第一个参数为用户第二个为组,这里只有用户)
#user nobody;
# 指定工作进程数(一般设置为CPU核数)
worker_processes 1;
# 指定错误日志为 logs/ 目录下的 error.log 文件
#error_log logs/error.log;
# 指定错误日志,并指定写入格式为 notice
#error_log logs/error.log notice;
# 指定错误日志,并指定写入格式为 info
#error_log logs/error.log info;
# 指定 pid 文件(存放主进程 pid 号)
#pid logs/nginx.pid;
# nginx 连接配置模块
events {
# 指定每个工作进程最大连接数为 1024
worker_connections 1024;
}
# http 配置模块
http {
# 通过 include 加载 mime.types 文件,里面的 types {} 模块将文件扩展名映射到响应
的 MIME 类型
include mime.types;
# 定义响应的默认 MIME 类型
default_type application/octet-stream;
# 写入格式 main 的内容格式如下
#log_format main '$remote_addr - $remote_user [$time_local] "$request"'
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
# 指定访问日志和写入格式为 main
#access_log logs/access.log main;
# 启用或者禁用 sendfile()
sendfile on;
# 启用或者禁用使用套接字选项(仅在 sendfile 使用时使用)
#tcp_nopush on;
# 0 值禁用保持活动的客户端连接
#keepalive_timeout 0;
# 65 s 超时
keepalive_timeout 65;
# 启用或者禁用 gzip
#gzip on;
# 虚拟主机配置模块
server {
# 监听 80 端口
listen 80;
# 监听域名为 localhost
server_name localhost;
# 将指定的 charset 添加到 “Content-Type” 响应头字段。
# 如果此charset与source_charset指令中指定的charset不同,则执行转换。
#charset koi8-r;
# 指定该虚拟主机的访问日志
#access_log logs/host.access.log main;
# 将特定的文件或目录重新定位,如 php 文件,image 目录等
location / {
# 设置请求的根目录
root html;
# 定义索引,按顺序匹配
index index.html index.htm;
}
# 定义显示 404 错误的 uri
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
# location 精准匹配 '/50x.html'
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
# 正则表达式匹配 php 文件
#location ~ \.php$ {
# 设置代理服务器的协议和地址,以及应该映射位置的可选URI。作为协议,可以指定
“http”或“https”。该地址可以指定为一个域名或IP地址,以及一个可选端口
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# 设置 FastCGI 服务器的地址。地址可以指定为一个域名或 IP 地址,以及一个端口
# fastcgi_pass 127.0.0.1:9000;
# 设置将在以斜杠结尾的URI之后追加的文件名,
# fastcgi_index index.php;
# 设置一个应该传递给FastCGI服务器的参数。
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# 加载 conf/fastcgi_params 文件
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based
configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
# ssl 配置,要启用 ssl 模块需要在编译 nginx 时加上 --with-http_ssl_module 参数
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
4. Nginx负载均衡
4.1. 集群搭建
节点分布
节点\角色 | Nginx | Tomcat | JDK |
---|---|---|---|
basenode | * | * | |
node01 | * | * | |
node02 | * | * | |
node03 | * | * |
BaseNode修改配置文件
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 0;
upstream lzj {
server 192.168.58.101:8080;
server 192.168.58.102:8080;
server 192.168.58.103:8080;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://lzj;
}
}
}
Tomcat配置信息
vi /opt/lzj/apache-tomcat--8.5.47/webapps/ROOT/index.jsp
<%@ page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>樂字节教育</title>
<link href="favicon.ico" rel="icon" type="image/x-icon" />
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon"
/>
</head>
<body>
<h1>welcome to 樂字节</h1>
<h2>Server:<%=request.getLocalAddr() %></h2>
<h2>Port:<%=request.getLocalPort() %></h2>
<h2>Client:<%=request.getRemoteAddr() %></h2>
<h2>Session:<%=session.getId() %></h2>
<hr/>
<img src="/static/img/qbl.jpg" height="200px" />
</body>
</html>
启动Tomcat和Nginx
访问Nginx,会依次将Tomcat页面显示到也面
4.2. 负载策略
4.2.1. 请求轮询
依次转发给配置的服务器
4.2.2. 增加权重
使用服务器权重,还可以进一步影响nginx负载均衡算法,谁的权重越大,分发到的请求就越多。
说你行你就行不行也行
upstream lzjweight {
server 192.168.58.101:8080 weight=2;
server 192.168.58.103:8080 weight=1;
}
4.2.3. 最少连接数
在连接负载最少的情况下,nginx会尽量避免将过多的请求分发给繁忙的应用程序服务器,而是将新请求分发给不太繁忙的服务器,避免服务器过载。
upstream lzjleast {
least_conn;
server 192.168.58.101:8080;
server 192.168.58.103:8080;
}
4.2.4. IpHash
确保来自同一客户端的请求将始终定向到同一台服务器,除非此服务器不可用
upstream lzjhash {
ip_hash;
server 192.168.58.101:8080;
server 192.168.58.103:8080;
}
5. 资源静态化
5.1. 图床
由外部服务器统一管理图片
5.2. 配置静态资源
<body>
<h1> welcome to cluster</h1>
<h1> 服务器地址: <%= request.getLocalAddr() %> </h1>
<h1> 客户端地址: <%= request.getRemoteAddr() %> </h1>
<h1> Session的ID : <%= session.getId() %> </h1>
<img width="200px" src="/static/qbl.jpg" />
</body>
##在Nginx的home目录下创建一个static文件夹,然后存放图片
location ^~ /static/ {
root html;
}
5.3. 路径路由规则
location = / {
#规则A
}
location = /login {
#规则B
}
location ^~ /static/ {
#规则C
}
location ~ \.(gif|jpg|png|js|css)$ {
#规则D
}
location ~* \.png$ {
#规则E
}
location !~ \.xhtml$ {
#规则F
}
location !~* \.xhtml$ {
#规则G
}
location / {
#规则H
}
访问根目录/, 比如http://localhost/ 将匹配规则A
访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H
访问 http://localhost/static/a.html 将匹配规则C
访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用, 而 http://localhost/static/c.png 则优先匹配到 规则C
访问 http://localhost/a.PNG 则匹配规则E, 而不会匹配规则D,因为规则E不区分大小写。
访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。
访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理服务器存在。
6. 单Linux搭建多Tomcat
6.1. 拷贝多台
6.2. 环境变量
设置并执行 source /etc/profile
#tomcat8080
export CATALINA_HOME=/opt/lzj/apache-tomcat-8080
export CATALINA_BASE=/opt/lzj/apache-tomcat-8080
export TOMCAT_HOME=/opt/lzj/apache-tomcat-8080
#tomcat18080
export CATALINA_HOME18080=/opt/lzj/apache-tomcat-18080
export CATALINA_BASE18080=/opt/lzj/apache-tomcat-18080
export TOMCAT_HOME18080=/opt/lzj/apache-tomcat-18080
6.3. server.xml文件
只需要修改tomcat18080即可,第一台保持不变
22--默认为8005--》修改为18005
<Server port="18005" shutdown="SHUTDOWN">
69--默认为8080--》修改为18080
<Connector port="18080" protocol="HTTP/1.1" connectionTimeout="20000"
redirectPort="8443" />
116-默认为8009--》修改为18009
<Connector port="18009" protocol="AJP/1.3" redirectPort="8443" />
6.4. catalina.sh脚本
只需要修改Tomcat18080即可,修改catalina.sh
####################第二台tomcat配置,113行开始
export CATALINA_BASE=$CATALINA_BASE18080
export CATALINA_HOME=$CATALINA_HOME18080
export TOMCAT_HOME=$TOMCAT_HOME18080
6.5. 启动Tomcat
/apache-tomcat8080/bin/startup.sh
./apache-tomcat18080/bin/startup.sh
7. 虚拟主机
- 虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机,每台虚拟主机都可以是一个独立的网站,可以具有独立的域名,具有完整的Intemet服务器功能(WWW、FTP、Email等),同一台主机上的虚拟主机之间是完全独立的。从网站访问者来
看,每一台虚拟主机和一台独立的主机完全一样。 - 分类
- 1、基于域名的虚拟主机,通过域名来区分虚拟主机
- 2、基于端口的虚拟主机,通过端口来区分虚拟主机
7.1. 基于域名
修改Window的 C:\Windows\System32\drivers\etchosts
文件
192.168.58.100 www.lezijie666.com
192.168.58.100 www.lezijie888.com
修改Nginx配置文件
http {
upstream lzj666 {
server 192.168.58.101:8080;
server 192.168.58.102:8080;
server 192.168.58.103:8080;
}
upstream lzj888 {
server 192.168.58.101:18080;
server 192.168.58.102:18080;
server 192.168.58.103:18080;
}
server {
listen 80;
server_name www.lezijie666.com;
location / {
proxy_pass http://lzj666;
}
}
server {
listen 80;
server_name www.lezijie888.com;
location / {
proxy_pass http://lzj888;
}
}
}
7.2. 基于端口
修改Window的 C:\Windows\System32\drivers\etchosts
文件
192.168.58.100 www.lezijie10086.com
修改Nginx配置文件
http {
upstream lzj8080 {
server 192.168.58.101:8080;
server 192.168.58.102:8080;
server 192.168.58.103:8080;
}
upstream lzj18080 {
server 192.168.58.101:18080;
server 192.168.58.102:18080;
server 192.168.58.103:18080;
}
server {
listen 8080;
server_name www.lezijie10086.com;
location / {
proxy_pass http://lzj8080;
}
}
server {
listen 18080;
server_name www.lezijie10086.com;
location / {
proxy_pass http://lzj18080;
}
}
}
8. Session一致性
节点分布
节点\角色 | Nginx | Tomcat | JDK | memcached |
---|---|---|---|---|
basenode | * | * | ||
node01 | * | * | ||
node02 | * | * | ||
node03 | * | * |
- 内存数据库
- 安装数据库
- yum install memcached -y
- 开启数据库服务
- systemctl status memcached
- systemctl start memcached
- systemctl enable memcached
- vim /etc/sysconfig/memcached
- 安装数据库
- Tomcat
- 拷贝jar包到当前服务器lib目录下
- 要注意memcached的版本
- 如果一个机器有多个tomcat都需要session一致
- 配置tomcat/conf/server.xml
- 相同项目如果想共享session,需要把jvmRoute命名一致
- 如果你只有一个tomcat,忽略此步骤
- 拷贝jar包到当前服务器lib目录下
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm18080"></Engine>
配置 tomcat/conf/context.xml
<Manager
className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.58.101:11211"
sticky="true"
lockingMode="auto"
sessionBackupAsync="false"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
sessionBackupTimeout="1000"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoT
ranscoderFactory" />
重启Tomcat服务器
访问发现同一个server是可以共享session的,但是不同server因为涉及到跨域的问题
session还是不同的,需要设置cookie的domain
9.ssl 配置nginx
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#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 logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
# 设置字符集
charset utf-8;
listen 443 ssl;
# 配置HTTPS的默认访问端口为443。
# 如果未在此处配置HTTPS的默认访问端口,可能会造成Nginx无法启动。
# 如果您使用Nginx 1.15.0及以上版本,请使用listen 443 ssl代替listen 443和ssl on。
server_name jbzg.net;
# 需要将 /xxx更换为你的web目录
index index.html index.htm;
ssl_certificate /home/ssl/10162768_jbzg.net.pem;
# 需要将 /home/cert/xxx.pem替换成已上传的证书文件的名称。
ssl_certificate_key /home/ssl/10162768_jbzg.net.key;
# 需要将 /home/cert/xxx.key替换成已上传的证书密钥文件的名称和所在目录。
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
# 表示使用的加密套件的类型。
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #表示使用的TLS协议的类型。
ssl_prefer_server_ciphers on;
# ↓开启GZIP ,可以不开启。
gzip on;
gzip_buffers 32 4K;
gzip_comp_level 6;
gzip_min_length 100;
gzip_types application/javascript text/css text/xml;
gzip_disable "MSIE [1-6]\.";
gzip_vary on;
location / {
root /usr/local/nginx/html/aurora;
index index.html index.htm;
}
#location /api/ {
#proxy_pass http://后端地址/api/;
#}
}
}
报错:
nginx: [emerg] the "ssl" parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf:
参考
阿里云配置 https
参考