本系统由客户端与若干服务端组成,应实现客户端发送数据至指定服务端,且该指定服务端将数据同步到所有服务端,在实现过程中应达到一下要求:
- 各服务端数据保持一致。
- 各服务端的建立与关闭不影响整个系统的运行。
服务端可分为_开启服务_、接收数据(来自客户端)和_同步数据_(同步所有服务端)三个模块:
开启服务是服务器运行的第一步,主要开启接收数据服务和开启同步数据服务,需要服务端双方协作。步骤如下:
- 与指定服务端建立TCP连接。假设服务端A想连接服务器B,只需要知道B的地址和端口号就能建立TCP连接。
- B记录A的地址和端口号到TCP连接表(格式见下文)。
- A提供本地数据库中records最大的id给B(含义见下文)。
- B根据A传来的id查询大于id的记录,并传送给A。
- A接收到B传来的records(可能有多条)后,更新本地数据records,这样在初始状态A的数据就与B同步了。
- B将自己的TCP连接表传递给A。
- A根据建立的接收到的TCP连接表建立自己的TCP连接表(只需将目的地址和端口号为A换成B就行了)。
- A分别根据TCP连接表建立除与B的TCP连接。
- A开启接收数据监听端口。
- A开启同步数据监听端口。
接收来自客户端的数据,采用HTTP协议
- 数据格式。 服务端接收如下HTTP.POST请求数据格式
{
"from" : string,
"to" : string,
"value": float
}
- 数据存储。在key-value数据库存储数据格式为
{
"records": [{
"id" : int , //-- 数据自增id,从0开始
"data" : { //-- 实际的数据
"from" : string,
"to" : string,
"value": float
}
}]
}
指各服务端之间TCP连接表、数据库records数据保持一致
1)TCP连接表格式
{
"addr" : string, //-- 目的IP地址
"port" : string //-- 目的端口号
}
TCP连接表保存在内存中,在Go中还要记录TCP的连接
type TCPConnList struct{
conn *TCPConn
addr string
port string
}
2)同步数据步骤
- 按照(2)接收数据。
- 向以建立的TCP连接服务端发送接收到的数据,记录未连接成功的服务端(认为该服务端已断开连接)。
- 已接收到来自TCP的数据的服务端开始同步到本地数据库中。
- 释放并删除已断开的TCP连接,并将这些断开的地址和端口号发送至其他服务端。
- 其他服务端释放并删除的TCP连接。
客户端按照上述格式发送数据到服务端即可