keijack / python-eureka-client

A eureka client written in python. Support registering your python component to Eureka Server, as well as calling remote services by pulling the the Eureka registry.
MIT License
184 stars 43 forks source link

Application更新Instance的时候发生死锁 #8

Closed sunxiang0918 closed 5 years ago

sunxiang0918 commented 5 years ago

你好,我在使用eureka-client过程中发现在 一个其他的应用注册到eureka后,触发delta 更新实例的时候,会发生死锁的情况.

分析了一下您的代码, 原因在于:

__fetch_delta()方法获取eureka的增量更新的时候,如果delta有变化,就会执行__merge_delta 操作. 在 合并delta操作的过程中,会判断是否需要更新应用的实例: existingApp.update_instance(instance)

这个方法进入后,会加一个锁: with self.__inst_lock. 然后,这个方法的结尾,如果判断这个实例不是更新而是新增的话,就会调用self.add_instance(instance) 这个方法. 而Application#add_instance(instance)这个方法一进去也会对self.__inst_lock加锁操作. 这就导致了 self.__inst_lock这个锁的重复acquire.从而导致死锁.

不知道我表达清楚没有...

我想,这里的self.__inst_lock 是否需要 修改成 RLock,即重入锁,从而避免死锁呢? 谢谢!!

wx20190226-115419

keijack commented 5 years ago

Thanks for submitting, I will handle it soon.

sunxiang0918 commented 5 years ago

非常感谢.

BTW, 我还发现了一个在Python3下面的问题.不知道是不是我没用对.

方法 def walk_nodes(self, app_name="", service="", prefer_ip=False, prefer_https=False, walker=None)的最后一行 抛出一个 raise urllib2.HTTPError("Try all up instances in registry, but all fail")的 异常.

因为你使用了urllib2别名 在python3中 urllib2.HTTPError, 其实际是 urllib.error. HTTPError. 而这个类的构造函数要求有5个参数.
因此, 运行到这是会抛异常的 TypeError: __init__() missing 4 required positional arguments: 'code', 'msg', 'hdrs', and 'fp'

image image image
keijack commented 5 years ago

All fixed, thanks for submitting!