CentOS7系统安装uWSGI Nginx运行Django应用

1. 基础环境配置

先安装好基础环境

cd ~
sudo yum groupinstall "Development tools"
sudo yum install python34 python34-devel python34-pip
pip3 install virtualenv
virtualenv python34
source python34/bin/activate

测试python环境

python --version
pip --version

如果是python3.4的环境,至此python环境配置好了,如果有错,多用一下Google解决。

2. Nginx安装

参考Nginx官网的安装文档,建议新手使用yum安装,后续升级维护方便。

  • 首先要安装Nginx仓库,sudo vi /etc/yum.repos.d/nginx.repo添加以下内容:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=1
enabled=1
  • 下载Nginx的key文件,wget https://nginx.org/keys/nginx_signing.key
  • 安装key文件,sudo rpm –import nginx_signing.key
  • 安装Nginx,sudo yum install nginx
  • 测试Nginx,sudo nginx

3. uWSGI安装

从此往下都需要在Python34的虚拟环境下,检查自己是否在Python34虚拟环境下,不在的话执行source python34/bin/activate确认进入虚拟环境,执行pip install uwsgi安装uWSGI,测试uWSGI是否安装好。执行vi test.py输入一下内容保存:

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]

开启uWSGI服务,uwsgi –http :8000 –wsgi-file test.py,打开浏览器,输入(你的IP):8000看到Hello World代表web client到uWSGI到Python的连接正常。

4. Django配置

先执行pip install -r requirements.txt安装好Python包,正式部署前要配置好Django项目的配置(settings.py),修改一下项目:

DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1','localhost','(你的域名)']
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

然后记得执行一下语句:

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser # 创建超级用户
python manage.py collectstatic

然后执行python manage.py runserver测试Django项目运行是否正常。

5. uWSGI到Django配置

uwsgi --http :8000 --module (你的Djnago项目名).wsgi

打开浏览器测试(8000端口),如果Django项目运行正常,表示Web Client到uWSGI到Django运行正常。

vi uwsgi.ini添加以下内容并保存

[uwsgi]
socket = :8001
chdir= (你的Django项目地址)
wsgi-file = (你的Django项目地址下wsgi.py所在位置)
touch-reload = ~/reload # 如果reload文件有更改,重启uWSGI
module=(你的Django项目名称).wsgi
master=true
processes = 2 # 进程数
threads = 4 # 线程数
chmod-socket    = 664
chown-socket = (centos用户名):(centos组)
vacuum=true
pidfile = ~/tmp/uwsgi.pid #pid 文件位置

执行uWSGI –ini uwsgi.ini &运行uWSGI,如果Django项目有更改的话可以执行touch ~/reload重启uWSGI。

6. 配置Nginx

执行 sudo vi /etc/nginx/nginx.conf修改添加一下内容

# 注意,这只是nginx.conf中的一部分,其他内容不熟悉的话不要修改。

http {
    upstream django {
        server 127.0.0.1:8001;
    }

    server {
        listen       80;
        server_name  (你的域名地址);
        if ($host != 'www.willtunner.me' ) {
            rewrite ^/(.*)$ http://www.willtunner.me/$1 permanent;
        }   # 此处修改自动添加www

        charset utf-8;
        access_log  logs/host.access.log  main;

        location / {
            uwsgi_pass  django;
            include     /etc/nginx/uwsgi_params;
        }

        location /static/ {
            alias (你的Django项目static地址);
        }

        location /media/ {
            alias (你的Django项目media地址);
        }

        location ~ .*.txt$ {
            root (robots.txt所在地址);
        }
    }
}

当然Nginx虚拟主机配置最好使用include语法放置在其他文件夹下,多个虚拟主机比较好管理,这里我只有一个虚拟主机,故直接在这里修改了。

改好了之后执行sudo nginx -s stop和sudo nginx重新加载Nginx的配置。

没有出错的话,至此从Web Client到Nginx到uWSGi到Django的通路便建立好了。网站可以正常访问了。

Flask服务部署(Nginx Gunicorn Gevent)

Flask 项目部署

我们开发好了一个flask项目, 需要部署到线上服务器, 那我们的线上服务应该如何部署呢

基本的架构如下

未分类

Nginx

在开发环境, 我们一般直接运行Python服务, 启动了某个端口(一般是5000端口), 然后通过该端口进行开发调试

但线上环境一般不会直接这样提供服务, 一般的线上服务需要通过 Nginx 将外部请求转发到Python服务

这样有什么好处

  • 隐藏python服务, 避免直接将python服务暴露出去
  • 提高web服务的连接处理能力(Nginx)
  • 作为反向代理, 提升python整体服务处理能力

我们可以配置的Nginx配置如下

upstream flask_servers {
    server 127.0.0.1:9889;
}

server {
    listen 80;
    server_name dev.simple-cms.com;

    access_log  /data/logs/nginx/simple_cms_access.log main;
    error_log /data/logs/nginx/simple_cms_error.log debug;

    location / {
        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_redirect off;
        proxy_pass  http://flask_servers;
    }

    location ^~ /static {
        root /data/www;
    }
}

如果有多个python服务器, 可在upstream下继续添加其他的python服务列表

Gunicorn + Gevent

Gunicorn

Guicorn 是一个python的一个 WSGI 的web sever, 什么是WSGI

Web Server <=====WSGI=====> Python APP

WSGI 其实是一种网关协议, 用以把http请求参数转换为python服务可以读取的内容, 这样在python的框架里能根据请求参数进行不同的业务处理了

Gunicorn 就是这么一种WSGI的实现, 他也是个web server, 可以直接提供对外的web服务, 但在一般的部署中, 他只是作为python服务的运行的容器, 运行和管理python应用程序

通过这个容器, 从Nginx转发的请求就能转发到某个python app了

除此之外, Gunicorn 还提供了多个运行参数, 常用的如下

-w 设置启动`python app` worker进程的数量
-k 运行模式(sync, gevent等等)
-b gunicorn 启动绑定的host和port
--max-requests 最大处理量, 单woker进程如果处理了超过该数量的请求, 该woker会平滑重启

Gevent

单进程直接运行Python app服务时, 当有两个并发请求过来时, 进程只能先处理一个请求, 等第一个请求处理完成后, 才能处理第二个, 势必影响用户的体验

