最近在研究分布式系统,将部分服务拆分出去,只会python,所以用python的zerorpc写服务
整个都是从pysnowflake里面复制出来的,pysnowflake可以启动一个http服务,我以前一直都用这个服务的。这里只是将http服务变成rpc服务
import time
from loguru import logger
EPOCH_TIMESTAMP = 550281600000
class Generator(object):
def __init__(self):
self.dc = 1
self.worker = 1
self.node_id = ((self.dc & 0x03) << 8) | (self.worker & 0xff)
self.last_timestamp = EPOCH_TIMESTAMP
self.sequence = 0
self.sequence_overload = 0
self.errors = 0
self.generated_ids = 0
def get_next_id(self) -> int:
curr_time = int(time.time() * 1000)
if curr_time < self.last_timestamp:
# stop handling requests til we've caught back up
self.errors += 1
raise EnvironmentError("服务器时间不对,当前时间低于最后一次请求时间")
if curr_time > self.last_timestamp:
self.sequence = 0
self.last_timestamp = curr_time
self.sequence += 1
if self.sequence > 4095:
# the sequence is overload, just wait to next sequence
logger.warning('The sequence has been overload')
self.sequence_overload += 1
time.sleep(0.001)
return self.get_next_id()
generated_id = ((curr_time - EPOCH_TIMESTAMP) << 22) | (self.node_id << 12) | self.sequence
self.generated_ids += 1
return generated_id
@property
def stats(self):
return {
'dc': self.dc,
'worker': self.worker,
'timestamp': int(time.time() * 1000), # current timestamp for this worker
'last_timestamp': self.last_timestamp, # the last timestamp that generated ID on
'sequence': self.sequence, # the sequence number for last timestamp
'sequence_overload': self.sequence_overload, # the number of times that the sequence is overflow
'errors': self.errors, # the number of times that clock went backward
}
import zerorpc
from loguru import logger
from 雪花算法服务.算法 import Generator
class HandleModel():
generator = Generator()
def getID(self):
logger.info("收到一次RPC请求,返回id")
return str(self.generator.get_next_id())
def get_status(self):
logger.info("收到一次RPC请求,服务状态")
return self.generator.stats
if __name__ == '__main__':
logger.info("准备开启rpc服务")
s = zerorpc.Server(HandleModel())
s.bind(["tcp://0.0.0.0:2441","tcp://0.0.0.0:2442"])
logger.info(f"开启服务,端口是{2441}")
s.run()
结束