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.*" %>
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);
}
%>
测试: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
23
24
25
28
29
31
34
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同时挂掉,数据也不会丢失。