当前位置: 首页 > 后端技术 > Java

nginxsticky实现基于cookie的负载均衡

时间:2023-04-01 18:41:44 Java

nginxsticky实现基于cookie的负载均衡本文主要介绍nginx的第三方模块sticky,依靠它实现基于cookie的负载均衡,不依赖后端前言sticky是一个nginx第三方模块,在nginxrelease版本中不需要额外编译该模块。它的思路不是依赖后端生成cookie,而是sticky在nginx这里生成cookie,然后发送给客户端。客户端收到cookie后,后续带着这个cookie的请求都会通过这个cookie进行哈希处理,定位到后端的某个服务器。优点:相对于纯iphashload有优势。纯iphash就像在局域网中访问ip一样。访问会导致ip倾斜于hash$cookie_jsessionid的好处是不依赖后端,不需要后端产生session,从而减少后端资源。想一想为什么要用这个sticky把用户尽可能定位到一台服务器上?在有多个后端服务器的情况下,为了保证一个客户端只与一台服务器通信,我们必须使用长连接。这种连接是用什么方法实现的呢?一般使用nginx自带的ip_hash。我认为这绝对不是一个好办法。如果前端是CDN,或者局域网中的客户端同时访问服务器,就会出现服务器。分布不均衡,不能保证每次访问都停留在同一台服务器上。如果是基于cookies,考虑一下。每台计算机都会有不同的cookie。在保持长连接的同时,也保证了服务器的压力平衡。Nginxsticky值得推荐。如果浏览器不支持cookies,那么sticky就不会生效。毕竟整个模块都是为cookies实现的。1.cookie_jsessionid负载均衡说sticky之前,先看看nginx通过cookie_jessionid的负载均衡方式1.1后端准备@Autowiredlateinitvarenv:Environment@GetMapping("/server")funserver(request:HttpServletRequest):String{//获取当前服务的端口valport=env.getProperty("local.server.port")println("nowport:$port")//调用request.getSession(true)会有创建会话无会话valsession=request.getSession(true)valname=session.getAttribute("name")println("name:$name")if(name==null){session.setAttribute("name","johnny")}return"success"}1.2hash$cookie_jsessionid;配置upstream配置hash的方式,使用cookie_jsessionid做hash#usernobody;worker_processes1;#error_loglogs/error.log;#error_loglogs/error.lognotice;#error_loglogs/error.loginfo;#pidlogs/nginx.pid;events{worker_connections1024;}http{includemime.types;default_type应用程序/八位字节流;发送文件;#tcp_nopush上;#keepalive_timeout0;keepalive_timeout65;#gzip上;upstreambackend{#指定hash方式为cookie_jessionidnginx自带hash$cookie_jsessionid;服务器172.16.225.1:8081;服务器172.16.225.1:8080;}服务器{听80;服务器名称本地主机;#charsetkoi8-r;#access_log日志/host.access.logmain;location/{#指定加载到后端upstreamproxy_passhttp://backend;}error_page500502503504/50x.html;location=/50x.html{根html;可以看到服务端发送的cookieJSESSIONID多次请求后不会改变,因为nginx每次都根据JSESSIONID进行hash每次加载到同一个后端服务器,因为这个后端服务器已经有这个session了,所以不会再创建了。可以看到有多个请求命中了这个8081后端服务。2.nginxstickyloadbalancing2.1下载stickyBitbuckethttps://bitbucket.org/nginx-g...2.2重新编译升级nginx1)下载完成,放入服务器解压,记住解压后的位2)进入nginx安装文件3)配置nginxtar-xvfnginx-goodies-nginx-sticky-module-ng-c78b7dd79d0d.tar.gzmvnginx-goodies-nginx-sticky-module-ng-c78b7dd79d0dnginx-sticky#添加stickymodule./configure\--prefix=/usr/local/nginx\--add-module=/opt/nginx-stickymake编译时可能会报错找到刚才sticky的解压目录,进入修改后的文件vimngx_http_sticky_misc.c,添加如下头文件#include#include再make,当然如果后面还是报错,openssl检查是否安装apt-getinstall-yopenssl2.3上游配置粘性配置重启nginx上游后端{#hash$cookie_jsessionid;黏;#指定使用sticky进行负载均衡server172.16.225.1:8081;服务器172.16.225.1:8080;}2.4修改后端,此时不再创建session后端不会创建session,也不会下发cookiejsessionid@Autowiredlateinitvarenv:Environment@GetMapping("/server")funserver(request:HttpServletRequest):String{valport=env.getProperty("local.server.port")println("nowport:$port")return"success"}2.5多次请求后可以看到Gotostick帮我们发送路由cookie,这个默认是不会变的。关闭浏览器就失效了。可以看到请求只会落在一台服务器上。3.Sticky其他用法sticky[name=route][domain=.foo.bar][path=/][expires=1h][hash=index|md5|sha1][no_fallback];name:可以是任意字符串字符,默认是routedomain:哪些域名可以使用这个cookiepath:which在路径上启用sticky,比如path/test,那么只有test的目录才会使用sticky做负载均衡expires:cookie过期时间,默认浏览器会过期默认浏览器关闭时,即会话模式no_fallbackup:如果设置了这个,cookie对应的服务器down了,会返回502(badgatewayorproxyerror),建议不要启用发送一个路由cookie,nginx使用这个cookie进行哈希加载,这样客户每次访问都会粘在同一个服务器上。欢迎大家访问个人博客Johnnyhut欢迎关注个人公众号