Nginx反向代理+负载均衡

使用环境

最近在做一个网页的即时通讯,用的是SignalR的即时通讯,之前缓存是直接写在程序里面的,不同的服务器之间无法共享缓存。因为这次主要是做了Redis的缓存,以及Nginx的反向代理+负载均衡,以便实现即使通讯的负载均衡。

基于SignalR的Nginx配置

先讲一下这个项目上用到的Nginx达到了什么样子的效果吧,因为相信很多和我一样没有接触过Nginx的小伙伴下载了Nginx之后上网只能查到一些配置文件的讲解,照做之后肯定也是一脸懵的。
对于我这个项目来说,即时通讯,如果没有用Nginx,那我客户端的服务(或服务端,我这里拿客户端来讲)登陆用的就是客户端的链接(举个例子:http://localhost:7070/chatpage.html),那如果因为某种情况导致这个服务挂掉之后,聊天服务就不能继续正常使用了。用到Nginx之后,我们可以设置多个服务,就会有多个链接,那我们将这些服务集群到一个Nginx上面,然后使用Nginx的端口号去访问这个聊天服务,Nginx就会自己根据负载均衡调配这些资源,当其中某一个服务挂掉之后,聊天服务依旧可以正常的运行,我现在看前台大概会有几秒的卡顿,几乎感觉不到切换服务器。据我目前的了解,大概是这个样子。以下是我的一些配置。
1.首先下载的话,Nginx是开源的,因此直接去官网下载最新版本的就可以了,我这里下载的是nginx-1.21.0版本的。
2. 下载之后可以找到nginx-1.21.0->conf->nginx.conf,这个就是我们的配置文件。
3. 下载下来之后里面会有一些模板,网上也能找到一些基础的配置。这里有一篇比较好懂的配置,引给大家看一下(链接: Nginx的四个作用.),基础的配置看这篇文章就够了,为防止链接失效,我也会写在下面,可以参照下面的目录:(Nginx的四个作用)
4. 下面来说说我的配置,因为我的即时通讯是用的SignalR,所以要参照nginx websocket的配置,一开始也是按照下面基础配置来的,但是每次nginx都无法获取代理的端口号导致服务无法正常使用。
下面看看我的配置:

#user  nobody;#配置用户或者组,默认为nobody nobody。
worker_processes  2; #允许生成的进程数,默认为1
error_log  logs/error.log;#制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
pid        logs/nginx.pid; #指定nginx进程运行文件存放地址

events {
	accept_mutex on;   #设置网路连接序列化,防止惊群现象发生,默认为on
    multi_accept on;  #设置一个进程是否同时接受多个网络连接,默认为off
    #use epoll;      #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
    worker_connections  1024; #最大连接数,默认为512
}

http {
    include       mime.types;#文件扩展名与文件类型映射表
    default_type  application/octet-stream; #默认文件类型,默认为text/plain
    sendfile        on;#允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
    #sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
    keepalive_timeout  20;#连接超时时间,默认为75s,可以在http,server,location块。

	map $http_upgrade $connection_upgrade {
		default upgrade;
		'' close;
	}

	upstream mysvr {
		ip_hash;
        #server localhost:7086;
		server localhost:7087;
        server localhost:7088;
	}
	error_page 404 https://www.baidu.com; 
    server {
        listen       82; #监听端口
        server_name  localhost; #监听地址
		client_max_body_size 1024M;
		
        location / {
			proxy_pass  http://mysvr;  #请求转向mysvr定义的服务器列表
			proxy_read_timeout 30s;
			proxy_set_header Host $host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_http_version 1.1;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection $connection_upgrade;
        }  
		location ~/Hub {
			proxy_pass  http://mysvr; 
			proxy_read_timeout 30s;
			proxy_set_header Host $host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_http_version 1.1;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection $connection_upgrade;
		}		
    }
}

最重要的就是在反向代理的配置中增加了如下两行,其它的部分和普通的HTTP反向代理没有任何差别。

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

这里面的关键部分在于HTTP的请求中多了如下头部:

Upgrade: websocket
Connection: Upgrade

这两个字段表示请求服务器升级协议为WebSocket。服务器处理完请求后,响应如下报文# 状态码为101

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: upgrade

告诉客户端已成功切换协议,升级为Websocket协议。握手成功之后,服务器端和客户端便角色对等,就像普通的Socket一
样,能够双向通信。不再进行HTTP的交互,而是开始WebSocket的数据帧协议实现数据交换。
这里使用map指令可以将变量组合成为新的变量,会根据客户端传来的连接中是否带有Upgrade头来决定是否给源站传递
Connection头,这样做的方法比直接全部传递upgrade更加优雅。
默认情况下,连接将会在无数据传输60秒后关闭,proxy_read_timeout参数可以延长这个时间或者源站通过定期发送ping帧以
保持连接并确认连接是否还在使用。

大致就是学到了这些,接下来有时间还会继续把Redis整理一下。后续也会将SignalR的通信直接换成http的,近期大概就是在做这些了。

Nginx的四个作用

反向代理应该是Nginx做的最多的一件事了。反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。简单来说就是真实的服务器不能直接被外部网络访问,所以需要一台代理服务器,而代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络环境,当然也可能是同一台服务器,端口不同而已。
下面贴上一段简单的实现反向代理的代码

Nginx的四个作用:(只针对Nginx在不加载第三方模块的情况能处理哪些事情)
1.反向代理
反向代理应该是Nginx做的最多的一件事了。反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。简单来说就是真实的服务器不能直接被外部网络访问,所以需要一台代理服务器,而代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络环境,当然也可能是同一台服务器,端口不同而已。
下面贴上一段简单的实现反向代理的代码

upstream test {
        server localhost:8080;
        server localhost:8081;
}
server {
  listen       81;                                                         
  server_name  localhost;                                               
  client_max_body_size 1024M;

  location / {
    proxy_pass http://test;
    proxy_set_header Host $host:$server_port;
  }
}

2.负载均衡
负载均衡也是Nginx常用的一个功能,负载均衡其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。简单而言就是当有2台或以上服务器时,根据规则随机的将请求分发到指定的服务器上处理,负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。而Nginx目前支持自带3种负载均衡策略,还有2种常用的第三方策略。

1、简单配置
upstream test {
        server localhost:8080;
        server localhost:8081;
}
server {
  listen       81;                                                         
  server_name  localhost;                                               
  client_max_body_size 1024M;

  location / {
    proxy_pass http://test;
    proxy_set_header Host $host:$server_port;
  }
}
2、权重:指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
upstream test {
        server localhost:8080 weight=9;
        server localhost:8081 weight=1;
}
3、ip_hash
上面的2种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了session中,那么跳转到另外一台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用iphash了,iphash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream test {
    ip_hash;
    server localhost:8080;
    server localhost:8081;
}
4.fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backend { 
        fair; 
        server localhost:8080;
        server localhost:8081;
}

5url_hash(第三方):按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法
upstream backend { 
        hash $request_uri; 
        hash_method crc32; 
        server localhost:8080;
        server localhost:8081;
}

以上5种负载均衡各自适用不同情况下使用,所以可以根据实际情况选择使用哪种策略模式,不过fair和url_hash需要安装第三方模块才能使用,由于本文主要介绍Nginx能做的事情,所以Nginx安装第三方模块不会再本文介绍

3.Http服务器(动静分离):Nginx本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用Nginx来做服务器,同时现在也很流行动静分离,就可以通过Nginx来实现,首先看看Nginx做静态资源服务器

server {
        listen       80;                                                         
        server_name  localhost;                                               
        client_max_body_size 1024M;

        location / {
               root   e:\wwwroot;
               index  index.html;
        }
}

这样如果访问http://localhost 就会默认访问到E盘wwwroot目录下面的index.html,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署。
动静分离:
动静分离是让动态网站里的动态网页根据一定规则把不变的资源和经常变的资源区分开来,动静资源做好了拆分以后,我们就可以根据静态资源的特点将其做缓存操作,这就是网站静态化处理的核心思路

upstream test{  
       server localhost:8080;  
       server localhost:8081;  
    }   

    server {  
        listen       80;  
        server_name  localhost;  

        location / {  
            root   e:\wwwroot;  
            index  index.html;  
        }  

        # 所有静态请求都由nginx处理,存放目录为html  
        location ~ \.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {  
            root    e:\wwwroot;  
        }  

        # 所有动态请求都转发给tomcat处理  
        location ~ \.(jsp|do)$ {  
            proxy_pass  http://test;  
        }  

        error_page   500 502 503 504  /50x.html;  
        location = /50x.html {  
            root   e:\wwwroot;  
        }  
    }

这样我们就可以吧HTML以及图片和css以及js放到wwwroot目录下,而tomcat只负责处理jsp和请求,例如当我们后缀为gif的时候,Nginx默认会从wwwroot获取到当前请求的动态图文件返回,当然这里的静态文件跟Nginx是同一台服务器,我们也可以在另外一台服务器,然后通过反向代理和负载均衡配置过去就好了,只要搞清楚了最基本的流程,很多配置就很简单了,另外localtion后面其实是一个正则表达式,所以非常灵活

4.正向代理: 正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。当你需要把你的服务器作为代理服务器的时候,可以用Nginx来实现正向代理,但是目前Nginx有一个问题,那么就是不支持HTTPS,虽然我百度到过配置HTTPS的正向代理,但是到最后发现还是代理不了,当然可能是我配置的不对,所以也希望有知道正确方法的同志们留言说明一下。
 resolver是配置正向代理的DNS服务器,listen 是正向代理的端口,配置好了就可以在ie上面或者其他代理插件上面使用服务器ip+端口号进行代理了。

resolver 114.114.114.114 8.8.8.8;
    server {

        resolver_timeout 5s;

        listen 81;

        access_log  e:\wwwroot\proxy.access.log;
        error_log   e:\wwwroot\proxy.error.log;

        location / {
            proxy_pass http://$host$request_uri;
        }
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值