Java Web分布式篇之常见问题(ID/幂等性/Session/锁)探讨及解决方案

Java Web系列文章汇总贴: Java Web知识总结汇总


分布式ID

常见的分布式ID的设计方案:

  • 1、数据库自增长序列或字段(缺点:可能有单点故障或性能问题)
  • 2、UUID(缺点:无法保证递增,传输量大,存储空间大,查询效率低)
  • 3、UUID->INT64,添加时间戳,保证有序
  • 4、Redis生成,可以用Redis的原子操作 INCR和INCRBY来实现
  • 5、Twitter的snowflake算法
    snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。
  • 6、ZooKeeper生成
    ZooKeeper主要通过其znode数据版本来生成序列号,可以生成32位和64位的数据版本号,客户端可以使用这个版本号来作为唯一的序列号。
    很少会使用zookeeper来生成唯一ID。主要是由于需要依赖zookeeper,并且是多步调用API,如果在竞争较大的情况下,需要考虑使用分布式锁。因此,性能在高并发的分布式环境下,也不甚理想。

更多:
分布式系统唯一ID生成方案汇总


幂等性

基本概念

就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。如多次点击不能重复扣款等。

解决方案

  • 1、每个请求必须有一个唯一的标识。
  • 2、处理完这个请求之后,必须有一个记录标识这个请求处理过了,可存入数据库。
  • 3、每次请求需要判断之前是否处理过。如上述存入数据库的记录id,有唯一键约束,再次插入处理的话,会报错。
  • 4、上述操作只是举例说明,需要结合自己的业务处理,比如订单支付场景,Redis中存储order,用order_id作为唯一键,只有成功插入这个支付流水,才可以实际扣款;状态检查,在实际处理前,先检查订单的状态,没有处理过才进行处理,处理过直接返回状态。

更多:
深入理解幂等性


分布式缓存

  • 1、页面缓存、浏览器缓存
  • 2、网络缓存(Web代理缓存、CDN)
  • 3、服务端缓存(数据库缓存如MySQL、应用级缓存如Redis)
  • 4、多级缓存架构:Nginx本地缓存解决热点数据缓存问题;Redis分布式缓存减少访问回源率;Tomcat缓存防止缓存失效/崩溃之后的冲击;数据库换成提高查询效率

更多:
《深入分布式缓存:从原理到实践》学习笔记(1)
《深入分布式缓存:从原理到实践》学习笔记(2)


分布式锁

三种实现方式:

  • 1、zoopkeeper – 临时节点特性
  • 2、redis – setnx特性
  • 3、数据库实现 – 唯一性约束、排它锁for update

详细:
分布式锁的几种使用方式(redis、zookeeper、数据库)


分布式Session

Cookie与Session

Cookie

是什么

当一个用户通过HTTP协议访问一个服务器的时候,服务器会将一些key/value键值对(Cookie)返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时,这个用户下次访问这个服务器的时候,数据又被完整地带回给服务器。

为什么

为了记录用户在一段时间内访问Web的行为路径。由于HTTP协议是无状态的协议,服务器无法知道下一次来访问的还是不是上次访问的用户,这样就无法针对特定用户的数据做缓存处理以提高性能。Cookie的作用正在于此,每次同一客户端发出的请求都会带有第一次访问时服务端设置的信息(一般放在HTTP Header信息中),这样服务端就可以根据Cookie值来划分访问的用户了。

好不好

优点:

  • 使用简单,轻松解决分布式问题

缺点:

  • 1、存储限制,存储在浏览器中,大小和数量受限(Cookie个数的限制都是50个。总大小不超过4KB)
  • 2、Cookie管理的混乱,每个应用都有自己的Cookie
  • 3、安全问题,在浏览器中存储很容易被窃取或篡改

Session

是什么

前面介绍了Cookie可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie,如果Cookie很多,这无形地增加了客户端与服务端的数据传输量,而Session的出现正是为了解决这个问题。

同一个客户端每次和服务端交互时,不需要每次都传回所有的Cookie值,而是只要传回一个ID,这个ID是客户端第一次访问服务器的时候生成的,而且每个客户端是唯一的。这样每个客户端就有了一个唯一的ID,客户端只要传回这个ID就行了,这个ID通常是NANE为JSESIONID的一个Cookie。

好不好

优点:安全,重复提交表单等场景也可以通过生成token来校验合法性
缺点:不容易在多台服务器之间共享。

总结

Cookie和Session都是为了保持用户访问的连续状态,之所以要保持这种状态,一方面是为了方便业务实现,另一方面就是简化服务端程序设计,提高访问性能,但是这也带来了另外一些挑战,如安全问题、应用的分布式部署带来的Session的同步问题及跨域名Session的同步等一系列问题,而这些问题可以通过分布式Session框架来解决。

分布式Session怎么做

分布式Session解决问题

既然Cookie有以上这些问题,Session也有它的好处,为何不结合使用Session和Cookie呢?下面是分布式Session框架可以解决的问题:
◎ Session配置的统一管理。
◎ Cookie使用的监控和统一规范管理。
◎ Session存储的多元化。
◎ Session配置的动态修改。
◎ Session加密key的定期修改。
◎ 充分的容灾机制,保持框架的使用稳定性。
◎ Session各种存储的监控和报警支持。
◎ Session框架的可扩展性,兼容更多的session机制如wapSession。
◎ 跨域名Session与Cookie如何共享,现在同一个网站可能存在多个域名,如何将Session和Cookie在不同的域名之间共享是一个具有挑战性的问题。

分布式Session如何构建

  • 1、使用ZooKeeper等高可用的一致性协调组件来存储Cookie,统一管理Cookie,订阅推送公用Cookie。
  • 2、采用分布式缓存系统,如Memcache或Tair等来存储session,分布式Session架构图:

猜你喜欢

转载自blog.csdn.net/zangdaiyang1991/article/details/92104447