alibaba-rsocket-broker icon indicating copy to clipboard operation
alibaba-rsocket-broker copied to clipboard

关于服务粘性调用中,是否可以实现服务p2p通信

Open pc859107393 opened this issue 4 years ago • 16 comments

前面我已经实现了在这个项目上面的服务粘性调用,以及粘性调用的负载均衡。在一段特殊标记的数据范围内,实现服务粘性调用,当数据标记发生变化后,会发生链路的重新路由。那么再这种场景下面我们是否可以实现服务之间的p2p通信呢?

我的项目git地址是:https://gitee.com/pc_859107393/alibaba-rsocket-broker.git ,主要分支是:dev_base_cheng

pc859107393 avatar Jan 16 '21 07:01 pc859107393

我现在有个思路。在粘性调用第一步的时候,我们RSocketBrokerResponderHandler将请求的链路信息发通知给请求者,请求者在一旦检查到有对应连路调用信息后,就立即创建链接到具体的目标微服务,如果链接不上,则继续走broker转发,否则链接成功后,后续相同标记的固定链路调用则直接p2p通信。

pc859107393 avatar Jan 16 '21 08:01 pc859107393

这样的话,在一些海量数据的透传场景是不是整体处理更加有效。

pc859107393 avatar Jan 16 '21 08:01 pc859107393

服务粘性调这个确实比较麻烦。 目前还有一个特性,就是broker将一个服务的对应的服务器列表发送给客户端,客户端在构建服务时,随机指定某一server id,目前GSVRoutingMetadata的endpoint是支持id路由的,只需将endpoint的值设置为id:1134 这样,这样服务就是始终与某一provider通讯。 如果服务列表发生变化,客户端只需要重新指定一下 id 即可。 在broker中维护这一特性有些复杂,同时也会造成broker的复杂性,使用这样特性的应用并不多,可以考虑在客户端实现,可以创建另外一个 rsocket-sticky-session.jar ,来实现这一功能。

另外broker端,即便根据ID找不到service provider,同样可以选择其他的一个service provider,不会影响服务调用,只是路由到其他service provider啦。

linux-china avatar Jan 20 '21 23:01 linux-china

快到年关了,传统的中国节日即将到来,提前祝您节日快乐。^~^/ 根据我对代码的回溯,我这边相对还是觉得在broker提供一个固定链路的检查,然后在RSocketBrokerResponderHandler中提供第一次调用的消息通知,然后客户端接受到这个endpoint相关的信息,直接发起rsocket链接直达这个底层服务,感觉相对效果比较好,能够提供动态的路由规划,同时能够更加友好的提供服务上下线。另外,我司的场景中,可能更加需要的是相对分布式去中心化,在我的规划中,后期可能会考虑在一些场景中加入客户端路由功能,这就涉及到服务信息传递相关的东西。目前现阶段我还是需要快速解决服务p2p问题,在有限网络资源下,服务p2p更好,同时更加利于服务的按区划分。还有很多东西,目前我这边关于微服务开发的核心人员较少,本项目我这边的分支目前是我一个人在维护,整体思路我还在不断地整理。希望我们这个项目能够走得更加长远,目前这个项目我这边的分支已经应用于我司的线上产品,现阶段维护难度还是比较大,而且后期我司项目更会涉及到跨云(目前已经跨区),希望能够多多交流。

pc859107393 avatar Jan 27 '21 14:01 pc859107393

我review了一下sticky服务的实现,目前是绑定的,也就是tag中包括sticky的标识,也就是sticky=1,在broker端第一次会查找并绑定一个对应的provider。 如果客户端想绑定多个接口,可以考虑使用客户端IP或UUID作为随机数,然后在broker,从provider列表中根据一定的算法找一个,如取余操作,一致性hash算法等,这样可以保证一定程度上连接到某一服务器。

一致性hash算法之前写过一个: https://gist.github.com/linux-china/7817485, 这影响面是最小的。

现在的sticky实现也是随机的,只是不能动态,一旦绑定,除非服务提供方下线,不然就不解绑,这样的好处是不受扩容影响,但是坏处是扩容后,不能动态调整。

linux-china avatar Jan 27 '21 20:01 linux-china

我review了一下sticky服务的实现,目前是绑定的,也就是tag中包括sticky的标识,也就是sticky=1,在broker端第一次会查找并绑定一个对应的provider。 如果客户端想绑定多个接口,可以考虑使用客户端IP或UUID作为随机数,然后在broker,从provider列表中根据一定的算法找一个,如取余操作,一致性hash算法等,这样可以保证一定程度上连接到某一服务器。

一致性hash算法之前写过一个: https://gist.github.com/linux-china/7817485, 这影响面是最小的。

现在的sticky实现也是随机的,只是不能动态,一旦绑定,除非服务提供方下线,不然就不解绑,这样的好处是不受扩容影响,但是坏处是扩容后,不能动态调整。

我这边目前是定义了一个枚举表明是否为粘性调用,然后我增加了一个seq变量,加入了请求唯一标志,这个标志用来在broker决定具体转发到什么服务。

pc859107393 avatar Jan 28 '21 17:01 pc859107393

关于粘性服务调用的一点建议。

从终端上来的数据有时会被分拆成数份进行传输,如希望能够实现对这一批数据定向的进行服务调用,是否可以考虑在Broker中增加根据某一特定的标识进行路由的缓存,后续相同标识的请求将直接调用缓存中的服务接口;并提供清除当前标识缓存的标识,在这批数据结束时得以清除路由的缓存。

对比现有使用sticky标识来标识的方案,此来可以实现数据和操作的一致性,同时又有一定的负载能力,而且数据的负载不会被绑定到某一个应用上,而是比接口层面更细粒度的控制。

