• web服务器-nginx


    一、nginx之前

    同步与异步:

    同步与异步的重点在消息通知的方式上,也就是调用结果的通知方式不同。

    同步:当一个同步调用发出去后,调用者要一直等待调用的结果通知后,才能进行后续的操作。

    异步:当一个异步调用发出去后,调用者不必一直等待调用结果的返回,异步调用,要想获得结果,一般有两种方式:

    1. 主动轮询异步调用的结果;

    2. 被调用方通过 callback (回调通知)来通知调用方调用结果。

    实例解释:

    同步取快递:小明收到快递将送达的短信,在楼下一直等到快递送达。

    异步取快递:小明收到快递将送达的短信,快递到楼下后,小明再下楼去取。

    异步取快递:小明知道快递到达楼下有两种方式:

    1. 不停的打电话询问快递到了没有,即主动轮询;

    2. 快递到楼下后,电话通知小明,然后小明下楼取快递,即回调通知。

    阻塞与非阻塞:

    阻塞与非阻塞的重点在于进程/线程等待消息时候的行为,也就是等待消息的时候,当前进程/线程是挂起状态,还是非挂起状态。

    阻塞:调用发出去后,在消息返回之前,当前进程/线程会被挂起,直到消息返回,当前进程/线程才会被激活。

    非阻塞:调用在发出去后,不会阻塞当前进程/线程,而会立即返回。

    实例解释:

    阻塞取快递:小明收到快递将送达的消息后,什么事都不做,一直专门等快递。

    非阻塞取快递:小明收到快递即将送达的消息后,等快递的时候,还一边敲代码,一边聊微信。

    同步与异步,重点在于消息通知的方式;阻塞与非阻塞,重点在于等消息时候的行为。

    故,有了以下4中组合方式:

    同步阻塞:小明收到消息后,什么都不做,等快递;

    同步非阻塞:小明收到消息后,边刷微博,边等快递;

    异步阻塞:小明收到消息后,什么都不做,一直等着快递员通知他取快递;

    异步非阻塞:小明收到消息后,边刷微博,边等着快递员通知他取快递。

    大部分程序的I/O模型都是同步阻塞的,单个进程每次只在一个文件描述符上执行I/O操作,每次I/O系统调用都会阻塞,知道数据传输完成。传统的服务器采用的就是同步阻塞的多进程模型。一个server采用一个进程负责一个request的方式,一个进程负责一个request,直到会话结束。进程数就是并发数,而操作系统支持的进程数是有限的,且进程数越多,调度的开销也越大,因此无法面对高并发。

    nginx采用了异步非阻塞的方式工作。了解一下I/O多路复用中的epoll模型。

    epoll模型:

    当连接I/O事件产生的时候,epoll就会去告诉进程哪个连接有I/O事件产生,然后进程就去处理这个事件。

    例如:小明家楼下有一个收发室,每次快递到了,门卫就先代收并做标记;然后通知小明去取送给小明的快递。

    为什么Nginx 比其他web 服务器并发高(nginx工作原理)

    nginx配置 use epoll 后,以异步非阻塞方式工作,能够轻松处理百万级的并发连接。

    处理过程:每进来一个request,会有一个worker 进程去处理。但不是全程的处理,处理到可能发生阻塞的地方。比如向后端服务器转发request,并等待请求返回。那么,这个处理的 worker 进程不会一直傻等,他会在发送请求后,注册一个事件:"如果后端服务器返回了,告诉我一声,我再接着干"。于是他就休息去了。此时,如果再有新的 request 进来,他就可以很快再按这种方式处理。而一旦后端服务器返回了,就会触发这个事件,worker 才会来接手,这个request才会接着往下走。通过这种快速处理,快速释放请求的方式,达到同样的配置可以处理更大并发量的目的。

    二、nginx详解

    1. 概述

      nginx(engine x)是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的,第一个公开版本0.1.0发布于2004年10月4日。

      nginx是一款轻量级的web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下运行。特点是占用内存少,并发能力强。

    2. 工作模式

    nginx有两种工作模式:master-worker 模式和单进程模式。在master-worker 模式下,有一个master进程和至少一个worker进程,单进程模式顾名思义只有一个进程。这两种模式有各自的特点和适用场景。

    master-worker:

    该模式下,nginx启动成功后,会有一个master进程和至少一个的worker进程。master进程负责处理系统信号,加载配置,管理worker进程(启动,杀死,监控,发送信息/信号等)。worker进程负责处理具体的业务逻辑,也就是说,对外部来说,真正提供服务的是worker进程。生产环境一般使用这种模式,因为这种模式有以下优点:

    a. 稳定性高,只要还有worker 进程存活,就能够提供服务,并且一个worker进程挂掉,master进程就会立即启动一个新的worker 进程,保证worker 进程数量不变,降低服务中断的几率。

    b. 配合linux 的cpu 亲和性配置,可以充分利用多核cpu 的优势,提升性能。

    c. 处理信号/配置重新加载/升级时可以做到尽可能少或者不中断服务(热重启)

    单进程模式:

    单进程模式下,nginx启动后只有一个进程,nginx的所有工作都由这个进程负责。由于只有一个进程,因此可以很方便地利用gdb等工具进行调试。该模式不支持nginx的平滑升级功能,任何的信号处理都可能造成服务中断,并且由于是单进程,进程挂掉后,在没有外部监控的情况下,无法重启服务。故,该模式一般只在开发阶段和调试时使用,生产环境下不使用。

    3. 配置文件结构

    user    www www;
    #程序运行用户和组
    worker_processes auto;
    #启动进程,指定nginx启动的工作进程数量,建议按照cpu数目来指定,一般等于cpu核心数目
    error_log    /home/wwwlogs/nginx_error.log    crit;
    #全局错误日志
    pid    /usr/local/nginx/logs/nginx.pid;
    #主进程PID保存文件
    worker_rlimit_nofile 51200;
    #文件描述符数量
    events {
        use epoll;
        #使用epoll模型,对于2.6以上的内核,建议使用epoll模型以提高性能
        worker_connections 51200;
        #工作进程的最大连接数量
        }
    http {
        #网站优化参数
        server {                          #具体的某一网站的配置信息
            listen 80;                    #监听端口
            root html;                    #网页根目录(/usr/local/nginx/html)
            server_name www.learn.com;    #服务器域名
            index index.html;             #默认加载页面
            access_log logs/access.log;   #访问日志保存位置
            ......;
            location (.*).php$ {
                用正则匹配具体的访问对象;
            }
            location {
                跳转等规则;
            }
        }
        server {
            虚拟主机;
        }
    }

    4. nginx实验

    注:

    1. 配置文件中的结尾有 ; 作为结束。

    2. 每次修改完配置文件后需重启nginx才会生效。

    4.1 nginx的状态统计

    a. 安装nginx时将 --with-http_stub_status_module 模块开启

    b. 修改nginx配置文件(写入要访问的server 标签中)

    location /nginx_status {
        stub_status on;
        access_log off;
    }

    c. 客户端访问网址:http://ip/nginx_status

      "Active connections"表示当前的活动连接数;

      "server accepts handled requests"表示已经处理的连接信息

      三个数字依次表示已处理的连接数、成功的TCP握手次数、已处理的请求数

    4.2 目录保护

    a. 原理和apache 的目录保护原理一样(利用上一个实验接着完成)

    b. 在状态统计的location 中添加:

    auth_basic "welcome to nginx_status!";
    auth_basic_user_file /usr/local/nginx/html/htpasswd.nginx;

    c. 使用http 的命令htpasswd 进行用户密码文件的创建(生成在上面指定的位置)

    htpasswd -c /usr/local/nginx/html/htpasswd.nginx user

    d. 重启nginx 服务并再次访问统计页面

    4.3 基于IP的身份验证(访问控制)

    a. 接着上一个实验完成操作

    b. 在状态统计的location 中添加:

    allow 192.168.80.130;
    deny 192.168.80.0/24;
    仅允许 192.168.80.130 访问服务器

    4.4 nginx 的虚拟主机(基于域名)

    a. 提前准备好两个网站的域名,并且规划好两个网站网页存放目录

    b. 在nginx 主配置文件中并列编写两个 server 标签,并分别写好各自信息

        server {
            listen 80;
            server_name blog.learn.com;
            index index.html;
            root html/blog;
            access_log logs/blog-access.log main;
        }
        server {
            listen 80;
            server_name bbs.learn.com;
            index index.html;
            root html/bbs;
            access_log logs/bbs-access.log main;
        }

    c. 分别访问两个不同的域名验证结果(注意修改hosts文件)

    4.5 nginx 反向代理

    代理和反向代理

    代理:找别人代替你去完成一件你完成不了的事(代购),代理的对象是客户端。

    反向代理:替厂家卖东西的人就叫反向代理(烟酒代理),代理的对象是服务端。

    a. 在另外一台机器上安装apache,并启动填写测试页面

    b. 在nginx 服务器的配置文件中添加(写在某个网站的 server 标签中)

        server {
            listen 80;
            server_name blog.learn.com;
            index index.html;
            root html/blog;
            access_log logs/blog-access.log main;
            location / {
                proxy_pass http://192.168.80.131:80;
            }
        }

    c. 重启nginx,并使用客户端访问测试

    4.6 负载均衡

    负载均衡(Load Balance)其意思就是将任务分摊到多个操作单元上进行执行,例如web服务器、ftp服务器、企业关联应用服务器和其他关键任务服务器等,从而共同完成工作任务。

    a. 使用默认的rr 轮询算法,修改nginx 配置文件

        upstream blog {                      #此标签加在server 标签之前
            server 192.168.80.132:80;
            server 192.168.80.131:80;
        }
        server {
            listen 80;
            server_name blog.learn.com;
            index index.html;
            root html/blog;
            access_log logs/blog-access.log main;
            #修改自带的location / 标签,将原内容删除,添加以下两项
            location / {
                proxy_pass http://blog;  #添加反向代理,代理地址填写 upstream 声明的名字
                proxy_set_header Host $host; #重写请求头部,保证网站所有的页面都可以访问成功
            }
        }

    b. 开启并设置两台 80.131 & 80.132 两台主机

        安装apache 并设置不同的 index.html 页面内容

    c. 重启nginx,并使用客户端访问测试

    扩展:rr 算法实现加权轮询

    upstream blog {
        server 192.168.80.132:80 weight=1;
        server 192.168.80.131:80 weight=2;
    }

    4.7 nginx 实现 https {证书+rewrite}

    a. 安装nginx时,需要将--with-http_ssl_module 模块开启

    b. 在对应要进行加密的 server 标签中添加以下内容开启SSL

        server {
            listen 443 ssl;
            server_name bbs.learn.com;
            index index.html;
            root html/bbs;
            access_log logs/bbs-access.log main;
            #ssl on;
            ssl_certificate /usr/local/nginx/conf/certs/nginx.crt;
            ssl_certificate_key /usr/local/nginx/conf/certs/nginx.key;
            ssl_session_timeout 5m;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_prefer_server_ciphers on;
            ssl_ciphers "EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5";
        }

    c. 生成证书和秘钥文件

    注:实验环境中可以使用命令生成测试,生成环境中必须要在 https 证书厂商注册

    [root@centos2 /usr/local/nginx/conf/certs]# openssl genrsa -out nginx.key 1024
    [root@centos2 /usr/local/nginx/conf/certs]# openssl req -new -key nginx.key -out nginx.csr
    [root@centos2 /usr/local/nginx/conf/certs]# openssl x509 -req -days 365 -sha256 -in nginx.csr -signkey nginx.key -out nginx.crt

    d. 新增以下server 标签(利用虚拟主机+rewrite 的功能)

        server {
            listen 80;
            server_name bbs.learn.com;
            rewrite ^(.*)$ https://bbs.learn.com permanent;
            root html/bbs;
            index index.html index.htm;
        }

    e. 重启nginx,测试。

  • 相关阅读:
    [51Nod] 配对
    [Poj] Roads in the North
    【Java学习笔记之二十六】深入理解Java匿名内部类
    【Java学习笔记之二十五】初步认知Java内部类
    【Java学习笔记之二十四】对Java多态性的一点理解
    【Java学习笔记之二十三】instanceof运算符的用法小结
    【Java学习笔记之二十二】解析接口在Java继承中的用法及实例分析
    图论--拓扑排序模板
    hdu 5384 AC自动机
    java大数
  • 原文地址:https://www.cnblogs.com/sswind/p/12050197.html
Copyright © 2020-2023  润新知