草庐IT

Nginx 高级扩展实例

peaceweb 2023-03-28 原文
一、首先安装Nginx:

  1. # yum -y install pcre-devel  
  2.  
  3. # groupadd -r nginx  
  4. # useradd -r -g nginx -s /sbin/nologin -M nginx  
  5.  
  6. # tar xf nginx-1.2.3.tar.gz   
  7. # cd nginx-1.2.3  
  8. # ./configure \  
  9.   --prefix=/usr \  
  10.   --sbin-path=/usr/sbin/nginx \  
  11.   --conf-path=/etc/nginx/nginx.conf \  
  12.   --error-log-path=/var/log/nginx/error.log \  
  13.   --http-log-path=/var/log/nginx/access.log \  
  14.   --pid-path=/var/run/nginx/nginx.pid  \  
  15.   --lock-path=/var/lock/nginx.lock \  
  16.   --user=nginx \  
  17.   --group=nginx \  
  18.   --with-http_ssl_module \  
  19.   --with-http_flv_module \  
  20.   --with-http_stub_status_module \  
  21.   --with-http_gzip_static_module \  
  22.   --http-client-body-temp-path=/var/tmp/nginx/client/ \  
  23.   --http-proxy-temp-path=/var/tmp/nginx/proxy/ \  
  24.   --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \  
  25.   --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \  
  26.   --http-scgi-temp-path=/var/tmp/nginx/scgi \  
  27.   --with-pcre  
  28.  
  29. # make && make install 
