新增用例
14
README.md
@ -82,16 +82,12 @@ spring-cloud:Finchley.SR2
|
|||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
## 4.分布式session和分布式事务
|
## 4.spring分布式session和分布式事务
|
||||||
|
|
||||||
| 描述 | sample | 官方文档 |
|
| sample | 描述 | 官方文档 |
|
||||||
| ---------------------------------------- | ---------------------------- | ------------------------------------------------------------ |
|
| ---------------------------- | -------------------------- | ------------------------------------------------------------ |
|
||||||
| 分布式session解决方案(一) | spring session | [spring session](https://spring.io/projects/spring-session#learn) |
|
| spring-session | spring 分布式 session | [spring session](https://spring.io/projects/spring-session#learn) |
|
||||||
| 分布式session 解决方案(二) | spring boot + spring session | |
|
| spring boot + spring session | spring boot 分布式 session | [spring session](https://spring.io/projects/spring-session#learn) |
|
||||||
| 分布式session 解决方案(三) | memcached-session-manager | |
|
|
||||||
| 分布式事务解决方案(一)——JPA | 待补充 | |
|
|
||||||
| 分布式事务解决方案(二)——Spring事务同步 | 待补充 | |
|
|
||||||
| 分布式事务解决方案(三)——链式事务 | 待补充 | |
|
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
67
distributed solution/msm/pom.xml
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
|
<groupId>com.heibaiying</groupId>
|
||||||
|
<artifactId>msm</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>8</source>
|
||||||
|
<target>8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<spring-base-version>5.1.3.RELEASE</spring-base-version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>${spring-base-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-beans</artifactId>
|
||||||
|
<version>${spring-base-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>${spring-base-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-web</artifactId>
|
||||||
|
<version>${spring-base-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-webmvc</artifactId>
|
||||||
|
<version>${spring-base-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.heibaiying.bean;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : heibaiying
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class User implements Serializable {
|
||||||
|
|
||||||
|
private long userId;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.heibaiying.controller;
|
||||||
|
|
||||||
|
import com.heibaiying.bean.User;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : heibaiying
|
||||||
|
* @description : 登录
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public String index(){
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("home")
|
||||||
|
public String home(){
|
||||||
|
return "home";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("login")
|
||||||
|
public String login(User user, HttpSession session, HttpServletRequest request, Model model){
|
||||||
|
// 随机生成用户id
|
||||||
|
user.setUserId(Math.round(Math.floor(Math.random() *10*1000)));
|
||||||
|
// 将用户信息保存到id中
|
||||||
|
session.setAttribute("USER",user);
|
||||||
|
return "redirect:home";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
|
||||||
|
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
|
||||||
|
|
||||||
|
<!-- 开启注解包扫描-->
|
||||||
|
<context:component-scan base-package="com.heibaiying.*"/>
|
||||||
|
|
||||||
|
<!--使用默认的Servlet来响应静态文件-->
|
||||||
|
<mvc:default-servlet-handler/>
|
||||||
|
|
||||||
|
|
||||||
|
<mvc:annotation-driven/>
|
||||||
|
|
||||||
|
<!-- 配置视图解析器 -->
|
||||||
|
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
|
||||||
|
id="internalResourceViewResolver">
|
||||||
|
<!-- 前缀 -->
|
||||||
|
<property name="prefix" value="/WEB-INF/jsp/"/>
|
||||||
|
<!-- 后缀 -->
|
||||||
|
<property name="suffix" value=".jsp"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
</beans>
|
@ -0,0 +1,11 @@
|
|||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>主页面</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h5>服务器:<%=request.getServerName()+":"+request.getServerPort()%></h5>
|
||||||
|
<h5>登录用户: ${sessionScope.USER.username} </h5>
|
||||||
|
<h5>用户编号: ${sessionScope.USER.userId} </h5>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,14 @@
|
|||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>登录页面</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h5>服务器:<%=request.getServerName()+":"+request.getServerPort()%></h5>
|
||||||
|
<form action="${pageContext.request.contextPath}/login" method="post">
|
||||||
|
用户:<input type="text" name="username"><br/>
|
||||||
|
密码:<input type="password" name="password"><br/>
|
||||||
|
<button type="submit">登录</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
42
distributed solution/msm/src/main/webapp/WEB-INF/web.xml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||||
|
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||||
|
version="3.1">
|
||||||
|
|
||||||
|
<!--配置spring前端控制器-->
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>springMvc</servlet-name>
|
||||||
|
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>contextConfigLocation</param-name>
|
||||||
|
<param-value>classpath:springApplication.xml</param-value>
|
||||||
|
</init-param>
|
||||||
|
<load-on-startup>1</load-on-startup>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>springMvc</servlet-name>
|
||||||
|
<url-pattern>/</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<!--防止中文乱码-->
|
||||||
|
<filter>
|
||||||
|
<filter-name>characterEncodingFilter</filter-name>
|
||||||
|
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>encoding</param-name>
|
||||||
|
<param-value>UTF-8</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>forceEncoding</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</init-param>
|
||||||
|
</filter>
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>characterEncodingFilter</filter-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</filter-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
152
distributed solution/spring-boot-session/README.md
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
# spring boot 实现分布式 session
|
||||||
|
|
||||||
|
## 一、项目结构
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 二、分布式session的配置
|
||||||
|
|
||||||
|
#### 2.1 引入依赖
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!--分布式 session 相关依赖-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.session</groupId>
|
||||||
|
<artifactId>spring-session-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2 Redis配置
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
redis:
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 6379
|
||||||
|
jedis:
|
||||||
|
pool:
|
||||||
|
# 连接池最大连接数,使用负值表示无限制。
|
||||||
|
max-active: 8
|
||||||
|
# 连接池最大阻塞等待时间,使用负值表示无限制。
|
||||||
|
max-wait: -1s
|
||||||
|
# 连接池最大空闲数,使用负值表示无限制。
|
||||||
|
max-idle: 8
|
||||||
|
# 连接池最小空闲连接,只有设置为正值时候才有效
|
||||||
|
min-idle: 1
|
||||||
|
timeout: 300ms
|
||||||
|
session:
|
||||||
|
# session 存储方式 支持redis、mongo、jdbc、hazelcast
|
||||||
|
store-type: redis
|
||||||
|
|
||||||
|
# 如果是集群节点 采用如下配置指定节点
|
||||||
|
#spring.redis.cluster.nodes
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
有两点需要特别说明:
|
||||||
|
|
||||||
|
1. spring-session 不仅提供了redis作为公共session存储的方案,同时也支持jdbc、mongodb、Hazelcast等作为公共session的存储,可以用session.store-type 指定;
|
||||||
|
2. 对于redis 存储方案而言,官方也提供了不止一种整合方式,这里我们选取的整合方案是jedis客户端作为连接,当然也可以使用Lettuce作为客户端连接。
|
||||||
|
|
||||||
|
#### 2.3 启动类上添加@EnableRedisHttpSession 注解开启 spring-session-redis 整合方案的自动配置
|
||||||
|
|
||||||
|
```java
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableRedisHttpSession(maxInactiveIntervalInSeconds= 1800) //开启redis session支持,并配置session过期时间
|
||||||
|
public class SpringBootSessionApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SpringBootSessionApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 三、验证分布式session
|
||||||
|
|
||||||
|
#### 3.1 创建测试controller和测试页面
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Controller
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public String index() {
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("home")
|
||||||
|
public String home() {
|
||||||
|
return "home";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("login")
|
||||||
|
public String login(User user, HttpSession session) {
|
||||||
|
// 随机生成用户id
|
||||||
|
user.setUserId(Math.round(Math.floor(Math.random() * 10 * 1000)));
|
||||||
|
// 将用户信息保存到id中
|
||||||
|
session.setAttribute("USER", user);
|
||||||
|
return "home";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
登录页面index.ftl:
|
||||||
|
|
||||||
|
```jsp
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>登录页面</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form action="/login" method="post">
|
||||||
|
用户:<input type="text" name="username"><br/>
|
||||||
|
密码:<input type="password" name="password"><br/>
|
||||||
|
<button type="submit">登录</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
session 信息展示页面home.ftl:
|
||||||
|
|
||||||
|
```jsp
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>主页面</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h5>登录用户: ${Session["USER"].username} </h5>
|
||||||
|
<h5>用户编号: ${Session["USER"].userId} </h5>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 启动项目
|
||||||
|
|
||||||
|
由于我们这里采用的是spring boot 的内置容器作为web容器,所以直接启动两个实例测试即可。
|
||||||
|
|
||||||
|
应用1启动配置:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
应用2启动配置,需要用 `--server.port `指定不同的端口号:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**测试结果:**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
60
distributed solution/spring-boot-session/pom.xml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.1.2.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.heibaiying</groupId>
|
||||||
|
<artifactId>spring-boot-session</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>spring-boot-session</name>
|
||||||
|
<description>spring session project for Spring Boot</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.session</groupId>
|
||||||
|
<artifactId>spring-session-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.heibaiying.springboot;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableRedisHttpSession(maxInactiveIntervalInSeconds= 1800) //开启redis session支持,并配置session过期时间
|
||||||
|
public class SpringBootSessionApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SpringBootSessionApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.heibaiying.springboot.bean;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : heibaiying
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class User implements Serializable {
|
||||||
|
|
||||||
|
private long userId;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.heibaiying.springboot.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import com.heibaiying.springboot.bean.User;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : heibaiying
|
||||||
|
* @description : 登录
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public String index() {
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("home")
|
||||||
|
public String home() {
|
||||||
|
return "home";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("login")
|
||||||
|
public String login(User user, HttpSession session) {
|
||||||
|
// 随机生成用户id
|
||||||
|
user.setUserId(Math.round(Math.floor(Math.random() * 10 * 1000)));
|
||||||
|
// 将用户信息保存到id中
|
||||||
|
session.setAttribute("USER", user);
|
||||||
|
return "home";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
spring:
|
||||||
|
redis:
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 6379
|
||||||
|
jedis:
|
||||||
|
pool:
|
||||||
|
# 连接池最大连接数,使用负值表示无限制。
|
||||||
|
max-active: 8
|
||||||
|
# 连接池最大阻塞等待时间,使用负值表示无限制。
|
||||||
|
max-wait: -1s
|
||||||
|
# 连接池最大空闲数,使用负值表示无限制。
|
||||||
|
max-idle: 8
|
||||||
|
# 连接池最小空闲连接,只有设置为正值时候才有效
|
||||||
|
min-idle: 1
|
||||||
|
timeout: 300ms
|
||||||
|
session:
|
||||||
|
# session 存储方式 支持redis、mongo、jdbc、hazelcast
|
||||||
|
store-type: redis
|
||||||
|
|
||||||
|
# 如果是集群节点 采用如下配置指定节点
|
||||||
|
#spring.redis.cluster.nodes
|
@ -0,0 +1,10 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>主页面</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h5>登录用户: ${Session["USER"].username} </h5>
|
||||||
|
<h5>用户编号: ${Session["USER"].userId} </h5>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>登录页面</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form action="/login" method="post">
|
||||||
|
用户:<input type="text" name="username"><br/>
|
||||||
|
密码:<input type="password" name="password"><br/>
|
||||||
|
<button type="submit">登录</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.heibaiying.springboot;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
public class SpringBootSessionApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
189
distributed solution/spring-session/README.md
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
# spring session 实现分布式 session
|
||||||
|
|
||||||
|
## 一、项目结构
|
||||||
|
|
||||||
|
分布式session 主要配置文件为spring-session.xml和web.xml,其他的配置为标准的web工程的配置。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 二、分布式session的配置
|
||||||
|
|
||||||
|
#### 2.1 引入依赖
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!--分布式 session 相关依赖-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-redis</artifactId>
|
||||||
|
<version>2.1.3.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>redis.clients</groupId>
|
||||||
|
<artifactId>jedis</artifactId>
|
||||||
|
<version>2.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.session</groupId>
|
||||||
|
<artifactId>spring-session-data-redis</artifactId>
|
||||||
|
<version>2.1.3.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2 在web.xml中配置session拦截器
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!--配置http session-->
|
||||||
|
<filter>
|
||||||
|
<filter-name>springSessionRepositoryFilter</filter-name>
|
||||||
|
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
||||||
|
</filter>
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>springSessionRepositoryFilter</filter-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</filter-mapping>
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.3 创建配置文件spring- session.xml,配置redis连接
|
||||||
|
|
||||||
|
有两点需要特别说明:
|
||||||
|
|
||||||
|
1. spring-session 不仅提供了redis作为公共session存储的方案,同时也支持jdbc、mongodb、Hazelcast等作为公共session的存储;
|
||||||
|
2. 对于redis 存储方案而言,官方也提供了不止一种整合方式,这里我们选取的整合方案是jedis客户端作为连接,当然也可以使用Lettuce作为客户端连接。
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
|
||||||
|
|
||||||
|
<context:property-placeholder location="classpath:redis.properties"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!--配置 http session-->
|
||||||
|
<bean id="redisHttpSessionConfiguration"
|
||||||
|
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
|
||||||
|
<!--session 有效期 单位秒 每次访问都会刷新有效期-->
|
||||||
|
<property name="maxInactiveIntervalInSeconds" value="1800"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!--单机版本配置redis 配置-->
|
||||||
|
<bean id="redisStandaloneConfiguration"
|
||||||
|
class="org.springframework.data.redis.connection.RedisStandaloneConfiguration">
|
||||||
|
<constructor-arg name="hostName" value="${redis.host}"/>
|
||||||
|
<constructor-arg name="port" value="${redis.port}"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
|
||||||
|
p:usePool="true">
|
||||||
|
<!--单机版本配置-->
|
||||||
|
<constructor-arg name="standaloneConfig" ref="redisStandaloneConfiguration"/>
|
||||||
|
<!--集群配置-->
|
||||||
|
<!--<constructor-arg name="clusterConfig" ref="redisClusterConfiguration"/>-->
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
<!--集群配置-->
|
||||||
|
<!--<bean id="redisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
|
||||||
|
<property name="maxRedirects" value="3"/>
|
||||||
|
<constructor-arg>
|
||||||
|
<set>
|
||||||
|
<value>127.0.0.1:6379</value>
|
||||||
|
<value>127.0.0.1:6380</value>
|
||||||
|
<value>127.0.0.1:6381</value>
|
||||||
|
</set>
|
||||||
|
</constructor-arg>
|
||||||
|
</bean>-->
|
||||||
|
|
||||||
|
|
||||||
|
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
|
||||||
|
p:connection-factory-ref="jedisConnectionFactory"/>
|
||||||
|
|
||||||
|
</beans>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 三、验证分布式session
|
||||||
|
|
||||||
|
#### 3.1 创建测试controller和测试页面
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Controller
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public String index(){
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("home")
|
||||||
|
public String home(){
|
||||||
|
return "home";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("login")
|
||||||
|
public String login(User user, HttpSession session, HttpServletRequest request, Model model){
|
||||||
|
// 随机生成用户id
|
||||||
|
user.setUserId(Math.round(Math.floor(Math.random() *10*1000)));
|
||||||
|
// 将用户信息保存到id中
|
||||||
|
session.setAttribute("USER",user);
|
||||||
|
return "redirect:home";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
登录页面:
|
||||||
|
|
||||||
|
```jsp
|
||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>登录页面</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h5>服务器:<%=request.getServerName()+":"+request.getServerPort()%></h5>
|
||||||
|
<form action="${pageContext.request.contextPath}/login" method="post">
|
||||||
|
用户:<input type="text" name="username"><br/>
|
||||||
|
密码:<input type="password" name="password"><br/>
|
||||||
|
<button type="submit">登录</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
session 信息展示页面(home.jsp):
|
||||||
|
|
||||||
|
```jsp
|
||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>主页面</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h5>服务器:<%=request.getServerName()+":"+request.getServerPort()%></h5>
|
||||||
|
<h5>登录用户: ${sessionScope.USER.username} </h5>
|
||||||
|
<h5>用户编号: ${sessionScope.USER.userId} </h5>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 启动项目
|
||||||
|
|
||||||
|
这里我们采用两个tomcat分别启动项目,在第一个项目index.jsp页面进行登录,第二个项目不登录,直接访问session展示页(home.jsp)
|
||||||
|
|
||||||
|
tomcat 1 配置:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
tomcat 2 配置:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**测试结果:**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
82
distributed solution/spring-session/pom.xml
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.heibaiying</groupId>
|
||||||
|
<artifactId>spring-session</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>8</source>
|
||||||
|
<target>8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<spring-base-version>5.1.3.RELEASE</spring-base-version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>${spring-base-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-beans</artifactId>
|
||||||
|
<version>${spring-base-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>${spring-base-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-web</artifactId>
|
||||||
|
<version>${spring-base-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-webmvc</artifactId>
|
||||||
|
<version>${spring-base-version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!--分布式 session 相关依赖-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-redis</artifactId>
|
||||||
|
<version>2.1.3.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>redis.clients</groupId>
|
||||||
|
<artifactId>jedis</artifactId>
|
||||||
|
<version>2.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.session</groupId>
|
||||||
|
<artifactId>spring-session-data-redis</artifactId>
|
||||||
|
<version>2.1.3.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.heibaiying.bean;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : heibaiying
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class User implements Serializable {
|
||||||
|
|
||||||
|
private long userId;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.heibaiying.controller;
|
||||||
|
|
||||||
|
import com.heibaiying.bean.User;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : heibaiying
|
||||||
|
* @description : 登录
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
@RequestMapping
|
||||||
|
public String index(){
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("home")
|
||||||
|
public String home(){
|
||||||
|
return "home";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("login")
|
||||||
|
public String login(User user, HttpSession session, HttpServletRequest request, Model model){
|
||||||
|
// 随机生成用户id
|
||||||
|
user.setUserId(Math.round(Math.floor(Math.random() *10*1000)));
|
||||||
|
// 将用户信息保存到id中
|
||||||
|
session.setAttribute("USER",user);
|
||||||
|
return "redirect:home";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
redis.host=127.0.0.1
|
||||||
|
redis.port=6379
|
||||||
|
# 连接超时时间
|
||||||
|
redis.timeout=2000
|
||||||
|
# 最大空闲连接数
|
||||||
|
redis.maxIdle=8
|
||||||
|
# 最大连接数
|
||||||
|
redis.maxTotal=16
|
@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
|
||||||
|
|
||||||
|
<context:property-placeholder location="classpath:redis.properties"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!--配置 http session-->
|
||||||
|
<bean id="redisHttpSessionConfiguration"
|
||||||
|
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
|
||||||
|
<!--session 有效期 单位秒 每次访问都会刷新有效期-->
|
||||||
|
<property name="maxInactiveIntervalInSeconds" value="1800"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!--单机版本配置redis 配置-->
|
||||||
|
<bean id="redisStandaloneConfiguration"
|
||||||
|
class="org.springframework.data.redis.connection.RedisStandaloneConfiguration">
|
||||||
|
<constructor-arg name="hostName" value="${redis.host}"/>
|
||||||
|
<constructor-arg name="port" value="${redis.port}"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
|
||||||
|
p:usePool="true">
|
||||||
|
<!--单机版本配置-->
|
||||||
|
<constructor-arg name="standaloneConfig" ref="redisStandaloneConfiguration"/>
|
||||||
|
<!--集群配置-->
|
||||||
|
<!--<constructor-arg name="clusterConfig" ref="redisClusterConfiguration"/>-->
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
<!--集群配置-->
|
||||||
|
<!--<bean id="redisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
|
||||||
|
<property name="maxRedirects" value="3"/>
|
||||||
|
<constructor-arg>
|
||||||
|
<set>
|
||||||
|
<value>127.0.0.1:6379</value>
|
||||||
|
<value>127.0.0.1:6380</value>
|
||||||
|
<value>127.0.0.1:6381</value>
|
||||||
|
</set>
|
||||||
|
</constructor-arg>
|
||||||
|
</bean>-->
|
||||||
|
|
||||||
|
|
||||||
|
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
|
||||||
|
p:connection-factory-ref="jedisConnectionFactory"/>
|
||||||
|
|
||||||
|
</beans>
|
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
|
||||||
|
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
|
||||||
|
|
||||||
|
<!-- 开启注解包扫描-->
|
||||||
|
<context:component-scan base-package="com.heibaiying.*"/>
|
||||||
|
|
||||||
|
<!--使用默认的Servlet来响应静态文件-->
|
||||||
|
<mvc:default-servlet-handler/>
|
||||||
|
|
||||||
|
|
||||||
|
<mvc:annotation-driven/>
|
||||||
|
|
||||||
|
<!-- 配置视图解析器 -->
|
||||||
|
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
|
||||||
|
id="internalResourceViewResolver">
|
||||||
|
<!-- 前缀 -->
|
||||||
|
<property name="prefix" value="/WEB-INF/jsp/"/>
|
||||||
|
<!-- 后缀 -->
|
||||||
|
<property name="suffix" value=".jsp"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!--导入 spring session 的配置-->
|
||||||
|
<import resource="spring-session.xml"/>
|
||||||
|
|
||||||
|
</beans>
|
@ -0,0 +1,11 @@
|
|||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>主页面</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h5>服务器:<%=request.getServerName()+":"+request.getServerPort()%></h5>
|
||||||
|
<h5>登录用户: ${sessionScope.USER.username} </h5>
|
||||||
|
<h5>用户编号: ${sessionScope.USER.userId} </h5>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,14 @@
|
|||||||
|
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>登录页面</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h5>服务器:<%=request.getServerName()+":"+request.getServerPort()%></h5>
|
||||||
|
<form action="${pageContext.request.contextPath}/login" method="post">
|
||||||
|
用户:<input type="text" name="username"><br/>
|
||||||
|
密码:<input type="password" name="password"><br/>
|
||||||
|
<button type="submit">登录</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||||
|
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||||
|
version="3.1">
|
||||||
|
|
||||||
|
<!--配置spring前端控制器-->
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>springMvc</servlet-name>
|
||||||
|
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>contextConfigLocation</param-name>
|
||||||
|
<param-value>classpath:springApplication.xml</param-value>
|
||||||
|
</init-param>
|
||||||
|
<load-on-startup>1</load-on-startup>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>springMvc</servlet-name>
|
||||||
|
<url-pattern>/</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
|
||||||
|
<!--配置http session-->
|
||||||
|
<filter>
|
||||||
|
<filter-name>springSessionRepositoryFilter</filter-name>
|
||||||
|
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
||||||
|
</filter>
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>springSessionRepositoryFilter</filter-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</filter-mapping>
|
||||||
|
|
||||||
|
|
||||||
|
<!--防止中文-->
|
||||||
|
<filter>
|
||||||
|
<filter-name>characterEncodingFilter</filter-name>
|
||||||
|
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>encoding</param-name>
|
||||||
|
<param-value>UTF-8</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>forceEncoding</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</init-param>
|
||||||
|
</filter>
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>characterEncodingFilter</filter-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</filter-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
BIN
pictures/eureka-application.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
pictures/eureka-server-client.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
pictures/spring-boot-session-8080.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
pictures/spring-boot-session-8090.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
pictures/spring-boot-session-app1.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
pictures/spring-boot-session-app2.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
pictures/spring-boot-session.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
pictures/spring-cloud-eureka-cluster.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
pictures/spring-cloud-eureka.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
pictures/spring-session-8080.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
pictures/spring-session-8090.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
pictures/spring-session-tomcat01.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
pictures/spring-session-tomcat02.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
pictures/spring-session.png
Normal file
After Width: | Height: | Size: 17 KiB |
@ -1,3 +1,194 @@
|
|||||||
2019-01-11 11:16:14.320 INFO 13496 --- [nio-8010-exec-4] c.n.e.registry.AbstractInstanceRegistry : Registered instance SERVER/DESKTOP-8JGSFLJ:server:8010 with status UP (replication=true)
|
# eureka 高可用注册中心的搭建
|
||||||
2019-01-11 11:16:15.084 INFO 13496 --- [ Thread-41] c.n.e.registry.AbstractInstanceRegistry : Registered instance SERVER/DESKTOP-8JGSFLJ:server:8020 with status UP (replication=true)
|
|
||||||
2019-01-11 11:16:15.085 INFO 13496 --- [ Thread-41] c.n.e.registry.AbstractInstanceRegistry : Registered instance SERVER/DESKTOP-8JGSFLJ:server:8030 with status UP (replication=true)
|
## 一、项目结构
|
||||||
|
|
||||||
|
eureka-server为服务注册中心,负责服务的管理;
|
||||||
|
|
||||||
|
eureka-client 为eureka客户端;
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 二、三步搭建eureka 高可用注册中心
|
||||||
|
|
||||||
|
这里我们以单机伪集群的方式搭建,让三个单机注册中心互相注册,实现注册中心的高可用。配置示意图如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### 2.1 引入eureka服务端依赖
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2 创建三份配置文件,分别代表不同注册中心的配置
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
application-01.yml:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: server
|
||||||
|
server:
|
||||||
|
port: 8010
|
||||||
|
eureka:
|
||||||
|
server:
|
||||||
|
# 关闭自我保护机制 开发的时候可以开启 保证不可用的服务能够及时剔除
|
||||||
|
enable-self-preservation: false
|
||||||
|
instance:
|
||||||
|
hostname: 127.0.0.1
|
||||||
|
client:
|
||||||
|
serviceUrl:
|
||||||
|
defaultZone: http://localhost:8020/eureka/,http://192.168.200.228:8030/eureka/
|
||||||
|
```
|
||||||
|
|
||||||
|
application-02.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: server
|
||||||
|
server:
|
||||||
|
port: 8020
|
||||||
|
eureka:
|
||||||
|
server:
|
||||||
|
# 关闭自我保护机制 开发的时候可以开启 保证不可用的服务能够及时剔除
|
||||||
|
enable-self-preservation: false
|
||||||
|
instance:
|
||||||
|
hostname: localhost
|
||||||
|
client:
|
||||||
|
serviceUrl:
|
||||||
|
defaultZone: http://127.0.0.1:8010/eureka/,http://192.168.200.228:8030/eureka/
|
||||||
|
```
|
||||||
|
|
||||||
|
application-03.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: server
|
||||||
|
server:
|
||||||
|
port: 8030
|
||||||
|
eureka:
|
||||||
|
server:
|
||||||
|
# 关闭自我保护机制 开发的时候可以开启 保证不可用的服务能够及时从列表中剔除
|
||||||
|
enable-self-preservation: false
|
||||||
|
instance:
|
||||||
|
hostname: 192.168.200.228
|
||||||
|
client:
|
||||||
|
serviceUrl:
|
||||||
|
defaultZone: http://127.0.0.1:8010/eureka/,http://localhost:8020/eureka/
|
||||||
|
```
|
||||||
|
|
||||||
|
需要注意的是Eureka互相注册要求各个Eureka实例的eureka.instance.hostname不同,如果相同,则会被Eureka标记为unavailable-replicas(不可用副本)。
|
||||||
|
|
||||||
|
#### 2.3 启动类上增加注解@EnableEurekaServer激活eureka服务端自动配置
|
||||||
|
|
||||||
|
```java
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableEurekaServer
|
||||||
|
public class EurekaServerApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(EurekaServerApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 三、三步搭建eureka 客户端
|
||||||
|
|
||||||
|
#### 3.1 引入eureka客户端依赖
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 eureka 客户端配置,指定注册中心地址
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
server:
|
||||||
|
port: 8040
|
||||||
|
# 指定服务命名
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: eureka-client
|
||||||
|
# 指定注册中心地址
|
||||||
|
eureka:
|
||||||
|
client:
|
||||||
|
serviceUrl:
|
||||||
|
defaultZone: http://127.0.0.1:8010/eureka/,http://localhost:8020/eureka/,http://192.168.200.228:8030/eureka/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.3 启动类上增加注解@EnableDiscoveryClient激活eureka客户端自动配置
|
||||||
|
|
||||||
|
```java
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
public class EurekaClientApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(EurekaClientApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4.启动项目
|
||||||
|
|
||||||
|
### 4.1 这里我们可以采用命令行方式指定配置,分别启动三个注册中心
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 4.2 高可用集群搭建成功的判定
|
||||||
|
|
||||||
|
这里需要主要的是仅仅status中出现其他注册中心时,并不一定是搭建成功的,**一定是当注册中心的DS Replicas 和 available replicas中显示其余的注册中心时候**,才代表搭建成功。
|
||||||
|
|
||||||
|
#### **4.2.1 点击下面注册中心的可用实例列表中的地址,访问链接分以下几个情况:**
|
||||||
|
|
||||||
|
1. hostname和prefer-ip-address都没有配置,则访问 主机名:服务名:端口号,
|
||||||
|
|
||||||
|
```
|
||||||
|
如:http://desktop-8jgsflj:8761/info
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 配置了hostname而没有配置prefer-ip-address,则访问 hostname:服务名:端口号,
|
||||||
|
|
||||||
|
如:http://server:8761/info
|
||||||
|
|
||||||
|
3. 如果配置了prefer-ip-address,则访问 ipAddress:服务名:端口号,
|
||||||
|
|
||||||
|
如:http://192.168.200.228:8761/info
|
||||||
|
|
||||||
|
8010 注册中心:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
8020 注册中心:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
8030 注册中心:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 4.3 prefer-ip-address 参数说明
|
||||||
|
|
||||||
|
在有的配置示例中,配置了prefer-ip-address为true。
|
||||||
|
|
||||||
|
```properties
|
||||||
|
eureka.instance.prefer-ip-address=true
|
||||||
|
```
|
||||||
|
|
||||||
|
在多机器独立部署的情况下是没有问题的,配置prefer-ip-address为ture,代表发现服务时候优先按照ip去搜寻,对于多集群而言,可以保证尽快准确搜索到服务。而对于单机部署来说,ip地址都是相同的,这会导致其余注册中心出现在unavailable-replicas(不可用副本)中。所以单机部署时候不建议开启这个参数(默认值为false),多机部署时候可以开启。
|
@ -0,0 +1,98 @@
|
|||||||
|
# eureka 服务的注册与发现
|
||||||
|
|
||||||
|
## 一、项目结构
|
||||||
|
|
||||||
|
eureka-server为服务注册中心,负责服务的管理;
|
||||||
|
|
||||||
|
eureka-client 为eureka客户端;
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 二、三步搭建eureka 服务注册中心
|
||||||
|
|
||||||
|
#### 2.1 引入eureka服务端依赖
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2 eureka 服务端配置
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
server:
|
||||||
|
port: 8010
|
||||||
|
eureka:
|
||||||
|
instance:
|
||||||
|
hostname: localhost
|
||||||
|
client:
|
||||||
|
# 设置为false,代表不向注册中心注册自己
|
||||||
|
register-with-eureka: false
|
||||||
|
# 注册中心主要用于维护服务,并不需要检索服务,所以设置为false
|
||||||
|
fetch-registry: false
|
||||||
|
serviceUrl:
|
||||||
|
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.3 启动类上增加注解@EnableEurekaServer激活eureka服务端自动配置
|
||||||
|
|
||||||
|
```java
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableEurekaServer
|
||||||
|
public class EurekaServerApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(EurekaServerApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 三、三步搭建eureka 客户端
|
||||||
|
|
||||||
|
#### 3.1 引入eureka客户端依赖
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 eureka 客户端配置
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
server:
|
||||||
|
port: 8020
|
||||||
|
# 指定服务命名
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: eureka-client
|
||||||
|
# 指定注册中心地址
|
||||||
|
eureka:
|
||||||
|
client:
|
||||||
|
serviceUrl:
|
||||||
|
defaultZone: http://localhost:8010/eureka/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.3 启动类上增加注解@EnableDiscoveryClient激活eureka客户端自动配置
|
||||||
|
|
||||||
|
```java
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
public class EurekaClientApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(EurekaClientApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4.启动项目
|
||||||
|
|
||||||
|
#### 4.1 进入注册中心控制台,查看服务注册情况
|
||||||
|
|
||||||
|

|