Java 进程的 HealthChecker
HealthChecker for Java Process
我想创建一个健康检查程序,它将检查 java 进程的健康状况。我的进程做了很多事情并且是多线程的。可能会抛出各种异常,例如 Service / SQL / IO 等。我的计划是调用 HealthChecker
来检查各个线程中来自 catch 块的进程。这将检查所有不同的健康状况,如果有任何问题,它将暂停线程,并适当记录。将有其他进程读取该进程的日志,并提醒支持人员采取适当的措施。
下面是 java 过程的一般结构。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Schedular {
private static int numOfTasks = 10 ;
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
while(true){
for(int i=0;i<numOfTasks;i++){
service.execute(new Workers());
}
}
}
}
class Workers implements Runnable{
@Override
public void run() {
/*
* This can throw different exceptions , eg:
*/
try{
}catch(Exception e){
e.printStackTrace();
HealthChecker.checkHealth();
}
}
}
class HealthChecker{
public static void checkHealth() {
//Check health and then , log and pause all the threads
}
}
我想不出暂停所有线程的方法。如果出现数据库异常,我希望所有线程都暂停。我正在请求一些建议。
您与最佳实践相去甚远,但您没有询问监控线程健康状况的最佳实践 - 所以我不会回答这个问题。相反,我只会回答您提出的问题:如何暂停由 ExecutorService 管理的一组线程?
假设你的 Workers.run()
最终会在没有干预的情况下结束(换句话说,它不是无限循环——有意或无意),正确的做法是调用 service.shutdown()
(其中服务是您的 ExecutorService 实例)。为此,您可以将服务作为新参数传递给 HealthCheck.healthCheck()
。调用 shutdown() 将允许当前-运行 个线程完成,然后停止执行程序。
如果 Workers.run()
不会自然完成,最佳做法是您需要更改代码以使其完成。您可以调用 Thread.stop()
方法来暂停线程,还可以调用 Thread.suspend()
方法来暂停线程。这两个都是你使用的双重坏主意,原因有两个:
- 它们已被弃用,将使线程处于极不健康的状态。你用了以后会遇到很棘手的问题。
- 您正在使用 ExecutorService。这意味着您将线程管理委托给 class。如果你去搞乱 ExecutorService 下的 Threads 的状态,它就不能为你管理线程池,同样,你以后会遇到非常困难的问题。
您需要一种方法来阻止线程,直到发生某些允许线程继续运行的事件。我发现代码存在一些主要问题:
1) 主线程中的 while(true)
可能会导致 WhosebugError
。随着 while 循环的每次迭代,您将向执行程序添加 10 个以上的线程,并且这将无限继续。
2) 你的 运行() 中没有循环,所以即使捕获到异常并且我们等待 HealthCheck,运行() 方法仍然会退出。如果您可以不断地从主线程执行新线程来代替已终止的线程,则 运行() 中不需要循环,但主循环中目前不存在该逻辑。
但是,将这些问题搁置一旁是阻塞工作线程直到发生某些事件(可能是 HealthCheck 全部清除)的一种方法。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Schedular {
private static int numOfTasks = 10 ;
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
HealtchChecker hChecker = new HealthChecker();
for(int i=0;i<numOfTasks;i++){
service.execute(new Workers(hChecker));
}
}
}
class Workers implements Runnable{
private HealtchChecker hChecker;
public Workers(HealtchChecker hChecker){
this.hChecker = hChecker;
}
@Override
public void run() {
/*
* This can throw different exceptions , eg:
*/
while(true) {
try{
}catch (InterruptedException ie) {
throw ie;
}catch(Exception e){
e.printStackTrace();
HealthChecker.checkHealth();
}
}
}
}
class HealthChecker implements Runnable {
private final Semaphore semaphore = new Semaphore(1, true);
public void checkHealth() {
try {
semaphore.acquire();
} finally {
semaphore.release();
}
}
@Override
public void run(){
//code to check for errors that cause threads to pause.
if (inErrorState) {
semaphore.acquire();
} else {
semaphore.release();
}
}
}
有几件事值得一提。
1) 主线程只创建 10 个线程,数量没有限制。您可以根据需要进行调整。
2) Worker 线程是长期存在的,这意味着它会继续 运行ning 即使它遇到异常,除了 InterruptException。
3) HealthCheck不再是静态对象。它是一个共享对象。
4) HealthCheck 是一个 运行nable,可以在其自己的线程中执行以监视错误。我没有添加代码来执行这个线程。
5) HealCheck 使用信号量使线程阻塞,直到错误状态被清除。我寻找可以执行此操作的其他对象,例如 CountDownLatch 或 CyclicBarrier 或 Phaser,但这个对象最接近于为我们提供从一个点阻塞所有线程所需的东西(运行() 方法)。
它并不完美,但我认为它能让你更接近你想要的东西。
我想创建一个健康检查程序,它将检查 java 进程的健康状况。我的进程做了很多事情并且是多线程的。可能会抛出各种异常,例如 Service / SQL / IO 等。我的计划是调用 HealthChecker
来检查各个线程中来自 catch 块的进程。这将检查所有不同的健康状况,如果有任何问题,它将暂停线程,并适当记录。将有其他进程读取该进程的日志,并提醒支持人员采取适当的措施。
下面是 java 过程的一般结构。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Schedular {
private static int numOfTasks = 10 ;
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
while(true){
for(int i=0;i<numOfTasks;i++){
service.execute(new Workers());
}
}
}
}
class Workers implements Runnable{
@Override
public void run() {
/*
* This can throw different exceptions , eg:
*/
try{
}catch(Exception e){
e.printStackTrace();
HealthChecker.checkHealth();
}
}
}
class HealthChecker{
public static void checkHealth() {
//Check health and then , log and pause all the threads
}
}
我想不出暂停所有线程的方法。如果出现数据库异常,我希望所有线程都暂停。我正在请求一些建议。
您与最佳实践相去甚远,但您没有询问监控线程健康状况的最佳实践 - 所以我不会回答这个问题。相反,我只会回答您提出的问题:如何暂停由 ExecutorService 管理的一组线程?
假设你的 Workers.run()
最终会在没有干预的情况下结束(换句话说,它不是无限循环——有意或无意),正确的做法是调用 service.shutdown()
(其中服务是您的 ExecutorService 实例)。为此,您可以将服务作为新参数传递给 HealthCheck.healthCheck()
。调用 shutdown() 将允许当前-运行 个线程完成,然后停止执行程序。
如果 Workers.run()
不会自然完成,最佳做法是您需要更改代码以使其完成。您可以调用 Thread.stop()
方法来暂停线程,还可以调用 Thread.suspend()
方法来暂停线程。这两个都是你使用的双重坏主意,原因有两个:
- 它们已被弃用,将使线程处于极不健康的状态。你用了以后会遇到很棘手的问题。
- 您正在使用 ExecutorService。这意味着您将线程管理委托给 class。如果你去搞乱 ExecutorService 下的 Threads 的状态,它就不能为你管理线程池,同样,你以后会遇到非常困难的问题。
您需要一种方法来阻止线程,直到发生某些允许线程继续运行的事件。我发现代码存在一些主要问题:
1) 主线程中的 while(true)
可能会导致 WhosebugError
。随着 while 循环的每次迭代,您将向执行程序添加 10 个以上的线程,并且这将无限继续。
2) 你的 运行() 中没有循环,所以即使捕获到异常并且我们等待 HealthCheck,运行() 方法仍然会退出。如果您可以不断地从主线程执行新线程来代替已终止的线程,则 运行() 中不需要循环,但主循环中目前不存在该逻辑。
但是,将这些问题搁置一旁是阻塞工作线程直到发生某些事件(可能是 HealthCheck 全部清除)的一种方法。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Schedular {
private static int numOfTasks = 10 ;
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
HealtchChecker hChecker = new HealthChecker();
for(int i=0;i<numOfTasks;i++){
service.execute(new Workers(hChecker));
}
}
}
class Workers implements Runnable{
private HealtchChecker hChecker;
public Workers(HealtchChecker hChecker){
this.hChecker = hChecker;
}
@Override
public void run() {
/*
* This can throw different exceptions , eg:
*/
while(true) {
try{
}catch (InterruptedException ie) {
throw ie;
}catch(Exception e){
e.printStackTrace();
HealthChecker.checkHealth();
}
}
}
}
class HealthChecker implements Runnable {
private final Semaphore semaphore = new Semaphore(1, true);
public void checkHealth() {
try {
semaphore.acquire();
} finally {
semaphore.release();
}
}
@Override
public void run(){
//code to check for errors that cause threads to pause.
if (inErrorState) {
semaphore.acquire();
} else {
semaphore.release();
}
}
}
有几件事值得一提。
1) 主线程只创建 10 个线程,数量没有限制。您可以根据需要进行调整。
2) Worker 线程是长期存在的,这意味着它会继续 运行ning 即使它遇到异常,除了 InterruptException。
3) HealthCheck不再是静态对象。它是一个共享对象。
4) HealthCheck 是一个 运行nable,可以在其自己的线程中执行以监视错误。我没有添加代码来执行这个线程。
5) HealCheck 使用信号量使线程阻塞,直到错误状态被清除。我寻找可以执行此操作的其他对象,例如 CountDownLatch 或 CyclicBarrier 或 Phaser,但这个对象最接近于为我们提供从一个点阻塞所有线程所需的东西(运行() 方法)。
它并不完美,但我认为它能让你更接近你想要的东西。