nginx是以多进程的方式工作的,有一个master进程和多个worker进程
master进程用来管理worker进程
(1)向各worker进程发送信号
(2)监控worker进程,当一个worker进程出现异常后,会启动新的worker进程。

master进程会先建立好需要监听的socket,fork函数生成子进程workers,继承scoket,一般来讲,当有连接进入后,所有accept在这个socket上面的进程都会收到通知,而只有一个进程会accept这个连接,其它都会失败。  ---> 共享锁

(惊群现象)当一个事件被触发以后,,等待这个的所有线程/进程都会被唤醒,但是只有一个去响应。
解决这种现象nginx提出了共享锁的概念,有了这把锁(比如accept_mutex)同一个时刻,就会只有一个进程在accept连接。

nginx比apache高效的原因就是,nginx采用异步非阻塞方式,而apache采用同步阻塞方式

阻塞和非阻塞
阻塞和非阻塞指的是执行一个操作是等操作结束再返回,还是立即返回。
比如去餐厅点菜,传菜员将菜单给厨师:
(1)阻塞:在窗口等待,直到厨师完成后将菜第到窗口,然后再上菜,这期间服务员不能干其它事情。
(2)非阻塞:可以先去干其它事情,过一会来到窗口问好了没,没好等会再过来继续询问,知道好了为止。

同步和异步
同步和异步是事件本身的一种属性;
(1)同步:服务员直接跟厨师打交道,菜好没好,服务员直接知道,知道菜好了由厨师交给服务员。
(2)异步:厨师和服务员之间还有传菜员,厨师做好后,由传菜员将菜递到传菜窗口,通知服务员或者不通知。
同步的事情只能以阻塞的方式做
异步的事情可以用阻塞和非阻塞的方式去做。非阻塞既可以是主动查询,也可以是被动接收,被动接收的效率高于主动查询。



实验环境:
redhat6.5虚拟机三台
server1  172.25.44.1
server2  172.25.44.2
server3  172.25.44.3
火墙和selinux均处于关闭状态
编辑/etc/hosts文件,加入解析


server1:
用到nginx-1.8.1版本
tar zxf nginx-1.8.1.tar.gz ###解压
 cd nginx-1.8.1   ###进入解压目录

vim src/core/nginx.h    ###屏蔽nginx版本信息,安全性
    14 #define NGINX_VER          "nginx/"
vim auto/cc/gcc        ###关闭debug调式模式(开启的话软件臃肿)
    178 # debug
    179 #CFLAGS="$CFLAGS -g"   ###注释此行

 
yum insall pcre-devel openssl-devel gcc gcc-c++ -y  ###需要解决的一些依赖关系
./configure \
--prefix=/usr/local/nginx \    ###安装的位置
--with-http_stub_status_module \    ###监控模块
--with-http_ssl_module
 
make && make install

将路径/usr/local/nginx/sbin加入~/.bash_profile 文件中
source ~/.bash_profile  ###使文件生效

下面介绍一些nginx常用的命令
nginx              ###开启nginx
nginx -t           ###检查配置文件
nginx -s reload    ###重新加载
nginx -s stop      ###停止

vim /usr/local/nginx/conf/nginx.conf
    #user  nobody;
    worker_processes  1;  ###cpu使用个数
    #worker_cpu-affinity 0001 0010 0100 1000;  ##绑定cpu,4个cpu

    events {
        use epoll;      ###异步非阻塞模式
        worker_connections  1024;   ##连接数
    }

     19     upstream linux{
     20         server 172.25.44.2:80;
     21         server 172.25.44.3:80;
     22 }
    
     48         location / {
     49             proxy_pass http://linux;  ###代理
     50            # root   html;
     51            # index  index.html index.htm;
     52         }

重新加载服务nginx -s reload


server2 :
yum install httpd -y
echo "

server2

" > /var/www/html/index.html
/etc/init.d/httpd  start

server3 :
yum install httpd -y
echo "server3" > /var/www/html/index.html
/etc/init.d/httpd  start

测试:网页访问测试server1的ip 172.25.44.1
测试结果为server2和server3轮询显示

