从 2020-01-15 的版本起,FineBI 推出了 Web 集群 &BI 单节点的应用方案,该方案不需要 Spider 多节点支持,仅需部署 BI 的 Web 集群,规定好主节点后,配置 Nginx 即可。
对于不同版本的 JAR ,有不同的实现方案。不同方案实现的效果不同,具体说明如下所示:
1)方案一效果:
JAR 需要在 2020-01-15 及之后,只区分 FineBI 和 FineReport 的请求。
BI 的数据更新和所有 BI 相关请求都会在这个主节点完成,其余 FR 或者管理系统的请求会随机转发到集群节点上面。
2)方案二效果:
JAR 需要在 2021-04-02 及之后,直连和 Spider 的请求可以区分开,在 Nginx 中配置相应转发。
直连的请求和 FineReport 的请求会随机转发到集群节点上,Spider 的请求在主节点完成。
该部署方案在部署好 Web 集群的基础上,在 BI 的配置文件中规定好主节点,并配置 Nginx 中的主次节点。
已按照 Web集群 文档部署好集群环境。
以集群两个节点,192.168.5.12 为主节点,192.168.5.11 为子节点,负载均衡地址是 192.168.5.11 的 Nginx 配置演示部署方案,可以根据实际场景进行修改。
1)关闭 Web 集群,在外置数据库中找到 FINE_CONF_ENTITY 表,并在其中增加一条 ID 记录:SystemOptimizationConfig.biClusterMasterNodeHostName,用来规定 Web 集群中的主节点,value 对应主节点服务器的 hostname。比如主节点服务器为 192.168.5.12 ,其对应 hostname 为 test02 ,则在表中增加的记录如下图所示:
2)此处主节点的服务器中,需要确保在/etc/hosts文件中,已经配置好 IP 和 hostname 的对应关系,如下图所示:
集群环境中,若节点一是主节点,更新的数据都在节点一上,而定时调度在进行请求转发时,没有特定指定某一个节点,所以当请求转发到节点二这个非数据节点上时,定时调度生成 pdf 文件将会报错没有权限导出数据。
关闭 Web 集群,在外置数据库中找到 FINE_CONF_ENTITY 表,并在其中增加一条 ID 记录:SystemOptimizationConfig.ClientMasterId,值为主节点的 ID 。
可在工程部署路径下的webapps\webroot\WEB-INF\config配置文件中查看主节点 ID ,如下图所示:
进入 Nginx 安装目录/usr/nginx/conf,打开 nginx.conf 文件,复制如下内容并修改其中的 IP 和端口,替换掉原文件内容。代码如下所示:
#user root;worker_processes auto;#worker_cpu_affinity auto;error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info;#pid logs/nginx.pid;events { worker_connections 1024;}http { include mime.types; 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 off; #access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65s; types_hash_max_size 2048; #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 { server 192.168.5.12:37799 max_fails=15 fail_timeout=300s; server 192.168.5.11:37799 max_fails=15 fail_timeout=300s; check interval=1000 rise=5 fall=10 timeout=8000 type=http; check_http_send "GET /webroot/decision/system/info HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx; } upstream BI.main.com { server 192.168.5.12:37799 max_fails=15 fail_timeout=300s; } upstream WBS.com { server 192.168.5.12:48888 max_fails=15 fail_timeout=300s; server 192.168.5.11:48888 max_fails=15 fail_timeout=300s; ip_hash; } server { listen 9090; server_name localhost; underscores_in_headers on; #charset koi8-r; #access_log logs/host.access.log main; location /status { healthcheck_status html; } location ~*/decision/v10/schedule/ { proxy_http_version 1.1; proxy_pass http://BI.main.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header X-Forwarded-Scheme $scheme; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header X-Forwarded-Host $host; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location ~*/decision/v5/conf/ { proxy_http_version 1.1; proxy_pass http://BI.main.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location ~*/decision/v5/design/ { proxy_http_version 1.1; proxy_pass http://BI.main.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location ~*/decision/link/ { proxy_http_version 1.1; proxy_pass http://BI.main.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location ~*/decision/file { proxy_http_version 1.1; proxy_pass http://FR.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; if ($query_string ~ "TextGenerator") { proxy_pass http://BI.main.com; } } location ~*/decision/v10/bi/package/field/ { proxy_http_version 1.1; proxy_pass http://BI.main.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; } location ~*/decision/v10/entry/access/ { proxy_http_version 1.1; if ($query_string ~* ^(.*)dashboardType=(4|5)(.*)$) { proxy_pass http://BI.main.com; } proxy_pass http://FR.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location / { proxy_http_version 1.1; proxy_pass http://FR.com; 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; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; #proxy_buffering off; #proxy_buffer_size 64k; #proxy_buffers 32 64k; #proxy_busy_buffers_size 64k; proxy_connect_timeout 120; proxy_read_timeout 600; proxy_send_timeout 600; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } server { #FineReport:38889 FineBI:48889 listen 48889; #listen 48889; server_name localhost; location / { #add_header Access-Control-Allow-Origin *; proxy_http_version 1.1; proxy_pass http://WBS.com; proxy_connect_timeout 120; proxy_read_timeout 600; proxy_send_timeout 600; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }}
注:IP、port 需要修改为自身环境对应的 IP 和端口,详细的配置参数说明可参考 nginx.conf 配置手册 ,增加了集群主节点的配置。修改后保存该配置。
1)配置主子节点的 IP。如下图所示:
2)配置 nginx 转发。如下图所示:
3)配置 nginx 检查请求。有些客户版本从9.0升级上来地址还是"/WebReport/ReportServer/",或者客户自己改过Servlet后会出现nginx无法访问的问题。所以这部分根据实际最终地址进行修改。如下图所示:
启动 Web 集群,即部署完成。
进入 Nginx 安装目录/usr/nginx/conf,打开 nginx.conf 文件,复制如下内容并修改其中的 IP 和端口,替换掉原文件内容。
如下代码所示:
#user root;worker_processes auto;#worker_cpu_affinity auto;error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info;#pid logs/nginx.pid;events { worker_connections 1024;}http { include mime.types; default_type application/octet-stream; log_format main '[$time_local] $remote_addr => $upstream_addr \n' '"$request" $http_x_forwarded_for $status \n\n'; # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for" $upstream_addr'; access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65s; types_hash_max_size 2048; #gzip on; #gzip_disable "MSIE [1-6]."; client_header_buffer_size 512k; large_client_header_buffers 4 512k; client_max_body_size 300M; #抽取部分固定主节点请求 upstream BI.main.com { server 192.168.5.249:8080 max_fails=15 fail_timeout=300s; }#随机转发请求 upstream BI.cluster.com { server 192.168.5.249:8080 max_fails=15 fail_timeout=300s; server 192.168.5.207:8080 max_fails=15 fail_timeout=300s; check interval=2000 rise=5 fall=10 timeout=10000 type=http; check_http_send "GET /webroot/decision/system/health HTTP/1.0\r\n\r\n"; # 检查请求 check_http_expect_alive http_2xx http_3xx; }#直连部分仪表板和数据准备请求 upstream BI.com { hash "$cookie_fine_login_users - $http_sessionid"; server 192.168.5.249:8080 max_fails=15 fail_timeout=300s; server 192.168.5.207:8080 max_fails=15 fail_timeout=300s; keepalive 300; check interval=2000 rise=5 fall=10 timeout=10000 type=http; check_http_send "GET /webroot/decision/system/health HTTP/1.0\r\n\r\n"; # 检查请求 check_http_expect_alive http_2xx http_3xx; } upstream WBS.com { server 192.168.5.249:48888 max_fails=15 fail_timeout=300s; server 192.168.5.207:48888 max_fails=15 fail_timeout=300s; ip_hash; } server { listen 80; #访问nginx端口 server_name 192.168.5.221; #访问nginxip underscores_in_headers on; location ~*/decision/v5/conf/ { proxy_http_version 1.1; proxy_pass http://BI.main.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location ~*/decision/v5/direct/conf/ { proxy_http_version 1.1; proxy_pass http://BI.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location ~*/decision/v5/design/ { proxy_http_version 1.1; if ($query_string ~* ^(.*)engineType=1(.*)$) { proxy_pass http://BI.com; } proxy_pass http://BI.main.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location ~*/decision/link/ { proxy_http_version 1.1; proxy_pass http://BI.main.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location ~*/decision/file { proxy_http_version 1.1; proxy_pass http://BI.cluster.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k;# if ($query_string ~ "TextGenerator") {# proxy_pass http://BI.main.com;# } } location ~*/decision/v10/bi/package/field/ { proxy_http_version 1.1; proxy_pass http://BI.main.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; } location /status { healthcheck_status html; } location ~*/decision/v10/entry/access/ { proxy_http_version 1.1; if ($query_string ~* ^(.*)dashboardType=(4|5)(.*)$) { proxy_pass http://BI.main.com; } proxy_pass http://BI.cluster.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } location / { proxy_http_version 1.1; proxy_pass http://BI.cluster.com; proxy_next_upstream http_500 http_502 http_503 http_504 http_403 http_404 http_429 error timeout invalid_header non_idempotent; proxy_redirect off; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_connect_timeout 20; proxy_read_timeout 1000; proxy_send_timeout 300; proxy_buffer_size 64k; proxy_buffers 32 32k; proxy_busy_buffers_size 128k; } #charset koi8-r; #access_log logs/host.access.log main; #error_page 404 /404.html; # redirect server error pages to the static page /50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } server { #FineReport:38889 FineBI:48889 listen 48889; #listen 48889; server_name 192.168.5.249; location / { #add_header Access-Control-Allow-Origin *; proxy_http_version 1.1; proxy_pass http://WBS.com; proxy_connect_timeout 120; proxy_read_timeout 600; proxy_send_timeout 600; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }}
单表更新卡住,重启后更新进度页面显示仍在更新。
集群若只有一个节点重启,不会清状态服务器 Redis 里的更新进度,需要重启整个集群,才会重置更新进度,如果只重启一个节点,之前在进行中的任务会强制失败,未开始的任务会继续更新。
将所有的集群节点关闭之后全部重启。
若同时使用 FineReport 和 FineBI ,且 Tomcat 版本为 8.0.23,FR 目录上挂出的 BI 仪表板打开显示空白。
1)升级 Tomcat 版本到 8.5。
2)进入 Nginx 安装目录/usr/nginx/conf,打开 nginx.conf 文件,在以下位置加上proxy_http_version 1.1;,如下图所示:
目前的 Web 集群+BI的 Spider 引擎单节点部署方案是通过 Nginx 转发访问节点,Spider 引擎更新的数据文件只存储在主节点上,只有主节点可以访问到这些文件上,不支持数据同步,即子节点上没有更新数据。 Spider 引擎的双机热备详情参见:热备集群部署