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版
证书,解压下载文件后得到pem
和key
文件,随后把这两个文件上传到服务器任意位置即可
修改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模块。
- 首先进入到Nginx的源码包
这个源码包位置在哪就看你自己放在哪了,比如我的就是放在了opt目录下
cd /opt/nginx-1.12.2
- 查看nginx原有的模块
/usr/local/nginx/sbin/nginx -V
- 在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
-
等他配置好后再执行
make
命令 -
为了保险起见,你可以备份以前的Nginx
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
- 停掉线上运行的Nginx,然后将刚刚编译好的Nginx覆盖掉原有的Nginx
cp ./objs/nginx /usr/local/nginx/sbin/
- 启动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-IP
和 X-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;
}