历史版本31 :Websocket简介 返回文档
编辑时间: 内容长度:图片数:目录数: 修改原因:

目录:

1. 概述编辑

1.1 版本

报表服务器版本

JAR 包版本

新增功能
10.0--
10.02019-11-08

WebSocket 转发端口字段由 WebSocketConfig.requestPort改为 WebSocketConfig.requestPortS

WebSocket 转发端口支持设置多个值

10.0.92020-08-31WebSocket 未连接时,管理员登录平台,去除顶部弹窗提示。

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.requestPort38889不支持
2019-11-08 及之后WebSocketConfig.requestPorts38889不支持

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)设置完成后需重启工程,请杀死工程的所有进程,等待 2 分钟端口释放后,重启工程。

3)集群,需要在负载均衡层面配置 Websocket 的转发策略为粘滞,详情请参见:负载均衡配置指导 

4)集群,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 等。

19.png

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设置错误,修改设置后保存并重启工程即可。如下图所示:

2020-10-21_17-11-19.png

5.5 JAR 包冲突

5.5.1 现象描述

工程下的 JAR 包出现冲突时,会出现服务器部署向导,提示「WebSocket 端口异常」,如下图所示:

image.png

5.5.2 解决方法

删除造成冲突的 JAR 包,杀死工程的进程,等待 2 分钟端口释放后,重启工程。

如果 Apache Impala  是从官网下载的,不要将 slf4j-log4j12-1.5.11.jarslf4j-api-1.5.11.jar 放到%FineReport%\webapps\webroot\WEB-INF\lib下,否则会造 Websoket 端口异常。