Distributed session Research (i):D ocker + Spring boot +nginx building distributed applications

Source: Internet
Author: User
Tags redis sessions set cookie nginx load balancing

Because I have been obsessed with the design principle and practice of large distributed system. But the conditions are limited, after all, still reading, can not touch the real distributed, real big data. can only on their own computer through the Docker of this virtualization technology to build their own "distributed system" to play, experience a distributed session, distributed things and so on.

This article will build a "distributed" system, and first experience in the Distributed System session management problems, and through the centralized session management solution build two springboot mirrors to provide session service.

First use Springboot to build a restful interface and do some very simple session operations.
Maven:

    <parent> <groupId>org.springframework.boot</groupId> <artifactid>spring-boot-s Tarter-parent</artifactid> <version>1.4.0.RELEASE</version> <relativepath></rel ativepath> </parent> <dependencies> <dependency> <groupid>org.spri Ngframework.boot</groupid> <artifactId>spring-boot-starter-web</artifactId> &LT;/DEP endency> <dependency> <groupId>javax.servlet</groupId> <artifactid >servlet-api</artifactId> <version>2.5</version> </dependency> < Dependency> <groupId>org.springframework.boot</groupId> <artifactid>spring-bo ot-starter-test</artifactid> <scope>test</scope> </dependency> </depend Encies>

Then write a relatively simple controller:

@SpringBootApplication
@RestController Public
class app{

    @RequestMapping ("/setsession")
    public String Home (HttpServletRequest request) {
        request.getsession (). setattribute ("User", "Jack");
        Return "I am one." You are session has k-v User-wang. "+request.getsession (). getattribute (" user ");
    }

