前言
最近有一个前后端分离的项目,前端部署在Nginx,由于接触过的web服务器只有ibm的ws,还有weblogic等,还没有在生产中使用过Nginx来做web服务器,所以踩了不少的坑,以此记录,愿余生不用在Nginx踩坑~
Nginx的安装
Nginx的安装有一个坑,那就是最好安装最新的稳定版,因为低版本坑爹,一开始我们安装了一个低版本的,然后配置了HTTPS(跟着阿里云提供的ssl配置,所以配置错误的几率不大),但是一直访问不了HTTPS,后面搞了好久换了最新的稳定版本,然后才配置成功。安装的过程如下:
1.安装PCRE依赖
yum install -y pcre pcre-devel
复制代码
2.安装Zlib的依赖
yum install -y zlib zlib-devel
复制代码
3.安装c++的依赖
yum install -y gcc-c++
复制代码
4.安装ssl的依赖(如果需要配置SSL证书的需要)
yum install -y openssl openssl-devel
复制代码
5.下载Nginx(最好下载最新的稳定版)
wget -c https://nginx.org/download/nginx-1.10.2.tar.gz
复制代码
6.解压并且使用默认的配置
tar -zvxf nginx-1.10.2.tar.gz
cd nginx-1.10.2.tar.gz
./configure
复制代码
7.编译还有安装
make
make install
复制代码
8. 查看安装的路径,然后启动
whereis nginx
nginx -t //检查默认的配置文件,可以得知配置文件的路径
nginx -c /etc/nginx/nginx.conf //第二步的配置文件路径
复制代码
Nginx的反向代理
1.Nginx的反向代理
结合场景,假设我现在想要把**/api**下的所有请求代理到我的后端接口(eg:www.mydomain.com/api/xxxxx 转发到 www.mydomain.com:8080/xxxxx),那么需要向配置文件配置
location /api/ {
proxy_pass http://www.mydomain.com:8080/;
}
复制代码
此处有个地方需要注意,Nginx的配置是自上而下,也就是说如果你之前先配置了如下面
location / {
root /www/resource/;
index index.html index.htm;
}
location /api/ {
proxy_pass http://www.mydomain.com:8080/;
}
复制代码
这样子是不会生效的,因为满足**/api/的匹配规则也是满足/** 的匹配规则,而且Nginx是自上而下配置,所以全部都被代理转发到/匹配规则里面了。
更多的反向代理规则如下:
location = / {
# 精确匹配 / ,主机名后面不能带任何字符串
}
location / {
# 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
# 但是正则和最长字符串会优先匹配
}
location /documents/ {
# 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
}
location ~ /documents/Abc {
# 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
}
location ^~ /images/ {
# 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配所有以 gif,jpg或jpeg 结尾的请求
# 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
}
location /images/ {
# 字符匹配到 /images/,继续往下,会发现 ^~ 存在
}
location /images/abc {
# 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
# F与G的放置顺序是没有关系的
}
location ~ /images/abc/ {
# 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
}
复制代码
2.Nginx获取参数
结合场景,假设我现在想要把/api下的请求参数获取出来,然后转发(eg:www.mydomain.com/api?img=htt…),需要修改配置如下:
location /api/ {
proxy_pass $arg_img; # $arg_参数名:可以获取参数内容
}
复制代码
这里有个小坑,如果不同域的话,需要在配置文件写上
server {
listen 80;
resovler 8.8.8.8;
}
复制代码
resovler相当于Nginx帮你解析ip,然后去代理访问,如果不设置resovler 8.8.8.8的话,Nginx会报502.
3.Nginx设置Cookie
结合场景,假设我现在想要把/api 下的请求参数获取出来,并且设置到Cookie里(eg.www.mydomain.com/api?cookie=…)
location /api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
add_header 'Set-Cookie' 'mycookie=$arg_cookie';
add_header 'domain' '.mydomain.com';
proxy_pass https://www.mydomain.com/;
}
复制代码
前两个参数设置了用户的访问的IP,设置Cookie,其中涉及到一个问题,如果后台的Set-Cookie,浏览器是不会保存Cookie,因为不同域,浏览器会丢掉这个Cookie,假如是用Java写Set-Cookie的话
Cookie cookie = new Cookie("cookie","cookie");
cookie.setPath("/");
cookie.setDomain(".domain.com");
request.addCookie(cookie);
复制代码
也是需要设置域,区分一下域和域名(.mydomain.com是域,www,mydomain.com则是域名),域名可以DNS解析为IP。
所以Nginx再设置Cookie的时候需要注意一点,就是还要
add_header 'domain' 'xxxx';
复制代码
4.Nginx的负载均衡
Nginx还有一个比较出名的用处就是负载均衡,其中负载均衡策略有6种:权重(weight),ip_hash(依据ip分配方式),least_conn(最少连接数),fair(根据响应时间),url_hash(根据URL分配)。下面以权重的负载均衡策略配置为例:
//假设现在在 https://www.mydomain.com:8090 还有https://www.mydomain.com:8091 部署两个后台
upstream tomcat_pool
{
    server https://www.mydomain.com:8090 weight=4 max_fails=2 fail_timeout=30s;
  server https://www.mydomain.com:8091 weight=4 max_fails=2 fail_timeout=30s;
}
复制代码
其中weight代表权重,权重较大者,被分配到的机会比较大,max_fails是指最大失败次数,如果达到失败次数,那么该节点会被标记为不可用,等待fail_timeout为时间周期到,再去请求~
Nginx的优化
1.worker_processes
Nginx的进程数worker_processes,按照CPU的数目来写,一般是CPU的倍数。
2.I/O模型
配置一下Nginx的I/O模型,在Linux 2.6版本之后都支持了epoll。如果系统不支持epoll的话,Nginx会默认选择Select 或者 Poll的I/O模型,好像window就是Select模型。
events{
use epoll;
}
复制代码
3.worker_rlimit_nofile
worker_rlimit_nofile一般跟系统的文件操作数相同(ulimit -n)。拓展一下如何获取优化系统的文件操作数。
首先修改进程最大的文件句柄
ulimit -n 1048576
复制代码
修改单个进程可分配的最大文件数
echo 2097152 > /proc/sys/fs/nr_open
复制代码
写进配置文件/etc/security/limits.conf
* soft nofile 1048576
* hard nofile 1048576
* soft nproc unlimited
root soft nproc unlimited
复制代码
最后清掉一下旧的文件
rm -rf /etc/security/limits.d/*
复制代码
然后再修改/etc/sysctl.conf文件
fs.nr_open=2097152
fs.file-max = 1048576
复制代码
fs.nr_open 是指单个进程可分配的最大文件操作数,file-max是指最大的文件句柄,然后使配置文件生效。
systcl -p
复制代码
4.worker_connections
Nginx的最大连接数,理论上可以达到Nginx的进程数worker_processes * Ngin的最大连接数 worker_connections;
worker_connections 102400;
复制代码
5.keepalive_timeout
keepalive 的超时时间。
keepalive_timeout 60;
复制代码