1. 概述编辑
1.1 版本
报表服务器版本 | JAR 包版本 | 新增功能 |
---|---|---|
10.0 | 2019-12-05 | - |
10.0.9 | 2020-08-31 | WebSocket 未连接时,管理员登录平台,去除顶部弹窗提示:Socket未连接,使用过程中将无法保持登录状态,相关端口可能未开放 |
Websocket 未连接时,token可自动刷新 |
1.2 问题描述
WebSocket 是服务器给浏览器主动推送消息的一个端口,主要用于刷新 token、用户被踢出、平台消息、内存和 CPU 显示、平台日志处当前系统在线人数、数据连接编辑状态的确定。Websocket 端口被占用或无法使用时,将对用户的使用造成困扰。
当数据决策系统出现本文 2.1 节所描述的现象时 ,需要进行排查。
1.3 解决思路
确认连接结果——确认端口开放情况——检查端口是否被占用——确认配置代理服务器情况——确认配置 HTTPS 情况——确认防火墙情况
2. WebSocket 未连接编辑
2.1 现象
下面介绍 WebSocket 未连接时出现的问题现象:
1)管理员登录数据决策系统,点击「管理系统>智能运维>内存管理」,「内存预警」Tab 下「内存利用率和「CPU 利用率」这两张图显示空白(工程刚启动需要等待一两分钟才会显示)。
2)管理员登录数据决策系统,点击「管理系统>智能运维>平台日志」,「访问统计」Tab 下「当前系统在线人数」无法正确显示。
3)踢出登录失效,不能实时踢出,在框架内显示登录页面,即没有跳出框架直接跳转到登录界面。如下图所示:
该问题出现的场景:单一登录踢出、禁用用户、修改用户密码、修改认证方式、切换同步导入、平台使用用户禁用用户/打开限制开关,更换 Lic 等。
4)用户收不到右下角消息弹窗且小铃铛处无消息提示,但是可以点击小铃铛进入消息面板查看。
5)登录数据决策系统时不勾选「保持登录状态」:
「管理系统>系统管理>登录超时设置」设置为 1 小时,WebSocket 未连接,查看 token 有效期:例如 3 点登录,4 点被踢出(平台无操作情况下),若 3 点 20 在平台操作,则不能重新获取 token ,依旧 4 点被踢出,若 WebSocket 连接成功,应为 4 点 20 被踢出(平台无操作情况下)。
登录数据决策系统时勾选「保持登录状态」:
WebSocket 未连接,查看 token 有效期:正常是 14 天,若 14 天内在平台上操作,不能重新获取 token ,依旧 14 天后被踢出。
注1:2020-08-31 及之后的 JAR ,Websocket 未连接时,token 可手动/自动刷新。
注2:2020-08031 之前的 JAR ,若无法开放额外端口或不允许使用 socket,可以安装「socket无法使用备用方案插件」解决这个问题。
6)在插件商城安装或者删除插件时没有成功或者失败的提示。
7)可能存在多人同时编辑同一个数据连接的情况。
2.2 消息提示
如果是 WebSocket 端口未开放导致的,那么在客户愿意开放端口的前提下,需要提醒管理员开启 WebSocket 端口。提示信息如下表所示:
序号 | 问题 | 问题描述 | 提示信息 |
---|---|---|---|
1 | 登录超时 | 平台使用时会刷新 token ,若 socket 未连接上,超过登录时间就需要重新登录 | 管理员登录平台后,顶部弹出提示信息:Socket 未连接,使用过程中将无法保持登录状态,相关端口可能未开放 每次刷新平台页面也会弹出提示,刷新指浏览器刷新如 F5 注:2020-08-31 及之后的 JAR 没有该提示 |
2 | 内存和 CPU 的图 | 内存利用率和 CPU 利用率的图不能加载出来 | 进入实时内存查看页面,顶部弹出提示信息: Socket 未连接,实时内存显示等异常,相关端口可能未开放 |
3 | 日志统计记录 | 系统在线人数不能正确显示,模板执行过程统计如内存、耗时等无法记录 | 进入页面,顶部弹出提示信息: Socket 未连接,系统访问用户统计等异常,请开启相关端口,相关端口可能未开放 |
4 | 数据连接编辑状态唯一 | 可能存在多人同时编辑同一个数据连接的情况 | 进入数据连接编辑界面,顶部弹出提示信息: Socket 未连接,可能存在多人同时编辑造成冲突,相关端口可能未开放 |
3. 排查步骤编辑
WebSocket 未连接可能是 WebSocket 端口未开放或者 WebSocket 端口被占用导致的。目前可以通过以下办法检测 WebSocket 是否连接成功。
3.1 确认 Websocket 是否连接成功
直接查看「管理系统>智能运维>内存管理>实时内存」的两张图片能不能出来,不显示则未连接。
F12 打开控制台,输入「Dec.socket.connected」,如果是「false」表示未连接。
F12 打开控制台,如果有关于 38889(代理服务器默认端口号) 之类 Socket 端口的报错,且最后出现了「connect error」那就是没有连接成功。
3.2 确认端口的开放情况
通过命令「telnet ip port」来确认端口是否开放;
Windows下若始终显示正在连接而没有弹出新的窗口,则为对应端口未开放,如下图所示:
Linux下若未回显 Connected 则为对应端口未开放。
若端口未开放,需开放端口。
3.3 检查端口是否被占用
可使用「netstat -tunlp | grep port」检查是什么进程占用了端口,如果当前端口必须被占用,用户需要手动修改 Websocket 的端口,解决端口冲突问题。
在 FineDB 数据库的 fine_conf_entity 表中修改 WebSocket 端口,Websocket 端口和 Websocket 转发端口设置过后,需重启工程生效。具体字段介绍如下表所示:
注:提供给 Web 服务器的端口范围应在 1024~65535 之间。
注2:两个转发端口字段不能同时存在 fine_conf_entity 表中,否则会出现异常。
端口 | JAR | ID | VALUE | 作用 |
---|---|---|---|---|
Websocket 端口 | - | WebSocketConfig.port | 默认值为["38888", "39888"] | 单机工程的 Websocket 端口;未手动配置时使用默认值 |
Websocket 转发端口 | 2019-11-08 之前 | WebSocketConfig.requestPort | 只支持单个,默认值为 38889 | 集群工程的 Websocket 转发端口;未手动配置时使用默认值 |
2019-11-08 及之后 | WebSocketConfig.requestPorts | 支持多个,值的格式示例:["38889","40000"] |
注意点如下所示:
Websocket 端口和 Websocket 转发端口设置过后,需重启工程生效。
WebSocketConfig.port、WebSocketConfig.requestPort、WebSocketConfig.requestPorts 大小写错误,配置不生效;数据库中进行配置时,字段前后存在空格,配置不生效。
单机工程时,防火墙要开放WebSocketConfig.port的端口,集群工程时,防火墙要开放WebSocketConfig.requestPort的端口,并且要在负载均衡层面配置 Websocket 的转发策略为粘滞,详情请参见 负载均衡配置指导
当一台服务器部署了多个工程,WebSocketConfig.port的值可以设置为数组["48886","48887","48888"](具体端口根据实际情况确定,要部署几个节点就数组中就至少需要几个不重复的值),这样每个节点都会选择当前可用的端口,从而不会因为端口占用而导致服务器无法启动。
3.3.1 单机工程示例
1)未 迁移外置数据库
修改报表服务器使用的配置数据库 FineDB,将 fine_conf_entity 表中的端口 ID,调整值为 40000,重启工程。具体如下表所示:
修改步骤请参见:报表内置 HSQL 数据库 FineDB
表 | ID | 值 |
---|---|---|
fine_conf_entity | WebSocketConfig.port | 40000 |
WebSocketConfig.requestPort | 40000 |
2)迁移了外置数据库
可以直接使用 Navicat 等数据库管理软件来修改上面的字段,重启工程。
注1:端口号的值不要使用远程端口 39999 。
注2:两个端口号值建议设置为不一样,设置不一样时 WebSocketConfig.requestPort 为备用端口。
3.3.2 注意事项
1)集群模式下修改 Websocket 端口时,也参照上面的步骤进行修改,修改完毕后需要同步修改负载均衡的 Websocket 配置。
2)如果忘记使用的是哪个外置数据库,可以在WEB_INF/config文件夹中的 db.properties 中查看数据库信息,如下图所示:
3)目前 2018-10-30 号之后的 JAR 在同一台设备中不可以同时启动设计器和 Tomcat,上述处理方法同样适用。
3.4 是否配置代理
如果配置了代理,可能是代理服务器本身的 WebSocket 监听端口没开,导致浏览器连不上;或者端口开了但是只配置了 HTTP 请求的转发,没配置 WebSocket 的转发,导致浏览器的请求没有被转发到决策平台服务器上。结合通用配置文件检查客户设置的转发配置。
如果配置 Nginx 代理服务器,有两种情况:
1)需要开启代理服务器本身的 WebSocket 监听端口,例如 38889 。
2)需转发两个端口:
工程访问端口,例如用 Nginx 服务器的 8123 端口转发工程的访问端口 8080 。
Websocket 端口,例如用设置的 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";
}
}
3.5 是否配置HTTPS
注:一般情况下都是配置文件有问题,根据通用配置文件检查。
3.6 防火墙
若防火墙开启,可关闭防火墙,或者单独开放端口。
若云服务器有安全组或者类似的内容,需要设置端口对外开放。
检测方式:在可以访问的机器(非服务器)测试某网址或IP端口能否访问nc -vz -w 2 [ip] [port]
如果是 Windows 使用 Telnet,详情参见:telnet用法-测试端口号
4. 注意事项编辑
4.1 端口异常
如果 Apache Impala 是从官网下载的,则不需要将 slf4j-log4j12-1.5.11.jar\slf4j-api-1.5.11.jar 放置到%FineBI%\webapps\webroot\WEB-INF\lib下,否则会造 Websoket 端口异常,如下图所示: