nginx以前对session 保持支持不太好,主要采用ip_hash把同一来源的客户(同一C段的IP)固定指向后端的同一台机器,ip_hash有个缺点是不能实现很好的负载均衡;直到nginx的扩展模块nginx-sticky-module的出现,解决了session sticky的问题。
个人感觉tengine的session sticky模块更好一些,于是把tengine的sticky移植到了nginx里。
temgine session_sticky_module模块是一个负载均衡模块,通过cookie实现客户端与后端服务器的会话保持, 在一定条件下可以保证同一个客户端访问的都是同一个后端服务器。
mode设置cookie的模式:
option 设置用于session sticky的cookie的选项,可设置成indirect或direct。indirect不会将session sticky的cookie传送给后端服务,该cookie对后端应用完全透明。direct则与indirect相反。
maxidle设置session cookie的最长空闲的超时时间
目前控制台只支持两种模式,insert和rewrite模式。
两种模式下,其他的配置都是相同的。
在insert模式下,cookie的值不经过后端,完全由lb进行管理,每个后端的rs生成一个唯一的id值,加上maxidle和maxlife值,用分隔符隔开,用作cookie的value,来进行会话保持,这个条件需要option=indirect和session_sticky_hide_cookie配合。
在rewrite模式下,除了mode改变,其他完全没变,cookie的值由后端rs是否设置来决定。
第一次请求的时候,因为请求不带cookie值,或者说cookie值本身是错误的,会触发第一次选取rs,并且将cookie值通过response返回
curl -v 127.0.0.3:978
* About to connect() to 127.0.0.3 port 978 (#0)
* Trying 127.0.0.3... connected
* Connected to 127.0.0.3 (127.0.0.3) port 978 (#0)
> GET / HTTP/1.1
> User-Agent: kcurl/1.0 (curl 7.19.7) (x86_64-unknown-linux-gnu) libcurl/7.19.7 OpenSSL/1.0.1e zlib/1.2.3
> Host: 127.0.0.3:978
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Tengine/2.3.0
< Date: Sun, 28 Apr 2019 10:24:01 GMT
< Content-Type: text/plain
< Content-Length: 3
< Connection: keep-alive
< Set-Cookie: KLBRSID=d349ca31adc862f4d7e6faa19e516d6d|1556447041|1556447041; Path=/
<
* Connection #0 to host 127.0.0.3 left intact
* Closing connection #0
821
返回的cookie值构成为,
KLBRSID=d349ca31adc862f4d7e6faa19e516d6d|1556447041|1556447041;
KLBRSID:配置文件中session_sticky指定的键值
d349ca31adc862f4d7e6faa19e516d6d:所选取的后端计算出来的哈希值
1556447041:lastseen,最后一次使用这个cookie的时间戳(用于比较maxidle,下一次请求的将把这个时间戳带回来,如果与当前的时间戳比较超出maxidle,过期处理)
1556447041:firstseen,第一次使用这个cookie的时间戳(用于比较maxlife,基本在请求和返回交互的过程中不会修改)
curl --cookie "KLBRSID=d349ca31adc862f4d7e6faa19e516d6d|1556447041|1556447041; Path=/" 127.0.0.3:978
* About to connect() to 127.0.0.3 port 978 (#0)
* Trying 127.0.0.3... connected
* Connected to 127.0.0.3 (127.0.0.3) port 978 (#0)
> GET / HTTP/1.1
> User-Agent: kcurl/1.0 (curl 7.19.7) (x86_64-unknown-linux-gnu) libcurl/7.19.7 OpenSSL/1.0.1e zlib/1.2.3
> Host: 127.0.0.3:978
> Accept: */*
> Cookie: KLBRSID=d349ca31adc862f4d7e6faa19e516d6d|1556447041|1556447041; Path=/
>
< HTTP/1.1 200 OK
< Server: Tengine/2.3.0
< Date: Sun, 28 Apr 2019 10:30:13 GMT
< Content-Type: text/plain
< Content-Length: 3
< Connection: keep-alive
< Set-Cookie: KLBRSID=d349ca31adc862f4d7e6faa19e516d6d|1556447413|1556447041; Path=/
<
* Connection #0 to host 127.0.0.3 left intact
* Closing connection #0
821
可见,第二次请求带着cookie,返回值更新了,lastseen,并且选定了刚刚的rs(d349ca31adc862f4d7e6faa19e516d6d),并且lastseen也更新了时间戳
curl 120.92.117.233/ok -v
* About to connect() to 120.92.117.233 port 80 (#0)
* Trying 120.92.117.233...
* Connected to 120.92.117.233 (120.92.117.233) port 80 (#0)
> GET /ok HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 120.92.117.233
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: CLOUD ELB 1.0.0
< Date: Thu, 17 Oct 2019 07:26:09 GMT
< Content-Type: application/octet-stream
< Content-Length: 2
< Connection: keep-alive
< Set-Cookie: KLBRSID=10.0.234.20:80|1571297169|1571297169; Path=/
<
* Connection #0 to host 120.92.117.233 left intact
ok
第一次请求选择了rs:10.0.234.20:80
curl --cookie "KLBRSID=10.0.234.20:80|1571297169|1571297169; Path=/" 120.92.117.233/ok -v
* About to connect() to 120.92.117.233 port 80 (#0)
* Trying 120.92.117.233...
* Connected to 120.92.117.233 (120.92.117.233) port 80 (#0)
> GET /ok HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 120.92.117.233
> Accept: */*
> Cookie: KLBRSID=10.0.234.20:80|1571297169|1571297169; Path=/
>
< HTTP/1.1 200 OK
< Server: CLOUD ELB 1.0.0
< Date: Thu, 17 Oct 2019 07:26:38 GMT
< Content-Type: application/octet-stream
< Content-Length: 2
< Connection: keep-alive
< Set-Cookie: KLBRSID=10.0.234.20:80|1571297198|1571297169; Path=/
<
* Connection #0 to host 120.92.117.233 left intact
ok
max_idle设置为30,在18秒内的请求没有超时,继续使用10.0.234.20:80这个rs。
curl --cookie "KLBRSID=10.0.234.20:80|1571297198|1571297169; Path=/" 120.92.117.233/ok -v
* About to connect() to 120.92.117.233 port 80 (#0)
* Trying 120.92.117.233...
* Connected to 120.92.117.233 (120.92.117.233) port 80 (#0)
> GET /ok HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 120.92.117.233
> Accept: */*
> Cookie: KLBRSID=10.0.234.20:80|1571297198|1571297169; Path=/
>
< HTTP/1.1 200 OK
< Server: CLOUD ELB 1.0.0
< Date: Thu, 17 Oct 2019 07:27:47 GMT
< Content-Type: application/octet-stream
< Content-Length: 2
< Connection: keep-alive
< Set-Cookie: KLBRSID=10.0.234.6:80|1571297267|1571297267; Path=/
<
* Connection #0 to host 120.92.117.233 left intact
ok
一旦超过max_idle,该session失效,重新选择rs,更新lastseen和firstseen