[分布式会话]zuul通过Ribbon配置负载均衡策略实现粘性会话(sticky session)
2018-12-18 22:31
1351 查看
分布式Session处理方式
分布式Session一般分为以下几种处理方式:
- 黏性会话(sticky session):通过使每个用户每访问的服务端实例为同一个来确保session的正常使用
- 会话拷贝(session replication):通过各个服务端实例之间的session复制,来确保每个服务端实例均具有session中的信息,以达到session的一致性
- 会话第三方管理:通过redis等第三方的工具来存储session信息,使所有服务器实例均能访问到相同的session
黏性Session
实现粘性会话的方式主要在于确保每个用户在通过Session有效期内,访问的服务器实例为同一台,以此来保证Session信息保持
在分布式系统中,通常所有用户都会通过统一的入口(即网关Gateway)来访问系统,因此我们只需要在网关处确保用户请求的转发目的地是同一个就可以完成。而这通过实现负载均衡的策略来实现。
在使用SpringCloud进行开发的过程中,如果使用的网关服务zuul使用Ribbon实现负载均衡,则可以使用如下的方式实现一个策略来保证:
/** * 对访问者地址进行hash计算,使同一访问者访问同一实例 * 参考自 * @see com.netflix.loadbalancer.RoundRobinRule * @author YWS * @data 2018/11/08 */ public class StickyLoadBalancerRule extends AbstractLoadBalancerRule { private static final Logger logger = LoggerFactory.getLogger(StickyLoadBalancerRule.class); public StickyLoadBalancerRule() {} public StickyLoadBalancerRule(ILoadBalancer lb) { this(); this.setLoadBalancer(lb); } @Override public void initWithNiwsConfig(IClientConfig iClientConfig) {} @Override public Server choose(Object key) { return this.choose(this.getLoadBalancer(), key); } public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { logger.warn("no load balancer"); return null; } else { Server server = null; int count = 0; while (true) { if (server == null && count++ < 10) { List<Server> reachableServers = lb.getReachableServers(); List<Server> allServers = lb.getAllServers(); int upCount = reachableServers.size(); int serverCount = allServers.size(); if (upCount != 0 && serverCount != 0) { int nextServerIndex = this.addrHash(serverCount, count); List<Server> tArr = new ArrayList(allServers); tArr.sort(Comparator.comparing(Server::getHost)); server = tArr.get(nextServerIndex); if (server != null && server.isAlive() && server.isReadyToServe()) { return server; } else { server = null; } continue; } logger.warn("No up servers available from load balancer: {}", lb); return null; } if (count >= 10) { logger.warn("No available alive servers after 10 tries from load balancer: {}", lb); } return server; } } } public int addrHash(int serverCount, int offset) { String remoteAddr = this.getRemoteAddr(); return Math.abs(remoteAddr.hashCode() + offset) % serverCount; } public String getRemoteAddr() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); String forwardedFor = request.getHeader("X-FORWARDED-FOR"); String remoteAddr = StringUtils.isEmpty(forwardedFor) ? request.getRemoteAddr() : forwardedFor; return remoteAddr; } }
扩展文章
[分布式会话]springboot中实现session replication
GitHub
阅读更多相关文章推荐
- Nginx+Tomcat+Redis实现负载均衡与Session共享之三 — Gradle下载配置
- tomcat+nginx+redis实现均衡负载、session共享---让Tomcat把会话Session保存到Redis数据库。
- Ribbon负载均衡策略配置
- Nginx+Tomcat+Memcached 集群Session共享[memcached服务安装、tomcat使用memcache存储session、nginx安装配置实现tomcat负载均衡]
- springCloud(8):Ribbon实现客户端侧负载均衡-自定义Ribbon配置
- Ribbon 负载均衡策略配置
- SpringCloud(第 007 篇)电影微服务,使用定制化 Ribbon 在客户端进行负载均衡,使用 RibbonClient 不同服务不同配置策略
- 详解之:linux下tomcat、nginx的负载均衡及memcached对session共享的实现配置详细总结
- Ribbon负载均衡策略配置
- SpringCloud(第 007 篇)电影微服务,使用定制化 Ribbon 在客户端进行负载均衡,使用 RibbonClient 不同服务不同配置策略
- Nginx 配置轮询分流-实现负载均衡【测试通过】
- 使用 ngx_http_upstream_session_sticky_module 实现基于cookie的负载均衡
- Apache + tomcat实现高并发负载均衡方案(二)----stickysession的集群
- Ribbon负载均衡策略配置
- SpringCloud五:自定义配置Ribbon负载均衡策略
- nginx + tomcat 集群配置详解, 实现负载均衡 URLRewrite Session复制
- 分布式集群实现负载均衡和Session共享~多个Tomcat7+Nginx+Redis的session共享实现
- Ribbon负载均衡策略配置
- 详解之:linux下tomcat、nginx的负载均衡及memcached对session共享的实现配置详细总结
- nginx 配置轮询分流-实现负载均衡【测试通过】