新建文件/etc/rc.d/init.d/nginx,内容如下:

  1. #!/bin/sh  
  2. #  
  3. # nginx - this script starts and stops the nginx daemon  
  4. #  
  5. # chkconfig:   - 85 15   
  6. # description:  Nginx is an HTTP(S) server, HTTP(S) reverse \  
  7. #               proxy and IMAP/POP3 proxy server  
  8. # processname: nginx  
  9. # config:      /etc/nginx/nginx.conf  
  10. # config:      /etc/sysconfig/nginx  
  11. # pidfile:     /var/run/nginx.pid  
  12.    
  13. # Source function library.  
  14. . /etc/rc.d/init.d/functions  
  15.    
  16. # Source networking configuration.  
  17. . /etc/sysconfig/network  
  18.    
  19. # Check that networking is up.  
  20. [ "$NETWORKING" = "no" ] && exit 0  
  21.    
  22. nginx="/usr/sbin/nginx" 
  23. prog=$(basename $nginx)  
  24.    
  25. NGINX_CONF_FILE="/etc/nginx/nginx.conf" 
  26.    
  27. [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx  
  28.    
  29. lockfile=/var/lock/subsys/nginx  
  30.    
  31. make_dirs() {  
  32.    # make required directories  
  33.    user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`  
  34.    options=`$nginx -V 2>&1 | grep 'configure arguments:'`  
  35.    for opt in $options; do  
  36.        if [ `echo $opt | grep '.*-temp-path'` ]; then  
  37.            value=`echo $opt | cut -d "=" -f 2`  
  38.            if [ ! -d "$value" ]; then  
  39.                # echo "creating" $value  
  40.                mkdir -p $value && chown -R $user $value  
  41.            fi  
  42.        fi  
  43.    done  
  44. }  
  45.    
  46. start() {  
  47.     [ -x $nginx ] || exit 5  
  48.     [ -f $NGINX_CONF_FILE ] || exit 6  
  49.     make_dirs  
  50.     echo -n $"Starting $prog: "  
  51.     daemon $nginx -c $NGINX_CONF_FILE  
  52.     retval=$?  
  53.     echo  
  54.     [ $retval -eq 0 ] && touch $lockfile  
  55.     return $retval  
  56. }  
  57.    
  58. stop() {  
  59.     echo -n $"Stopping $prog: "  
  60.     killproc $prog -QUIT  
  61.     retval=$?  
  62.     echo  
  63.     [ $retval -eq 0 ] && rm -f $lockfile  
  64.     return $retval  
  65. }  
  66.    
  67. restart() {  
  68.     configtest || return $?  
  69.     stop  
  70.     sleep 1  
  71.     start  
  72. }  
  73.    
  74. reload() {  
  75.     configtest || return $?  
  76.     echo -n $"Reloading $prog: "  
  77.     killproc $nginx -HUP  
  78.     RETVAL=$?  
  79.     echo  
  80. }  
  81.    
  82. force_reload() {  
  83.     restart  
  84. }  
  85.    
  86. configtest() {  
  87.   $nginx -t -c $NGINX_CONF_FILE  
  88. }  
  89.    
  90. rh_status() {  
  91.     status $prog  
  92. }  
  93.    
  94. rh_status_q() {  
  95.     rh_status >/dev/null 2>&1  
  96. }  
  97.    
  98. case "$1" in  
  99.     start)  
  100.         rh_status_q && exit 0  
  101.         $1  
  102.         ;;  
  103.     stop)  
  104.         rh_status_q || exit 0  
  105.         $1  
  106.         ;;  
  107.     restart|configtest)  
  108.         $1  
  109.         ;;  
  110.     reload)  
  111.         rh_status_q || exit 7  
  112.         $1  
  113.         ;;  
  114.     force-reload)  
  115.         force_reload  
  116.         ;;  
  117.     status)  
  118.         rh_status  
  119.         ;;  
  120.     condrestart|try-restart)  
  121.         rh_status_q || exit 0  
  122.             ;;  
  123.     *)  
  124.         echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"  
  125.         exit 2  
  126. esac 
而后为此脚本赋予执行权限:
# chmod +x /etc/rc.d/init.d/nginx

添加至服务管理列表,并让其开机自动启动:
# chkconfig --add nginx
# chkconfig nginx on

而后就可以启动服务并测试了:
# service nginx start



二、URL重写:
格式如下
rewrite <源匹配类型> <替换后的地址> <标识>

例:rewrite /p_w_picpaths/(.*\.jpg) http://192.168.80.146/p_w_picpaths/$1 permanent;

将访问本机的任何以.jpg结尾的都永久重定向到http://192.168.80.146/p_w_picpaths/下的.jpg去


标识有以下四种:
last —— 持续标识,替换后的规则在继续匹配,拿更改后的地址重新去匹配,会产生死循环
 例:location /p_w_picpath/ {
          rewrite /p_w_picpaths/.*\.jpg http://192.168.80.143/p_w_picpaths/a.jpg last;
  }
  这样就残生死循环了,所以在定义的时候要避免重复
  
break —— 结束标识,表示到此为止,不再继续匹配
redirect —— 临时重定向标识,http协议代码为302
permanent —— 永久重定向标识,http协议代码为301

例:在192.168.80.146上定义重写如下
location / {
                rewrite ^/forum/(test.html)$ http://192.168.80.143/bbs/$1 permanent;
        }

# server nginx restart

并在192.168.80.143上建立/var/www/html/bbs/test.html文件

在浏览器中输入http://192.168.80.146/forum/test.html 访问看看:


可以看到自动重写为http://192.168.80.143/bbs/test.html

这里重定向也可以使用if指令:
语法: if (condition) { ... }
应用环境: server, location

条件:
1、变量名; false values are: empty string ("", or any string starting with "0";)
2、对于变量进行的比较表达式,可使用=或!=进行测试;
3、正则表达式的模式匹配:
 ~  区分大小的模式匹配
 ~* 不区分字母大小写的模式匹配
 !~ 和 !~* 分别对上面的两种测试取反
4、测试文件是否存在-f或!-f
5、测试目录是否存在-d或!-d
6、测试目录、文件或链接文件的存在性-e或!-e
7、检查一个文件的执行权限-x或!-x

例:如果用户请求的页面不存在,实现自定义跳转:

if (!-f $request_filename) {
      rewrite ^(/.*)$ /rewrite.html permanent;
}


三、配置反向代理缓存:
nginx : 192.168.80.146
web1:192.168.80.143

web1配置:

  1. # yum -y install httpd  
  2. # echo "web1" > /var/www/html/index.html  
  3. # service httpd start 
nginx配置:

  1. # egrep -v "^$|#" /etc/nginx/nginx.conf  
  2. worker_processes  1;  
  3. events {  
  4.     worker_connections  1024;  
  5. }  
  6. http {  
  7.     include       mime.types;  
  8.     default_type  application/octet-stream;  
  9.     proxy_cache_path /var/www/cache levels=1:2 keys_zone=mycache:20m  max_size=2048m inactive=60m;   //指定缓存目录/var/www/cache,levels定义缓存级别,缓存名字mycache,最大缓存2048M,非活动时间  
  10.     proxy_temp_path /var/www/cache/tmp;  //临时缓存目录  
  11.     sendfile        on;  
  12.     keepalive_timeout  65;  
  13.     server {  
  14.         listen       80;  
  15.         server_name  localhost;  
  16.         location / {  
  17.      proxy_pass http://192.168.80.143;  //指定web服务器  
  18.      proxy_cache mycache;   //指定前面定义的缓存名字  
  19.             proxy_cache_valid 200 302 60m;  //定义http协议200,302 的缓存60min  
  20.      proxy_cache_valid 404 1m;   //http协议404缓存1min  
  21.         }  
  22.         error_page   500 502 503 504  /50x.html;  
  23.         location = /50x.html {  
  24.             root   html;  
  25.         }  
  26.     }  
  27. }  
  28.  
  29. # mkdir -p /var/www/cache  
  30. # service nginx restart 
配置好了以后先访问先80.146看到是默认nginx的页面:

之后我们启动服务开始代理,在访问80.146看到的后端web1的页面:

 


 

 

四、nginx负载均衡:
nginx:192.168.80.146
web1:192.168.80.143
web2:192.168.80.144
web2同web1即可)

  1. # egrep -v "^$|#" /etc/nginx/nginx.conf  
  2. worker_processes  1;  
  3. events {  
  4.     worker_connections  1024;  
  5. }  
  6. http {  
  7.     include       mime.types;  
  8.     default_type  application/octet-stream;  
  9.     upstream peace {     //名字为peace  
  10.   server 192.168.80.143 weight=1;   //定义节点信息,weight指定权重  
  11.   server 192.168.80.144 weight=2;  
  12.     }  
  13.     sendfile        on;  
  14.     keepalive_timeout  65;  
  15.     server {  
  16.         listen       80;  
  17.         server_name  localhost;  
  18.         location / {  
  19.       proxy_pass http://peace;   //引用peace的负载均衡  
  20.         }  
  21.         error_page   500 502 503 504  /50x.html;  
  22.         location = /50x.html {  
  23.             root   html;  
  24.         }  
  25.     }  
  26. }  
  27.  
  28. # service nginx restart 
下面访问下nginx可以看到有轮询

 


但是这里有个问题就是没有状态检查,有错误时还照样轮询,所以这里使用第三方来做健康监测



五、nginx 负载均衡+ 第三方模块,健康状态检测

开始打算用cep21-healthcheck_nginx_upstreams-16d6ae7.zip来做的,但是发现有版本错误,在网上找了篇文章,http://www.myhack58.com/Article/sort099/sort0102/2012/34260.htm 可以再1.2.1以上使用了,结合了healthcheck_nginx_upstreams的来做

https://github.com/yaoweibin/nginx_upstream_check_module 下载软件
需要打补丁,并且重新编译

  1. # unzip yaoweibin-nginx_upstream_check_module-v0.1.6-17-gdfee401.zip  
  2.  
  3. # cd nginx-1.2.3  
  4. # patch -p1 < /root/yaoweibin-nginx_upstream_check_module-dfee401/check_1.2.1+.patch  
  5.  
  6. (如果nginx版本不是1.2.1以上的,用patch -p1 < /usr/local/yaoweibin-nginx_upstream_check_module-dfee401/check.patch打补丁)  
  7.  
  8.  # ./configure \  
  9.   --prefix=/usr \  
  10.   --sbin-path=/usr/sbin/nginx \  
  11.   --conf-path=/etc/nginx/nginx.conf \  
  12.   --error-log-path=/var/log/nginx/error.log \  
  13.   --http-log-path=/var/log/nginx/access.log \  
  14.   --pid-path=/var/run/nginx/nginx.pid  \  
  15.   --lock-path=/var/lock/nginx.lock \  
  16.   --user=nginx \  
  17.   --group=nginx \  
  18.   --with-http_ssl_module \  
  19.   --with-http_flv_module \  
  20.   --with-http_stub_status_module \  
  21.   --with-http_gzip_static_module \  
  22.   --http-client-body-temp-path=/var/tmp/nginx/client/ \  
  23.   --http-proxy-temp-path=/var/tmp/nginx/proxy/ \  
  24.   --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \  
  25.   --with-pcre \  
  26.   --add-module=/root/yaoweibin-nginx_upstream_check_module-dfee401/  
  27.  
  28. # make && make install 
修改配置文件:

  1. # egrep -v "^$|#" /etc/nginx/nginx.conf  
  2. worker_processes  1;  
  3. events {  
  4.     worker_connections  1024;  
  5. }  
  6. http {  
  7.     include       mime.types;  
  8.     default_type  application/octet-stream;  
  9.     upstream peace {  
  10.         server 192.168.80.143 weight=1;  //指定节点web1  
  11.  server 192.168.80.144 weight=2;  //指定节点web2  
  12.         check interval=1000 rise=2 fall=2 timeout=1000;  //interval检测间隔时间,rsie请求2次正常的话为up,fail请求2次失败的话为down,timeout检查超时时间(毫秒)  
  13.  check_http_send "GET /.test.html HTTP/1.0";  //所发送的检测请求  
  14.     }  
  15.     sendfile        on;  
  16.     keepalive_timeout  65;  
  17.     server {  
  18.         listen       80;  
  19.         server_name  localhost;  
  20.         location / {  
  21.      proxy_pass http://peace;  //引用  
  22.         }     
  23.  location /status {   //定义一个类似stub_status的方式输出检测信息  
  24.   check_status;  
  25.  }  
  26.         error_page   500 502 503 504  /50x.html;  
  27.         location = /50x.html {  
  28.             root   html;  
  29.         }  
  30.     }  
  31. }  
  32.  
  33. # service nginx restart 
下面访问下192.168.80.146/status可以看到两台都up,并且页面正常:


之后关闭一台web2,可以看到已经down,并且访问都是web1工作:

至此Nginx的相关扩展就结束了,如有错误请指出,非常感谢!

有关Nginx 高级扩展实例的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  4. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  5. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  6. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

  7. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

  8. c - mkmf 在编译 C 扩展时忽略子文件夹中的文件 - 2

    我想这样组织C源代码:+/||___+ext||||___+native_extension||||___+lib||||||___(Sourcefilesarekeptinhere-maycontainsub-folders)||||___native_extension.c||___native_extension.h||___extconf.rb||___+lib||||___(Rubysourcecode)||___Rakefile我无法使此设置与mkmf一起正常工作。native_extension/lib中的文件(包含在native_extension.c中)将被完全忽略。

  9. ruby - 为什么当我调用类的实例方法时,初始化不显示为方法? - 2

    我正在写一篇关于在Ruby中几乎一切都是对象的博客文章,我试图通过以下示例来展示这一点:classCoolBeansattr_accessor:beansdefinitialize@bean=[]enddefcount_beans@beans.countendend所以从类中我们可以看出它有4个方法(当然,除非我错了):它可以在创建新实例时初始化一个默认的空bean数组它可以计算它有多少个bean它可以读取它有多少个bean(通过attr_accessor)它可以向空数组写入(或添加)更多bean(也通过attr_accessor)但是,当我询问类本身它有哪些实例方法时,我没有看到默认

  10. ruby - 在 Ruby 中,在类方法的上下文中,什么是实例变量和类变量? - 2

    如果我有以下一段Ruby代码:classBlahdefself.bleh@blih="Hello"@@bloh="World"endend@blih和@@bloh到底是什么?@blih是Blah类中的一个实例变量,@@bloh是Blah类中的一个类变量,对吗?这是否意味着@@bloh是Blah的类Class中的一个变量? 最佳答案 人们似乎忽略了该方法是类方法。@blih将是常量Bleh的类Class实例的实例变量。因此:irb(main):001:0>classBlehirb(main):002:1>defself.blehirb

随机推荐