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

时间:2022-04-28
本文章向大家介绍企业网站架构之Nginx详解原理以及工作模块;源码Lnmp架构,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Nginx详解及lnmp环境架构

一、Nginx详解以及优点

在当前互联网环境下,一般高端的服务前端都采用nginx作为web前端,而更多的都是采用lnmp架构,真正的后端服务器才会采用apache.

为什么这么做,要取决于nginx和apache两者之间的优缺性.:

nginx与apache相比有以下优势:在性能上,nginx占用很少的系统资源,能支持更多的并发链接,达到更高的访问率;在功能上,Nginx是优秀的代理服务器和负载均衡器;在安装配置上,简单灵活。

nginx模块基本都是静态编译,同时对Fast-CGI支持比较好.在处理链接上,nginx支持epoll,而且体积小一般只有几百K。

Nginx的优点有以下几点:

1.作为Web服务器,nginx处理静态文件、索引文件以及自动索引效率非常高。

2.作为代理服务器,Nginx可以实现无缓存的反向代理加速,提高网站运行速度。

3.作为负载均衡服务器,Nginx既可以在内部直接支持Rails和PHP,也可以支持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 block(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。

Nginx的模块从结构上分为核心模块、基础模块和第三方模块,HTTP模块、EVENT模块和MAIL模块等属于核心模块,HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块属于基本模块,而HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块属于第三方模块,用户根据自己的需要开发的模块都属于第三方模块。正是有了这么多模块的支撑,Nginx的功能才会如此强大。

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

  1. Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers处理器模块一般只能有一个。
  2. Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx 输出。
  3. 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
download:nginx-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
指定base和data的目录权限和目录选项呗
#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
将mhash的lib链接到/usr/local/lib/
mhash的include链接到/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和.pem的key文件

#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只负责处理静态的网页,将php和jsp等交给后端的服务器处理,从而实现方向代理

阿里: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   默认会自动进行调度到24和16主机

分析:这样还是没有实现高校代理的个功能啊,要是让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上安装php的memcache支持

#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 

增加php的memcache支持了

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

测试内存memcache

8.优化php,php-nginx的权限关系

php不再虚拟主机中支持,

它只支持在同一个nginx中的server块

如果需要虚拟主机也支持,可以加入

但是,这样的化,相当与两个网站都使用一个php的cgi请求

防止跨站访问

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