Nginx实现反向代理等最基本的操作就不做介绍了

Nginx配置upstream实现负载均衡

在Http节点下,加入upstream节点。

upstream www.yixun.com { 
		# IP和端口号怎么填根据情况具体对待,可能IP一致端口不一致,也可能反之
      server IP:端口号; 
      server IP:端口号; 
}

修改proxy_pass

将server节点下的location节点中的proxy_pass配置为:http:// + upstream名称http://www.yixun.com

location / { 
            root  html; 
            index  index.html index.htm; 
            proxy_pass http://www.yixun.com; 
}

保存配置重启Nginx即可,这样负载均衡就初步圆满了,Nginx会默认按照轮询方式进行负载。

upstream的分配策略

weight(权重)

指定轮询几率,weight和訪问比率成正比,用于后端服务器性能不均的情况。

upstream www.yixun.com { 
      server IP:8080 weight=5; 
      server IP:8081 weight=10; 
}

ip_hash(訪问ip)

每一个请求按訪问ip的hash结果分配。这样每一个訪客固定訪问一个后端服务器,能够解决session的问题。

upstream www.yixun.com { 
	  ip_hash; 
      server IP:8080; 
      server IP:8081; 
}

fair

按后端服务器的响应时间来分配请求。响应时间短的优先分配。

与weight分配策略相似。

upstream favresin{      
      server 1.1.1.0:8080; 
      server 1.1.1.2:8080; 
      fair; 
}

upstream还能够为每一个设备设置状态值,这些状态值的含义分别例如以下:

  • down 表示单前的server临时不參与负载.
  • weight 默觉得1.weight越大,负载的权重就越大。
  • max_fails :同意请求失败的次数默觉得1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误.
  • fail_timeout : max_fails次失败后。暂停的时间。
  • backup: 其他全部的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

Http->Https

这里需要使用到阿里云的SSL证书

购买证书

登陆阿里云找到产品SSL产品证书

进去之后点击购买证书,选择免费版,然后下一步点到头

申请证书

购买成功后,选中刚才买的证书点击申请,填写好相关内容,然后下一步点到头,不出意外的话,等个一会就会签发成功

Nginx配置

当你证书签发成功后点击下载Nginx版证书,解压下载文件后得到pemkey文件,随后把这两个文件上传到服务器任意位置即可

修改nginx.conf

upstream的配置上面有所以就不多说了,其余的照搬即可

upstream www.yixun.com{
    server 11.11.11.11:8080;
}
server {
    listen       80;
    listen 443 ssl;
    server_name  www.yixun.com;
    ssl_certificate   xxxx.pem; # 换成自己的路径
    ssl_certificate_key  xxxx.key; # 换成自己的路径
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    
    #HTTP转HTTPS
    if ($ssl_protocol = "") { return 301 https://$host$request_uri; } 
    location / {
            root   html;
        index  index.html index.htm;
        proxy_pass http://www.yixun.com;
        proxy_set_header           Host $host;
        proxy_set_header           X-Real-IP $remote_addr;
        proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for; 
    }
}

修改好之后,重启nginx之后,就可以了。 在你修改好之后,你可以使用HTTPS去访问,也可以使用HTTP去访问,比如:
HTTPS:https://blog.yixun.store
HTTP:http://blog.yixun.store

因为配置了Http转Https,所以发送http请求会强转成https请求

其实这些东西,官方就有,但是往往一般人的服务器,是不会这么顺利的,总会遇上那么几个错误,比如我自己(允悲.jpg)

可能遇见的问题

下面贴出来的就是我自己遇到的一些问题

问题一

nginx: [emerg] the "ssl" parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf:37

这是因为你的Nginx没有开启SSL模块。

  1. 首先进入到Nginx的源码包

这个源码包位置在哪就看你自己放在哪了,比如我的就是放在了opt目录下

cd /opt/nginx-1.12.2
  1. 查看nginx原有的模块
/usr/local/nginx/sbin/nginx -V
  1. 在configure arguments:后面显示的原有的configure参数:
--prefix=/usr/local/nginx --with-http_stub_status_module

直接执行下面代码即可↓
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
  1. 等他配置好后再执行 make 命令

  2. 为了保险起见,你可以备份以前的Nginx

cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
  1. 停掉线上运行的Nginx,然后将刚刚编译好的Nginx覆盖掉原有的Nginx
cp ./objs/nginx /usr/local/nginx/sbin/
  1. 启动Nginx即可,可以通过命令查看是否已经加入成功
/usr/local/nginx/sbin/nginx -V

这个是我自己配置好后的:

问题二

nginx: [alert] could not open error log file: open() "/usr/local/nginx/logs/error.log" failed

这个问题挺好解决的,一般来说就是在/usr/local/nginx下没有log文件夹,创建一个即可

问题三

[emerg] SSL_CTX_use_PrivateKey_file("/opt/cert/blog.pem") failed (SSL: errorxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

这个问题,其实解决之后,又气又乐的,是自己粗心大意,本该读取key文件的,也被我写成了读取pem文件,其实这个问题,只要自己当时仔细读一下错误码就能知道的 PrivateKey_file("/opt/cert/blog.pem")key_file 对应的却是pem结尾的文件

ssl_certificate   xxxx.pem; # 换成自己的路径
 ssl_certificate_key  xxxx.key; # 换成自己的路径

但是可能有的人这里没写错也遇到了一样的错误,一顿百度过后,网上的帖子基本上都是一个样,内容完全一致,一点都不带改的,所以我也就直接截了个图

获取客户端IP

nginx配置

location里面配置 X-Real-IPX-Forwarded-For请求头:

location ^~ /your-service/ {
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://localhost/your-service/;	
}

java代码

public String getIpAddr(HttpServletRequest request) {
    String Xip = request.getHeader("X-Real-IP");
    String XFor = request.getHeader("X-Forwarded-For");
    if (StringUtils.isNotBlank(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
        //多次反向代理后会有多个ip值,第一个ip才是真实ip
        int index = XFor.indexOf(",");
        if (index != -1) {
            return XFor.substring(0, index);
        } else {
            return XFor;
        }
    }
    XFor = Xip;
    if (!StringUtils.isNotBlank(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
        return XFor;
    }
    if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
        XFor = request.getHeader("Proxy-Client-IP");
    }
    if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
        XFor = request.getHeader("WL-Proxy-Client-IP");
    }
    if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
        XFor = request.getHeader("HTTP_CLIENT_IP");
    }
    if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
        XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
    }
    if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
        XFor = request.getRemoteAddr();
    }
    return XFor;
}