vim /usr/local/nginx/conf/nginx.conf
     19     upstream linux{
     20         ip_hash;    ###哈希绑定,同一个ip只能访问一个页面
     21         server 172.25.44.2:80;
     22         server 172.25.44.3:80;
     23 }
 
nginx -t    nginx -s reload
网页测试访问,因为哈希绑定ip,第一次显示server2,当server2一直不挂掉的话,一直刷新,就一直显示sever2,挂掉的话就显示server3


如果一个局域网的客户同时访问服务器,导致服务器分配不均衡;sticky实现了基于cookie的负载均衡
sticky  粘制算法  需要静态编译
nginx -s stop   ###停止nginx
tar zxf nginx-sticky-module-1.0.tar.gz -C nginx-1.8.1  ###解压到指定位置
make clean
 ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module  \
--add-module=nginx-sticky-module-1.0/   ###需要加上nginx  sticky模块

make && make install


sticky no_fallback;###不做故障转移;当server2挂掉,网页出现错误页面,不往server3上转移
server 172.25.33.22:80 down ;不参加调度
server 172.25.33.22:80 weight=5 ; 权重为5,与出现次数成正比关系

真机for in in $(seq 10);do curl http://172.25.44.1;done     ###用命令进行检测


常见的fair url_hash 第三方 同stiky,需要重新编译
rr ip_hash weight 本地,不需要重新编译



tomcat 轻量级应用服务器,项目部署到tomcat上,就可以通过外部访问项目的页面。
server2 server3
cd /usr/local
sh  jdk-6u32-linux-x64.bin
tar zxf apache-tomcat-7.0.37.tar.gz
ln -s jdk1.6.0_32 java
ln -sapache-tomcat-7.0.37  tomcat
vim /etc/profile
    export JAVA_HOME=/usr/local/java
    export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
    export PATH=$PATH:$JAVA_HOME/bin
source /etc/profile

cd /usr/local/tomcat/bin
./startup.sh
访问:172.25.44.2:8080   172.25.44.3:8080


默认发布目录/usr/local/tomcat/webapps/ROOT
vim test.jsp     ###编辑测试页
      The time is: <%=new java.util.Date() %>
访问http://172.25.44.2:8080/test.jsp
    http://172.25.44.3:8080/test.jsp


server1
vim /usr/local/nginx/conf/nginx.conf
     18 http {
     19     upstream linux{
     20         server 172.25.44.2:8080;  轮询监听8080端口
     21         server 172.25.44.3:8080;
     22 }

     48         location / {
     49           #  proxy_pass http://linux;
    50             root   html;
     51             index  index.html index.htm;
    52         }
     
     65         location ~ \.jsp$ {
     66             proxy_pass   http://linux;
     67         }
重启服务
server2 server3

test.jsp内容
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
Cluster App Test

Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"
");%>
<%
out.println("
ID " + session.getId()+"
");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("Session list");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"
");
System.out.println( name + " = " + value);
}
%>

name:


key:







测试:172.25.44.1/test.jsp
sticky 模式当用户访问,只要访问主机tomcat不挂,就一直访问同一个
server2:bin/shutdown.sh
存储的数据保存在44.2中,当44.2挂掉,转到44.3上,但44.2之前的数据已经不在了
由此提出交叉存储的概念

memcache高速缓存 交叉存储解决session问题

server2 server3
yum install memcached -y
/usr/local/tomcat/conf/context.xml
19
 20
 21    
 22     WEB-INF/web.xml
 23
 24    
 25    
 28
 29    
 31    
 34  35     memcachedNodes="n1:172.25.44.2:11211,n2:172.25.44.3:11211"  ####
 36    failoverNodes="n1"   ###根据自己的ip修改节点号
 37    requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
 38  transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscode    rFactory"
 39  />
 40



传jar包至目录/usr/local/tomcat/lib,
rm -fr memcached-session-manager-tc6-1.6.3.jar
(这里tomcat用的7.0版本,所以删掉6版本)

/etc/init.d/memcached  start
bin/startup.sh

测试访问http://172.25.44.1/test.jsp
这种做法主要解决了交叉存储问题,T1存储到T2的memcache中,这样即使当T1和M1同时挂掉,数据也不会丢失。