分布式session共享一致性问题

一、什么是Session

Session 是客户端与服务器通讯会话技术, 比如浏览器登陆、记录整个浏览会话信息

Session实现原理

客户对向服务器端发送请求后,Session 创建在服务器端,返回Sessionid给客户端浏览器保存在本地,当下次发送请求的时候,在请求头中传递sessionId获取对应的从服务器上获取对应的Sesison

Session常见问题
  • Session 保证在那里?

答案:存放在服务器上

  • 关闭浏览器Session会失效吗

答案:不会消失

@SpringBootApplication
@RestController
public class TestSessionController {
	// 创建session 会话
	@RequestMapping("/createSession")
	public String createSession(HttpServletRequest request, String nameValue) {
		HttpSession session = request.getSession();
		System.out.println("存入Session  sessionid:信息" + session.getId() + ",nameValue:" + nameValue);
		session.setAttribute("name", nameValue);
		return "success";
	}
	// 获取session 会话
	@RequestMapping("/getSession")
	public Object getSession(HttpServletRequest request) {
		HttpSession session = request.getSession();
		System.out.println("获取Session sessionid:信息" + session.getId());
		Object value = session.getAttribute("name");
		return value;
	}

	public static void main(String[] args) {
		SpringApplication.run(TestSessionController.class, args);
	}
}
服务集群会产生那些问题

如果服务器产生了集群后,因为session是存放在服务器上,客户端会使用同一个Sessionid在多个不同的服务器上获取对应的Session,从而会导致Session不一致问题。

Nginx配置负载均衡

Nginx负载均衡提供上游服务器(真实业务逻辑访问的服务器),负载均衡、故障转移、失败重试、容错、健康检查等。
当上游服务器(真实业务逻辑访问的服务器)发生故障时,可以转移到其他上游服务器(真实业务逻辑访问的服务器)。

Upstream Server配置
  • upstream 主要配置如下:

    IP地址和端口号:配置上游服务器的IP地址和端口

    ###定义上游服务器(需要被nginx真实代理访问的服务器) 默认是轮训机制
    upstream  backServer{
        server 127.0.0.1:8080;
        server 127.0.0.1:8081;
    }
    server {
        listen       80;
        server_name  www.lisy.com;
        location / {
    	    ### 指定上游服务器负载均衡服务器
    	    proxy_pass http://backServer;
            index  index.html index.htm;
        }
    }
    
负载均衡算法
1、轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务,如果后端某台服务器死机,自动剔除故障系统,使用户访问不受影响。

2、weight(轮询权值)

weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下。或者仅仅为在主从的情况下设置不同的权值,达到合理有效的地利用主机资源。

3、ip_hash

每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。俗称IP绑定。

4、fair(第三方)

比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。

5、url_hash(第三方)

按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。

// 设置session过期时间
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 10)
// 关闭数据源
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@RestController
public class TestSessionController {
	@Value("${server.port}")
	private String serverPort;
	@RequestMapping("/")
	public String index() {
		return serverPort;
	}
	// 创建session 会话
	@RequestMapping("/createSession")
	public String createSession(HttpServletRequest request, String nameValue) {
		HttpSession session = request.getSession();
		System.out.println(
				"Session  sessionid:" + session.getId() + " nameValue:" + nameValue + ",serverPort:" + serverPort);
		session.setAttribute("name", nameValue);
		return "success-" + serverPort;
	}
	// 获取session 会话
	@RequestMapping("/getSession")
	public Object getSession(HttpServletRequest request) {
		HttpSession session = request.getSession(false);
		if (session == null) {
			return serverPort + "-" + "没有找到对应的session值";
		}
		System.out.println("Session sessionid:" + session.getId() + "serverPort:" + serverPort);
		Object value = session.getAttribute("name");
		return serverPort + "-" + value;
	}
	public static void main(String[] args) {
		SpringApplication.run(TestSessionController.class, args);
	}
}

分布式Session一致性解决方案

  • nginx或者haproxy实现IP绑定
1、用Nginx 做的负载均衡可以添加ip_hash这个配置,
2、 用haproxy做的负载均衡可以用 balance source这个配置。从而使同一个ip的请求发到同一台服务器。
3、 利用数据库同步session
4、使用Session集群存放Redis
5、 使用spring-session框架,底层实现原理是重写httpsession
引入maven依赖
<dependencies>
		<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-core</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!--Spring session data redis-->
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
        <!--<version>2.1.4.RELEASE</version>-->
    </dependency>
    <!--热部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
</dependencies>
YML配置信息
server:
  port: 8080
spring:
#  redis配置
  redis:
  #密码
    password: 123456
    # ip
    host: 192.168.0.118
    # 端口
    port: 6379

此上已完成代码测试功能

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值