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 端口和 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 單機
3.1.1 修改字段值
超級管理員可通過「fine_conf_entity可視化配置插件」修改 WebSocket 端口。重啓服務器後設置生效。
注:修改 FineDB 數據庫表字段值的方法請參考 FineDB 常用表字段修改 。
配置項 | 修改規則 |
---|---|
WebSocketConfig.port | 參數值爲端口數組["port1","port2"] port均屬於區間(1024,65535] 默認值爲["38888","39888"] |
3.1.2 開放端口
若防火牆開啓,可關閉防火牆,或者單獨開放端口。
若雲服務器有安全組或者類似的内容,需要設置端口對外開放。
3.1.3 重啓工程
殺死報表工程下運行的進程,等待 2 分鍾端口釋放後,再重啓工程。
3.2 集群
3.2.1 修改字段值
用戶可通過修改 config 項更改數據庫配置,以便修改 WebSocket 端口和 WebSocket 轉發端口。
修改 FineDB 中 fine_conf_entity 表中的 WebSocketConfig.port 和 WebSocketConfig.requestPort/WebSocketConfig.requestPorts,調整值。
端口号可設置範圍:1024~65535,若爲多個值,設置格式爲:[端口号1,端口号2,端口号3]
修改步驟請參見:報表内置 HSQL 數據庫 FineDB
注:若 fine_conf_entity 表中無該字段,請手動添加。
3.2.2 修改集群轉發策略
在負載均衡層面配置 Websocket 的轉發策略爲粘滞,詳情請參見:負載均衡配置指導
3.2.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";
}
}
3.2.4 開放端口
若防火牆開啓,可關閉防火牆,或者單獨開放端口。
若雲服務器有安全組或者類似的内容,需要設置端口對外開放。
3.2.5 重啓工程
殺死報表工程下運行的進程,等待 2 分鍾端口釋放後,再重啓工程。
3.3 注意事項
1)端口号可設置範圍:1024~65535,若爲多個值,設置格式爲:[端口号1,端口号2,端口号3]
2)建議「WebSocket端口」設置多個值,作爲備用,防止一台服務器部署了多個工程,端口被占用。
3)建議「WebSocket轉發端口」的值要多於集群節點數,保證每個節點都會選擇當前可用的端口,不會因爲端口占用而導緻服務器無法啓動。
4)不要設置端口号爲服務器遠程連接端口39999
5)如果報表工程和 nginx 負載均衡在一個環境下,不要重複設置某個端口号既是 WebSocket 端口,又是 WebSocket 轉發端口
6)WebSocketConfig.port、WebSocketConfig.requestPort、WebSocketConfig.requestPorts 字段後面有空格,配置不生效。
7)WebSocketConfig.port、WebSocketConfig.requestPort、WebSocketConfig.requestPorts 大小寫錯誤,配置不生效。
8)WebSocketConfig.requestPort 和 WebSocketConfig.requestPorts 不能同時存在於 fine_conf_entity 表中,否則會出錯。
9)單機/集群,需要開放防火牆和安全組相關端口
10)設置完成後需重啓工程,請殺死工程的所有進程,等待 2 分鍾端口釋放後,重啓工程。
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 包,殺死工程的進程,等待 2 分鍾端口釋放後,重啓工程。
如果 Apache Impala 是從官網下載的,不要将 slf4j-log4j12-1.5.11.jar和slf4j-api-1.5.11.jar 放到%FineReport%\webapps\webroot\WEB-INF\lib下,否則會造 Websoket 端口異常。
6. 注意事項
1)重啓工程時,需要殺死工程下運行的進程,等待 2 分鍾端口釋放後,再重啓工程,否則有可能重啓失敗。
2)通過上文排查修改,websocket 可正常連接後,僅能獲取之後的内存和 CPU 顯示、平台日志等數據。曆史數據無法恢複。