Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

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

Open
pc859107393 opened this issue Jan 16, 2021 · 16 comments
Open

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

pc859107393 opened this issue Jan 16, 2021 · 16 comments

Comments

@pc859107393
Copy link

pc859107393 commented Jan 16, 2021

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

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

@pc859107393
Copy link
Author

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

@pc859107393
Copy link
Author

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

@linux-china
Copy link
Collaborator

linux-china commented Jan 20, 2021

服务粘性调这个确实比较麻烦。 目前还有一个特性,就是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啦。

@pc859107393
Copy link
Author

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

@linux-china
Copy link
Collaborator

linux-china commented Jan 27, 2021

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

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

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

@pc859107393
Copy link
Author

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

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

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

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

@hupeiD
Copy link

hupeiD commented Jun 11, 2021

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

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

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

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

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

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

@pc859107393
Copy link
Author

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

@pc859107393
Copy link
Author

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

@tingyanshen
Copy link

服务粘性调这个确实比较麻烦。 目前还有一个特性,就是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
Copy link
Collaborator

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

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

@tingyanshen
Copy link

tingyanshen commented Jun 25, 2021

忘记说明啦, 大家不要认为现在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 没必要做这些事情。

@linux-china
Copy link
Collaborator

linux-china commented Jun 25, 2021

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

@pc859107393
Copy link
Author

pc859107393 commented Jun 25, 2021 via email

@linux-china
Copy link
Collaborator

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

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

@pc859107393
Copy link
Author

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

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

感谢。

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants