All in One到”分布式“迁移过程中的坑
为什么“分布式”要加引号?
与其他公司提高并发性能的场景可能不太一样,我们的系统之前是多个模块共用一个tomcat来运行的(All in One),模块有很多,光安装包就几十个。当某个模块或某几个模块出问题的时候,整个tomcat就挂了,请求时间长、内存占用高、垃圾回收频繁、错误日志不停的刷....现场工程解决问题的办法是,重启tomcat(小问题重启浏览器,大问题重启tomcat,万能的重启^_^)!!当然,这个对用户的使用体验很差,用户甚至提出要弃用我们公司系统的说法了,领导压力大啊...
因本项目历史久远、技术落后、规模庞大、交接频率高,想系统的发现及解决问题是件很困难的事。重新开发一套系统也是不可能的事(这套系统积累了太多的心血在上面了,无论从人力、时间成本来说都花费太大,下不了狠心)。于是,分布式部署的方案被提上了工作日程,目的是将各模块隔离开来,出问题的时候互不影响。但是,一套不是面向分布式的设计的系统,要想实现分布式部署,就像是将一大团的乱麻分成一团团小的乱麻(哈哈,这比喻我觉得挺恰当的,分开来后还是乱麻^_^),谈何容易啊!
艰巨而又头疼的任务分给了我们组。经过几轮讨论后,列出了几个关键的问题:
1、 静态变量共享问题。单独部署的情况下,各业务注册的数据,如字典数据、关键词类型等,存放在全局的静态变量中的;分布的情况下,各业务只能获取到自己模块注册的数据,获取不到全量的数据。
2、 定时任务重复执行问题。分布式的情况下,会有多个界面框架模块共存。界面框架中的定时任务执行次数和执行频率都会变高。其实从机器中的定时任务是不需要的。
3、 文件上传与读取问题。All in One的情况下,界面框架提供统一的上传组件,文件上传到一个固定目录下,各业务可以通过绝对路径获取到文件,直接操作文件流。分布式的情况下,业务上传的文件会上传至主框架上,当从节点通过绝对路径去访问时,肯定是获取不到文件的。
4、 session共享问题。All in One的情况下,各业务拿到的是同一个session;分布式的情况下,各业务的sessionID不通,session也不是同一个session,一个机器上修改了session的数据,其他机器要实时感知到数据的变化。
5、 请求分发问题。各业务的请求,应该被正确的分发给各业务机器处理,各业务机器处理请求时不需要登录,登录统一由主框架负责处理。
6、 安装时重复刷菜单的问题。All in One的情况下,安装或升级某个包时,会将对应的菜单刷到菜单表中。分布式的情况下,各从机器升级界面框架包时,也会刷界面框架的菜单,很可能导致菜单表的数据出问题。
7、 单例问题。不确定具体的影响范围。
8、 多线程执行顺序问题。不确定具体的影响范围。
9、 事务。不确定具体的影响范围。
10、 各机器对时。不确定具体的影响范围。
大概确定了思路如下:
1、 各模块单独部署在各自的tomcat里,各模块安装需依赖界面框架模块。
2、 通过nginx做代理,保证对用户的入口唯一。按各模块url请求规则,分配到各自的tomcat上处理请求。平台公共的请求由一个tomcat单独处理。
3、 tomcat通过共享session,与nginx呼应,确保用户会话在多个tomcat共享。
4、 引入Spring-session模块,将session存储到redis服务器上。
5、 将静态变量通过redis的发布/通知机制,修改代码,实现静态变量的同步。
6、 增加nginx配置服务,用于管理各业务的请求转发规则,并定义各机器的角色。主节点只能有一台,负责处理公共请求、执行界面定时任务、刷界面框架的菜单;从节点的界面框架负责支撑业务功能。
7、 增加文件服务器,将上传的文件存储到文件服务器上。
8、 其他问题暂不确定具体的影响范围。
未完待续,后面整理迁移过程中遇到的坑!
坑1:Spring session 提交问题
因要对session共享,使用的spring session本以为万事大吉,结果问题来了。看下代码:
UserBean user = (UserBean )session.getAttribute("currentLoginUser"); System.out.println(user.getName());
user.setName("张三");
单机的情况下,没毛病吧,我就想改下session里的用户信息。如果你这么放心的把sesson交给spring,那就等着测试部提问题吧。如果不退出或关闭浏览器的话,你会发现修改的用户信息,你刷新后,竟然没有生效!!!于是就想,spring-session是怎么保证session存储到redis上的呢?不卖关子了,redis通过hash类型存储session中的数据,session内的数据有变化时,会将修改的数据更新到redis上,为了提高效率,spring在filterchain结束的时候提交一次session数据到redis,而不是每次修改session数据都去提交一次。那spring怎么知道session的哪些数据变了呢?跟了下源码发下,只有在主动调用session的setAttribute和removeAttribute方法时,才会将修改的数据放到this.delta中,最后提交数据时,就是把这里的数据更新到redis的。所以为什么修改的user数据没有生效呢?因为没再次调用setAttribute方法,spring感知不到对象属性的变化!!坑爹啊~~自己修改了spring的提交逻辑,与旧的session进行了equals对比,把有变化的数据放入this.delta中,解决问题了?并没有!!最终发现UserBean重写了equals和Hash方法,只要用户ID相同,就返回true,我只想说,你大爷的!!
坑2:与其他系统融合的问题
暂给我们的系统取名A系统,现有个B系统也要用B系统的一些数据,于是取了个名字叫“A与B系统的融合”。所谓A与B的融合,其实就是实现B系统的免登陆,并获取A系统的一些内存数据。于是,两个不同的系统,session就共享了...
于是,当你在使用A系统的时候,很多莫名其妙的反序列的问题就出来了。为什么会报反序列化的错误?因为session里面有B系统的对象,但A系统根本就没有B系统的jar包。实现免登陆,可以走单点登录吧?想获取A系统的数据,可以让A系统提供接口吧?为什么要共享session?我也不知道了。
All in One到”分布式“迁移过程中的坑的更多相关文章
- 转载自lanceyan: 一致性hash和solr千万级数据分布式搜索引擎中的应用
一致性hash和solr千万级数据分布式搜索引擎中的应用 互联网创业中大部分人都是草根创业,这个时候没有强劲的服务器,也没有钱去买很昂贵的海量数据库.在这样严峻的条件下,一批又一批的创业者从创业中获得 ...
- 分布式数据库中的Paxos 算法
分布式数据库中的Paxos 算法 http://baike.baidu.com/link?url=ChmfvtXRZQl7X1VmRU6ypsmZ4b4MbQX1pelw_VenRLnFpq7rMvY ...
- 分布式服务框架 Zookeeper -- 管理分布式环境中的数据
转自:http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/index.html Zookeeper 分布式服务框架是 Apa ...
- ZooKeeper学习第五期--ZooKeeper管理分布式环境中的数据
引言 本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它涉及到了paxos算法.Zab协议.通信协议等相关知识,理解起来比较抽象所以还需要借助一些应用场景,来帮我们 ...
- J2EE分布式事务中的提交、回滚方法调用异常。
这个是昨天上班的时候,写一个后台程序的调试程序时碰到的问题,和项目经理纠结了一天,最后搞定了.于是今天上班正好闲着,花了几乎一天的时间去网上找各种相关的资料.目前了解的内容如此: 根据使用的weblo ...
- 分布式服务框架 Zookeeper -- 管理分布式环境中的数据(转载)
本文转载自:http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/ Zookeeper 分布式服务框架是 Apache Had ...
- 分布式服务框架 Zookeeper -- 管理分布式环境中的数据--转载
原文:http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/ Zookeeper 分布式服务框架是 Apache Hadoop ...
- 在分布式数据库中CAP原理CAP+BASE
本篇博文的内容均来源于网络,本人只是整理,仅供学习! 一.关系型数据库 关系型数据库遵循ACID规则 事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性: 1.A (At ...
- SQLServer2PostgreSQL迁移过程中的几个问题
1.PostgreSQL 跨平台迁移工具Migration Toolkit的使用指南:http://www.enterprisedb.com/docs/en/8.4/mtkguide/Table%20 ...
随机推荐
- 使用postgresql作为cm的数据库时候添加报错
如下图,当postgresql安装成功,建立好数据库scm,rman,amon之后,添加cm对应服务报错hadoopNode2没有相应数据库: No database server found run ...
- LinqToExcel使用简介一
最近才看到原来也可以用Linq来访问Excel,功能还挺强大的.要使用这个功能,首先得下载一个LinqToExcel的相关文件,然后就可以调用相关的方法. 使用前面介 ...
- Java Algorithm Problems
Java Algorithm Problems 程序员的一天 从开始这个Github已经有将近两年时间, 很高兴这个repo可以帮到有需要的人. 我一直认为, 知识本身是无价的, 因此每逢闲暇, 我就 ...
- 对工具的反思 & deadlines与致歉
人和动物最大的区别就是使用工具的水平. 有些人只凭着对工具的熟练掌握便成了牛人. 工具,到底应该以何种态度去看待? 在我小的时候,工具仅仅是指树枝.线.粉笔,可以让自己有更多游戏可玩:上学之后,便又有 ...
- Ubuntu下使用Git_4
在这个第四个文章中,我将练习GIT的高级阶段了,由于高级阶段的内容转的比较多,我自己的代码除了我自己可以看懂意外,大家可能看不懂,所以我将会按照 http://git.wiki.navisec.it/ ...
- python 基础篇 11 函数进阶----装饰器
11. 前⽅⾼能-装饰器初识本节主要内容:1. 函数名的运⽤, 第⼀类对象2. 闭包3. 装饰器初识 一:函数名的运用: 函数名是一个变量,但他是一个特殊变量,加上括号可以执行函数. ⼆. 闭包什么是 ...
- su: Authentication failure
su: Authentication failure问题解决: su 命令切换失败,提示su: Authentication failure,只要你sudo passwd root过一次之后,下次再s ...
- POI 导入 一直报400问题
排查过程:1.400一般都是参数或者请求不对,但是我这个情况是本地好用,只是服务器有问题,所以排除了传值的格式等问题. 2.服务器和本地网络隔离,所以没办法比较代码,分两次全量覆盖了html和js部分 ...
- TCP的挥手协议和握手协议2
三次握手协议:三次握手协议的主要过程是交互彼此之间的初始序列号,如果没有确认的ACK帧可以么?肯定是可以的 client A -------> server B client A 发送了自己的初 ...
- 日期时间选择器datetimepicker.js
在做项目中,往往会遇到需要用户输入2014-07-19 09:55:53这样的格式的数据.就是典型的年月日时分秒这样的格式.这个时候,使用datetimepicker会比较简单. DateTimePi ...