那么单进程的时候, 如何能提高并发处理能力,

大多数情况下, 我们的服务中, 导致性能低下的原因是I/O, 比如对数据库的读写, 发送Http请求等等, 当进程进行I/O的时候, 是不占用CPU时间的, 这个时候, CPU可以被腾出来处理其他请求

Gevent就是完成这个工作的

幸运的是, 我们不需要再代码中自己实现这部分功能, Gunicorn 实现了Gevent模式的运行方式(-k 参数指定), 允许你的Python APP 更高性能的处理业务

通过 Gunicorn + Gevent, 我们可以如下启动

gunicorn --max-requests 300 --pid /tmp/flask.pid --timeout 3 -k gevent -w 2 -b 127.0.0.1:9889 run:app

从Nginx代理的请求, 就可以转发到Gunicorn启动的9889端口上了

supervisor

上面我们通过Gunicorn+Gevent 启动了Python服务, 在某些情况下, 我们的服务会停掉(系统掉电重启, 误杀, 不知道停了 🙁 ),

我们不可能时刻都看着线上服务, 在这种情况下, 我们希望系统能自动拉起停掉的服务, 保证线上服务的稳定

supervisor 就是干这个的, supervisor会守护配置好的进程, 在进程停止后重新启动服务进程, 并保留日志

比如Nginx服务的配置可以如下

[program:nginx]
command = /usr/local/bin/nginx -g 'daemon off;' -c /usr/local/etc/nginx/nginx.conf
autostart = true
startsecs = 5
autorestart = true
startretries = 3
user = root

其中command 就是我们nginx服务的启动命令,

同理, gunicorn启动的supervisor 配置如下

[program:gunicorn]
directory=/path/to/flask_app
command = /path/to/gunicorn --max-requests 3000 --pid /tmp/flask.pid --timeout 3 -k gevent -w 2 -b 127.0.0.1:9889 run:app autostart = true
startsecs = 5
autorestart = true
startretries = 3
user = www-data

以上配置好好, 执行

sudo supervisorctl -c /path/to/supervisord.ini update

就可以让supervisor 守护我们的gunicorn 服务了

状态查看

sudo supervisorctl -c /path/to/supervisord.ini status

可以看到

gunicorn             RUNNING   pid 35640, uptime 0:00:14

状态是running

总结

以上, 我们实现了线上python服务的基础架构部署, 主要是针对python服务的部署, 基本遵循了文首的架构图

以上是我们在项目中实践的架构部署, 欢迎各位一起交流

nginx apache webbench压力测试比较

简介

Nginx (“engine x”) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器;
作为一款轻量级的Web服务器,具有占有内存少,并发能力强等优势,是高连接并发场景下Apache的不错的替代品;
本篇主要介绍Nginx作为Web服务器时,相对于Apache的性能优势;
下一篇将会介绍Nginx作为方向代理服务器的实现;

重要特点

非阻塞:数据复制时,磁盘I/O的第一阶段是非阻塞的;
事件驱动:通信机制采用epoll模型,支持更大的并发连接;
master/worker结构:一个master进程,生成一个或多个worker进程;

基础架构

未分类
Nginx如何实现高并发:
I/O模型采用异步非阻塞的事件驱动机制,由进程循环处理多个准备好的事件,如epoll机制;
Nginx与Apache对高并发处理上的区别:
对于Apache,每个请求都会独占一个工作线程,当并发量增大时,也会产生大量的工作线程,导致内存占用急剧上升,同时线程的上下文切换也会导致CPU开销增大,导致在高并发场景下性能下降严重;
对于Nginx,一个worker进程只有一个主线程,通过事件驱动机制,实现循环处理多个准备好的事件,从而实现轻量级和高并发;

部署配置

安装

yum -y groupinstall “Development tools”
yum -y groupinstall “Server Platform Development”
yum install gcc openssl-devel pcre-devel zlib-devel
groupadd -r nginx
useradd -r -g nginx -s /sbin/nologin -M nginx
tar xf nginx-1.4.7.tar.gz
cd nginx-1.4.7
mkdir -pv /var/tmp/nginx
./configure 
--prefix=/usr 
--sbin-path=/usr/sbin/nginx 
--conf-path=/etc/nginx/nginx.conf 
--error-log-path=/var/log/nginx/error.log 
--http-log-path=/var/log/nginx/access.log 
--pid-path=/var/run/nginx/nginx.pid 
--lock-path=/var/lock/nginx.lock 
--user=nginx 
--group=nginx 
--with-http_ssl_module 
--with-http_flv_module 
--with-http_stub_status_module 
--with-http_gzip_static_module 
--http-client-body-temp-path=/var/tmp/nginx/client/ 
--http-proxy-temp-path=/var/tmp/nginx/proxy/ 
--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ 
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi 
--http-scgi-temp-path=/var/tmp/nginx/scgi 
--with-pcre
make && make install

配置

    vi /etc/init.d/nginx # 配置服务脚本
    #!/bin/sh
    #
    # nginx - this script starts and stops the nginx daemon
    #
    # chkconfig: - 85 15
    # description: Nginx is an HTTP(S) server, HTTP(S) reverse 
    # proxy and IMAP/POP3 proxy server
    # processname: nginx
    # config: /etc/nginx/nginx.conf
    # config: /etc/sysconfig/nginx
    # pidfile: /var/run/nginx.pid
    # Source function library.
    . /etc/rc.d/init.d/functions
    # Source networking configuration.
    . /etc/sysconfig/network
    # Check that networking is up.
    [ "$NETWORKING" = "no" ] && exit 0
    nginx="/usr/sbin/nginx"
    prog=$(basename $nginx)
    NGINX_CONF_FILE="/etc/nginx/nginx.conf"
    [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
    lockfile=/var/lock/subsys/nginx
    make_dirs() {
    # make required directories
    user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=([^ ]*).*/1/g' -`
    options=`$nginx -V 2>&1 | grep 'configure arguments:'`
    for opt in $options; do
    if [ `echo $opt | grep '.*-temp-path'` ]; then
    value=`echo $opt | cut -d "=" -f 2`
    if [ ! -d "$value" ]; then
    # echo "creating" $value
    mkdir -p $value && chown -R $user $value
    fi
    fi
    done
    }
    start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
    }
    stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
    }
    restart() {
    configtest || return $?
    stop
    sleep 1
    start
    }
    reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
    }
    force_reload() {
    restart
    }
    configtest() {
    $nginx -t -c $NGINX_CONF_FILE
    }
    rh_status() {
    status $prog
    }
    rh_status_q() {
    rh_status >/dev/null 2>&1
    }
    case "$1" in
    start)
    rh_status_q && exit 0
    $1
    ;;
    stop)
    rh_status_q || exit 0
    $1
    ;;
    restart|configtest)
    $1
    ;;
    reload)
    rh_status_q || exit 7
    $1
    ;;
    force-reload)
    force_reload
    ;;
    status)
    rh_status
    ;;
    condrestart|try-restart)
    rh_status_q || exit 0
    ;;
    *)
    echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
    exit 2
