Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。
处理静态文件,索引文件以及自动索引;打开文件描述符缓冲。(html)
缺点:nginx支持高并发,但nginx没有处理动态语言的能力(php、jsp等),所以它会交给后端的apache处理。
无缓存的反向代理加速,简单的负载均衡和容错,可以实现高速缓存和负载均衡。Nginx作为负载均衡服务,在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP代理服务对外进行服务。Nginx采用C进行编写,不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多。
FastCGI,简单的负载均衡和容错。
API,nginx可以做为应用程序的接口,使用 openresty(本质上也是nginx) ,它集成了nginx的一些模块和第三方插件。
user在增长,根据摩尔定律,最初在我们想提升apache性能的时候,回去提升apache 的配置,但随着硬件配置不断的提升,apache的并发量增长的甚至越来越低,这个时候我们的nginx出现了,它的特点是高并发,高性能,可拓展性非常好,因为他的外围文档非常全面,可以二次开发,添加别的插件,并且它内存消耗特别少。3W的并发量,10个nginx进程只消耗150M内存。
nginx的配置文件非常简单
成本非常低,相比于F5等硬件负载均衡非常换算
支持重写规则,根据域名url 把我们的http请求分发到不同的http服务器组。
比如我们访问 baidu.com
会自动的定向到:
这就是重写的功能。
他还具有自带健康检查功能。
节省带宽,支持gzip压缩
模块化
nginx.org 开源网站
nginx.com 提供更高级的功能
安装稳定版
auto里面是一些辅助编译的工具,一些操作系统,函数库之类的辅助信息
changeds文件里面记录了历史的一些改动和bug修复信息
changes.ru 作者是俄罗斯人,这里面是俄罗斯版本的chenges
conf 配置文件,主要为了方便运维护人员进行配置,里面都是配置文件
configure 是编译用的二进制文件
contrib 提供的nginx语法检测的一些字体,通常用于检测字体。
比如我们此时的配置文件是由黑色和蓝色字体组成:
mkdir ~/.vim
cp -r ./vim/* ~/.vim 复制当前的vim目录到家目录下的.vim目录
此时我们在看刚才打开的文件就有颜色了,这样方便我们编写配置文件:
license 是一些证书
man 是一些文档手册
readme 是是说明
src 是源码目录。
编译:
安装依赖的开发包
yum install pcre-devel -y
yum install gcc -y
yum install openssl-devel -y
./configure --prefix=/usr/local/nginx --with-http_ssl_module 支持https
里面的Makefile是用来指定c语言之间的一些文件的调用关系。指定编译逻辑
然后
make
nginx 就是nginx的主程序
ngx_module_c 用来存放模块
最后
make install
conf 配置文件目录
html 默认发布目录
logs 日志目录
sbin 二进制程序目录
./nginx
说明我们的服务已经配置好了。
vim /usr/local/nginx/html/index.html
改变成功
cd nginx/sbin
./nginx -V
我们先从官网下载一个1.17版本的包用于更新,(其实这里应该先下载1.17版本,更新至1.18版本更合适,但这样同样也属于更新。)
我们先 备份 ,以防操作失误。
我们还是对1.17版本进行相同的解压和编译。
./configure --prefix=/usr/local/nginx --with-http_ssl_module
make
注意这时就不能在执行make install 了,make install 只在第一次编译安装nginx的时候执行,我们回滚不需要
这里在1.17的目录下也会出现objs的目录,下面也会产生一个 nginx 的二进制文件:
我们只需要把这个二进制文件复制到原来的1.18的nginx 的目录下的nginx二进制文件进行替换就行了
可见此时我们的版本已经是1.17版本了
这是nginx的两个进程。
但是此时我们程序中用户请求是还访问的是1.18版本的,我们应该让用户请求的时候访问1.17版本的:
kill -USR2 17476 USR2 是告诉17476进程不要在接受用户请求了并产生一个新的master进程来接收请求
这里说一下master 和worker 的作用;
如果没有修改配置文件的话,默认值与一个worker进程,master进程的作用是fork 和监控worker进程的,如果worker进程有异常,它就会重新fork一个worker进程进行接收请求,master进程本身不处理请求,worker进程才是真实处理请求的进程。
此时旧的master进程可能还正在处理请求:
kill -WINCH 17476 等它处理完请求后将它关闭
可以看出它还留了一个master 进程,它的作用其实还是备份,如果更新不成功,旧的进程还在,就可以恢复到原来的状态。
这样,我们就更新到1.17版本了。
我们现在将后来更新1.17版本回滚到第一次安装的1.18版本。
这时原来的nginx.old备份就其作用了
cd /usr/local/nginx/sbin/
cp -f nginx.old nginx 强制覆盖
./nginx -V 查看版本
此时又回到了1.18版本。
我们此时就要告诉原来的17476 master 进程重新拉起 worker进程进行接收请求。
此时又多了一个worker进程,它的父进程是17476进程,
同时告诉新的master 不要接收请求了,并让他执行完当前请求后就关闭它从属的worker进程:
kill -USR2 20316
kill -WINCH 20316
kill -9 20316
由于访问的请求巨大,如果我们不进行切割的话,一个日志文件就会大至几个G,如果大小大于了内存,这个文件就打不开了。通常我们查日志文件的时候也会一天一天的查,混在一起很不方便
日志放在 logs 目录里边,分为普通正常日志和错误日志:
ab -c 1 -n 100000 http://172.25.254.1/index.html
一个并发,十万此请求 ,我们以此来增加日志的大小
du -sh
现在已经有11M了,然后我们进行切割。
我们先备份它的日志:
备份成当日的日志:
mv access.log `date +%F -d -1day`_access.log
我们可以在当天十二点自动执行这个命令,这样每天就会把当天的日志文件生成一个日期了
我们重新打开nginx就会产生新的日志文件
[root@server1 logs]\# ../sbin/nginx -s reopen
error.log 也同理可以备份。
我们可以把这些操作写进脚本里放在crontab中每天定时执行。
我们先把默认访问页面的大小扩充至:
我们访问,然后fn+f12查看详细信息:
文件有5M的大小,我们实际也转换了5M
我们可以使用gzip压缩,我们去配置文件里面进行更改:
打开gzip开关,设置最小为1k的时候不压缩,并设置压缩等级为2,以什么类型压缩。
进行一个语法检测:
sbin/nginx -t
./sbin/nginx -s reload
再次访问:
文件转换过来就只有62.21kb了。
这就是gzip的作用,这样用户再加载这个页面时就会非常快。就好比传送图片时候的查看原图,就是经过压缩过的。
官方把服务的管理一般都放在 /usr/lib/systemd/system :
但是我们自己搭的服务官方建议我们放在 /etc/systemd/system中进行管理.
nginx其实也是一个http服务器,我们可以安装一个httpd ,把它的配置文件给nginx使用,两个是共通的
cp /usr/lib/systemd/system/httpd.service /etc/systemd/system/nginx.service
我们修改配置文件:
改成这样子,我们就可以通过systemctl start/stop 来控制 nginx.service 了
systemctl start nginx.service
端口打开,且访问成功
vim /usr/local/nginx/conf/nginx.conf
user nginx nginx; 指定用户和组打开nginx
worker_processes 1; worker 的进程数,通常设置为cpu 的核心数
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 65535; 最大并发连接数,作为反向代理时支持的是这个数字的一半
}
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;
gzip_min_length 1; 最先压缩大侠
gzip_comp_level 2; 压缩级别
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
server {
listen 80; 端口
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm; 默认发布页面
}
#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 {
root html; 报错界面
}
。。。。。。。。
}
更改配置文件:
limit_conn_zone $binary_remote_addr zone=addr:10m;
location /download/ {
limit_conn addr 1;
} 访问/download/目录时就会使用addr这个共享内存并发数为1
定义了一个共享区域 addr 大小为10M 超过就会报错。
放到图中的位置。
测试:
创建目录:
mkdir /usr/local/nginx/html/download 建立目录
../sbin/nginx -s reload 重新加载
在里面放入一个图片。
尝试访问:
访问成功。
我们用ab的方式测试2个并发:
ab -c 1 -n 10 http://172.25.254.1/download/vim.jpg -c一个并发 -n 访问10次
ab -c 2 -n 10 http://172.25.254.1/download/vim.jpg
更改配置文件
速率为一秒一个,超过的速率会在one区域进行等待,等待的队列只能有5个请求。
每秒请求1.11。
ab -c 1 -n 2 http://172.25.254.1/download/vim.jpg
图片大小为350k,所以应该时间为14s
nginx的日志都默认为这种格式:
我们可以在配置文件中打开 log_format 参数和 access_log 参数
这里边的内容对应上面图片中的每个部分。
表示访问下面的目录时的日志会保存到这个目录下。
重新加载nginx,测试:
curl 172.25.254.1 访问一次
我们访问百度的时候,实际访问的时220.181.38.148这个地址,但是我们的ip地址明显不再一个网段,为什么我们能上网是因为中间有路由器,我们获得路由器分配的ip地址,就可以和路由器通信了,路由器连接的时电信公司,一级一级的我们就可以去上网了。
我们上网的时候,我们的ip时172.25.254.1,上网的流程是:
比如我们访问淘宝:
client(172.25.254.1) —》 ADSL(192.168.0.34) ----》cdn(10.0.0.1) -----》slb(阿里云的负载11.0.0.1) --》 nginx(12.0.0.1)
这里nginx获取的ip都来源于,11.0.0.1,而我们想要收集 172.25.254.1 这个ip地址时,就可以用nginx获取源地址。
而我们使用的参数就是 X-Forwarded_For
在通信时每个ip地址都会加一个herader 到X-Forwarded_For上
set_real_ip_from 192.168.1.0/24;
set_real_ip_from 192.168.2.1;
set_real_ip_from 2001:0db8::/32; 设置可信ip,三种类型都可,一般为上级ip地址
real_ip_header X-Forwarded-For; 从哪个header检测我们要的ip
real_ip_recursive on; 第归排除上面的realip
这样我们检测到客户端的ip不再realip中时,就获取到了客户ip。
先编译realip模块到nginx中
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_realip_module
make && make install
我们编辑nginx的配置文件:
添加一个虚拟主机:
做好解析:
尝试访问:
指定两个header,可见排除了 172.25.254.1 这个realip,只剩了真实的物理ip地址
http {
upstream backend {
server backend1.example.com weight=5; weight是权重,访问五次这个服务器,在访问下面的服务器
server backend2.example.com;
server 192.0.0.1 backup; 后端服务器全挂时访问的ip
}
}
server {
location / {
proxy_pass http://backend; 将请求传递给后端服务器
}
}
比如淘宝这类的网站,里面的图片非常之多,为了压缩图片大小,提升用户体验,需要添加图片过滤模块。
重新编译加入模块:–with-http_image_filter_module=dynamic 动态模块,编译后可以加入参数使用
先在pkgs 网站下载需要的 GD开发包,然后安装,不然会报错
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module=dynamic
make && make install
我们需要将objs中的ngx_http_image_filter_module.so手动的集成到 ngx_modules.c 中去,因为我们所有的模块都集成在这个文件中。不然不可以使用。
[root@server1 objs]# cp nginx /usr/local/nginx/sbin/
cp: overwrite ‘/usr/local/nginx/sbin/nginx’? y
[root@server1 objs]# mkdir /usr/local/nginx/modules
[root@server1 objs]# cp ngx_http_image_filter_module.so /usr/local/nginx/modules/
然后再nginx的安装目录中编辑配置文件,最开头加上:
表示在运行的时候加载这个模块。否则模块不生效,加的配置参数系统不识别。
在加上参数:
可见传过来的大小和源图大小基本一致为350kb。
然欧我们打开这个参数
再次访问:
就变的只有4 kb 了而且图片也变成了设定的像素大小。这就是图片的压缩
配置文件中又专门支持https 的配置:
我们需要把https模块编译到nginx中。
在进行配置。打开刚才注释掉的配置,更改如下:
然后生成证书:
cd /etc/pki/tls/certs/ 证书生成目录
make cert.pem 生成证书
cp cert.pem /usr/local/nginx/conf/ 拷贝到配置文件下
mkdir /web 创建资源目录
vim /web/index.html 配置访问页面
重新加载在nginx ,配置本地解析,然后测试访问
我们的证书不具备法律效益,我们自己获取证书
点 confirm,
访问成功。
这就是我们自己获取的证书,上面的内容和我们生成时设定的内容相同。
但是我们在访问时不加https时;
访问的就是我门另外一个访问页面了,所以说这是不可控的,用户在访问的时候不会去主动加上https,所以我们应该配置nginx的重写规则,让用户固定访问加密的通道。
表示不论以什么开头结尾访问www.westos.org都定向到https://www.westos.org ,$1是用户输入的内容。
^表示开头,(.*)表示结尾
建立 /bbs 目录,创建访问页面。
重新加载nginx。
再次访问www.westos.org ,就直接定向到了https://
可见它是临时重定向,不缓存到本地。
只需要在i重写规则后面加上permanent参数就行了。
此时就是永久重定向了。
表示不论以什么,以bbs结尾就定向到 https://bbs.westos.org/
生活中存在盗链行为,就是盗取别人的资源为自己所用,让别人访问自己时指定到别人的资源。
nginx中就有相应的设置,不是直接访问自己的ip时就不提供资源。
我们模拟一下场景
重新开启一台nginx服务其server2,充当 盗链的人,server1当作真实服务器。
在nginx/html/下放一张图片供我们访问时使用。
更改server1的配置文件:
让访问www.westos.org 时访问html目录里面的发布页面。
配置本地解析解析 daolian.westos.org
建立server2上的 /web 和 发布页面
启动server2上的nginx,
配置本地解析:
测试访问:
这时盗链这就可以盗用别人的资源了。
为了避免这种情况,我们应该设置防盗链:
配置server1的配置文件:
即通过www.westos.org访问时允许通过,通过其它网址访问时拒绝。
重新加载nginx。
访问:
就访问不到了。
即通过www.westos.org访问时不阻挡,通过其它地址访问时重写到自己禁止盗链页面
goexcess第三方软件,官网地址
官网戳这里
下载1.3版本。
编译:
在pkgs中下载GeoIP 和GeoIP-devel 和groipupdate的安装包。 版本需要相同。
yum install ncurses-devel -y 依赖性
./configure --prefix=/usr/local/goaccess --enable-utf8 --enable-geoip=legacy --with-openssl
make && make install
将 /usr/local/goaccess/bin/goaccess 软连接到 /usr/local/bin
ln -s /usr/local/goaccess/bin/goaccess /usr/local/bin/
然后我们就可以使用命令的方式去监控日志了:
这是一个联合日志,会生成一个html页面
goaccess access.log -o ../html/report.html --real-time-html --time-format='%H:%M:%S' --date-format='%d/%b/%Y' --log-format=COMBINED
此时打开了一个7890的端口:
我们需要现在nginx中进行配置。
即当我们访问/report.html 时访问的是 /usr/local/nginx/html/report.html 这个页面。
测试访问:
是不是很炫酷?!