一点心得

SQLServer同步与Tomcat集群问题

现在是2010年2月26日凌晨4:43:04,刚从市政府升级回来,在机房站了一晚上,屁股蛋子都站疼了。很累,不写长篇大论了——也写不了——把今晚遇到的问题和解决心得记录下来,以备日后自己和他人参考。

今晚主要捣鼓的是SQLServer 2005的数据同步一个局域网内多个apache组成的tomcat集群问题。

SQLServer 的数据库同步不知配过多少次了,经常碰到配好订阅服务器的订阅后一直在等待跟发布服务器同步但一直无法同步的情况,今晚终于找到病根彻底解决。一直等待时在同步监视器里看到的提示是“快照尚未准备好”或“无法找到快照”甚至是一些其他乱七八糟的事务或服务未启动之类,以前碰到这种情况不论三七二十一一律删掉重新部署,结果经常要重试好几次才会成功,出现“正在同步表XXXXX”(注意,只有看到类似这样的提示才是同步成功了)。今天才发现问题不是出在配置订阅服务上,而是“快照尚未准备好”!也就是说,分发服务器还没准备好要分发的资料,你订阅的就过来排队来拿了,那能拿到吗?

所以这个时候就不要只看同步的监视了,要看一下快照的生成,如果碰到一直在等待快照迟迟无法同步数据的情况,那十有八九是发布服务器的快照生成出现问题了。

今晚解决的另外一个问题就是一个局域网内运行多套(注意不是多个)tomcat集群时的session复制问题。事情的起因是原来有一套apache带着的两个tomcat服务,session是共享的,准备另外再布一套同样的独立的备用的apache带两个tomcat服务时,发现这四个tomcat之间的session是共享的!

………………

太困了,直接写问题是如何解决的吧,在配置好session复制的tomcat配置文件server.xml里,有这么一处地方让人怀疑:

...

<Membership
                className="org.apache.catalina.cluster.mcast.McastService"
                mcastAddr="228.0.0.4"
                mcastPort="45564"
                mcastFrequency="500"
                mcastDropTime="3000"/>
...

看见没,问题就是出在这个mcastAddr上了。今晚特地咨询了联通搞网络的工程师,这个mcastAddr是一个组播地址,只要配了同样地址的tomcat,他们之间的信息,就是共享的。

人家解释的很专业,224.0.0.0-239.255.255.255是公网还是什么私网地址,后面一大通我已经听不进去了,因为对我来说,问题解决就这么简单:把新布的两个tomcat组播地址由228.0.0.4改成其他任意一个地址如228.0.0.8(当然要在上面说的范围之内),问题就解决了!

对于这种问题,我公司的网络工程师还提出了另一种解决方案:将另两台服务器在交换机上单独做一个Vlan,这样组播时也不会影响。这个创意是我想出来的(本意是想通过改子网掩码的方式使这四台机器不在一个子网),实现方法是他们提供的,这种方法很笨,是不到最后万不得已的杀手锏,哈哈。

唉,越活年纪越大,反而文笔越来越差了,还不如年轻时写的流畅。摇摇头,睡觉了

好的,我会按照您要求的格式和流程进行回答,并提供详尽的解决方案、代码及解释。同时会在最后提出相关问题。 --- ### 问题:如何实现一个线程安全的单例模式? #### 回答问题 在多线程环境中,确保单例模式的安全性是一个常见的需求。以下是一个使用 Python 实现的线程安全的单例模式示例: ```python import threading class Singleton: _instance_lock = threading.Lock() # 创建一个锁对象,用于线程同步 _instance = None # 类属性,存储唯一的实例 def __new__(cls, *args, **kwargs): if not cls._instance: # 如果实例尚未创建 with cls._instance_lock: # 加锁,防止多个线程同时进入 if not cls._instance: # 再次检查,确保只有一个线程创建实例 cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs) return cls._instance def __init__(self): self.value = "Singleton Instance" # 测试代码 def test_singleton(): singleton = Singleton() print(f"Thread {threading.current_thread().name} got instance: {singleton}") threads = [] for i in range(5): t = threading.Thread(target=test_singleton, name=f"Thread-{i}") threads.append(t) t.start() for t in threads: t.join() ``` --- #### 给出解释 1. **`__new__` 方法**: - `__new__` 是 Python 中的一个特殊方法,负责创建类的实例。 - 在单例模式中,我们重写 `__new__` 方法,确保每次调用时返回的是同一个实例。 2. **线程安全性**: - 使用了 `threading.Lock()` 来保证多线程环境下的安全性。 - 在创建实例时,先检查 `_instance` 是否为 `None`,然后加锁,避免多个线程同时进入创建逻辑。 - 解锁后再次检查 `_instance` 是否为 `None`(双重检查锁定),以确保只有一个线程成功创建实例。 3. **测试代码**: - 创建了多个线程来测试单例模式是否在线程间共享同一个实例。 - 每个线程打印其获取的实例对象地址,验证所有线程共享的是同一个实例。 --- #### 心得体会 1. **单例模式的重要性**: - 单例模式适用于需要全局唯一实例的场景,例如配置管理器、日志记录器等。 - 它可以节省资源,避免重复创建对象。 2. **线程安全的挑战**: - 在多线程环境下,如果不加锁,可能会导致多个线程同时创建实例,破坏单例模式。 - 使用锁虽然能解决问题,但可能带来性能开销,因此需要权衡。 3. **双重检查锁定的意义**: - 第一次检查避免不必要的加锁操作,提高性能。 - 第二次检查确保在加锁后没有其他线程已经创建了实例。 4. **Python 的 GIL(全局解释器锁)**: - 虽然 Python 的 GIL 限制了多线程的并行执行,但在涉及 I/O 或外部资源的操作中,线程安全仍然非常重要。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值