1. 概述编辑
1.1 版本
报表服务器版本 | JAR 包版本 | 新增功能 |
---|---|---|
10.0 | - | - |
10.0 | 2019-11-08 | WebSocket 转发端口字段由 WebSocketConfig.requestPort改为 WebSocketConfig.requestPortS WebSocket 转发端口支持设置多个值 |
10.0.9 | 2020-08-31 | WebSocket 未连接时,管理员登录平台,去除顶部弹窗提示。 Websocket 未连接时,token可自动刷新 |
1.2 应用场景
WebSocket 是服务器给浏览器主动推送消息的一个端口。
WebSocket 主要用于刷新 token、用户被踢出、平台消息、内存和 CPU 显示、平台日志处当前系统在线人数、数据连接编辑状态的确定。
Websocket 端口被占用或无法使用时,将对用户的使用造成困扰。
1.3 解决思路
本文将简单介绍 WebSocket 端口配置方法、连接失败时的现象、连接失败时的排查方法。
2. WebSocket 默认端口编辑
FineReport 工程默认配置了 WebSocket 端口和 WebSocket 转发端口。
单机下使用 WebSocket 端口。
集群下使用 WebSocket 端口和 WebSocket 转发端口。
端口 | JAR 包 | ID | 默认值 | 是否支持 设置多个值 |
---|---|---|---|---|
Websocket 端口 | - | WebSocketConfig.port | ["38888", "39888"] | 支持 |
Websocket 转发端口 | 2019-11-08 之前 | WebSocketConfig.requestPort | 38889 | 不支持 |
2019-11-08 及之后 | WebSocketConfig.requestPorts | 38889 | 不支持 |
3. 修改 WebSocket 端口编辑
由于集群节点过多,端口被占用,需要开放特定端口等原因,用户需要手动修改 WebSocket 端口和 WebSocket 转发端口。。
3.1 修改端口号
用户可通过修改 config 项更改数据库配置,以便修改 WebSocket 端口和 WebSocket 转发端口。
单机:修改 FineDB 中 fine_conf_entity 表中的 WebSocketConfig.port,调整值。
集群:修改 FineDB 中 fine_conf_entity 表中的 WebSocketConfig.port 和 WebSocketConfig.requestPort/WebSocketConfig.requestPorts,调整值。
修改步骤请参见:报表内置 HSQL 数据库 FineDB
如果FineDB迁移到外置数据库,可以直接使用 navicat 等数据库管理软件来修改上面的字段。
3.2 注意事项
3.2.1 端口号
1)端口号可设置范围:1024~65535,若为多个值,设置格式为:[端口号1,端口号2,端口号3]
2)建议「WebSocket端口」设置多个值,作为备用,防止一台服务器部署了多个工程,端口被占用。
3)建议「WebSocket转发端口」的值要多于集群节点数,保证每个节点都会选择当前可用的端口,不会因为端口占用而导致服务器无法启动。
4)不要设置端口号为服务器远程连接端口39999
5)如果报表工程和 nginx 负载均衡在一个环境下,不要重复设置某个端口号既是 WebSocket 端口,又是 WebSocket 转发端口
3.2.2 字段
1)WebSocketConfig.port、WebSocketConfig.requestPort、WebSocketConfig.requestPorts 字段后面有空格,配置不生效。
2)WebSocketConfig.port、WebSocketConfig.requestPort、WebSocketConfig.requestPorts 大小写错误,配置不生效。
3)WebSocketConfig.requestPort 和 WebSocketConfig.requestPorts 不能同时存在于 fine_conf_entity 表中,否则会出错。
3.2.3 其他
1)单机/集群,需要开放防火墙和安全组相关端口
2)集群,需要在负载均衡层面配置 Websocket 的转发策略为粘滞,详情请参见:负载均衡配置指导
3)集群,nginx.conf 文件中,server 的 listen 端口需要与「WebSocket 转发端口」配置一致,详情请参见:Linux 系统安装配置 Nginx 4.1 节
例如用设置的 Websocket 转发端口(WebSocketConfig.requestPort默认38889)转发 Websocket 端口(WebSocketConfig.port默认 38888 )
以下示例为工程服务器 IP 为 192.168.6.171,Nginx 服务器 IP 为 192.168.6.181,如下图所示:
#用户或者用户组 默认为nobody
#user root;
#允许进程数量,建议设置为cpu核心数或者auto自动检测,注意Windows服务器上虽然可以启动多个processes,但是实际只会用其中一个
worker_processes auto;
#自动根据CPU数目绑定CPU亲缘性,nginx1.9.10及以上版本才能用
#worker_cpu_affinity auto;
#error日志存放位置
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#PID存放位置
#pid logs/nginx.pid;
#工作模式及连接数上限
events {
#每个worker_processes的最大连接数,Windows服务器无论这里设置多大实际都只有1024
#并发数是 worker_processes 和 worker_connections 的乘积
worker_connections 1024;
}
http {
#设定mime类型,类型由mime.type文件定义
include mime.types;
#默认文件类型,默认为text/plain
default_type application/octet-stream;
#日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" $upstream_addr';
#access_log确定了Nginx是否保存访问日志,将这个设置为关闭可以降低磁盘IO而提升速度
access_log off;
#access_log logs/access.log main;
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
#以平衡磁盘与网络I/O处理速度,降低系统的uptime.
sendfile on;
#tcp_nopush on;
#http长连接(client <-> nginx)超时时间,请求完成之后连接保持的时间
keepalive_timeout 65s;
#types_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能上升
types_hash_max_size 2048;
#开启gzip压缩
#gzip on;
#gzip_disable "MSIE [1-6].";
#设定请求缓冲
client_header_buffer_size 512k;
large_client_header_buffers 4 512k;
#允许用户最大上传数据大小,根据业务需求调整上传文件大小限制
client_max_body_size 100M;
upstream FR.com {
#max_fails=n fail_timeout=m 表示m时间内超时n次失败尝试,将会在接下来m时间内标记此节点不可用(m时间过后无论此节点是否启动都会被重新标记为可用状态)
#其中fails为“失败尝试”,失败尝试由下面server配置中,proxy_next_upstream指令定义
server 192.168.6.171:8080 max_fails=15 fail_timeout=300s;
keepalive 300;
#其它server参数说明:
#down 标记服务器挂掉
#backup 备份服务器,当主服务器(例如上面的95和96)不可用时才加入服务器;
#weight=number 权重,默认为1
#内置负载均衡策略有ip hash、轮询、加权轮询(设置server的weight值)
#ip_hash;
#↓====================主动健康检查模块配置====================↓#
## interval:向后端发送的健康检查包的间隔,单位ms。
## fall(fall_count): 如果连续失败次数达到fall_count,服务器就被认为是down
## rise(rise_count): 如果连续成功次数达到rise_count,服务器就被认为是up。
## timeout: 后端健康请求的超时时间,单位ms。
## type:健康检查包的类型,现在支持tcp、udp、http类型
#check interval=2000 rise=5 fall=10 timeout=10000 type=http;
# 检查请求, 7-16之前的persist版本,只能使用 /webroot/decision/system/info HTTP;
#check_http_send "GET /webroot/decision/system/health HTTP/1.0\r\n\r\n"; # 检查请求
#check_http_expect_alive http_2xx http_3xx; #该指令指定HTTP回复的成功状态,默认认为2XX和3XX的状态是健康的。
#↑====================主动健康检查模块配置====================↑#
}
upstream WBS.com {
server 192.168.6.171:38888 max_fails=15 fail_timeout=300s;
#这里必须使用ip_hash
ip_hash;
}
server {
listen 8123;
server_name 192.168.6.181;
#nginx默认不转发带下划线的header,比如请求的header中有_device_这个header,转发到负载服务器时默认会丢弃
#可以在http或者http -> server这两个上下文中加入一条属性
underscores_in_headers on;
#charset koi8-r;
#access_log logs/host.access.log main;
#↓====================主动健康检查模块监测页面====================↓#
#location /status {
# healthcheck_status html;
#}
#↑====================主动健康检查模块监测页面====================↑#
#根/下的请求默认转发到的位置,即端口后面跟的请求全部转发到如下反向代理
location / {
#对于HTTP代理,proxy_http_version指令应该设置为“1.1”,同时“Connection”头的值也应被清空(如下proxy_set_header Connection "")
proxy_http_version 1.1;
#定义转发到的服务器(组)
proxy_pass http://FR.com;
#设置nginx转发时转发到下一个服务器的条件,此处设置将未成功请求(proxy_next_upstream定义的40x, 50x等)传递到下一步进行处理
# 失败尝试说明:50x和429在此配置会被当作fail,error,timeout并 invalid_header无论配置与否都被认为fail,http_403 and http_404配置与否都不是fail。
# error:与后端服务器建立连接、传递请求、读取请求头发生的错误
# timeout:与后端服务器建立连接、传递请求、读取请求头超时,设置在proxy_next_upstream_timeout和proxy_next_upstream_tries(默认值都是0)
# invalid_header:服务器返回非法或者为空
proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent;
#proxy_next_upstream_timeout 0;
#proxy_next_upstream_tries 0;
#重定向,参数off将在这个字段中禁止所有的proxy_redirect指令
proxy_redirect off;
#请求头的一些设置,语法proxy_set_header [field] [value];
#$host为请求的主机名称(即nginx代理服务器), $server_port为主机端口(即nginx端口),如果有外网映射,这里应改写 外网地址:外网端口 形式(不要带协议)
proxy_set_header Host $host:$server_port;
#这里$remote_addr客户端ip地址
proxy_set_header X-Real-IP $remote_addr;
#这里$proxy_add_x_forwarded_for是代理层级,如果由多层代理,这里就写client,proxy1,proxy2,这里应该是client即客户端ip
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#与后端服务器的连接不需要保持
proxy_set_header Connection "";
#NGINX会缓冲来自代理服务器的响应。响应存储在内部缓冲区中,并且在收到整个响应之前不会发送到客户端。
#缓冲有助于优化慢客户端的性能,如果响应从NGINX同步传递到客户端,则会浪费代理服务器时间。
#但是,当启用缓冲时,NGINX允许代理服务器快速处理响应,而NGINX将响应存储的时间与客户端下载它们所需的时间相同
#是否开启缓冲,默认开启
#proxy_buffering off;
#设置缓冲区的大小为size
#proxy_buffer_size 64k;
#每个连接设置缓冲区的数量和大小,proxy_buffers [number] [size];
#proxy_buffers 32 64k;
#当开启缓冲响应的功能以后,在没有读到全部响应的情况下,写缓冲到达一定大小时,nginx一定会向客户端发送响应,直到缓冲小于此值
#proxy_busy_buffers_size 64k;
#连接到代理服务器超时时间,默认60s,不能超过75s
#不宜太长或者太短,配合max_fails和fail_timeout设置
#并发量高的情况下,服务器压力过大时容易出现超时,可以考虑max_fails和fail_timeout设置大一点,减少nginx错误踢出节点的几率
proxy_connect_timeout 75;
#读取超时,默认60s,如果在超时时间内服务器未返回任何数据,视为超时。如果没有大数据量计算或导出的模板,则建议配置不超过100s,如果有大数据量计算或导出的模板,则根据最长耗时的模板时间进行配置。
proxy_read_timeout 400;
#写入超时,默认60s,如果在超时时间内服务器未收到数据表示超时,视为超时。如果没有大数据量计算或导出的模板,则建议配置不超过100s,如果有大数据量计算或导出的模板,则根据最长耗时的模板时间进行配置。
proxy_send_timeout 400;
}
#定义404页面
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#定义50x页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
server {
#此处为websocket端口,如果是集群部署,FineReport工程为38889,FineBI工程为48889
listen 38889;
server_name 192.168.6.181;
location / {
proxy_http_version 1.1;
proxy_pass http://WBS.com;
proxy_connect_timeout 75;
proxy_read_timeout 400;
proxy_send_timeout 400;
#升级目标为$http_upgrade 值实际为websocket
proxy_set_header Upgrade $http_upgrade;
#Connection设置升级
proxy_set_header Connection "upgrade";
}
}
4. WebSocket 连接失败编辑
4.1 现象描述
1)管理员登录数据决策系统,点击「管理系统>智能运维>内存管理」,「内存预警」Tab 下「内存利用率和「CPU 利用率」两张图显示空白。
顶部弹出提示信息:Socket 未连接,实时内存显示等异常,相关端口可能未开放
2)管理员登录数据决策系统,点击「管理系统>智能运维>平台日志」,「访问统计」Tab 下「当前系统在线人数」无法正确显示。模板执行过程统计如内存、耗时等无法记录。
顶部弹出提示信息:Socket 未连接,系统访问用户统计等异常,请开启相关端口,相关端口可能未开放
3)用户点击「管理系统>数据连接」,进入数据连接编辑界面,可能存在多人同时编辑同一个数据连接的情况。
顶部弹出提示信息:Socket 未连接,可能存在多人同时编辑造成冲突,相关端口可能未开放
4)踢出登录失效,不能实时踢出,在框架内显示登录页面,即没有跳出框架直接跳转到登录界面。如下图所示:
注:该问题出现的场景:单一登录踢出、禁用用户、修改用户密码、修改认证方式、切换同步导入、平台使用用户禁用用户/打开限制开关,更换 Lic 等。
5)用户收不到右下角消息弹窗且小铃铛处无消息提示,但是可以点击小铃铛进入消息面板查看。
6)登录超时,无法获取正确的 token 有效期
用户登录数据决策系统时,不勾选「保持登录状态」。登录超时设置为 1 小时,若用户在3点登录,3点20分在平台进行了操作。
WebSocket 连接成功,应为 4 点 20 被踢出(平台无操作情况下)。
WebSocket 未连接,则不能重新获取 token ,4 点即被踢出。
用户登录数据决策系统时,勾选「保持登录状态」,默认无操作 14 天后被踢出,若 14 天内在平台上操作,不能重新获取 token ,依旧 14 天后被踢出。
注1:2020-08-31 及之后的 JAR ,Websocket 未连接时,不会出现这个现象。
注2:2020-08-31 之前的 JAR ,若无法开放额外端口或不允许使用 socket,可以安装「socket无法使用备用方案插件」解决这个问题。
管理员登录平台后,顶部弹出提示信息:Socket 未连接,使用过程中将无法保持登录状态,相关端口可能未开放
每次刷新平台页面也会弹出提示,刷新指浏览器刷新如 F5。
注:2020-08-31 及之后的 JAR ,Websocket 未连接时,没有该提示。
7)在插件商城安装或者删除插件时没有成功或者失败的提示。
4.2 确认连接失败
直接查看「管理系统>智能运维>内存管理>实时内存」的两张图片能不能出来,不显示则未连接。
F12 打开控制台,输入「Dec.socket.connected」,如果是「false」表示未连接。
F12 打开控制台,如果有关于 38889(代理服务器默认端口号) 之类 Socket 端口的报错,且最后出现了「connect error」那就是没有连接成功。
5. WebSocket 连接排查编辑
5.1 端口未开放
5.1.1 排查方法
通过命令「telnet ip port」来确认端口是否开放:
Windows下若始终显示正在连接而没有弹出新的窗口,则为对应端口未开放。
Linux下若未回显 Connected 则为对应端口未开放。
5.1.2 解决方法
若防火墙开启,可关闭防火墙,或者单独开放端口。
若云服务器有安全组或者类似的内容,需要设置端口对外开放。
5.2 端口被占用
5.2.1 排查方法
可使用「netstat -tunlp | grep port」检查是否有进程占用了端口。
5.2.2 解决方法
如果进程不必要,可直接杀死进程
如果进程必要,请参照本文第三章,手动修改 Websocket 的端口
5.3 配置了代理服务器
1)代理服务器的 WebSocket 监听端口未开放
2)代理服务器的 WebSocket 监听端口开放了,但是未配置 WebSocket 的转发,请参见 3.2.3 节修改 server 的 listen 端口与「WebSocket 转发端口」配置一致
5.4 配置了 HTTPS
1)若同时配置了 HTTP 和 HTTPS,那么只有HTTPS 的 WebSocket 设置生效,HTTP 的不生效。
2)HTTPS 配置文件存在错误,请参见通用配置文件进行检查:10.0下HTTPS环境配置WebSocket
3)数据决策系统中,「管理系统>系统管理>常规」中的 WebSocket设置错误,修改设置后保存并重启工程即可。如下图所示:
5.5 JAR 包冲突
5.5.1 现象描述
工程下的 JAR 包出现冲突时,会出现服务器部署向导,提示「WebSocket 端口异常」,如下图所示:
5.5.2 解决方法
删除造成冲突的 JAR 包即可。
如果 Apache Impala 是从官网下载的,不要将 slf4j-log4j12-1.5.11.jar和slf4j-api-1.5.11.jar 放到%FineReport%\webapps\webroot\WEB-INF\lib下,否则会造 Websoket 端口异常。