ThingWorx 高可用性 > HA クラスタのトラブルシューティング
HA クラスタのトラブルシューティング
アプリケーションキーが各サーバーに存在するが、その値が空白になっている
暗号化キーがサーバーごとに異なる場合にこの問題が発生します。これはキーストアが正しく共有されていない場合に発生する可能性があります。
セキュリティ管理ツールを使用して、keystore-password と keystore.pfx  ファイルを設定できます。その場合、各プラットフォームインスタンスによって ThingworxStorage ディレクトリが共有されている必要があります。
これが不可能な場合、1 台のサーバーを起動して keystore-password と keystore.pfx ファイルを作成し、別のマシンにこれをコピーしてからそのマシンを起動する必要があります。
1. 1 台のサーバーを起動して /ThingworxPlatform/keystore-password ファイルおよび /ThingworxStorage/keystore.pfx ファイルを作成します。
2. これらのファイルをその他のサーバーにコピーしてから、そのサーバーを起動します。
サーバー A で作成された Thing がサーバー B に存在しない
高可用性 (HA) はデータベースを介してモデルを同期化することによって機能します。この同期化は約 100 ミリ秒ごとに実行されますが、設定することも可能です。すべてのサーバーが同じ PostgreSQL データベースインスタンスを参照している必要があるので、プラットフォームの設定でデータベースコンフィギュレーションをチェックして接続の設定が一致していることを確認してください。HA クラスタで PostgreSQL を実行する場合、Pgpool-II とプライマリ-セカンダリ PostgreSQL コンフィギュレーションを使用した PostgreSQL HA のコンフィギュレーションを採用する必要があります。
一部のサーバーでプロパティの値が設定されない
サーバー A でメモリ内プロパティの値を設定したときに、サーバー B でその値が更新されない場合、状態を保存するキャッシュレイヤーが正しく設定されていません。ThingWorx は埋め込みまたは分散として実行可能な Apache Ignite キャッシュにプロパティの状態を保存します。トポロジーログがアプリケーションログと Ignite ログに書き込まれ、これらのログにはクラスタ内のクライアントとサーバーの数が示されます。このログに記録されているサーバーの数が、想定するサーバーの数と一致していることを検証する必要があります。サーバーが互いに通信できない場合、ファイアウォールが原因である可能性があり、Ignite はローカルでのみ稼動します。
例:
# log entry showing platform 1 has 2 clients and 1 server
platform1_1 | 13-Jan-2020 17:08:53.231 INFO [disco-event-worker-#37%twx-core-server%] org.apache.ignite.logger.java.JavaLogger.info Topology snapshot [ver=5, locNode=0cab6e47, servers=1, clients=2, state=ACTIVE, CPUs=12, offheap=1.6GB, heap=9.9GB]
# log entry showing platform 2 has 2 clients and 1 server
platform2_1 | 13-Jan-2020 15:02:29.736 INFO [ForkJoinPool.commonPool-worker-1] org.apache.ignite.logger.java.JavaLogger.info Topology snapshot [ver=4, locNode=c7383c40, servers=1, clients=3, state=ACTIVE, CPUs=16, offheap=1.6GB, heap=14.0GB]
HTTP_PORT エラーが原因でサーバーが起動しない
サービス検出を実装するためには、外部サービスが ThingWorx に接続する際に経由する必要がある HTTP_PORT が、サーバーの起動前に定義されている必要があります。これはプラットフォームアプリケーションが実行されている Apache Tomcat で公開されるポートです。Tomcat を実行しているプロセスでこの環境変数が使用可能でなければなりません。これを setEnv ファイルで設定することも、サービス定義を更新することもできます。
Tomcat サービス定義:
[Unit]
Description=Apache Tomcat Web Application Container
After=network.target
[Service]
Type=forking
PIDFile=/var/run/tomcat.pid
Environment=CATALINA_PID=/var/run/tomcat.pid
Environment=JAVA_HOME=/usr/lib/jvm/jdk1.8.0_191
Environment=HTTP_PORT=8080
Environment=CATALINA_HOME=/usr/share/tomcat9/9.0.26
Environment=CATALINA_BASE=/usr/share/tomcat9/9.0.26
ThingWorx Connection Server が認証エラーで ThingWorx に接続できない
ThingWorx サーバーでアプリケーションキーを作成し、このアプリケーションキーを ThingWorx Connection Server コンフィギュレーションに追加する必要があります。このキーが存在しないか一致しない場合、Connection Server はプラットフォームへの接続を確立する際に認証エラーを返します。
ThingWorx Connection Server が ThingWorx サーバーを検出できない
ThingWorx Connection Server がプラットフォームに接続しない場合、ThingWorx サーバーに保存されている環境変数 HTTP_PORT が、プラットフォームが動作しているポートに設定され、サービス名が ThingWorx に設定されているものと一致していることを確認してください。いずれかが間違っている場合、Connection Server は ThingWorx サーバーを検出しません。
また、ThingWorx サーバーが Apache ZooKeeper で不正なアドレスを登録している可能性があります。これは ZooKeeper が動作しているマシンの IP アドレスを ThingWorx サーバーが特定する際に発生する可能性があります。アドレスリゾルバはホストマシン上にあるすべてのネットワークインタフェースのすべての IP アドレスをスキャンして、そのマシンの LAN アドレスである可能性が最も高い IP アドレスを特定します。マシンに複数の IP アドレスがある場合、マシンにサイトローカル IP アドレスが 1 つあればそのアドレスが優先され (例: 192.168.x.x または 10.10.x.x、通常は IPv4)、マシンにサイトローカル IP アドレスが 2 つ以上ある場合には 1 つ目のサイトローカルアドレスが返されます。マシンにサイトローカルアドレスがない場合、検出された 1 つ目の非ループバックアドレス (IPv4 または IPv6) が返されます。
アプリケーションのパフォーマンスに関する問題
クラスタ環境では、Thing データが分散しているので、アプリケーションの記述方法がパフォーマンスに大きな影響を与えます。スクリプトが実行されているサーバー以外へのラウンドトリップを削減することが重要です。詳細については、HA アプリケーションの最良事例を参照してください。
キャッシュプロバイダが起動しない
Apache Ignite キャッシュプロバイダが起動しない場合、コンフィギュレーションに問題がある可能性があります。例:
platform1_1 | 2020-07-13 17:34:14.965+0000 [L: ERROR] [O: E.c.q.l.c.Logger] [I: ] [U: SuperUser] [S: ] [P: platform1] [T: main] *** CRITICAL ERROR ON STARTUP: Failed to start CacheProvider com.thingworx.cache.ignite.IgniteCacheProvider
ZooKeeper ノードをチェックして、ZooKeeper が正しく動作していることを確認し、ローカルノードが設定済みポートで ZooKeeper サーバーにアクセスできることを確認することをお勧めします。
ZooKeeper に問題なければ、Ignite クラスタが正常に動作しているかどうかを確認します。ログで問題がないか確認し、トポロジースナップショットでクラスタが正しいサイズであることを確認します。ローカルノードが必要なすべてのポートで Ignite ホストにアクセスできることを確認します。
Apache Ignite クライアントが ThingWorx JVM をシャットダウンする
Ignite クライアントは ThingWorx JVM をスローダウンさせ、Catalina ログで次のエラーを返すことがあります。
SEVERE: Blocked system-critical thread has been detected. This can lead to cluster-wide undefined behaviour [workerName=sys-stripe-5, threadName=sys-stripe-5-#6%twx-core-server%, blockedFor=10s] ...
SEVERE: JVM will be halted immediately due to the failure: [failureCtx=FailureContext [type=CRITICAL_ERROR, err=class o.a.i.IgniteInterruptedException: Got interrupted while waiting for future to complete.]]
Ignite ノードが一定期間同期できない場合、メモリが同期していないので VM をシャットダウンします。
アプリケーションの設計上の問題により、この動作は通常、非常に大規模なインフォテーブルがプロパティとして使用される場合に発生します。このような大規模なインフォテーブルを書き込むたびに、テーブルプロパティが完全に同期されます。これによって JVM が停止します。
大規模なインフォテーブルプロパティはデータベーステーブルに変換することをお勧めします。
Apache Ignite の接続性の問題
Ignite に接続タイムアウト、クライアント接続、またはネットワーク待ち時間の問題がある場合、platform-settings.json ファイルで cache 設定の下にある次の Ignite アドバンスコンフィギュレーションを有効にします。各値の設定方法については、Ignite のドキュメンテーションを参照してください。platform-settings.json ファイルの詳細については、ThingWorx HA のプラットフォームの設定を参照してください。
# This failure timeout automatically controls the following parameters: getSocketTimeout(), getAckTimeout(), getMaxAckTimeout(), getReconnectCount().
# If any of those parameters is set explicitly, the failure timeout setting will be ignored. For example, for stable low-latency networks the
# failure detection timeout may be set to ~120 ms.
failure-detection-timeout = 10000
client-failure-detection-timeout = 30000
# should only be used for advanced configuration
tcp-communication-spi {
connection-timeout = 5000
socket-write-timeout = 2000
slow-client-queue-limit = 0
}
# should only be used for advanced configuration
tcp-discovery-spi {
socket-timeout = 5000
ack-timeout = 5000
join-timeout = 5000
network-timeout = 5000
connection-recovery-timeout = 5000
reconnect-count = 10
reconnect-delay = 2000
so-linger = 5
stats-print-frequency = 0
}
モデルプロバイダでのスタックロック
モデル同期化では、データベースロックを使用して変更ログの一貫性が保証されます。スタックロックによって、少なくともモデルの変更では、システム全体がハングする可能性があります。スタックロックが発生した場合、以下の操作を実行できます。
PostgreSQL
a. https://www.postgresql.org/docs/9.3/static/runtime-config-client.html の説明に従って、PostgreSQL でロックタイムアウトを設定することで、スタックロックを待機している間にハングアップしないようにします。
以下に例を示します。
SET lock_timeout = 3000
b. テーブルのロックを取得するよう試みます。
c. ロックタイムアウトが原因でサーバーがロックの取得に失敗した場合、以下のクエリーを使用して既存のロックの経過時間を調べます。
select extract(epoch from (now() - query_start)) from pg_stat_activity where query like '%lock <tableName> in exclusive mode;'
d. ロックの経過時間が設定されているしきい値を超えている場合、以下のクエリーを実行して、指定されたテーブルのロックを保持しているプロセスを調べます。
SELECT t.schemaname,
t.relname,
l.locktype,
l.page,
l.virtualtransaction,
l.pid,
l.mode,
l.granted
FROM pg_locks l
JOIN pg_stat_all_tables t ON l.relation = t.relid
WHERE t.schemaname <> 'pg_toast'::name AND t.schemaname <> 'pg_catalog'::name and t.relname = '<tableName>'
e. 以下のコマンドを使用して、ロックを保持しているプロセスを終了します。
SELECT pg_terminate_backend(pid);
MS SQL:
a. https://docs.microsoft.com/en-us/sql/t-sql/statements/set-lock-timeout-transact-sql?view=sql-server-2017 の説明に従って、MS SQL でロックタイムアウトを設定することで、スタックロックを待機している間にハングアップしないようにします。
以下に例を示します。
set lock_timeout 3000;
b. テーブルのロックを取得するよう試みます。
c. ロックタイムアウトが原因でサーバーがロックの取得に失敗した場合、以下のクエリーを実行して、指定されたテーブルのロックを保持しているプロセスを調べます。
select
object_name(p.object_id) as tablename, request_owner_id, session_id
from
sys.dm_tran_locks l
inner join sys.partitions p on l.resource_associated_entity_id = p.object_id inner join sys.dm_tran_session_transactions tst ON l.request_owner_id = tst.transaction_id
and object_name(p.object_id) = '<tableName>'
d. 前の手順で取得した session_id を渡して以下のクエリーを使用することで、既存のロックの経過時間を調べます。
select datediff(second, (select last_batch from master.dbo.sysprocesses where spid = <session_id>), CURRENT_TIMESTAMP)
e. ロックの経過時間が設定されているしきい値を超えている場合、以下のコマンドで前のクエリーの結果の session_id を使用して、ロックを保持しているプロセスを終了します。
kill <sessionId>;
EnsembleTracker エラー
アプリケーションログに次のようなエラーが表示される場合、ZooKeeper サーバーが正常に動作していても、Apache Curator フレームワークがコンフィギュレーションの変更を処理できないことが問題の原因である可能性があります。
2021-03-22 06:35:10.092+0000 [L: ERROR] [O: o.a.c.f.i.EnsembleTracker] [I: ] [U: ] [S: ] [P: VTWSandboxSVA2] [T: main-EventThread] Invalid config event received: {server.2=52.149.229.159:2888:3888:participant, server.1=0.0.0.0:2888:3888:participant, server.3=13.92.154.53:2888:3888:participant, version=0}
これを解決するには、zoo.cfg で使用されているサーバーマッピングのコンフィギュレーションを、クライアントポートが含まれるように変更します。
次のコンフィギュレーションによってエラーが発生することがあります。
server.1= xx.xxx.x.xx:2888:3888
server.2= xx.xxx.x.xx:2888:3888
server.3= xx.xxx.x.xx:2888:3888
したがって、次のように、クライアントポートが含まれるようにコンフィギュレーションを更新します。
server.1= xx.xxx.x.xx:2888:3888;2181
server.2= xx.xxx.x.xx:2888:3888;2181
server.3= xx.xxx.x.xx:2888:3888;2181
これは役に立ちましたか?