esac
    chmod  x /etc/init.d/nginx # 复***务脚本执行权限
    vi /etc/nginx/nginx.conf # 编辑主配置文件
    worker_processes 2;
    error_log /var/log/nginx/nginx.error.log;
    pid /var/run/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"';
    sendfile on;
    keepalive_timeout 65;
    server {
    listen 80;
    server_name xxrenzhe.lnmmp.com;
    access_log /var/log/nginx/nginx.access.log main;
    location / {
    root /www/lnmmp.com;
    index index.php index.html index.htm;
    }
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root /www/lnmmp.com;
    }
    location ~ .php$ {
    root /www/lnmmp.com;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
    }
    }
    }
    vi /etc/nginx/fastcgi_params # 编辑fastcgi参数文件
    fastcgi_param GATEWAY_INTERFACE CGI/1.1;
    fastcgi_param SERVER_SOFTWARE nginx;
    fastcgi_param QUERY_STRING $query_string;
    fastcgi_param REQUEST_METHOD $request_method;
    fastcgi_param CONTENT_TYPE $content_type;
    fastcgi_param CONTENT_LENGTH $content_length;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    fastcgi_param REQUEST_URI $request_uri;
    fastcgi_param DOCUMENT_URI $document_uri;
    fastcgi_param DOCUMENT_ROOT $document_root;
    fastcgi_param SERVER_PROTOCOL $server_protocol;
    fastcgi_param REMOTE_ADDR $remote_addr;
    fastcgi_param REMOTE_PORT $remote_port;
    fastcgi_param SERVER_ADDR $server_addr;
    fastcgi_param SERVER_PORT $server_port;
    fastcgi_param SERVER_NAME $server_name;

启动服务

service nginx configtest # 服务启动前先验证配置文件是否正确
service nginx start
ps -ef |grep nginx # 检查nginx进程,尤其是worker进程是否与worker_processes值一致
ss -antupl |grep 80 # 检查服务端口是否启动

性能测试
测试说明
每次测试都进行3次,最后数据取平均值;
对比测试中的Apache采用event的MPM机制,最大化提高Apache的并发性能;
每次测试后,都需重新启动服务(httpd或nginx),以防止多次测试数据不准;
测试工具:webbench
优点:比ab能更好的模拟并发请求,最大支持模拟30000并发连接;
测试方法

# 安装webbench
wget http://blog.s135.com/soft/linux/webbench/webbench-1.5.tar.gz
tar xf webbench-1.5.tar.gz
cd webbench-1.5
make && make install
# 测试
webbench -c 100 -t 30 http://172.16.25.112/nginx.html # 测试静态文件访问
webbench -c 20 -t 30 http://172.16.25.112/test_mem.php # 测试动态文件访问

测试数据
未分类
未分类

分析趋势图

静态文件访问趋势图
未分类
动态文件访问趋势图
未分类

总结

综合上面测试得出的趋势图可以看出:
1、静态文件测试时,低并发(200以下)情况下,Nginx和Apach的处理能力相当(2000pages/sec左右),当并发数超过200后,则Apache的处理能力开始下降,而Nginx保持稳定;同时随着并发量的增大,Apache令人诟病的内存占用和负载开始急剧上升,与此同时,Nginx在内存占用和负载方面的略微提升则可以忽略不计了;
2、动态文件测试时,低并发(100以下)情况下,Nginx和Apache的处理能力相当(650pages/sec左右),但Nginx的内存占用和负载峰值只有Apache的50%左右;在高并发情况下(100以上),Apach的动态处理能力开始下滑,当并发达到500时,开始出现失败的请求,说明此时已达到的Apache的处理上限了,而反观Nginx,虽然处理动态请求会消耗更多的内存,但其处理能力随着并发量的上升而上升,即使并发1000动态请求,也未达到其处理能力上限;
3、故不管是在静态文件请求还是动态文件请求方面,Nginx的性能都是强势优于Apache的;虽然可以通过系统调优的方式提高Apache的处理性能,但和Nginx相比,还是不足以打动技术狂热份子的吧,哈哈!

Nginx解决惊群现象

惊群现象:所有的工作进程都在等待一个socket,当socket客户端连接时,所有工作线程都被唤醒,但最终有且仅有一个工作线程去处理该连接,其他进程又要进入睡眠状态。

Nginx通过控制争抢处理socket的进程数量和抢占ngx_accept_mutex锁解决惊群现象。只有一个ngx_accept_mutex锁,谁拿到锁,谁处理该socket的请求。

如果当前进程的连接数>最大连接数*7/8,则该进程不参与本轮竞争。

