Bright Chen

Results 217 comments of Bright Chen

> 备用Socket这里还有个问题,采用什么连接策略?比如原来是单连接,那么备用Socket也是单连接,还是说退化成一个临时的短连接?如果备用Socket也是单连接,管理起来比较复杂,如果退化成短连接,可能会导致性能下降或给后端带来太大压力? 备用Socket还是通过SelectOut::ptr返回给调用方。调用方将其当做main socket用。连接策略是由调用方使用方式决定即可。在调用方看来,备用Socket应该跟naming service下发的Socket并无区别。应该可以加多一个备用Socket的SocketMap,相同Channel不用LB复用Socket,连接数不会增加很多,不会给后端带来太大压力。 相比之下,SingleSocketPool的方案更好,将Socket管理逻辑收敛到main socket中,LB只需要实现恐慌策略,简化LB的实现逻辑,这样对于用户定义的LB更友好。 > 怎么判断实例是完全不可用呢?比如某一次连接ECONNREFUSED,后面再连有可能就成功了 Failed Socket在健康检查成功之前可以看作是不可用吧。如果是能连成功的话,健康检查成功,就Socket就会恢复了。 SingleSocketPool的方案将屏蔽状态和连接状态区分开来,更清晰了。 > 我在想能不能把SocketPool的逻辑稍微改一下,变成SingleSocketPool: > > GetSocket的逻辑: 如果pool里能找到不是Failed状态的Socket,就返回该Socket,且不从pool中删除 如果找到Failed状态的Socket,就从pool中删除 如果找不到可用的Socket,就新建一个Socket,并加入到Pool中,然后返回该Socket。 > > RPC连接的时候,对于单连接的情况,不再使用main socket进行交互,而是从main socket的SingleSocketPool中获取Socket。 > > 这样就是main socket的Failed状态表示屏蔽状态,和LB的现有逻辑兼容,然后socket pool中的socket的状态表示连接状态。...

> 这个方案的pr啥时候提出了? 目前写了个大概,还需要再完善一下和补充UT。尽量下个版本支持恐慌策略。

看看[持续下载](https://github.com/apache/brpc/blob/master/docs/cn/http_client.md#%E6%8C%81%E7%BB%AD%E4%B8%8B%E8%BD%BD)

object_pool应该没法完全解决 #1449 的问题吧,从object_pool取出来的KeyTable有可能已经有data了,先调用bthread_setspecific函数,旧data还是会泄漏。

https://github.com/apache/brpc/blob/b601c89aec9042a1f509ddbdad478aa4e3f118fe/src/brpc/server.h#L170-L183 https://github.com/apache/brpc/blob/b601c89aec9042a1f509ddbdad478aa4e3f118fe/src/brpc/server.cpp#L888-L914 应该没法废弃bthread_keytable_pool_t ,因为Server已经用了bthread_keytable_pool_t了,并对外提供了与之相关的设置项。 改造bthread_keytable_pool_t,将free_keytables由全局改成TLS,这样mutex就可以废弃了。同时修改reserved_thread_local_data语义:每个TLS上预留的data数量。这样可行吗?

> 我的理解,目前的实现是一个server会绑定一个全局的bthread_keytable_pool_t,在server的声明周期内,server和其生成的bthread使用同一个pool,在server结束时会销毁所有创建的KeyTable,通过bthread_keytable_pool_t内的链表;然后会从全局的KeyInfo中删除所有注册的Key。但是使用全局一个链表会存在锁的竞争问题,不知道理解的对不对。 嗯,我也是这样理解的。不过一般接口实现的瓶颈都是在业务逻辑,所以这个锁的影响应该不大。

> 改造bthread_keytable_pool_t ,其中引入一个类似Object_pool的成员,通过在成员内部使用tls变量来避免加互斥锁。然后对bthread_keytable_pool_t 中的锁的使用从互斥锁改为读写锁,来维护destroyed的值。在return_keytable内使用读锁,bthread_keytable_pool_init,bthread_keytable_pool_destroy时加写锁。这样就可以避免在sever未退出时多个线程return_keytable产生的锁的竞争。 不知道这样是否可行 之前考虑过在bthread_keytable_pool_t中使用ObjectPool,但是ObjectPool好像不能实现reserved_thread_local_data吧? destroyed应该可以用原子变量,就不用锁了吧。

> 如果使用TLS的话,当server结束调用Join时,通过bthread_keytable_pool_destroy方法需要删除所有线程内保存的TLS free_keytables才行,感觉也不是很方便? 用butil::ThreadLocal应该挺方便的吧。 bthread_keytable_pool_init的时候,new一个butil::ThreadLocal。 bthread_keytable_pool_destroy的时候,delete。

> > > 如果使用TLS的话,当server结束调用Join时,通过bthread_keytable_pool_destroy方法需要删除所有线程内保存的TLS free_keytables才行,感觉也不是很方便? > > > > > > 用butil::ThreadLocal应该挺方便的吧。 bthread_keytable_pool_init的时候,new一个butil::ThreadLocal。 bthread_keytable_pool_destroy的时候,delete。 > > 使用butil::ThreadLocal的话,new的object只有当线程结束才会释放,而目前基于bthread_keytable_pool_t的实现是在server Join后即清理释放所有的table,从KeyInfo中移除注册的key信息。如果使用butil::ThreadLocal,可以在delete后,析构所有的keytable吗? butil::ThreadLocal析构时,会delete使用过butil::ThreadLocal的每个线程上的local data。应该可以满足需求吧。

> 我看ResourcePool获取对象的模式是如下图,那么reserve时初始化多个全局的block是否可行。 ResourcePool也是单例哦。 > return_keytable时,加读锁的临界区是判断destroyed + 将对象返回给pool,感觉不能直接使用原子变量 嗯嗯,return_keytable和bthread_keytable_pool_destroy需要互斥,不能用原子变量。 无论是ObjectPool还是ResourcePool的实现方式,即使destroyed=1,也是要将KeyTable返回给ObjectPool或者ResourcePool的吧。