nginx
nginx:
- Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
- Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等
Nginx在web服务器的基本作用
- Nginx之反向代理
- Nginx之负载均衡
- Nginx之页面缓存
- Nginx之URL重写
- Nginx之读写分离
正向代理和反向代理:
- 正向代理的概念
正向代理,也就是传说中的代理,他的工作原理就像一个跳板,简单的说,我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器呢,他能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。从网站的角度,只在代理服务器来取内容的时候有一次记录,有时候并不知道是用户的请求,也隐藏了用户的资料,这取决于代理告不告诉网站。
结论就是,正向代理 是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。
反向代理的概念
例用户访问 http://www.test.com/readme,但www.test.com上并不存在readme页面,他是偷偷从另外一台服务器上取回来,然后作为自己的内容返回用户,但用户并不知情。这里所提到的 www.test.com 这个域名对应的服务器就设置了反向代理功能。
结论就是,反向代理正好相反,对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容原本就是它自己的一样。两者区别
从用途上来讲:
正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。正向代理还可以使用缓冲特性减少网络使用率。反向代理的典型用途是将防火墙后面的服务器提供给Internet用户访问。反向代理还可以为后端的多台服务器提供负载平衡,或为后端较慢的服务器提供缓冲服务。另外,反向代理还可以启用高级URL策略和管理技术,从而使处于不同web服务器系统的web页面同时存在于同一个URL空间下。
从安全性来讲:
正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此你必须采取安全措施以确保仅为经过授权的客户端提供服务。反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。
下载源码包:
wget ftp://172.25.254.250/pub/docs/lamp/nginx-1.12.0.tar.gz
tar zxf nginx-1.12.0.tar.gz
[root@server1 ~]# cd nginx-1.12.0
[root@server1 nginx-1.12.0]# vim auto/
cc/ have init module os/ threads
define have_headers install modules sources types/
endianness headers lib/ nohave stubs unix
feature include make options summary
[root@server1 nginx-1.12.0]# vim auto/cc/gcc
170
171 # debug
172 #CFLAGS="$CFLAGS -g" ##在nginx在编译的时候取消调试,因为调式的时候会增加编译的工作量
173
[root@server3 nginx-1.12.0]# vim src/core/nginx.h
12 #define nginx_version 1012000
13 #define NGINX_VERSION "1.12.0"
14 #define NGINX_VER "nginx" ##隐匿掉nginx的版本号信息
15
[root@server3 nginx-1.12.0]# ./configure --help #查看编译时需要的参数
--help print this message
--prefix=PATH set installation prefix
--sbin-path=PATH set nginx binary pathname
--modules-path=PATH set modules path
--conf-path=PATH set nginx.conf pathname
--error-log-path=PATH set error log pathname
--pid-path=PATH set nginx.pid pathname
--lock-path=PATH set nginx.lock pathname
--user=USER set non-privileged user for
worker processes
--group=GROUP set non-privileged group for
worker processes
.....
[root@server3 nginx-1.12.0]# ./configure --prefix=/usr/local/nginx --with-threads --with-file-aio --with-http_stub_status_module --with-http_ssl_module
checking for OS
+ Linux 2.6.32-431.el6.x86_64 x86_64
checking for C compiler ...
not found
./configure: error: C compiler cc is not found
#报错提示需要gcc,因为源码使用C写的编译的时候肯定需要编译器gcc
[root@server3 nginx-1.12.0]# yum install gcc -y
Loaded plugins: product-id, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package gcc.x86_64 0:4.4.7-4.el6 will be installed
[root@server3 nginx-1.12.0]# yum install gcc -y
Loaded plugins: product-id, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package gcc.x86_64 0:4.4.7-4.el6 will be installed
...
[root@server3 nginx-1.12.0]# ./configure --prefix=/usr/local/nginx --with-threads --with-file-aio --with-http_stub_status_module --with-http_ssl_module
checking for OS
+ Linux 2.6.32-431.el6.x86_64 x86_64
checking for C compiler ... found
+ using GNU C compiler
+ gcc version: 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
checking for gcc -pipe switch ... found
...
./configure: error: the HTTP rewrite module requires the PCRE library.
#报错提示需要pcre库,也就是pcre-devel这个安装包没装嘛
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.
[root@server3 nginx-1.12.0]# yum install pcre-devel -y
Loaded plugins: product-id, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package pcre-devel.x86_64 0:7.8-6.el6 will be installed
...
[root@server3 nginx-1.12.0]# ./configure --prefix=/usr/local/nginx --with-threads --with-file-aio --with-http_stub_status_module --with-http_ssl_module
checking for OS
+ Linux 2.6.32-431.el6.x86_64 x86_64
checking for C compiler ... found
+ using GNU C compiler
+ gcc version: 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
checking for gcc -pipe switch ... found
...
./configure: error: SSL modules require the OpenSSL library.
#提示需要openssl库,也是open-devel安装包
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.
[root@server3 nginx-1.12.0]# yum install openssl-devel -y
Loaded plugins: product-id, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package openssl-devel.x86_64 0:1.0.1e-15.el6 will be installed
...
[root@server3 nginx-1.12.0]# ./configure --prefix=/usr/local/nginx --with-threads --with-file-aio --with-http_stub_status_module --with-http_ssl_module
checking for OS
+ Linux 2.6.32-431.el6.x86_64 x86_64
checking for C compiler ... found
+ using GNU C compiler
+ gcc version: 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
checking for gcc -pipe switch ... found
...
checking for zlib library ... found
creating objs/Makefile #出现makefile就是编译成功了吧
Configuration summary
+ using threads
+ using system PCRE library
+ using system OpenSSL library
+ using system zlib library
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
...
[root@server3 nginx-1.12.0]# ls
auto CHANGES.ru configure html Makefile objs src
CHANGES conf contrib LICENSE man README
[root@server3 nginx-1.12.0]# make && make install
make -f objs/Makefile
make[1]: Entering directory `/root/nginx-1.12.0'
cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
-o objs/src/core/nginx.o \
src/core/nginx.c
...
[root@server3 nginx-1.12.0]# ls /usr/local/nginx/
conf/ html/ logs/ sbin/
[root@server3 nginx-1.12.0]# ls /usr/local/nginx/sbin/
nginx
[root@server3 nginx-1.12.0]# cd /usr/local/nginx/sbin/
[root@server3 sbin]# ls
nginx
[root@server3 sbin]# ./nginx #启动nginx服务,这样好像很不方便
[root@server3 sbin]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@server3 sbin]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ #所以给Nginx创建一个软连接,下次启动直接Nginx搞定
[root@server3 sbin]# nginx
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
测试:在客户端浏览器中nginx服务器ip 172.25.32.3
出现以下信息则说明安装成功
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further
...
Thank you for using nginx.
nginx web服务器框架机制
nginx配置:
- nginx虚拟主机配置
[root@server3 nginx]# vim conf/nginx.conf
2 user nginx nginx; #nginx服务的虚拟用户
3 worker_processes 2; #服务器中CPU个数
4 worker_cpu_affinity 01 10; #CPU和worker进程绑定
5 #worker_processes 4;
#worker_cpu_affinity 0001 0010 0100 1000; # 4核CPU的配置
6 #error_log logs/error.log;
7 #error_log logs/error.log notice;
8 #error_log logs/error.log info;
9
10 #pid logs/nginx.pid;
11
12
13 events {
14 worker_connections 65535; #每个worker进程支持的最大连接数
15 }
16
[root@server3 ~]# useradd -M -d /usr/local/nginx/ -s /sbin/nologin -u 3000 nginx #创建nginx虚拟用户
[root@server3 ~]# vim /etc/security/limits.
limits.conf limits.d/
[root@server3 ~]# vim /etc/security/limits.conf
50 # End of file
51 nginx - nofile 65535 #此处的值和每个worker进程支持的最大连接数要一致
[root@server3 Desktop]# vim /usr/local/nginx/conf/nginx.conf
33 #gzip on;
34
35 server {
36 listen 80;
37 server_name news.peter.com; #虚拟主机地址
38
39 #charset koi8-r;
40
41 #access_log logs/host.access.log main;
42
43 location / {
44 root /news; #虚拟主机发布目录
45 index index.html index.htm; #发布页
46 }
47
48 #error_page 404 /404.html;
49
[root@server3 Desktop]# cat /news/index.html
<h1>news.peter.com virt_host's page </h1>
[root@server3 Desktop]# nginx -t #检测有没有语法错误
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@server3 Desktop]# nginx -s reload #重新加载
[root@server3 Desktop]# curl news.peter.com
<h1>news.peter.com virt_host's page </h1> #说明配置成功,或者在浏览器中测试
- 带证书的HTTPS配置
96 # HTTPS server
97
98 server {
99 listen 443 ssl;
100 server_name music.peter.com; #地址
101
102 ssl_certificate cert.pem;
103 ssl_certificate_key cert.pem; #这里将key改成pem
104
105 ssl_session_cache shared:SSL:1m;
106 ssl_session_timeout 5m;
107
108 ssl_ciphers HIGH:!aNULL:!MD5;
109 ssl_prefer_server_ciphers on;
110
111 location / {
112 root /music ; #发布目录
113 index index.html index.htm; 发布页
114 }
115 }
root@server3 Desktop]# mkdir /music
[root@server3 Desktop]# cat >>index.html<<end
> ^C
[root@server3 Desktop]# cat >>/music/index.html<<end
> <h1>music.peter.com https test page</h1>
> end
[root@server3 Desktop]# cat /music/index.html
<h1>music.peter.com https test page</h1>
[root@server3 Desktop]# cd /etc/pki/tls/certs
[root@server3 certs]# ls
ca-bundle.crt ca-bundle.trust.crt make-dummy-cert Makefile renew-dummy-cert
[root@server3 certs]# make cert.pem
umask 77 ; \
PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
/usr/bin/openssl req -utf8 -newkey rsa:2048 -keyout $PEM1 -nodes -x509 -days 365 -out $PEM2 -set_serial 0 ; \
cat $PEM1 > cert.pem ; \
echo "" >> cert.pem ; \
cat $PEM2 >> cert.pem ; \
rm -f $PEM1 $PEM2
Generating a 2048 bit RSA private key
.................................................................................................+++
........................................+++
writing new private key to '/tmp/openssl.70ymZH'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shannxi
Locality Name (eg, city) [Default City]:xi'an
Organization Name (eg, company) [Default Company Ltd]:wetsos
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:server20
Email Address []:hubowestlife@yeah.net
[root@server3 certs]# ls
ca-bundle.crt ca-bundle.trust.crt cert.pem make-dummy-cert Makefile renew-dummy-cert
[root@server3 certs]# cp cert.pem /usr/local/nginx/conf/
[root@server3 certs]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@server3 certs]# nginx -s reload
[root@server3 certs]# vim /etc/hosts
1 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
2 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
3 192.168.25.20 server20 news.peter.com music.peter.com
#添加本地解析,浏览器才能识别地址
测试:
成功访问到
- 网址重写(网页跳转)
[root@server1 ~]# vim /usr/local/nginx/conf/nginx.conf
140 server {
141 listen 80;
142 server_name www.linux.org;
143 rewrite ^(.*)$ https://www.linux.org$1 permanent;
144 }
#以上在虚拟主机的基础上修改如上即可,如果新建一个以上内容会出现不会跳转,也就是重定向失败
- 负载均衡
root@server1 ~]# vim /usr/local/nginx/conf/nginx.conf
102 #https加密以及网页重定向
103 #
104 # HTTPS server
105
106 server {
107 listen 80;
108 server_name bbs.linux.org; #被重定向的地址
109 rewrite ^(.*)$ https://bbs.linux.org$1 permanent; #定向的目的地址
110 }
111
112 server {
113 listen 443 ssl;
114 server_name bbs.linux.org ;
115
116 ssl_certificate cert.pem;
117 ssl_certificate_key cert.pem;
118
119 ssl_session_cache shared:SSL:1m;
120 ssl_session_timeout 5m;
121
122 ssl_ciphers HIGH:!aNULL:!MD5;
123 ssl_prefer_server_ciphers on;
124
125 location / {
126 root /bbs; #重定向目的地址的发布目录
127 index index.html index.htm; #发布页面
128 }
129 }
130
测试:
自动跳转到https
131 #负载均衡,轮询机制
132 server {
133 listen 80;
134 server_name www.linux.org; #配置nginx的主机
135 location / {
136 # root /www;
137 # index index.html;
138 proxy_pass http://linux; #代理机制
139 }
140
141 }
142
144 upstream linux{
145 server 172.25.32.3:80; #两个后端服务器(无nginx)
146 server 172.25.32.2:80 weight=3 ;
以上两个后台服务器的apache服务需要开启,因为nginx在作代理的时候,访问的就是apache
147 }
- server2上给与权重3,意思就是在客户端访问www.linux.org的时候会去读取两个服务器读取相应的数据,但是server2的权重值3大于server3(默认权重值为1),所以再去获取后台服务器数据的时候,nginx会去server2上获取的次数是server3理论上是获取server3的三倍,实际可能会有所不同,唯一可以肯定的是,server2的访问次数肯定比server3多。缓解了一个后台服务器所引发的负载过大或者宕机问题。
测试:
[root@server1 ~]# for i in {1..15}; do curl www.linux.org ;done
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h2>www.linux.org.server3</h2>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h2>www.linux.org.server3</h2>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h2>www.linux.org.server3</h2>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
[root@server1 ~]# for i in {1..15}; do curl www.linux.org ;done
<h2>www.linux.org.server3</h2>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h2>www.linux.org.server3</h2>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h2>www.linux.org.server3</h2>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
<h2>www.linux.org.server3</h2>
<h1>www.linux.org-server2</h1>
<h1>www.linux.org-server2</h1>
现在负载均衡初步完成了。upstream按照轮询(默认)方式进行负载,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。虽然这种方式简便、成本低廉。但缺点是:可靠性低和负载分配不均衡。适用于图片服务器集群和纯静态页面服务器集群。
除了以上负载均衡的参数外还有其他参数:
weight(权重)
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。如下所示,10.0.0.88的访问比率要比10.0.0.77的访问比率高一倍。
upstream linuxidc{
server 10.0.0.77 weight=5;
server 10.0.0.88 weight=10;
}
ip_hash(访问ip)
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream favresin{
ip_hash;
server 10.0.0.10:8080;
server 10.0.0.11:8080;
}
fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。与weight分配策略类似。
upstream favresin{
server 10.0.0.10:8080;
server 10.0.0.11:8080;
fair;
}
url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
注意:在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法。
upstream resinserver{
server 10.0.0.10:7777;
server 10.0.0.11:8888;
hash $request_uri;
hash_method crc32;
}
upstream还可以为每个设备设置状态值,这些状态值的含义分别如下:
down 表示单前的server暂时不参与负载.
weight 默认为1.weight越大,负载的权重就越大。
max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误.
fail_timeout : max_fails次失败后,暂停的时间。
backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
upstream bakend{ #定义负载均衡设备的Ip及设备状态
ip_hash;
server 10.0.0.11:9090 down;
server 10.0.0.11:8080 weight=2;
server 10.0.0.11:6060;
server 10.0.0.11:7070 backup;
}