您的位置:首页 > 运维架构 > Nginx

企业网站架构之Nginx详解原理以及工作模块;源码Lnmp架构

2014-08-11 00:00 976 查看
Nginx详解及lnmp环境架构

一、Nginx详解以及优点
在当前互联网环境下,一般高端的服务前端都采用nginx作为web前端,而更多的都是采用lnmp架构,真正的后端服务器才会采用apache.
为什么这么做,要取决于nginxapache两者之间的优缺性.:
nginxapache相比有以下优势:在性能上,nginx占用很少的系统资源,能支持更多的并发链接,达到更高的访问率;在功能上,Nginx是优秀的代理服务器和负载均衡器;在安装配置上,简单灵活。
nginx模块基本都是静态编译,同时对Fast-CGI支持比较好.在处理链接上,nginx支持epoll,而且体积小一般只有几百K
Nginx的优点有以下几点:
1.作为Web服务器,nginx处理静态文件、索引文件以及自动索引效率非常高。
2.作为代理服务器,Nginx可以实现无缓存的反向代理加速,提高网站运行速度。
3.作为负载均衡服务器,Nginx既可以在内部直接支持RailsPHP,也可以支持HTTP代理服务器,对外进行服务。同时支持简单的容错和利用算法进行负载均衡。
4.在性能方面,Nginx是专门为性能优化而开发的,在实现上非常注重效率。它采用内核Poll模型,可以支持更多的并发连接,最大可以支持对50 000个并发连接数的响应,而且占用很低的内存资源。
5.在稳定性方面,Nginx采取了分阶段资源分配技术,使得对CPU与内存的占用率非常低。Nginx官方表示Nginx保持10 000个没有活动的连接,这些连接只占2.5M内存,因此,类似DOS这样的攻击对Nginx来说基本上是没有任何作用的。
6.在高可用性方面,Nginx支持热部署,启动速度特别迅速,因此可以在不间断服务的情况下,对软件版本或者配置进行升级,即使运行数月也无需重新启动,几乎可以做到7×24小时的不间断运行。
二、Nginx工作原理以及工作模块介绍
Nginx的工作原理以及工作模块:
Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location blocklocationNginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。
Nginx的模块从结构上分为核心模块、基础模块和第三方模块HTTP模块、EVENT模块和MAIL模块等属于核心模块,HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块属于基本模块,而HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块属于第三方模块,用户根据自己的需要开发的模块都属于第三方模块。正是有了这么多模块的支撑,Nginx的功能才会如此强大。

Nginx的模块从功能上分为三类,分别是:

Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers处理器模块一般只能有一个。

Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx 输出。

Proxies (代理类模块)。就是Nginx HTTP Upstream 之类的模块

这些模块主要与后端一些服务比如fastcgi 等操作交互,实现服务代理和负载均衡等功能。原理如下:
图1:


在工作方式上,Nginx分为单工作进程和多工作进程两种模式。
在单工作进程模式下,除主进程外,还有一个工作进程,工作进程是单线程的;
在多工作进程模式下,每个工作进程包含多个线程。
Nginx默认为单工作进程模式。
Nginx的模块直接被编译进Nginx,因此属于静态编译方式。启动Nginx后,Nginx的模块被自动加载,不像在Apache一样,首先将模块编译为一个so文件,然后在配置文件中指定是否进行加载。在解析配置文件时,Nginx的每个模块都有可能去处理某个请求,但是同一个处理请求只能由一个模块来完成。
如果由FastCGI或其它代理服务器处理单页中存在的多个SSI,则这项处理可以并行运行,而不需要相互等待。

三、Lnmp环境搭建
接下来就搭建一个LNMP环境:
所谓lnmp架构即为:linux +nginx +mysql+php/perl/python,本篇我们将只用linux(rhel6.5)+nginx+mysql+php构建企业web架构

环境:RHEL6.5
iptables -F
selinux is disabled
curl -I www.baidu.com 查看百度web服务器架构:

注意:在搭建lnmp环境前,必须检测系统内部不能存在相关的软件:(纯净搭建)
#rpm -qa | grep php
#rpm -qa | grep httpd
#rpm -qa | grep mysql

http://wiki.nginx.org查看中文支持页面

##################################################################################

1.nginx源码编译
nginx使用c编写,因此在编译的时候需要安装gcc和make
#yum install make gcc -y
downloadnginx-1.4.2.tar.gz mysql-5.5.12.tar.gz(www.mysql.org)

