作为一个前端,我觉得大部分人应该听说过nginx因为它在最近两年实在是很火,现在作为一个前端如果你不会ngxin那肯定不好意思说自己是一个大前端:我首先看一下nginx的官方介绍:
“Nginx是一款轻量级的HTTP服务器,采用事件驱动的异步非阻塞处理方式框架,这让其具有极好的IO性能,时常用于服务端的反向代理和负载均衡。”
nginx特性
IO多路复用多个描述符的IO操作都能在一个线程里交替书序完成,复用线程
1.select线程遍历文件描述符列表,1.效率底下2.最多只能有1024(注:这种模式其实就是轮询没过一段时间去检查一下任务是否完成,轮询的期间没办法执行其他操作,有些IO操作很慢的话不可能每秒都去轮询检查这样做无疑是效率低下的方式,当然因为系统限制只能有1024个线程)
2.epoll每当FD就绪,采用系统回调函数将fd放入1.效率高2.没有1024限制(注:这种方式有点类似于node的机制,不用去轮询检查任务是否完成而是任务完成后会自动通知将执行结果放入回调函数中) CPU亲和 一种把CPU核心和nginx工作进程绑定的方式,也就是没一个core核心就有一个nginx进程,把每个worker进程固定在一个cpu上执行减少了切换cpu和提交缓存命中率,获得更好的性能
sendfile零拷贝传输模式,这个模式的好处在于静态资源的代理,通常我们再linux服务器上读取静态文件需要经过用户空间,服务器上的内存空间然后返回到客户端,nginx作为静态资源服务器绕过了用户空间的缓存少了资源的拷贝传输更高效
Nginx的优点
支持海量高并发:采用IO多路复用epoll。官方测试Nginx能够支持5万并发链接,实际生产环境中可以支撑2-4万并发连接数。 内存消耗少:在主流的服务器中Nginx目前是内存消耗最小的了,比如我们用Nginx+PHP,在3万并发链接下,开启10个Nginx进程消耗150M内存。 免费使用可以商业化:Nginx为开源软件,采用的是2-clause BSD-like协议,可以免费使用,并且可以用于商业。 配置文件简单:网络和程序配置通俗易懂,即使非专业运维也能看懂。
安装
准备工作:1关闭防火墙等配置(本人购买的是阿里云ECS center OS)命令如下
systemctl stop firewalld.service
setenforce 0
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
2:安装必要的依赖(安装工具编译环境等)命令如下
yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
yum -y install weget httped-tools vim
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
3修改yum源 使用vim编译器新建一个yum配置文件我们使用的是vim编辑器上面已经安装了 vim /etc/yum.repos.d/nginx.repo
这里会新建一个yum源的配置文件我们使用i键进入insert模式把下面的配置粘贴进去
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
按下esc并且输入:wq保存并退出,这里都是linux的编辑器命令不做过多解释
如果都已经准备好了,那就可以开始安装了,安装的命令非常简单:
yum install nginx
安装完成后可以使用命令,来检测Nginx的版本。
nginx -v
学会使用
我们首先可以使用一条命令查找我们nginx安装的目录
/etc/nginx配置文件都在该文件下
\#运行用户,默认即是nginx,可以不进行设置
user nginx;
#Nginx进程,一般设置为和CPU核数一样
worker_processes 1;
#错误日志存放目录
error_log /var/log/nginx/error.log warn;
#进程pid存放位置
pid /var/run/nginx.pid;
events {
worker_connections 1024; # 单个后台进程的最大并发数
}
http {
include /etc/nginx/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 /var/log/nginx/access.log main; #nginx访问日志存放位置
sendfile on; #开启高效传输模式
#tcp_nopush on; #减少网络报文段的数量
keepalive_timeout 65; #保持连接的时间,也叫超时时间
#gzip on; #开启gzip压缩
include /etc/nginx/conf.d/*.conf; #包含的子配置项位置和文件
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
自配置文件在 conf.d的文件下
server {
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页面
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html; #错误状态码的显示页面,配置后需要重启
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# 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_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
#
#location ~ /\.ht {
# deny all;
#}
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
我们大部分的nginx的配置都是在上述的两个文件下进行 明白了这些配置项,我们知道我们的服务目录放在了/usr/share/nginx/html下,可以使用命令进入看一下目录下的文件,可以看到目录下面有两个文件,50x.html 和 index.html。我们可以使用vim进行编辑。学到这里,其实可以预想到,我们的nginx服务器已经可以为html提供服务器了。我们可以打开浏览器,访问ip地址试一试。
启动的和重启的基本命令
nginx直接启动 在CentOS7.4版本里(低版本是不行的),是可以直接直接使用nginx启动服务的。
nginx
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
使用systemctl命令启动,还可以使用个Linux的命令进行启动,我一般都是采用这种方法进行使用。因为这种方法无论启动什么服务,都是一样的,只是换一下服务的名字(不用增加额外的记忆点)。
systemctl start nginx.service
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
输入命令后,没有任何提示,那我们如何知道Nginx服务已经启动了哪?可以使用Linux的组合命令,进行查询服务的运行状况。
ps aux | grep nginx
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
停止Nginx服务的四种方法 停止Nginx 方法有很多种,可以根据需求采用不一样的方法,我们一个一个说明。 立即停止服务
nginx -s stop
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
这种方法比较强硬,无论进程是否在工作,都直接停止进程。 从容停止服务
nginx -s quit
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
这种方法较stop相比就比较温和一些了,需要进程完成当前工作后再停止。 killall 方法杀死进程 这种方法也是比较野蛮的,我们直接杀死进程,但是在上面使用没有效果时,我们用这种方法还是比较好的。
killall nginx
systemctl 停止
systemctl stop nginx.service
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
重启Nginx服务 有时候我们需要重启Nginx服务,这时候可以使用下面的命令。
systemctl restart nginx.service
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
检查自己的配置文件是否正确,可以再重启之前执行进行检查 nginx -t
重新载入配置文件 在重新编写或者修改Nginx的配置文件后,都需要作一下重新载入,这时候可以用Nginx给的命令,一般重载就可以使用了无需再次重启。
nginx -s reload
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
查看端口号
netstat -tlnp
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
自定义错误页和访问设置
没一个好的网站都会设置各种各样的友好的错误提示,比如由于网络原因我们没办法找到页面的时候,我们要提示页面没有找到。下面介绍一下错误页面在nginx的配置方式:
1.多错误指向一个页面
在/etc/nginx/conf.d/default.conf 是可以看到下面这句话的。
error_page 500 502 503 504 /50x.html;
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
error_page指令用于自定义错误页面,500、502、503、504这些都是常见的错误,当遇到这些错误的时候我们都会返回这个50x.html的页面中. 2.单独为错误置顶处理方式
有些时候是要把这些错误页面单独的表现出来,给用户更好的体验。所以就要为每个错误码设置不同的页面。设置方法如下:
error_page 404 /404_error.html;
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
上述页面都在/usr/share/nginx/html文件目录下
访问设置
location / {
deny 123.9.51.42;
allow 45.76.202.231;
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
在配置文件中我们可以加上deny和allow这两个配置项选择可以访问到该页面的IP地址段,我们也可以使用all关键字阻止其他用户比如下面的设置方式:
location / {
allow 45.76.202.231;
deny all;
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
这种方式就是指允许其中一个IP地址进行访问其他地址被禁止访问会进入403的页面,不能更换位置nginx的权限是从上向下执行的如果上面阻止了deny all那么
Nginx访问权限详细介绍
复杂访问控制权限匹配
在工作中我们可以使用表达式使权限控制变得更细化(=号代表精确匹配,使用了=后是根据其后的模式进行精确匹配。),我们可以设置图片为都可访问,我们将admin管理目录设置为外界不可访问这样是不是更安全了呢。
上面的需求,配置代码如下:
location =/img{
allow all;
}
location =/admin{
deny all;
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
使用正则表达式设置访问权限
仅仅使用精准匹配可能不满足我们的要求,有时候我们需要php这些后台的接口文件不被外界访问到,我们就可以使用正则进行匹配下面的代码中代表了所有以.php为结尾的文件都不能被访问到,这样就可以防止我们的关键性文件不会暴露出来。
代码如下:
location ~\.php$ {
deny all;
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
Nginx设置虚拟主机和设置反向代理
nginx可以为服务器划分成几个不同的虚拟主机,首先我们再阿里云域名解析上配置两个不同的二级域名一个是music.jackyfgh.top,另一个是blog.jackyfgh.top,我们在conf.d的文件夹下创建两个子配置项,这样做的目的是为了更好的管理
server {
listen 80;
server_name blog.jackyfgh.top;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:8090;
proxy_redirect off;
}
error_page 500 502 503 504 /50x.html;
error_page 404 /404_error.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
上述配置文件我们配置了servername指定了对应的二级域名,然后我们配置了相应的反向代理,代理到真实的ip地址,这里我使用koa做的后台服务8090为koa服务所监听的端口,我们把所有的请求都代理到这个地址下就可以通过这个二级域名去访问对应的网站了,music.conf的配置文件也同样,两个配置都监听者80端口但是访问的域名不同我们根据不同的域名代理到不同的服务器Ip地址上,这样就做到了虚拟机的分割。
server {
listen 80;
server_name music.jackyfgh.top;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:3000;
proxy_redirect off;
}
error_page 500 502 503 504 /50x.html;
error_page 404 /404_error.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
上面所说的反向代理这里介绍一下。 首先我们说一下什么是正向代理再介绍反向代理,作为一个程序员你肯定用过翻墙工具,它就是一个典型的正向代理,它会把一些不让我们访问的网页请求代理到一个可以访问的服务器上进行访问,也就是客户端的代理。然而反向代理就是代理了真实的服务器,当用户访问的时候我们访问的其实不是真正的服务器地址,这样就可以更大程度的保护我们真正的业务不被攻击,通常代理服务器都是安全级别很高的。
这里说一个注意事项那就是location配置的优先级,当我们配置多个匹配规则的时候会根据优先级进行匹配,这里我踩了一个坑因为该配置不是像正常理解的按照顺序去加载的,而是按照(location =) > (location 完整路径 >) >(location ^~ 路径) >(location ~* 正则) >(location 路径)这样的规则顺序去加载的,当碰到优先级高的匹配规则就不会向下匹配了。通常一个复杂的业务nginx可能高达2000行也说不准我们配置的时候一定要切记这种坑存在。 正向代理: 正向代理其实是代理真实的客户端,真实的客户端对于服务器是不可见的。 最常见的正向代理的应用就是翻墙软件,配置如下
server{
listen 80;
server www.google.com;
location /{
proxy_pass http://$http_host$request_uri;
}
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
因为nginx所在的服务器是可以访问谷歌的,所以当我们访问谷歌的时候,nginx代理到你请求的地址也就是上面写的
http://$http_host$request_uri
Nginx配置负载均衡
Nginx的负载均衡 使用集群是网站解决高并发、海量数据问题的常用手段 当一台服务器的处理能力、存储空间不足时,不要企图去换更强大的服务器,对大型网站而言,不管多么强大的服务器,都满足不了网站持续整张的业务需求 在这种情况下,更恰当的做法是增加一台服务器去分担原有服务器的访问及存储压力,通过负载均衡调度服务器,将来自浏览器的访问请求分发到应用服务器集群中的任何一台服务器上,如果有更多的用户,接在急群加入更多的应用服务器,使应用服务器的负载压力不再成为整个网站的瓶颈
upstream wexin{
ip_hash;
server wx.1234.cn
server wx.12345.cn
server wx.1234567.cn
}
server{
location ~ ^/api {
proxy_pass http:// wexin
}
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
以前我们配置的proxy_pass是一个地址现在我们配置的是一个集群,如果有以api开头的请求过来就会轮询访问这三个地址进行访问
Nginx适配PC或移动设备
下面我们说一下nginx如何做到像淘宝一样实现的适配PC和移动设备 Nginx通过内置变量$http_user_agent,可以获取到请求客户端的userAgent,就可以用户目前处于移动端还是PC端,进而展示不同的页面给用户。 操作步骤如下:
server{
listen 80;
server_name nginx2.jspang.com;
location / {
root /usr/share/nginx/pc;
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
root /usr/share/nginx/mobile;
}
index index.html;
}
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
这里~*符号代表了不区分大小写去匹配设备我们将资源路径指向了不同的地址默认指向PC的路径,当然这里的设备标识符可能不全面。
开启gzip压缩
首先我们说一下我们为什么要要开启gzip压缩呢?如果我们在浏览器输入一个地址的时候我们肯定会请求一堆文件,浏览器会加载这些网页如果这个资源很大我们怎么办,我们可不可以使用压缩文件来代替呢?这就是gzip技术。变化的部分在于浏览器和服务器,它成功的发送过去一个压缩文件。对于gzip压缩的要点有两点: 浏览器发送一个请求头,告诉服务器接受压缩版本的文件(gzip和deflate是两种压缩算法)Accept-Encoding:gzip,deflate 如果文件压缩了,服务器返回一个头信息:Content-Encoding:gzip 如果服务器没有返回Content-Encoding的头信息,意味着这文件是没压缩的(浏览器可以直接解析的)。请求头Accept-Encoding只是浏览器的一个请求,而不是命令。如果服务器不返回压缩文件,浏览器就不得不处理那庞大的源文件。 下面的就是我使用配置nuxt项目的nginx Gzip配置文件
server {
listen 80; # 监听端口
server_name your-domain; # wx.10086.cn
gzip on;
gzip_types text/plain application/xml text/css application/javascript;# 那些资源需要压缩
gzip_min_length 1000; # 设置允许压缩的页面最小字节数
location / {
expires $expires;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1m;
proxy_connect_timeout 1m;
proxy_pass http://127.0.0.1:3000; # 代理的node地址
}
}
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
然后说一下Gzip配置项的说明:
gzip : 该指令用于开启或 关闭gzip模块。
gzip_buffers : 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。
gzip_comp_level : gzip压缩比,压缩级别是1-9,1的压缩级别最低,9的压缩级别最高。压缩级别越高压缩率越大,压缩时间越长。
gzip_disable : 可以通过该指令对一些特定的User-Agent不使用压缩功能。
gzip_min_length:设置允许压缩的页面最小字节数,页面字节数从相应消息头的Content-length中进行获取。
gzip_http_version:识别HTTP协议版本,其值可以是1.1.或1.0.
gzip_proxied : 用于设置启用或禁用从代理服务器上收到相应内容gzip压缩。
gzip_vary : 用于在响应消息头中添加Vary:Accept-Encoding,使代理服务器根据请求头中的Accept-Encoding识别是否启用gzip压缩
//JS中文网 – 前端进阶资源分享 https://www.javascriptc.com/ 趣聊CSS系列
nginx作为一个http服务器被大家广为推崇,当然仅仅学习是不够的我们需要配合实际配置的经验才能更好地应用。
作者:白兔爱吃大灰狼
链接:https://juejin.im/post/6844903840592953352
看完两件小事
如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:
- 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
- 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程