wamp協議實現rpc調用

組成:

python爲例 server端


import datetime

from twisted.internet.defer import inlineCallbacks

from autobahn.twisted.wamp import ApplicationSession,ApplicationRunner
# from autobahn_autoreconnect import ApplicationRunner

class Component(ApplicationSession):
    """
    A simple time service application component.
    """

    @inlineCallbacks
    def onJoin(self, details):
        print("session attached")

        def utcnow():
            now = datetime.datetime.utcnow()
            return now.strftime("%Y-%m-%dT%H:%M:%SZ")

        try:
            yield self.register(utcnow, u'com.timeservice.now')
        except Exception as e:
            print("failed to register procedure: {}".format(e))
        else:
            print("procedure registered")


if __name__ == '__main__':
    runner = ApplicationRunner(u"ws://xxx.xxx.com:31000/ws", u"pwd")
    runner.run(Component, auto_reconnect=True)

客戶端

from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks

from autobahn.twisted.wamp import ApplicationSession, ApplicationRunner


class Component(ApplicationSession):
    """
    An application component using the time service.
    """

    @inlineCallbacks
    def onJoin(self, details):
        print("session attached")
        try:
            now = yield self.call(u'com.timeservice.now')
        except Exception as e:
            print("Error: {}".format(e))
        else:
            print("Current time from time service: {}".format(now))

        self.leave()

    def onDisconnect(self):
        print("disconnected")
        reactor.stop()


if __name__ == '__main__':
    runner = ApplicationRunner(u"ws://xxx.xxx.com:31000/ws", u"pwd")
    runner.run(Component, auto_reconnect=True)

經過一段時間的測試發現turnpike路由存在一個問題:
當server意外斷網後(拔網線這種), turnpike不會發現這個server已掉線, 重啓server註冊時提示函數已經存在, 必須重啓turnpike
現改用https://github.com/gammazero/nexus


後測試發現nexus也有這個問題,測試方法,但拔掉客戶端的網線再插上,報提示"REGISTER for already registered procedure"
目前通過修改nexus的代碼解決,使得收到註冊消息時永遠是替換方式
dealer.go:register函數

var created string
	var regID wamp.ID
	// If no existing registration found for the procedure, then create a new
	// registration.
	if reg == nil {  //改成 if true {
		regID = d.idGen.Next()
		created = wamp.NowISO8601()
		reg = &registration{

dealer.go delCalleeReg函數

	if len(reg.callees) == 0 {
		delete(d.registrations, regID)
		switch reg.match {
		default:
			if d.procRegMap[reg.procedure] != nil && d.procRegMap[reg.procedure].id ==  regID {
				delete(d.procRegMap, reg.procedure)
			}

2018.12.10
使用未按上面修改過的最新的nexus,加上autobahn js或python版可以實現rpc callee的負載均衡

    session.register('com.myapp.add2', add2, {
        'invoke': "random"  //負載方式 "single", "roundrobin", "random", "first", "last"
    });
python
yield self.register(utcnow, u'com.timeservice.now1', RegisterOptions(invoke=u'random'))

當時使用最新的autobahn python版客戶端會提示註冊失敗。

性能測試

單核本機caller +本機callee 每秒大約可以到2500個rpc請求 cpu跑滿

異常問題

啓動兩個callee,然後caller循環調用rpc,這時kill掉其中一個callee,有機率caller的call函數不再返回卡死,估計是nexus的bug
用crossbar.io做router就不存在這個問題,而且crossbar.io貌似支持集羣,可以規避router的單點故障,但crossbar.io的單核性能不如nexus

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章