#tar zxf nginx-1.4.2.tar.gz
#cd nginx-1.4.2/src/core/
#vim nginx.h 修改版本号,名称(每种版本都有bug)
#cd auto/cc/
#vim gcc
#CFLAGS="$CFLAGS -g" 注释debug功能,可以减少编译占用资源

#./configure --prefix=/usr/local/lnmp/nginx --with-http_ssl_module --with-http_stub_status_module
注意:一般会缺少*-devel包

#make && make install
#vim /usr/local/lnmp/nginx/conf/nginx.conf nginx主配置文件
use epoll; 高效模式
# ln -s /usr/local/lnmp/nginx/sbin/nginx /usr/sbin/ 便于之后的管理
#nginx -t 检查nginx配置
#nginx -s reload 重新加载配置文件
#netstat -antlp | grep 80 检测nginx开放的80端口
nginx 默认会在/usr/bin下执行
访问:http://nginx-server/ nginx的测试页。
nginx的默认发布目录:/usr/local/lnmp/nginx/html

##################################################################################
2.mysql的编译安装

download:www.mysql.comcve网站

#tar zxf mysql-5.5.12.tar.gz
mysql会使用cmake进行源码编译,过程中会显示安装进度,商业化的特色.

#yum install cmake -y

编译选项存储引擎可以选择一个
#cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql #安装目录
-DMYSQL_DATADIR=/usr/local/mysql/data \ #数据库存放目录
-DMYSQL_UNIX_ADDR=/usr/local/mysql/data/mysql.sock \ #Unix socket 文件路径
-DWITH_MYISAM_STORAGE_ENGINE=1 \ #安装myisam 存储引擎
-DWITH_INNOBASE_STORAGE_ENGINE=1 \ #安装 innodb 存储引擎
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \ #安装 archive存储引擎
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ #安装 blackhole 存储引擎
-DWITH_PARTITION_STORAGE_ENGINE=1 \ #安装数据库分区
-DENABLED_LOCAL_INFILE=1 \ #允许从本地导入数据
-DWITH_READLINE=1 \ #快捷键功能
-DWITH_SSL=yes \ #支持SSL
-DDEFAULT_CHARSET=utf8 \ #使用utf8 字符
-DDEFAULT_COLLATION=utf8_general_ci \ #校验字符
-DEXTRA_CHARSETS=all \ #安装所有扩展字符集
-DMYSQL_TCP_PORT=3306 \ #MySQL 监听端口(默认)
注意:myISAM引擎执行速度比较块,时候查找之类的inodb适合读操作

1>开始编译:
图2



在编译结束后会提示缺少相应的包依赖,顺序安装:(详细看提示)
需要注意的是:每次编译的时候会生成缓存文件,必须删除后重新编译
#rm -rf CmakeCache.txt
图3




说明缺少gcc-c++
## yum install gcc-c++ -y
#make && make install

2>初始化mysql
useradd -M 不需要创建用户家目录,-d为新用户创建家目录,-s指定shell

# useradd -M -d /usr/local/lnmp/mysql/data/ -s /sbin/nologin mysql

指定basedata的目录权限和目录选项呗
#cd /usr/local/lnmp/mysql
#chown -R mysql.mysql *
#cd support-files/
#file mysql.server 测试文件(启动脚本)
# mv support-files/mysql.server /etc/init.d/mysqld
#cp my-medium.cnf /etc/my.cnf my-medium.cnf已经加载好了mysql的socket,根据内存选择mysql的配置文件
#cd /usr/local/lnmp/mysql/scripts
# ./mysql_install_db --user=mysql --basedir=/usr/local/lnmp/mysql/ --datadir=/usr/local/lnmp/mysql/data/
初始化mysql显示两个ok就说明好了啊

#vim .bash_profile 配置当前用户环境
PATH=$PATH:$HOME/bin:/usr/local/lnmp/mysql/bin
#source .bash_profile 加载环境(只在当前用户可用,区别/etc/profile)
#echo $PATH

#cd /usr/local/lnmp/mysql/
#chown root * -R
#chown mysql -R data/ 只允许data/目录下的数据让mysql修改

#/etc/init.d/mysqld restart 启动mysqld开启3306
#chkconfig mysqld on
#mysql登录验证 mysql命令已经被加载到root用户的环境里了
# mysql_secure_installation 初始化mysql

###############################################################################
3.php源码编译

1>先安装php模块:

modules-download:ibiconv-1.13.1.tar.gz mhash-0.9.9.9.tar.bz2 libmcrypt-2.5.8.tar.bz2 mcrypt-2.6.8.tar.gz

#
tar zxf libiconv-1.13.1.tar.gz
cd libiconv-1.13.1
./configure --prefix=/usr/local/lnmp/modules/libiconv
make && make install

/usr/local/lnmp/modules/libiconv/lib lib库文件的位置
/usr/local/lnmp/modules/libiconv/include include头文件位置

##
tar jxf libmcrypt-2.5.8.tar.bz2
cd libmcrypt-2.5.8
./configure --prefix=/usr/local/lnmp/modules/libmcrypt
make && make install

cd libltdl/ 支持ltdl
./configure --prefix=/usr/local/lnmp/modules/libmcrypt/ --enable-ltdl-install
make && make install
提示:
Libraries have been installed in:
/usr/local/lnmp/modules/libmcrypt/lib

###
tar jxf mhash-0.9.9.9.tar.bz2
cd mhash-0.9.9.9
./configure --prefix=/usr/local/lnmp/modules/mhash
make && make install

####
tar zxf mcrypt-2.6.8.tar.gz
cd mcrypt-2.6.8
./configure --prefix=/usr/local/lnmp/modules/mcrypt 依赖于前面的模块

提示不找不到libmcrypt
ln -s /usr/local/lnmp/modules/libmcrypt/include/* /usr/local/
ln -s /usr/local/lnmp/modules/libmcrypt/lib/* /usr/local/lib/
ln -s /usr/local/lnmp/modules/mhash/lib/* /usr/local/lib /
ln -s /usr/local/lnmp/modules/mhash/include/* /usr/local/include/
重新编译
./configure --prefix=/usr/local/lnmp/modules/mcrypt --with-libmcrypt-prefix=/usr/local/lnmp/modules/libmcrypt/
make && make install

# cat /etc/ld.so.conf 开机自动加载动态链接库文件
include ld.so.conf.d/*.conf
/usr/local/lnmp/modules/libmcrypt/lib/
/usr/local/lnmp/modules/mhash/lib/
/usr/local/lib
mhashlib链接到/usr/local/lib/
mhashinclude链接到/usr/local/include/

2>php源码编译

#tar jxf php-5.4.12.tar.bz2
#cd php-5.4.12
#./configure --prefix=/usr/local/lnmp/php --with-config-file-path=/usr/local/lnmp/etc --with-mysql=/usr/local/lnmp/mysql/ --with-openssl --with-snmp --with-gd --with-zlib --with-curl --with-libxml-dir --with-png-dir --with-jpeg-dir --with-freetype-dir --without-pear --with-gettext --with-gmp --enable-inline-optimization --enable-soap --enable-ftp --enable-sockets --enable-mbstring --with-mysqli=/usr/local/lnmp/mysql/bin/mysql_config --enable-fpm --with-fpm-user=nginx --with-fpm-group=nginx (--with-libdir=lib64 --with-ldap --with-ldap-sasl)
libdir加上后会出现报错libmysqlclient
snmp 进行网络监控 soap 支持动态 fpm 支持fast-CGI 性能更好
yum install libxml2-devel
yum install libcurl-devel -y
yum install libjpeg-devel -y (jpeg.h注意,一般要是提示缺少*.h就需要安装devel包)
yum install libpng-devel -y
yum install freetype-devel -y
yum install gmp-devel -y
yum install openldap-devel -y
yum install net-snmp-devel -y

再次编译会发现不能链接libmysqlclient under /usr/local/lnmp/mysql/.

# useradd -M -d /usr/local/lnmp/nginx/ -s /sbin/nologin nginx
# ./configure --prefix=/usr/local/lnmp/php --with-config-file-path=/usr/local/lnmp/etc --with-mysql=/usr/local/lnmp/mysql/ --with-openssl --with-snmp --with-gd --with-zlib --with-curl --with-libxml-dir --with-png-dir --with-jpeg-dir --with-freetype-dir --with-pear --with-gettext --with-gmp --enable-inline-optimization --enable-soap --enable-ftp --enable-sockets --enable-mbstring --with-mysqli=/usr/local/lnmp/mysql/bin/mysql_config --enable-fpm --with-fpm-user=nginx --with-fpm-group=nginx--with-mhash=/usr/local/lnmp/modules/mhash/ --with-mcrypt=/usr/local/lnmp/modules/libmcrypt

zend用来加快php执行代码的速度
# make ZEND_EXTRA_LIBS='-liconv' (有时候会提示找不到liconv
#make install

3>.修改php配置

php的主配置文件默认存在php的主目录下

#cd php-5.4.12 去主目录寻找主配置文件
#cp php.ini-production /usr/local/lnmp/php/etc/php.ini 主配置文件
#cd /root/php-5.4.12/sapi/fpm/
#cp init.d.php-fpm /etc/init.d/php-fpm 此文件好像还不是脚本
#vim /usr/local/lnmp/php/etc/php.ini
cgi.fix_pathinfo=0 防止nginx检查漏洞
date.timezone = Asia/Shanghai

#vim /usr/local/lnmp/php/etc/php-fpm.conf
user=nginx group=nginx
pid = run/php-fpm.pid
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
上述参数选项必须得遵循一个公式,在生产环境下测试生成。
图4:



#/etc/init.d/php-fpm restart (使用fastCGI启动php成功)
#chkconfig php-fpm on

加载环境变量
#vim ~/.bash_profile
PATH=$PATH:$HOME/bin:/usr/local/lnmp/mysql/bin:/usr/local/lnmp/php/bin
#source ~/.bash_profile

4>.修改nginx,让支持php和各种图片格式。
#vim /usr/local/lnmp/nginx/conf/nginx.conf
pid logs/nginx.pid;
gzip on; 打开压缩个功能
server {
listen 80;
server_name lnmp.example.com;
location / {
root html;
index index.html index.htm index.php; 支持php ,先检测html(不再检查后面)
}
location ~ \.php$ { 以php结尾的交给本机的9000
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf; 包含fastcgi接口文件
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ 图片
{
expires 30d;
}
location ~ .*\.(js|css)$ js|css支持
{
expires 1h;
}

location /status 后台检测功能 (增加验证功能
{
stub_status on;
access_log off;
auth_basic hello-login; 自定义验证提示符
auth_basic_user_file /usr/local/lnmp/nginx/html/.htpasswd; 密码文件
}

#htpasswd -c /usr/loca/lnmp/nginx/html/.htpasswd admin 使用apache的加密算法创建admin

重新加载nginx配置文件
#nginx -s reload

编写php测试文件
#vim /usr/local/lnmp/nginx/html/index.php
<?phpinfo()
?>

测试:http://lnmp.example.com/index.php
http://lnmp.example.com/status 状态检测页面(需要使用上面的认证功能哦)

至此:lnmp环境搭建完毕

####################################################################### ##########

4.LNMP的简单应用(测试环境)

1>简单使用lnmp环境搭建论坛
download:Discuz_X2.5_SC_UTF8.zip
不能用网站的拥有者(nginx或者php的拥有者)发布网站
修改nginx先让执行index.php
# unzip Discuz_X2.5_SC_UTF8.zip
# cp -r upload/ /usr/local/lnmp/nginx/html/bbs/
## less readme/readme.txt 查看帮助,一步步安装
提示修改config/和data/需要可写权限
# chown nginx config/ data/ -R
http://lnmp.xxb.com/bbs/ 提示什么安装什么
一般使uc_client/和uc_server/没有写权限 ,给需要的目录文件权限,权限不能给太大咯
# chown nginx -R uc_client/
# chown nginx -R uc_server/
图5:



http://lnmp.xxb.com/bbs/ 重新安装配置bbs论坛
成功后可以使用登录mysql测试访问创建表的存在!
自己玩论坛吧!!!!!!!!!!

网站压力测试:
# ab -c 5 -n 100 http://node1.example.com/ -c 制定并发数-n制定请求数
Requests per second: 2.00 [#/sec] (mean) 每秒处理的数量(吞吐量)
Time taken for tests: 36.555 seconds 总共花费的时间
Time per request: 2503.795 [ms] (mean) 用户平均请求等待时间
Time per request: 500.759 [ms] (mean, across all concurrent requests) 服务器平均处理时间

#################################################################################
5.nginx的其他功能

使用nginx的反向代理功能\虚拟主机\加密认证功能哦

正向代理:前端CDN加速(主要应用为局域网减轻网速压力而使用,作为一个高速缓存)
反向代理:后端缓存(解决RS的真实压力,将不同的请求分发给不同的服务器)
反向代理其实就是使用nginx的负载均衡功能(应用层的,工作在7)
lvs是基于内核层次的负载均衡.

1.https加密认证功能
制作CA证书,linux下的CA证书默认识别的是.pem.pemkey文件
#cd /etc/pki/certs 默认使用Makefile进行制作(使用一系列的ssl加密命令生成)
cert.pem文件必须位于nginx的主配置文件目录下conf/

#cd /etc/pki/tls/certs
#make nginx.pem
# cp -p nginx.pem /usr/local/lnmp/nginx/conf/
#vim /usr/local/lnmp/nginx/conf/nginx.conf
server {
listen 443;
server_name lnmp.xxb.com; 主机名称

ssl on;
ssl_certificate nginx.pem; 指定认证文件和key
ssl_certificate_key nginx.pem;
}
#nginx -t && nginx -s reload
访问首次将会体现https认证

2.nginx的虚拟主机配置(实验必须得给两个虚拟主机设置解析哦)
# vim /usr/local/lnmp/nginx/conf/nginx.conf
server {
listen 80;
server_name www.xxb.com;
access_log logs/www.xxb.com.access.log main; 日志格式,可以在全局变量中定制,将打开日志的格式就ok
location / {
index index.html;
root /var/www/html/virtualhosts/xxb.com;
}
}
server {
listen 80;
server_name www.andy.com;
access_log logs/www.andy.com.access.log main;
location / {
index index.html;
root /var/www/html/virtualhosts/andy.com;
}
}

#mkdir -p /var/www/html/virtualhosts/xxb.com 创建虚拟主机发布目录
#mkdir -p /var/www/html/virtualhosts/andy.com
#echo www.andy.com > xxb.com/index.html
#echo www.xxb.com > andy.com/index.html
#nginx -t && nginx -s reload

3.nginx的负载均衡功能
nginx只负责处理静态的网页,phpjsp等交给后端的服务器处理,从而实现方向代理
阿里:lvs+haproxy
nginx在作为负载均衡器的时候也具有健康检查功能,能够自动切换.

# vim /usr/local/lnmp/nginx/conf/nginx.conf
在全局http{}中配置负载均衡器(24作为http和代理服务器)
upstream linux {
server 192.168.0.24; 可以根据硬件的不同设置相应的weight
server 192.168.0.16;
}
server{}中的location()添加使用反向代理
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://xxbandy;
}

#nginx -t && nginx -s reload
检测配置文件并且进行重新加载配置

测试访问://www.example.com 默认会自动进行调度到2416主机

分析:这样还是没有实现高校代理的个功能啊,要是让nginx前端作为静态网站,然后和后端动态rs相连,真正实现动静分离的负载均衡。

########################作为web服务器,必做的安全事项#############

4.防止错误访问(web服务器必做的事情,防止太多访问进而病毒)
首先给用户目录最低的权限,然后让程序写入文件cache不可读,用户上传目录不可执行
应用程序的缓存数据777,让程序自动写入缓存数据
写在php定义之前
location ~ "^/cache" { 程序自写的网站用户没有权限访问
return 403
}

location ~ "^/upload" { 用户上传的目录没有权限执行
}

#mkdir /usr/local/lnmp/nginx/html/upload/

#mkdir /usr/local/lnmp/nginx/html/cache

7.完善php相关模块,memcached
libevent动态异步处理库
Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。通过在内存里维护一个统一的巨大的Hash表,能够用来存储各种的数据。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。
php扩展的Memcache实际上是链接Memcache的方式。

memcached使用libevent库,才能在系统上发挥其高性能。
memcached可以将内存的数据写入I/O,同步到硬盘,不消耗cpu资源,但是只会占取一定内存

download:memcached-1.4.5.tar.gz memcache.tar.gz
使用telnet查看,stat查看memcached内部状态

#yum install memcached -y
#vim /etc/sysconfig/memcached memcached用户身份以及端口设置
#/etc/init.d/memcached restart
#telnet localhost 11211
add user 0 0 5 存数据(用户标识 存活时间 存储字节数)
123

get user 获取数据

1000个请求,500并发
#ab -n 1000 -n 500 http://lnmp.xxb.com apachce自带压力工具

lnmp上安装phpmemcache支持
#get memcache.2.5.tgz
#/usr/local/lnmp/php/bin/phpize
#./configure --enable-memcache --with-php-config=/usr/local/lnmp/php/bin/php-config

#make && make install
#cd /usr/local/lnmp/php/etc/
#vim php.ini
extension=mysql.so
extension=memcache.so

#/etc/init.d/php-fpm reload
增加phpmemcache支持了

#cp memcache.php /usr/local/lnmp/nginx/html/
#vim memcache.php 修改链接memcached和密码

测试内存memcache

8.优化phpphp-nginx的权限关系
php不再虚拟主机中支持,
它只支持在同一个nginx中的server
如果需要虚拟主机也支持,可以加入
但是,这样的化,相当与两个网站都使用一个phpcgi请求
防止跨站访问
vim /usr/local/lnmp/nginx/conf/fastcgi.conf
fastcgi param PHP_VALUE "open_basedir=$document_root";
# vim ../../php/etc/php.ini
open_basedir = /usr/local/lnmp/nginx/html

但是依然发现虚拟主机仍然可以访问php
http://my.oschina.net/xxbAndy/blog weichuangxxb@sina.cn
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息