while(true)
{
    //工作进程抢占锁,抢占成功的进程将ngx_accept_mutex_held变量置为1。拿到锁,意味着socket被放到本进程的epoll中了,如果没有拿到锁,则socket会被从epoll中取出。  
    if(pthread_mutex_trylock(&ngx_accept_mutex))
    {
        ngx_accept_mutex_held = 1;
    }
    else
    {
        //设置time时间,使得没有拿到锁的worker进程,去拿锁的频繁更高
        timer = 500;
        ngx_accept_mutex_held = 0;
    }

     //拿到锁的话,置flag为NGX_POST_EVENTS,这意味着ngx_process_events函数中,任何事件都将延后处理,会把accept事件都放到ngx_posted_accept_events链表中,epollin|epollout事件都放到ngx_posted_events链表中  
    if (ngx_accept_mutex_held) 
    {   
        flags |= NGX_POST_EVENTS;
    }

    //继续epoll_wait等待处理事件
    int num = epoll_wait(epollfd, events, length, timer);
    for(int i=0; i<num; ++i)
    {
        ......
        //如果是读事件
        if (revents & EPOLLIN)
        {
            //有NGX_POST_EVENTS标志的话,就把accept事件放到ngx_posted_accept_events队列中,把正常的事件放到ngx_posted_events队列中延迟处理
            if (flags & NGX_POST_EVENTS)
            {
                queue = rev->accept ? 
                    &ngx_posted_accept_events:&ngx_posted_events;

                ngx_post_event(rev, queue);
            }
            else//处理
            {
                rev->handler(rev);
            }
        }

        //如果是写事件
        if (revents & EPOLLOUT)
        {
            //同理,有NGX_POST_EVENTS标志的话,写事件延迟处理,放到ngx_posted_events队列中 
            if (flags & NGX_POST_EVENTS) 
            {
                ngx_post_event(rev, &ngx_posted_events);
            }
            else//处理
            {
                rev->handler(rev);
            }
        }

      //先处理新用户的连接事件
      ngx_event_process_posted(cycle, &ngx_posted_accept_events);

      //释放处理新连接的锁
      if(ngx_accept_mutex_held)
      {
          pthread_mutex_unlock(&ngx_accept_mutex);
      }

      //再处理已建立连接的用户读写事件
      ngx_event_process_posted(cycle, &ngx_posted_events);
    }

Nginx HTTP2配置教程

前言

从 2015 年 5 月 14 日 HTTP/2 协议正式版的发布到现在已经快有一年了,越来越多的网站部署了 HTTP2,HTTP2 的广泛应用带来了更好的浏览体验,只要是 Modern 浏览器都支持,所以部署 HTTP2 并不会带来太多困扰。

虽然 h2 有 h2c (HTTP/2 Cleartext) 可以通过非加密通道传输,但是支持的浏览器初期还是比较少的,所以目前部署 h2 还是需要走加密的,不过由于 Let’s Encrypt 大力推行免费证书和证书的廉价化,部署 h2 的成本并不高。

介绍

HTTP 2.0即超文本传输协议 2.0,是下一代HTTP协议。是由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。是自1999年http1.1发布后的首个更新。

HTTP/2 协议是从 SPDY 演变而来,SPDY 已经完成了使命并很快就会退出历史舞台(例如 Chrome 将在「2016 年初结束对 SPDY 的支持」;Nginx、Apache 也已经全面支持 HTTP/2 ,并也不再支持 SPDY)。

一般的大家把 HTTP2 简称为 h2,尽管有些朋友可能不怎么愿意,但是这个简称已经默认化了,特别是体现在浏览器对 HTTP2 都是这个简写的。

配置

普通的 HTTPS 网站浏览会比 HTTP 网站稍微慢一些,因为需要处理加密任务,而配置了 h2 的 HTTPS,在低延时的情况下速度会比 HTTP 更快更稳定!

现在电信劫持事件频发,网站部署了 HTTPS 加密后可以杜绝大部分劫持,但不是完全。像电子商务行业对 HTTPS 加密可是标配啊,因此部署 h2 更是势在必行。

证书

这里是 免费和便宜 SSL 证书介绍 ,大家可以从这里购买或者申请免费的 SSL 证书,免得 Chrome 弹出红色的页面令人不悦,从而拒绝了大多数访客。

Web 服务器

说明

默认编译的 Nginx 并不包含 h2 模块,我们需要加入参数来编译,截止发文,Nginx 1.9 开发版及以上版本源码需要自己加入编译参数,从软件源仓库下载的则默认编译。 Tengine 可以同时部署 h2 和 SPDY 保证兼容性,Nginx 则是一刀切不再支持 SPDY。

安装/编译

如果你编译的 Nginx 不支持,那么在 ./configure 中加入:–with-http_v2_module ,如果没有 SSL 支持,还需要加入 –with-http_ssl_module

然后 make && make install 即可。

配置

主要是配置 Nginx 的 server 块, 。
修改相关虚拟机的 .conf 文件,一般在 /usr/local/nginx/conf/vhost/ 或者 /etc/nginx/conf/,具体参考你的环境指导,不懂请回复。

server {
listen 443 ssl http2 default_server;
server_name www.mf8.biz;

ssl_certificate /path/to/public.crt;
ssl_certificate_key /path/to/private.key;

注:将 server_name www.mf8.biz; 中的 www.mf8.biz 替换为你的域名。

然后通过 /usr/local/nginx/sbin/nginx -t 或者 nginx -t 来检测是否配置正确,然后重启 Nginx ,即可。

检验

在 Chrome 浏览器上可以通过,HTTP/2 and SPDY indicator 来检验,如果地址栏出现蓝色的闪电就是 h2

也可以在 chrome://net-internals/#http2 中检查。注意版本要新,姿势要帅!

配置进阶

大家都知道去年的心血漏洞将 SSL 推到了风口浪尖,所以单单支持了 h2 ,我们任然需要对 SSL 做一些安全的优化!

配置赫尔曼密钥

openssl dhparam -out dhparam.pem 2048 // 在 ssh 运行, openssl 生成 2048 位的密钥而不是当作参数写入 nginx.conf 文件。

ssl_dhparam /path/to/dhparam.pem; //在 .conf 中配置

禁止不安全的 SSL 协议,使用安全协议

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

禁止已经不安全的加密算法

ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4';

缓解 BEAST 攻击

ssl_prefer_server_ciphers on;```

**启用 HSTS**

此举直接跳过 301 跳转,还降低了中间人攻击的风险!配置在 .conf 中即可

`add_header Strict-Transport-Security max-age=15768000;`

**301 跳转**

80 端口跳转到 443 端口
```nginx
server {
 listen 80;
 add_header Strict-Transport-Security max-age=15768000;
 return 301 https://www.yourwebsite.com$request_uri;
}

缓存连接凭据

ssl_session_cache shared:SSL:20m;
ssl_session_timeout 60m;

OCSP 缝合

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/cert/trustchain.crt;
resolver 233.5.5.5 233.6.6.6 valid=300s;

欢迎你的补充!

通过 www.ssllabs.com 即可检验 HTTPS 配置的安全性和实用性!

Nginx上传大文件超时出错解决方法

Nginx上传大文件出现出错超时

上传文件大小:1.4G
上传所使用的组件:swfupload
swfupload返回-220错误码,对应的是错误提示是IO_ERROR。
IO_ERROR #当读取和发送文件时出现了一些错误。通常发生在服务器非预期地关闭了终端连接的时候。

解决:

修改Nginx读取超时间与发请求超时间.

nginx配置参数如下:

fastcgi_connect_timeout 300; #连接超时
fastcgi_read_timeout 600;    #读超时
fastcgi_send_timeout 600;    #写超时

#选项注解:

fastcgi_read_timeout #FastCGI进程向Nginx进程发送response,整个过程的超时时间
fastcgi_send_timeout #Nginx进程向FastCGI进程发送request,整个过程的超时时间

nginx结合jwplayer实现视频流媒体点播

一、nginx简介:

Nginx是一个网页服务器,它能反向代理HTTP, HTTPS, SMTP, POP3, IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存。

Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。与旧版本(<=2.2)的Apache不同,nginx不采用每客户机一线程的设计模型,而是充分使用异步逻辑,削减了上下文调度开销,所以并发服务能力更强。整体采用模块化设计,有丰富的模块库和第三方模块库,配置灵活。 在Linux操作系统下,nginx使用epoll事件模型,得益于此,nginx在Linux操作系统下效率相当高。同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于epoll的高效事件模型kqueue。下图是实现的最终效果。

未分类

未分类

二、流媒体简介:

流媒体(Streaming media)是指将一连串的媒体数据压缩后,经过网络分段发送数据,在网络上即时传输影音以供观赏的一种技术与过程,此技术使得数据包得以像流水一样发送;如果不使用此技术,就必须在使用前下载整个媒体文件。流传输可发送现场影音或预存于服务器上的视频,当观看者在收看这些影音档时,影音数据在送达观赏者的电脑后立即由特定播放软件播放(如Windows Media Player,Real Player,或QuickTime Player)。

未分类

三、安装步骤:

1、 安装nginx

(1). 安装依赖包

yum -y install gcc openssl-devel pcre-devel httpd-tools gcc-c++

未分类

(2). 下载nginx

下载地址:http://nginx.org/download/nginx-1.10.2.tar.gz

wget http://nginx.org/download/nginx-1.10.2.tar.gz

(3). 解压nginx

tar xf nginx-1.10.2.tar.gz

(4). 进入nginx目录

cd nginx-1.10.2/

(5).创建nginx用户

useradd nginx

未分类

(6). 检查配置文件

> ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
> --with-http_ssl_module --with-http_mp4_module --with-http_flv_module

未分类

(7). 编译并安装

make && make install

未分类

(8). 建立快捷方式

ln -s /usr/local/nginx/sbin/nginx /usr/sbin/

(9). 启动nginx服务

nginx

(10). 检查nginx监听信息

netstat -anptu | grep nginx

未分类

(11). 修改配置

vim /usr/local/nginx/conf/nginx.conf

配置内容

worker_processes  1;
events {
    worker_connections  65535;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        location ~ .flv$ {
            flv;
            limit_conn addr 4;
            limit_rate 1024k;
        }
        location ~ .mp4$ {
            mp4;
            limit_conn addr 4;
            limit_rate 1024k;
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }
    }
}

未分类

(12). 刷新配置

nginx -s reload #重启nginx,刷新配置

未分类

(13). 浏览器检测

未分类

2、 部署代码

(1). 上传代码、jwplayer、视频

jwplayer下载官网:https://www.jwplayer.com/

> scp -r index.html jwplayer qyz.flv
> [email protected]:/usr/local/nginx/html

未分类

html代码

未分类

(2). 浏览器检测点播效果

输入地址:http://192.168.4.1,点击播放

未分类

Nginx技术原理介绍

Nginx Inc. 联合创始人 Andrew Alexeev 在 AOSA 上发表的文章 [1] ,涵盖 了 Nginx 项目想要解决的问题、程序整体架构、配置文件结构、请求处理流程和开发 Nginx 过程中的心得体会等等话题。本节对该文中提到的关键点进行摘录和整理。

一些信息

  • 发音:( engine x );
  • 俄罗斯软件工程师 Igor Sysoev 于 2004 年发布的开源 Web 服务器软件;
  • 目前,在开源 Web 服务器按市场占有率排列的名单中,Nginx 位列第二名(Apache HTTPD 第一名)(据 2015年8月10日 w3techs 的统计数字,Nginx 已经跃居榜首);
  • Nginx 专注于高性能、高并发和低内存占用;
  • 除基本的 Web 服务功能外,Nginx 还提供了诸如「负载均衡」、「缓存」、「访问控 制」、「带宽控制」、「HTTP/TCP/UDP 反向代理」等功能,它还能高效得和其它各类 应用结合使用;
  • Nginx 使用 C 语言开发,除了 libc, zlib, PCRE 和 OpenSSL 外, 不依赖其它开发库。
  • Nginx 是一个「模块化的」、「基于事件驱动的」、「异步的」、「单线程的」、「非 阻赛的」的 Web 服务器;
  • Nginx 使用 C 语言风格的配置文件;

技术原理

事件驱动 vs. 多进程/线程

  • 1995 年首次发布的 Apache HTTPD,在 2012 年 2.4 稳定版之前,在 Linux 平台上只 能选择 mpm-prefork [6] 或者 mpm-worker [7] 作为并发模式。在这两种工作模式里,Apache 会为每个 HTTP 请求分配独立的进程或 者线程,请求处理完成后,进程或线程才会被回放释放。2.4 版增加了 mpm-event 模式 [8],虽然使用了 epoll, kqueue 等事件驱动机制, 但是请求处理依然由线程完成。
  • 在上世纪90年代,由于操作系统、计算机硬件和当时互联网状态的限制,Apache 选择 上述的并发模型是合理的,并且它也提供了相当丰富的功能和特性。但是,这些特点的 代价是,在每个连接会使用更多的内存资源,不能很好地支持网站非线性伸缩 (nonlinear scalability)。
  • 创建进程和线程(新的堆、栈和执行上下文)内存和 CPU 等资源消耗大;
  • 过多的上下文切换(context switching)会造成 thread thrashing ;
  • 随着硬件、操作系统和网络带宽的发展,它们不再是制约网站规模增长的瓶径:
  • C10K Problem [2]
  • Why threads are a bad idea (for most purposes) – 1995 [4] vs. Why events are a bad idea (for high-concurrency servers) – 2003 [3]
  • 各操作系统对事件驱动的支持
  • Unix-like/Windows – select/poll – 未考证,很早
  • FreeBSD/NetBSD/OpenBSD/OS X – kqueue – 2000
  • Windows/AIX/solaris 10 – IOCP – Windows NT 3.5
  • Linux – epoll – 2.5.44, 2003 年前,2001 年初稿 [5]
  • It’s time for web servers to handle ten thousand clients simultaneously.
  • Lighttpd [10]
  • Nginx [9]
  • libevent [11]
  • libuv [12]

并发模型

以解决 C10K 问题 [2] 为使命的 Nginx,在底层架构上选择了事件驱动机制。事件 驱动机在需要对并发连接和吞吐率提供非线性伸缩 (nonlinear scalability) 的场景中比 多进程/多线程更适合:负载持续上升时,CPU 和内存占用依然在可控的范围内;在普 通硬件配置上,Nginx 就可以服务数以万计的并发连接。

  • 多路复用(multiplexting)、事件通知(event notification);
  • 每个使用单线程的工作进程(worker)通过高效的 runloop 处理数以千记的并发连 接;
  • 工作进程从共享 listening socket ,接收新连接并将其加入到自己的 runloop 中。新连接的分发由操作系统决定(thundering herd 问题 [13]);
  • 对工作进程个数选择的一般建议:
  • CPU 密集型业务,比如,启用了 SSL、数据解压缩等场景下,工作进程个数由 CPU 核 数决定;
  • 磁盘 IO 密集型业务,工作进程个数可以设为 CPU 核数的 1.5 倍到 2 倍;

实现细节

  • Ngnix 会根据不同操作系统的特点进行不同的优化,以提高 IO 性能;

  • 工作进程中的 runloop 是 Nginx 代码中最复杂的部分,它的实现基于异步任务处 理思想。Nginx 通过使用模块化、事件通知、大量的回调函数和仔细调整的计时器等 手段实现异步操作。

  • 基本原则就是尽量使用非阻塞操作;
  • 读写性能不足的硬盘的操作是 Nginx 中唯一可能发生阻塞的地方;

  • Nginx 谨慎地使用系统调用实现了诸如内存池( pool )、片内存分配器 ( slab memory allocator )等高效的数据结构,再加上选取的并发模型,可以有 效节省对 CPU、内存等系统资源的占用。即使在极高的负载下,Nginx 的 CPU 使用率通 常也是很低的。

  • 在某种程度上,Nginx 借鉴了 Apache 的内存分配机制:
  • 它尽可能在内部通过传递指针的方式地减少内存拷贝;
  • Nginx 为每个连接创建一个内存池,为该连接生命期内的各种操作分配内存。比 如,连接内存池可以用来存储请求包头和包体数据,可以用来创建请求结构体 ( ngx_http_request_t )。Nginx 在关闭连接时,释放连接内存池;
  • Nginx 还会为请求分配请求内存池,为该请求生命期内的各种操作分配内存。比 如,与该请求相关的变量值,解析后的请求包头信息等。Nginx 在请求处理完毕后 ,释放请求内存池;
  • Nginx 使用 slab memory allocator 管理共享内存。共享内存一般用来存储 acept mutex, cache metadata, SSL session cache 等需要在进程间共 享的数据。同时,Nginx 使用 mutex semaphore 等加锁机制保证共享数据的 安全。

  • Nginx 提供了针对阻塞磁盘 IO 的优化措施: sendfile, AIO, thread pool (1.7.11+);

  • 除了 master 进程和 worker 进程,Nginx 还会启动 cache loader 进程 和 cache manager 进程,这些进程之间使用共享内存作为主要通信方式。

  • master 进程的主要工作如下:
  • 读取和验证配置文件;
  • 创建、绑定和并闭 socket;
  • 启动和停止 worker 进程,并按照配置的工作进程个数维护工作进程;
  • 在不中断服务的前提下,重新加载配置文件;
  • 实现 Nginx 二进制热切换;
  • 根据信号重新打开日志文件;
  • 编译内嵌 Perl 脚本;
  • worker 进程负责接收和处理客户端连接、反向代理客户端请求和响应过滤 等等 Nginx 的对外提供其它功能;
  • cache loader 进程负责遍历和检查磁盘缓存数据,并使用获取到的缓存元数据为 Nginx 建立内存数据库,加快运行期间的缓存查找速度;
  • 每个被缓存的响应都作为独立文件存储于文件系统中;
  • 用户可以通过配置文件控制缓存目录的分级结构;
  • 从 upstream 得到的响应数据会先存储到临时文件中,随后将响应数据发送给 客户端后,Nginx 将此临时文件挪到缓存目录下;
  • cache manager 进程长驻后台,并负责维护缓存数据的有效性,清理过期缓存数 据;

  • try_files 配置项和配置文件变量 (variables) 是 Nginx 独有的特性;

The try_files directive was initially meant to gradually replace
conditional ``if`` configuration statements in a more proper way, and it
was designed to quickly and efficiently try/match against different
URI-to-content mappings...adopt its use whenever applicable.
Variables in Nginx were developed to provide an additional
even-more-powerful mechanism to control run-time configuration of a web
server. Variables are optimized for quick evaluation and are internally
pre-compiled to indices. Evaluation is done on command; i.e., the value
of a variable is typically calculated only once and cached for the
lifetime of a particular request. Variables can be used with different
configuration directives, providing additional flexibility for describing
conditional request process behavior.

模块分类

Nginx 是一个模块化/插件化的程序,1.9.11 版本之前,Nginx 只支持静态链接模块 代码,从 1.9.11 版本之后,才引入动态加载模块的功能。

Nginx 代码由一个核心模块(core module)和很多功能模块组成(funcional module), 核心模块实现了 Web 服务器的基础、Web 和 Mail 反向代理功能等,为 Nginx 提供了 底层网络协议支持,构造了必要的运行环境,并保证其它不同功能模块的无封结合。而 其它模块则负责提供应用协议相关的特性。

在核心模块和功能模块之间,还有像 http, mail 这样的中层模块(upper-level module),它们为功能模块提供了核心模块和其它底层功能的抽像。这些模块也根据应用 层协议决定「事件」的处理顺序,同时,它们和核心模块结合,维护其它相关功能模块的 调用顺序。

功能模块分为: event module, phase handler, output filter, variable handler, protocol, upstream, 和 balancer 。

Nginx 为模块提供了很多不同的调用时机,模块初始化时可以为不同的时机注册不同的 回调函数。时机到来时,Nginx 就会调用相应的回调函数。Nginx 提供的调用时机有:

* Before the configuration file is read and processed.
* For each configuration directive for the the location and the server
  where it appears
* When the main configuration is initialized.
* When the server is initialized.
* When the server configuration is merged with the main configuration.
* When the location configuration is initialized or merged with its parent
  server configuration.
* When the master process starts or exits.
* When a new worker process starts or exits.
* When handling a request.
* When filtering the response header and the body.
* When picking, initiating and reinitiating a request to an upstream
  server.
* When process the response from and upstream server.
* When finishing an interation with an upstream server.

请求处理

  • 一个 HTTP 请求的处理流程如下:
1. Client sends HTTP request.
2. Nginx core choose the appropriate phase handler based on the configured
location matching the request.
3. If configured to do so, a load balancer picks an upstream server for
proxying.
4. Phase handler does its job and passes each outout buffer to the first filter.
5. First filter passes the outout to the second filter (and so on).
6. Final response is send to the client.
  • Nginx 将 HTTP 请求的处理过程分成了几个阶段,每个阶段都有相应的处理函数( phase handler )。阶段处理函数由配置文件 location {} 中的配置项决定。 HTTP 请求包头接受完毕后,Nginx 为该请求匹配合适的虚拟主机,随后请求会再交由 如下几个阶段的处理函数处理:
1. server rewrite phase
2. location phase
3. location rewrite phase (which can bring the request back to the previous phase)
4. access control phase
5. try_files phase
6. content phase (content handler first, then content phase handler)
7. log phase
  • Nginx 为 HTTP 请求生成响应数据后,将响应数据交给 filter 模块处理。 filter 模块可以分别对响应头和响应体进行处理。据此, filter 模块 可以分为 header filter 和 body filter 两大类;

  • header filter 主要工作步骤如下:

1. Decide whether to operate on this response.
2. Operate on the response
3. Call the next filter.
  • body filter 用于操作响应包体。比如,使用 gzip 压缩响应数据, 使用 chunked 编码响应数据等;

  • 两个特殊的 filter : copy filter 负责填充用于存放响应数据的内存 缓冲区(比如,使用临时文件的数据); postpone filter 负责子请求 (subrequest)相关的处理。

  • 子请求 (subrequest)是 Nginx 的强大特性之一,它是请求处理逻辑中非常重 要的一环。通过子请求机制,Nginx 可以:

  • 将不同 URL 的请求响应数据返回给当前请求(即主请求);

  • 将多个子请求的响应数据合并,返回给当前请求;

  • 将子请求再分裂为更多的子请求(sub-subrequest),子子请求( sub-sub-subrequest),形成子请求的层次关系;

  • 使用子请求读取磁盘文件、访问 Upstream 服务器等;

  • 在 filter 中,根据当前请求的响应数据触发子请求,例如:

For example, the SSI module uses a filter to parse the contents of the
returned document, and then replaces ``include`` directives with the
contents of specified URLs. Or, it can be an example of making a filter
that treats the entire contents of a document as a URL to be retrieved,
and then appends the new document to the URL itself.

最后

从上面的描述可以看出,Nginx 各模块结合紧密,模块逻辑复杂,使用 C 开发模块难度 较高,开发效率较低。幸运的是, lua-nginx-module, stream-lua-nginx-module 等第三方模块和官方 ngx-http-js-module 模块出现,降低的模块开发的门槛。开发 者借助它们,甚至可以开发运行于 Nginx 内部的业务应用了。

Lession learned:

There is always room for improvement.

It is worth avoiding the dilution of development efforts on something that
is neither the developer's core competence or the target application.

nfs故障排查思路介绍

之前开发时就碰到过nfs客户端卡住的情况,umount -f /mnt提示device is busy,并且尝试访问挂载目录、df -h等操作都会使终端卡住,ctrl+c也不能强行退出。

当时忙着赶进度,没研究这个问题。最近倒出功夫研究一下,顺便学习一下nfs的优化。
造成这种现象的原因是nfs服务器/网络挂了,nfs客户端默认采用hard-mount选项,而不是soft-mount。他们的区别是
soft-mount: 当客户端加载NFS不成功时,重试retrans设定的次数.如果retrans次都不成功,则放弃此操作,返回错误信息 “Connect time out”
hard-mount: 当客户端加载NFS不成功时,一直重试,直到NFS服务器有响应。hard-mount 是系统的缺省值。在选定hard-mount 时,最好同时选 intr , 允许中断系统的调用请求,避免引起系统的挂起。当NFS服务器不能响应NFS客户端的 hard-mount请求时, NFS客户端会显示
“NFS server hostname not responding, still trying”

下面列出mount关于nfs相关的参数

(1)-a:把/etc/fstab中列出的路径全部挂载。
(2)-t:需要mount的类型,如nfs等。
(3)-r:将mount的路径定为read only。
(4)-v mount:过程的每一个操作都有message传回到屏幕上。
(5)rsize=n:在NFS服务器读取文件时NFS使用的字节数,默认值是4096个字节。
(6)wsize=n:向NFS服务器写文件时NFS使用的字节数,默认值是4096个字节。
(7)timeo=n:从超时后到第1次重新传送占用的1/7秒的数目,默认值是7/7秒。
(8)retry=n:在放弃后台mount操作之前可以尝试的次数,默认值是7 000次。
(9)soft:使用软挂载的方式挂载系统,若Client的请求得不到回应,则重新请求并传回错误信息。
(10)hard:使用硬挂载的方式挂载系统,该值是默认值,重复请求直到NFS服务器回应。
(11)intr:允许NFS中断文件操作和向调用它的程序返回值,默认不允许文件操作被中断。
(12)fg:一直在提示符下执行重复挂载。
(13)bg:如果第1次挂载文件系统失败,继续在后台尝试执行挂载,默认值是失败后不在后台处理。
(14)tcp:对文件系统的挂载使用TCP,而不是默认的UDP。

如#mount -t nfs -o soft 192.168.1.2:/home/nfs /mnt

至于传输尺寸的选择,可以进行实际测试:

time dd if=/dev/zero of=/mnt/nfs.dat bs=16k count=16384

即向nfs服务器上的nfs.dat文件里写入16384个16KB的块(也有经验说文件大小可以设定为nfs服务器内存的2倍)。
得到输出如:

输出了 16384+0 个块
user    0m0.200s
输出了 66535+0 个块
user    0m0.420s
192.168.1.4:/mnt  /home/nfs  nfs   rsize=8192,wsize=8192,timeo=10,intr

重新挂载nfs服务器,调整读写块大小后重复上述过程,可以找到最佳传输尺寸。

NFS服务器的故障排除

故障排除思路:

NFS出现了故障,可以从以下几个方面着手检查。

(1)NFS客户机和服务器的负荷是否太高,服务器和客户端之间的网络是否正常。
(2)/etc/exports文件的正确性。
(3)必要时重新启动NFS或portmap服务。

运行下列命令重新启动portmap和NFS:

service portmap restart
service nfs start

(4)检查客户端中的mount命令或/etc/fstab的语法是否正确。
(5)查看内核是否支持NFS和RPC服务。

普通的内核应有的选项为CONFIG_NFS_FS=m、CONFIG_NFS_V3=y、CONFIG_ NFSD=m、CONFIG_NFSD_V3=y和CONFIG_SUNRPC=m。
我们可以使用常见的网络连接和测试工具ping及tracerroute来测试网络连接及速度是否正常,网络连接正常是NFS作用的基础。rpcinfo命令用于显示系统的RPC信息
,一般使用-p参数列出某台主机的RPC服务。用rpcinfo-p命令检查服务器时,应该能看到portmapper、status、mountd nfs和nlockmgr。用该命令检查客户端时,应
该至少能看到portmapper服务。

使用nfsstat命令查看NFS服务器状态

nfsstat命令显示关于NFS和到内核的远程过程调用(RPC)接口的统计信息,也可以使用该命令重新初始化该信息。如果未给定标志,默认是nfsstat -csnr命令。使用该命令显示每条信息,但不能重新初始化任何信息。

nfsstat命令的主要参数如下。

(1)-b:显示NFS V4服务器的其他统计信息。
(2)c:只显示客户机端的NFS和RPC信息,允许用户仅查看客户机数据的报告。nfsstat命令提供关于被客户机发送和拒绝的RPC和NFS调用数目的信息。
要只显示客户机NFS或者RPC信息,将该参数与-n或者-r参数结合。
(3)-d:显示与NFS V4授权相关的信息。
(4)-g:显示RPCSEC_GSS信息。
(5)-m:显示每个NFS文件系统的统计信息,该文件系统和服务器名称、地址、安装标志、当前读和写大小,以及重新传输计数
(6)-n:为客户机和服务器显示NFS信息。要只显示NFS客户机或服务器信息,将该参数与-c和-s参数结合。
(7)-r:显示RPC信息。
(8)-s:显示服务器信息。
(9)-t:显示与NFS标识映射子系统的转换请求相关的统计信息,要只显示NFS客户机或服务器信息,将-c和-s选项结合。
(10)-4:当与-c、-n、-s或-z参数组合使用时,将包含NFS V4客户机或服务器的信息,以及现有的NFS V2和V3数据。
(11)-z:重新初始化统计信息。该参数仅供root用户使用,并且在显示上面的标志后可以和那些标志中的任何一个组合到统计信息的零特殊集合。

要显示关于客户机发送和拒绝的RPC和NFS调用数目的信息,输入:

nfsstat -c

要显示和打印与客户机NFS调用相关的信息,输入如下命令:

nfsstat -cn

要显示和打印客户机和服务器的与RPC调用相关的信息,输入如下命令:

nfsstat -r

要显示关于服务器接收和拒绝的RPC和NFS调用数目的信息,输入如下命令:

nfsstat –s

mysql主(master)从(slave)数据库复制的配置

主从数据库作用:

1、 对数据库进行读写分离,提高系统性能。主服务器专注于写操作,从数据库专注于读操作。
2、 从(slave)数据库在不破坏主数据库数据的情况下,执行数据备份。
3、 用主数据库产生实时数据,从(slave)数据库进行数据的分析。
4、 远程数据分布:创建远程站点的本地数据副本,不需要永久的访问主服务器。

步骤:

1、修改主服务器数据库的配置文件(my.ini或my.cnf),配置如下内容。

[mysqld]   
log-bin=mysql-bin   
server-id=156       //这里一般去服务器ip位数  

2、 为执行复制的从数据创建用户、密码,并分配权限。

mysql> CREATE USER 'cenliming'@'%' IDENTIFIED BY 'password';   //'%'代表允许 该用户远程访问数据库   
mysql> GRANT  REPLICATION  SLAVE ON  *.*   TO 'user'@'%';  

注意:如果在本地测试,要配置本地数据库允许远程连接。

3、 获取二进制日志文件信息,若显示为空,请重启数据库即可查看到。

mysql > SHOW MASTER STATUS;     
+------------------+----------+--------------+------------------+   
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |   
+------------------+----------+--------------+------------------+   
| mysql-bin.000003 | 73       | test         | manual,mysql     |   
+------------------+----------+--------------+------------------+

(File:日志文件名 Position: 文件坐标)

4、 在主数据库中释放表锁,在从数据库中进行相关配置。 a. 主数据库释放锁:

mysql> UNLOCK TABLES;  

修改从数据库配置文件,配置server-id:

[mysqld]   
server-id=232  

在从数据库中进行连接主数据库的配置:

mysql> CHANGE MASTER TO  
    ->     MASTER_HOST='master_host_name',   
    ->     MASTER_USER='replication_user_name',   
    ->     MASTER_PASSWORD='replication_password',   
    ->     MASTER_LOG_FILE='recorded_log_file_name',   
    ->     MASTER_LOG_POS=recorded_log_position;

5、 启动从服务器并查看状态:

mysql> start  slave;     //停止用 stop   
mysql>show slave stausG;  

未分类

Slave_IO_Running状态不为YES,说明从数据库未能成功连接到主数据库。 配置成功后,你对主数据库的更新操作都会更新到从数据库(异步处理)。