When deploying load balancing, use one Nginx as the front-end server and multiple Tomcat as the back-end server. Nginx will distribute the request to the Tomcat server according to the load policy. The session of the default Tomcat server cannot cross servers. If different requests from the same user are distributed to different Tomcat servers, the session variable will be lost and the user needs to log in again. Before I explain Redisson, I will first analyze the session sharing of the following two schemes.
Scheme 1: Nginx Native Upstream ip_hash
IP_hash is distributed according to the requested IP address. Requests for the same IP address will be forwarded to the same Tomcat server.
1. Nginx configuration is as follows:《 Nginx 1.3 cluster load balancer reverse proxy installation configuration optimization 》
upstream webservertomcat { ip_hash; server 10.10.204.63:8023 weight=1 max_fails=2 fail_timeout=2; server 10.10.204.64:8023 weight=1 max_fails=2 fail_timeout=2; #server 127.0.0.1:8080 backup; } server { listen 80; server_name www.myname.com myname.com; location / { proxy_pass //webservertomcat; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; add_header Access-Control-Allow-Origin *; } }
The above production environment is not recommended for two reasons:
one Nginx may not be the front-end server. For example, if Squid or CDN is used as front-end cache, Nginx actually takes the IP address of Squid or CDN server, which cannot achieve the effect of IP diversion according to the client's request.
two Some organizations use dynamic virtual IP or have multiple exit IPs, and the user access will switch the IP, so the request of a user cannot be fixed to the same Tomcat server.
Scheme 2: Nginx_Upstream_jvm_route
Nginx_upstream_jvm_route is a third-party nginx extension module that implements session stickiness through session cookies. If there is no session in cookies and urls, this is just a simple round robin load balancing.
Implementation method: When the user first requests to be distributed to the back-end server; The server ID of the response will be added to the cookie with the name of JSESSIONID; When jvm_route sees the name of the back-end server in the session, it will transfer the request to the corresponding server. Module address://code.google.com/archive/p/nginx upstream jvm route/
1. Nginx configuration is as follows:
upstream tomcats_jvm_route { server 10.10.204.63:8023 srun_id=tomcat1; server 10.10.204.64:8023 srun_id=tomcat2; jvm_route $cookie_JSESSIONID|sessionid reverse; }
2. Add the following configuration to server.xml of multiple Tomcat servers:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"> <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
3. After configuration, the server ID will be added at the end of the requested cookie with the name of JSESSIONID, as follows:
JSESSIONID=33775B80D8E0DB5AEAD61F86D6666C45.tomcat2;
4. It is not recommended to use in the production environment, because:
four point one According to the characteristics of tomcat, when the jvmRoute value is added to the server.xml configuration file, the sessionid will be suffixed with the jvmRoute value. According to this characteristic, nginx upstream_jvm_route will automatically match the sessionId value in each access request with the corresponding server. In this way, every visit will be to the same Tomcat Server, which solves the problem of changing the session of accessing different tomcat nodes. However, there will be a problem in this way. When the Tomcat server that has been accessed is down, the load will distribute users to other servers, which will cause session changes and require re login.
Scheme 3: Tomcat Redis Session Manager
Use Redis to share sessions, which is the focus of this section. The above two schemes store the session in the Tomcat container. When a request is forwarded from one Tomcat to another, the session will become invalid, because the session cannot be shared in each Tomcat. If Redis and other cache database systems are used to store sessions, session sharing can be realized between Tomcat instances.
The Java framework redisson implements the Tomcat Session Manager, which supports Apache Tomcat 6. x, 7. x, and 8. x. The configuration method is as follows:
1. Edit the TOMCAT_BASE/conf/context.xml file node and add the following contents:
<Manager className="org.redisson.tomcat.RedissonSessionManager"<Manager className="org.redisson.tomcat.RedissonSessionManager" configPath="${catalina.base}/redisson-config.json" />
Note: ConfigPath – refers to the configuration file path of Redisson in JSON or YAML format. configuration file See here 。
2. Copy the corresponding * * * two * * * JAR packages to the specified TOMCAT_BASE/lib directory:
Applicable to JDK 1.8+
redisson-all-3.5.0.jar
for Tomcat 6.x
redisson-tomcat-6-3.5.0.jar
for Tomcat 7.x
redisson-tomcat-7-3.5.0.jar
for Tomcat 8.x
redisson-tomcat-8-3.5.0.jar
3. According to the instructions of [Single instance mode] single instance mode, create and edit the redisson-config.json file in Json format, add the following content, upload it to TOMCAT_BASE, and then reload the Tomcat service.
{ "singleServerConfig":{ "idleConnectionTimeout":10000, "pingTimeout":1000, "connectTimeout":10000, "timeout":3000, "retryAttempts":3, "retryInterval":1500, "reconnectionTimeout":3000, "failedAttempts":3, "password":null, "subscriptionsPerConnection":5, "clientName":null, "address": " redis://127.0.0.1:6379 ", "subscriptionConnectionMinimumIdleSize":1, "subscriptionConnectionPoolSize":50, "connectionMinimumIdleSize":10, "connectionPoolSize":64, "database":0, "dnsMonitoring":false, "dnsMonitoringInterval":5000 }, "threads":0, "nettyThreads":0, "codec":null, "useLinuxNativeEpoll":false }
4. Start the test session. Create session.jsp, add the following code, and upload it to TOMCAT_BASE/webapps/ROOT/.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <! DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>shared session</title> </head> <body> <br>session id=<%=session.getId()%> </body> </html>
5. The following session information will appear when the browser accesses
session id=1D349A69E8F5A27E1C12DEEFC304F0DC
6. Now check whether the value is stored in Redis. If there is a session value, the session value will not change after you restart Tomcat.
# redis-cli 127.0.0.1:6379> keys * 1) "redisson_tomcat_session:1D349A69E8F5A27E1C12DEEFC304F0DC"
Has been successfully stored.
For Redis cluster or multi instance mode, please refer to the following additional information for configuration:
//github.com/redisson/redisson/wiki/14.-Integration%20with%20frameworks#144-tomcat-redis-session-manager
//github.com/redisson/redisson/wiki/2.-Configuration
//Github. com/redisson/redisson/wiki/2. -% E9% 85% 8D% E7% BD% AE% E6% 96% B9% E6% B3% 95 (Chinese document)