这也可以很好的满足@pc859107393 需求的场景,只要让缓存的标识和当前应用相关,与具体的业务数据无关即可,但此并非用于解决性能的瓶颈问题。同时可以添加关于时间的控制,在读写空闲一定时间后自动清除缓存的标识,从而释放服务调用的粘性。

因为同一批的数据一般会存在相同的唯一标识以及类似于“结束帧”的标识,感觉这个方案有一定的可行性。

问题是无法很好的和@RSocketService结合起来,或者是结合@ServiceMapping,增加一个规则匹配,用以解析入参的值。目前我这边正在考虑实现的方案,或者您那边有没有更好的建议,后续有结果了会提交代码,到时候麻烦看看是否合理。

hupeiD avatar Jun 11 '21 03:06 hupeiD

@hupeiD 目前我的设计实现是sticky这个标记保留,增加了一个字符串标记,如果没有字符串的情况下,我这边的粘性调用就是固定链路到被调用服务方下线为止。如果有这个字符串标志,我这边则是用这个字符串标志来绑定某个具体的服务,所有相同字符串标志的,都到同一个被调用服务方。如果超过3秒没有数据过来,我就会在broker清除这个数据标志。 后续我想把所有路由信息都推送到客户端,broker仅仅用于服务注册发现以及服务信息推送,根据场景实现适当的去中心化。

pc859107393 avatar Jun 11 '21 03:06 pc859107393

@hupeiD 最近我这边加入了新公司,比较忙。还在熟悉新的业务中,如果说有什么问题,可以发邮件 [email protected] 。 我这边可以把我的实现详细的复盘一下。 我这边同时也实现了 p2p 调用。 和粘性调用兼容的。 我是基于粘性调用上面推送 服务信息给发起调用方,发起调用方持有了 被调用方后,可以实现p2p通信。

pc859107393 avatar Jun 11 '21 03:06 pc859107393

服务粘性调这个确实比较麻烦。 目前还有一个特性,就是broker将一个服务的对应的服务器列表发送给客户端,客户端在构建服务时,随机指定某一server id,目前GSVRoutingMetadata的endpoint是支持id路由的,只需将endpoint的值设置为id:1134 这样,这样服务就是始终与某一provider通讯。 如果服务列表发生变化,客户端只需要重新指定一下 id 即可。 在broker中维护这一特性有些复杂,同时也会造成broker的复杂性,使用这样特性的应用并不多,可以考虑在客户端实现,可以创建另外一个 rsocket-sticky-session.jar ,来实现这一功能。

另外broker端,即便根据ID找不到service provider,同样可以选择其他的一个service provider,不会影响服务调用,只是路由到其他service provider啦。

如游戏。

tingyanshen avatar Jun 25 '21 05:06 tingyanshen

忘记说明啦, 大家不要认为现在broker不支持sticky session特性啊,现在Broker是支持sticky特性的,这个在broker中实现的,只是一个简单的算法,就是在broker端随机保存一个handler,详细请参考 https://github.com/alibaba/alibaba-rsocket-broker/wiki/RSocket-Routing

如果大家有更好的算法,这里留言一下,阐述一些思路和设计,我们再实现一个更好的算法。 :)

linux-china avatar Jun 25 '21 06:06 linux-china

忘记说明啦, 大家不要认为现在broker不支持sticky session特性啊,现在Broker是支持sticky特性的,这个在broker中实现的,只是一个简单的算法,就是在broker端随机保存一个handler,详细请参考 https://github.com/alibaba/alibaba-rsocket-broker/wiki/RSocket-Routing

如果大家有更好的算法,这里留言一下,阐述一些思路和设计,我们再实现一个更好的算法。 :)

对于使用 p2p 去支持海量数据透传的场景,在rsocket-udp-transport没有给出之前,个人觉得并不需要考虑。另外alibaba-rsocket-broker 给出的 p2p 模式我有不同的看法。

我觉得 p2p 模式本身就超出了 rsocket-broker 的标准,完全可以不在 broker 上实现。 相对应 broker 的模式 rsocket service 是不是应该可以支持 Standalone 的模式,可以让 rsocket 服务不接入 broker 单独服务。

关于这一点就如同 broker 的 config-service 实现一样,broker 没必要做这些事情。

tingyanshen avatar Jun 25 '21 07:06 tingyanshen

点对点通讯,这个RSocket Broker也是支持的, RSocket Broker这个时候就是 服务注册发现的角色, 这个时候客户端可以稍微调整一下代码,如只从服务实例列表中选择一个进行通讯,这个是非常容易做到的。 RSocket Broker P2P的文档这里 https://github.com/alibaba/alibaba-rsocket-broker/wiki/RSocket-P2P

linux-china avatar Jun 25 '21 07:06 linux-china

rsocket结合quic也是个不错的方向。

pc859107393 avatar Jun 25 '21 07:06 pc859107393

rsocket结合quic也是个不错的方向。

Netty QUIC https://github.com/netty/netty-incubator-codec-quic 快差不多啦,接下来就是Reactor Netty对其支持, 这个已经Issue提出啦,我会紧盯一下,有消息马上同步给大家。

linux-china avatar Jun 25 '21 08:06 linux-china

rsocket结合quic也是个不错的方向。

Netty QUIC https://github.com/netty/netty-incubator-codec-quic 快差不多啦,接下来就是Reactor Netty对其支持, 这个已经Issue提出啦,我会紧盯一下,有消息马上同步给大家。

感谢。

pc859107393 avatar Jun 25 '21 08:06 pc859107393