Relay 通用数据转发服务
Relay
是一个简单而高效的基于TCP连接的通用数据转发服务,主要用于将GPS/GNSS终端数据转发到各个平台,也可用于其它有数据转发需求的场合。
免费下载:relay-1.3.0.zip
功能特性
- 支持直接转发和负载均衡两种模式
- 基于TCP,可用于其上的各种通讯协议
- 可根据接入端入站连接的对方IP,选择分发至一个或一组后端
- 支持丢弃某个特定后端发回到接入端的所有数据包
- 支持多外连IP地址和指定端口范围:为转发服务提供更多的端口,转发服务可自行管理端口池
- 环路检测:在整个转发设置中检测潜在的环路
- 数据包缓存:在建立与后端连接之前,将一定数量的数据包缓存起来,待连接建立后再发给后端,减少丢包的情况
- 支持后端连接数限制:可限制连接到某个后端的最大连接数
- 后端平缓连接功能:当有接入端瞬时突发大量连接时,可平缓发起到后端的连接
- 后端链路失效检测:当发现后端链路异常时,限制到此后端的连接,并减少此后端占用的缓存
概念
- 后端:是连接和数据的目的地,通常在远程服务器,也可以是在本机,也可以是本转发服务定义的另一个
接入端
。 - 接入端: 定义一个接入端口,用于接收从其它设备或服务发来的数据,然后再分发到后端。每个
接入端
包含一个或多个规则
。- 启用状态:只有处于启用状态的接入端才能启动。转发服务重启后,将尝试自动启动所有标记为启用的接入端。
- 规则: 是一个入站IP匹配表达式和转发模式定义,其下包含一个或多个
后端连接
。- 入站IP匹配表达式: 当接入端的入站连接的IP匹配该
规则
的IP匹配表达式(CIDR)时,规则被选择,后面的规则被忽略。为空时,匹配所有入站地址。如果接入端
的所有规则都未配置,入站连接将被关闭。 - 转发模式:指定规则匹配后,建立连接和分发数据的方式,分为
直接转发
和负载均衡
两种- 直接转发:将创建到此规则下的所有后端的连接,然后将接入端接收到的每个数据包同时发到这些后端。 后端发回的数据包也转发到接入端,除非后端连接设置了"丢弃此后端发回的所有数据包"
。此模式下,与后端的连接断开时,服务将以一定的时间间隔尝试重连,除非规则下只定义了一个
后端连接
。 如果直接转发规则下只有一个后端连接,则当与后端的连接断开时,服务将关闭对应的接入端连接。 - 负载均衡:将依次选择一个后端,然后建立与它的连接,并将接入端接收到的每个数据包发到此后端。 后端发回的数据包也转发到接入端,除非后端连接设置了"丢弃此后端发回的所有数据包" 。此模式下,与某个后端的连接断开后,服务将关闭对应的接入端连接。
- 直接转发:将创建到此规则下的所有后端的连接,然后将接入端接收到的每个数据包同时发到这些后端。 后端发回的数据包也转发到接入端,除非后端连接设置了"丢弃此后端发回的所有数据包"
。此模式下,与后端的连接断开时,服务将以一定的时间间隔尝试重连,除非规则下只定义了一个
- 入站IP匹配表达式: 当接入端的入站连接的IP匹配该
- 后端连接:定义连接到某哪个
后端
,以及在连接和数据上的处理选项。
业务和规则
端口管理
为了能向外发出更多的连接,需要对操作系统进行调整,并由转发服务来管理系统的一部分端口。详情请参阅:转发服务的设置和Linux系统参数调优
根据设置,转发服务计算出整个端口池。当需要发出连接时,转发服务从端口池中取出端口使用,当连接断开或连接失败时,端口放回到一个回收池。 这些在回收池的端口经过一段时间后,又回到端口池。
如果由于其它程序占用,用取出的端口进行连接时出现端口冲突,转发服务将会将此端口放到回收池,再从端口池中取一个再重试。 当端口池的端口耗尽后,转发服务将自动使用动态端口。
后端连接管理
可选的连接数限制: 如果某个后端的处理能力不足,可以在定义后端时,通过限制到这个后端的连接数来确保后端不会承受过大的压力。接入端新进连接时, 如果所有的后端都已经达到连接数限制,这个新进连接被关闭。这个限制属于后端定义,如果应用了这个限制,所有连接到这个后端的后端连接定义都在这一个限制之下。
最大未完成连接、平缓连接: 每一个后端都有一个未完成连接计数和一个最大未完成连接限制,比如某一个后端的最大未完成连接限制为500, 当接入端出现瞬间大量连入时,转发服务根据规则向后端发起连接,但向这个后端每发起一个连接,增加未完成连接计数,当计数达到500时,就暂停发起连接, 这些连接请求进入一个队列进行排队。当已经发起的500个连接的某个连接完成时(成功或失败),未完成连接计数减1,从队列中取出请求发出,并又对未完成连接计数加1。 直到队列中所有请求都已经发起。这个最大未完成连接限制主要的作用是确保后端不会承受过大的瞬时连接压力,提高连接成功机率。将这个值设置为较大值,如100000, 即相当于禁用这个功能。注意:最大未完成连接限制值过小会增加连接建立的时间,增加数据包被丢弃的机率。参见后文 数据包缓存和丢弃 一节。
后端链路失效检测: 当发现后端链路异常时,此后端连接被钝化,即使接入端有大量的进站连接,转发服务只会向钝化后的后端一次尝试少量的连接,以减少端口的使用。 当检测到此后端的链路恢复时,后端连接也被活化,恢复正常的连接尝试。
数据包缓存和丢弃
由于到后端的连接的建立需要一定的时间,在建立与后端连接之前,需要将一定数量的数据包缓存起来,待连接建立后再发给后端,减少丢包的情况。 连接后端失败重连时也适用这个逻辑。这个功能特性适合于一些接入端一上来就发补传数据,而连接处理较慢的后端情况; 另外后端服务重启时,如果数据包缓存够大,后端服务重启速度够快,也可以减少丢包的情况。
当数据包上来,缓存队列已满或者缓存功能没启用,而连接又尚未建立,此时数据包将被丢弃。 每个后端连接都有一个丢弃数据包连接计数,每丢弃一个数据包,计数加1。
数据包缓存的数量是一个后端连接设置。设为0
时(默认为0
),数据包缓存不一定有很大的作用,设为0时禁用这个缓存功能。
限制的弱约束
后端连接的最大未完成连接数和连接数限制,这两个限制采用的是弱约束,即在实际执行这些限制时,实际的数据会少量超过这些限制值。 如最大未完成连接数限定为1000,实际可能出现未完成连接数1010的情况。采用弱约束主要是为了提高服务的并发性。
统计数据的弱一致性
界面上有多组统计数据,为了提高服务的并发性能,服务在获取这些统计数据时,是顺序采集各项数据,后面采集的数据和前面采集的有勾稽关系的数据可能在勾稽关系上不一致。 如:规则中显示的出站数和接入端显示的出站数不一致,或后端连接的出站数合计与规则中显示的出站数不一致等等。 但这些数据主要反映当前服务运行的状态, 不管服务运行时间多久,它们在采集的某一个瞬间可能一致,也可能不一致,但始终会趋向一致。
应用场景
将设备的数据转发到主服务器,并同时将数据分发到其它服务器
如下图示,服务在7510端口监听。当设备连到此端口后,转发服务将建立到以下地址的3条连接,并转发数据到这些地址:
- 主服务(n11.gratour.info:60001):当与主服务的连接断开(因重启等原因)时,对应的设备连接被关闭。
- 服务二(n11.gratour.info:60002):当与服务二的连接断开,服务将自动重连,重连后,将设备在与7510端口建立连接后的第一个数据包发送给服务二。
- 外部服务(159.75.250.190:17100):数据将转发到此外部服务,但此服务只接收数据,不允许它向设备发送的指令或数据。
将设备的数据均衡转发到服务集群
如下图示,服务在8000端口监听。当设备连到此端口后,转发服务轮次选择后端并建立连接,类似于负载均衡器:
使用说明
基本界面元素
转发分页
顶部工具栏
- 转发 按钮: 切换到
转发
分页 - 设置 按钮:切换到
设置
分页 - 刷新 按钮:重新从服务端加载数据并刷新界面
- 转发 按钮: 切换到
转发设置区,位于分页的中间,由接入端、规则、后端连接三个纵栏构成:
接入端 栏:展现已经定义的
接入端
按钮:点击后弹出新增接入端对话框
每个已经定义的接入端在接入端栏中用一个面板表示:
- 选中时,接入端面板以深色表示
启动/停止状态图标:绿色时,为已经启动状态;灰色时,为停止状态
编辑按钮,用于编辑当前
接入端
。如果当前接入端
处于启动状态时,编辑后保存到接入端的编辑副本,需重启接入端
编辑副本才真正应用。重启后,编辑副本变为运行副本。查看按钮,用于编辑当前
接入端
的详细设置。当前接入端
处于停止状态时,按钮不可见删除按钮,用于删除当前
接入端
。当前接入端
处于启动状态时,按钮不可见启动按钮,用于启动当前
接入端
。当前接入端
处于启动状态时,按钮不可见启动按钮,用于停止当前
接入端
。当前接入端
处于停止状态时,按钮不可见重启按钮,用于重启当前
接入端
。仅当有编辑副本时可见入
标签:当前接入端
的入站连接总数。仅当当前接入端
处于启动状态时有效出
标签:当前接入端
的出站连接总数。仅当当前接入端
处于启动状态时有效重连
标签:当前接入端
已经调度的到后端的重连数。启用
勾选框:当当前接入端
处于启用状态时勾选数率
标签:当前接入端
的过去15分钟平均入站数据率,单位:字节/秒。仅当当前接入端
处于启动状态时有效
规则栏:展现当前选中的
接入端
下定义的规则
按钮:点击后弹出新增规则对话框
在选中的接入端下,每个已定义的规则在规则端栏中用一个面板表示:
- 选中时,接入端面板以深色表示
入
标签:当前规则
的入站连接总数。仅当当前接入端
处于启动状态时有效出
标签:当前规则
的出站连接总数。仅当当前接入端
处于启动状态时有效
后端连接栏:展现当前选中的
规则
下定义的后端连接
按钮:点击后弹出新增后端连接对话框
在选中的规则下,每个已定义的规则在规则端栏中用一个面板表示:
- 选中时,接入端面板以深色表示
连接数
标签:当前后端连接
的连接数。仅当当前接入端
处于启动状态时有效
本机操作日志区
显示客户操作的日志。
设置分页
本地IP地址: 主要控制转发服务在连接
后端
时所采用的本地IP地址。输入时,以;
号分隔各个IP地址。 当输入多个IP时,转发服务在连接后端
时,将依次轮流使用这些IP地址作为本地IP地址。 留空时,连接所使用的本地IP地址由系统确定,转发服务不管理端口。注意:当设置多本地IP地址时,同时需要操作系统上作相应的本地IP地址设置。
本地端口范围: 定义由转发服务管理的端口的范围,可以指定多个分组,每分组格式:{开始端口号},{端口数量}。指定多个分组时,以
;
号分隔。 留空时,连接所使用的本地端口由系统确定,转发服务不管理端口。统计连接完成时间:勾选时会统计所有到后端的连接建立时间。主要用于调试。
后端设置: 为后端定义列表,可通过表格上方的
新增
、编辑
和删除
按钮来对后端定义进行维护。
编辑对话框简要说明
新增后端对话框
主机IP
输入框:输入后端的IP地址或域名端口
输入框:输入后端服务的端口号最大未完成连接
输入框:输入该后端服务可应对的瞬时并发连接数。最小值:50。连接数上限
输入框:输入该后端服务可支持的最大连接数。设为 0 时不限制。
新增接入端对话框
地址
输入框:接入端
监听时采用的绑定地址,留空时监听任意地址端口
输入框:接入端
监听的端口号连入后向终端发送下列数据
输入框:接入端
在接收到入站连接时首先向对方发送的特定数据包。以HEX字符串表示数据,如:` 6364A033'。不区分大小写,不要包含空格、Tab、回车等。主要用于接入一些特殊的设备,应用较少,可选。统计发回到接入端的数率
勾选框:勾选后,服务将统计发回到此接入端的数据率。启用活动保持(keepAlive)
勾选框:勾选后,服务打开接入端口时会启用活动保持。启用
勾选框:只有处于启用状态的接入端才能启动。转发服务重启后,将尝试自动启动所有标记为启用的接入端。
新增规则对话框
入站IP匹配
:可定义多个入站IP匹配。IP匹配表达式(CIDR),由IP地址和掩码位数构成,如192.168.1.180/32
表示完全匹配IP192.168.1.180
,而192.168.1.180/24
则匹配192.168.1.*
子网的所有IP。
主要用于要区分入站IP再决定转发到特定后端的情形。此时会定义两个或多个规则,前面的规则定义相应的入站IP匹配
,最后的规则匹配所有其它IP地址。如两个规则: 规则1匹配192.168.1.0/24
,规则2的入站IP匹配留空,则如果入站的对方IP在192.168.1.*
子网中,走规则1,否则走规则2。模式
单选框:指定规则应用时所使用的模式。
新增后端连接对话框
后端连接断开时,关闭接入端连接
勾选框:当后端连接发生断开时,转发服务将会断开相应的入站连接。后端重连后重发接入端的首个数据包
勾选框:勾选后,转发服务在接入端与设备建立连接后,将会缓存设备发来的第一个TCP帧分片,然后在后端发生断开重连时,服务在后端重连连接建立后首先发送此数据包。 注意:只适用于设备发送的第一个包为少于MTU的情形。最大缓存包数
输入框:输入此后端连接的最大缓存数据包数量。设置为0
时不缓存。丢弃此后端发送到接入端的所有数据包
勾选框:勾选后,后端发回的所有数据包都将被丢弃,而不是发回到接入端。适用于向某些服务推送数据但不允许其向设备下发指令、写入数据的情形。
使用过程
使用之初,需要先在设置页面设置本地IP地址和后端,再在转发页面进行转发设置。
版本和下载
- 2020-05-01:
1.0.0
版发布 - 2023-05-10:
1.1.0
版发布,修改内存泄露问题,增加丢弃数据包统计功能 - 2023-05-27:
1.2.0
版发布,大幅修改,提高性能,采用Java 17,增加平缓连接和链路异常检测功能 - 2023-06-26:
1.3.0
版发布,增加连接限制和连接保持功能
布署
运行环境要求64位Linux或Windows,环境中已经装有Java 11。 以下以Ubuntu为例,说明布署过程。
假设:
- 操作用户名为
yau
- Java目录在
/home/yau/app/jdk
- 转发服务计划安装在
/home/yau/app/relay
- 转发服务的Web页面端口为
8181
- 布署程序的服务器的IP地址为:
191.168.1.180
- 建立程序目录
mkdir ~/app/relay
- 下载、解压程序包
unzip relay-1.3.0.zip -d ~/app/relay
- 将
~/app/relay/application.yml
配置文件中的server.port
属性修改为8181
(Web页面端口号)
server:
port: 8181
logging:
level:
ROOT: INFO
注意:yml格式文件中的缩进使用的是空格,不能用Tab
。
- 修改
~/app/relay/start.sh
文件中的JAVA_HOME
属性为Java的实际目录
#!/bin/bash
export JAVA_HOME=/home/yau/app/jdk
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
java -Djava.net.preferIPv4Stack=true -jar relay-1.3.0.jar
- 给
start.sh
的文件添加可执行属性
chmod +x ~/app/relay/
- 修改
~/app/relay/relay.service
文件中的[Service]WorkingDirectory
和[Service]ExecStart
属性中的目录,使用之符合转发服务实际布署的目录。 修改[Service]User
,使之符合实际执行服务程序的操作系统用户的用户名(下面示例中为yau
):
[Unit]
Description=Relay Service
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
WorkingDirectory=/home/yau/app/relay
Restart=always
RestartSec=5
User=yau
ExecStart=/bin/bash /home/yau/app/relay/start.sh
[Install]
WantedBy=multi-user.target
- 将
~/app/relay/relay.service
文件复制到/etc/systemd/system
目录下,并启用服务
sudo cp ~/app/relay/relay.service /etc/systemd/system
sudo systemctl enable relay
- 启动服务
sudo systemctl start relay
- 打开服务器的防火墙
sudo ufw allow 8181
- 打开页面:用Chrome/Firefox/Edge/Safari等浏览器打开地址:http://192.168.1.180:8181/static/login.html
- 页面打开后,将出现登录页面,默认的用户名和密码均为
admin
- 修改密码。登录后,将出现主界面,在主界面的日志栏,会出现一个修改密码的链接,点击后可修改密码。
配置说明
以下说明 application.yml
文件中的各个属性。
应用属性
属性 | 说明 |
---|---|
relay.connect-timeout | 连接后端时连接超时值,单位:秒,值域:1-60。不设置时默认:15 |
relay.reconnect-interval-min | 重连后端的最小间隔,单位:秒,值域:1-60。不设置时默认:5 |
relay.reconnect-interval-max | 重连后端的最大间隔,单位:秒,必须 ≥ relay.reconnect-interval-min 。不设置时默认:60 |
示例:
relay:
connect-timeout: 10
reconnect-interval-min: 5
reconnect-interval-max: 60
server:
port: 8181
logging:
level:
ROOT: INFO
Web页面使用https
如果要在外网访问页面,页面应配置https,此时应在application.yml
配置文件中定义ssl属性。
示例,假设使用的域名SSL证书格式为:JDK
,文件放在:/home/yau/certs/dev.gratour.info.jks
,文件密码为password
,密钥别名为alias-key
, 则application.yml
文件的HTTPS配置为:
server:
port: 8181
ssl:
key-store-type: JKS
key-store: "/home/yau/certs/dev.gratour.info.jks"
key-store-password: "password"
key-alias: "alias-key"
enabled: true
logging:
level:
ROOT: INFO
问题反馈
在转发服务程序的使用过程中,如果发现问题,可发邮件至: alphax@vip.163.com