    @RequestMapping ("/getsession") public
    String session (HttpServletRequest request) {return
        "I am one." You are: "+request.getsession (). getattribute (" user ");

    public static void Main (string[] args) {
        springapplication.run (app.class, args);
    }


Now a Springboot project has been written. It provides only two rest interfaces. one sets the session value, one gets the session value. Note that the return value in the above code has an identifier for one . Now we're going to docker it: first by MVN package into a jar package, named Dockerone.jar write dockerfile generate mirrors and run

Dockerfile:

From REGISTRY.CN-HANGZHOU.ALIYUNCS.COM/ALIROBOT/ORACLEJDK8-NSCD #基础源
volume/tmp #挂载
Add Dockerone.jar App.jar #传递jar包
entrypoint ["Java", "-djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]
#运行命令

Then run sudo docker build-t dockerone/jdk8. Build the first mirror.
Follow the steps above to build a second mirror: one in the code is changed to two. The mirror name is also changed to DOCKERTWO/JDK8.

Start the above two mirrors, through inspect view IP for 192.168.110.2 192.168.110.3 (Docker Network Bridge for 192.168.110.1) build nginx and build load balance

Docker pull download a nginx after. We write a Nginx profile on this machine, and then mount it to the Docker mirror via the-V data volume.

#使用轮询法做负载均衡, the weights are 1, so the request can be randomly assigned.
upstream webservers{
 server 192.168.110.3:8080 weight=1;
 Server 192.168.110.2:8080 weight=1;
}

server {
    listen       ;
    server_name  localhost;

    #charset Koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    Location =/index.html{
       root/data;
    }
    Location/{
       proxy_pass  http://webservers;
    }
}

Start Nginx and view IP as 192.168.110.4 access 192.168.110.4 and observe the cookie and session return values that the browser carries

We know that the first time you visit the site (that is, the user has not created a session), the server's response will carry a Set-cookie value random value. Used to represent the session of the user. The next time the user visits the site, the cookie is brought in to the request with the header information of a cookie. This allows the server to find the user's unique session in memory.
First request/setsession

1. Request assigned to two server: not carrying cookie value, server conforms to e5dd28a3b255aeb9b95c2c5304342685
2. Request assigned to one server: Carry Cookie e5dd28a3b255aeb9b95c2c5304342685 but return to Set-cookie 75965aebc91a57b509bde095602b9f97
3. Request to two send 75965aebc91a57b509bde095602b9f97 but return 60BC939E156DBB21676BCC02EC0C7E2A
4. Request to one send 60BC939E156DBB21676BCC02EC0C7E2A but return e090da9b2aba7b7d08915df78edfa31e
5. Request to two send e090da9b2aba7b7d08915df78edfa31e but return 96ba8fcd5305a75ecc0684f9d541ebde

now request/getsession .

1. Request assign to one carry cookie 96ba8fcd5305a75ecc0684f9d541ebde
The return value is I am one. your session Is:null
Returns the set cookie value of 95833d8765eb2818b220ca9ac53da72c
2. Request assigned to two carry cookies 95833d8765eb2818b220ca9ac53da72c
The return value is I am two. your session Is:null
Returns the Set cookie value 6bfb1d62a6b3925a1774cc51c3b21893

Now we should be clear about the session in the distributed system problem, it is not clear that the user's request will be landed on that server. And for the session is to save the default only on the server you requested to landing, for the next request, if the landing on the server not on the previous request, there is no session information. session Centralized management for distributed session resolution

session centralized management is to unify the user's sessions to a central server (and possibly the central server is also built into a distributed cache cluster).

For our above project, there are three servers now. A Nginx load balancing server. Two servers that provide a rest interface. Now add a session cache server. Let the two rest interface servers give the session to the session cache server to hold.

specific implementation We use Spring-session,session cache in Redis

First, start a redis dcoker mirror. View IP as 192.168.110.5

Dependencies added to Redis in maven:

<parent> <groupId>org.springframework.boot</groupId> <artifactid>spring-boot-start Er-parent</artifactid> <version>1.4.0.RELEASE</version> <relativepath></relativ epath> </parent> <dependencies> <dependency> &LT;GROUPID&GT;ORG.SPRINGFR Amework.boot</groupid> <artifactId>spring-boot-starter-web</artifactId> </depende ncy> <dependency> <groupId>javax.servlet</groupId> <artifactId> servlet-api</artifactid> <version>2.5</version> </dependency> <depe Ndency> <groupId>org.springframework.boot</groupId> <artifactid>spring-boot-s tarter-test</artifactid> <scope>test</scope> </dependency> <depende Ncy> <Groupid>org.springframework.session</groupid> <artifactId>spring-session</artifactId> <version>1.2.2.RELEASE</version> </dependency> <dependency> & Lt;groupid>org.springframework.boot</groupid> &LT;ARTIFACTID&GT;SPRING-BOOT-STARTER-REDIS&LT;/ARTIFAC tid> </dependency> <dependency> <groupid>org.springframework.session</ Groupid> <artifactId>spring-session-data-redis</artifactId> <version>1.2.2.re lease</version> <type>pom</type> </dependency> </dependencies>

Configuration in Springboot:

@SpringBootApplication @RestController @EnableRedisHttpSession public class app{@RequestMapping ("/") public stri
        NG Home (HttpServletRequest request) {request.getsession (). setattribute ("User", "XI"); Return "I am two." You are session has k-v User-wang.
    "+request.getsession (). getattribute (" user "); @RequestMapping ("/getsession") public String session (HttpServletRequest request) {return "I am two.
    You are: "+request.getsession (). getattribute (" user ");
    public static void Main (string[] args) {Springapplication.run (app.class, args); #缓存服务器的配置 @Bean public jedisconnectionfactory connectionfactory () {jedisconnectionfactory Rediscon
        Nectionfactory = new Jedisconnectionfactory ();
        Redisconnectionfactory.setusepool (FALSE);
        Redisconnectionfactory.sethostname ("192.168.110.2");
        Redisconnectionfactory.setport (6379);
    return redisconnectionfactory; }

}

In fact, you can add the following configuration to the properties configuration file;

spring.redis.host=192.168.110.5
spring.redis.port=6379

@EnableRedisHttpSession This annotation is the most important thing, after adding it, Spring produces a new interceptor, used to implement session sharing operations, the implementation of this is not open. This jedisconnectionfactory is configured to have spring connect to Redis based on the configuration in the configuration file.
Now proceed to the previous step, the session problem can be resolved.

because no matter which server the final request landed on, the session shared server returns only one session to the browser, and the browser always carries only one cookie value

At this point we look at the Redis database:

dev@dev:~$ redis-cli  -H 192.168.110.5
192.168.110.5:6379> keys *
1) "Spring:session:sessions : 96b04dd3-4045-435f-ac2b-935c2af5eb52 "
3" spring:session:expirations:1484127300000 "
4)" Spring:session: Sessions:expires:96b04dd3-4045-435f-ac2b-935c2af5eb52 "
xxxx

One is the session expiration time, and the other is the cookie value we mentioned earlier.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.