Many projects in Dachang are deployed on multiple servers. These servers exist in various regions. When we access the service, although the same service is executed, it may be running on different servers. ;
I encountered such a login scenario when I was studying a project. Assume there are three servers as follows (as shown in the picture), and use session to store the user's login information. This information can be used to determine whether the user is logged in:
Assuming that this login is executed through server 01, then the login session information this time is stored in memory 01; but when I visit again, it is executed by server 02 operation, but the login session information is in memory 01, and server 02 cannot obtain it, so it will judge that I am not logged in and return the wrong information...
What we want to achieve isthrough a The session generated by server login can be shared with other servers, so how to achieve this?
Solution The idea is that since the memory of these servers cannot be shared, then as long as there is a shared space for these servers to access together (as shown in the picture);
The first thing that comes to mind should be the database. As long as these server clusters share a database and store the generated session information in the database, everyone can access it; Databases include relational and non-relational (NoSql):
Relational database: Mysql, etc.
Non-relational database: Redis (K /V database), etc.
It is actually best to choose a non-relational database here, because Redis is based on memory and has high read and write performance, which is very suitable for this situation where user information is frequently read;
It can also be implemented through the file server, which will not be introduced here;
There is also another method, which can be implemented through iphash of nginx. This method is very simple, but the idea is different from the above two. The principle That is, all requests for the same IP will be iphash calculated by nginx, and the results will be bound to the specified server. After that, this request will access the server.
But there are some problems with this. First of all, load balancing does not make much sense. If the bound server hangs up, then iphash will be invalid; or your request will be distributed by other services instead of the nginx service. , then iphash will also not take effect; so use it with caution;
Below I will simply simulate through code how to easily achieve session sharing through redis configuration
Here is one User management project, when logging in, the login logic code will record the session information of the logged in user:
Then the two services of the project are opened at the same time: localhost:8080 and localhost :8082 (can be used as projects running on two different servers)
After opening the service, you can access the corresponding interface document:
-----------------------------------Dividing line-------- ----------------------------------
This service has the following two interfaces: (The following tests are tested in the same service)
Login interface: record login user session information
Login test:
#Get the current user information interface: Get the current user information through the login session
Get the current logged in user Information test:
#Because these are two services now, it is definitely not possible to share sessions. Even if the service on port 8080 is logged in, the service on port 8082 cannot be logged in. Obtain the current user information; (I emphasize again: the above test can obtain the current user information because it is tested in the same service. The same service session is stored in its own memory and can of course be accessed by itself)
The following is to implement shared session through redis configuration:
First download redis and find tutorials online; here I directly use the redis container created by docker on the server (simple and easy to use, highly recommended):
You can connect it through the visual tool:
In this way, redis is configured. Now configure redis in the project code:
Introduce redis dependency into the project Depends on the spring-session configuration (automatically stores the session in redis):
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.6.4</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-redis --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>2.6.3</version> </dependency>
Configure the connection redis and session-related configurations in the application.yml file:
spring: # session配置 session: timeout: 86400 # 设置session失效时间 store-type: redis # 修改spring-session存储配置,默认存储到服务器内存中,现在设置存到redis中(关键) # redis配置 redis: port: 8081 # redis的端口号(这里是我的redis容器在docker中对应的端口号) host: xx.xxx.xxx.xxx # 我的云服务器ip database: 0 # 设置存入redis的哪一个库(默认是0)
In fact, there is only one key configuration: store-type: redis, as long as this is configured, the session in the code will be stored in redis instead of its own memory;
Then you can test it:
Call the login interface , generate user session information, check redis:
#You can see that the user login session has been stored in redis, so I log in at port 8080 and can also get it at 8082 Login session information:
Login:
Obtain information:
In this way, through redis Achieve session sharing;
Note: the introduced redis and spring-redis dependency versions need to be close.
The above is the detailed content of What is the method for redis to implement session sharing?. For more information, please follow other related articles on the PHP Chinese website!