首页 > 编程语言 >2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)

时间:2023-07-31 16:31:35浏览次数:38  
标签:程序运行 byteman thread 示例 rule start 监控 main



文章目录

  • 一、 统计方法耗时(程序运行中)
  • 1、创建示例类
  • 2、建立监控
  • 1)、获取运行程序的进程号
  • 2)、建立监控
  • 3、编制脚本
  • 4、检测脚本
  • 5、提交脚本
  • 6、验证
  • 7、卸载脚本
  • 二、其他示例
  • 1、javaagent示例(程序未运行)
  • 1)、创建示例类
  • 2)、编译及测试
  • 3)、编制脚本
  • 4)、运行脚本
  • 5)、测试
  • 2、监控jvm的类
  • 1)、创建示例类
  • 2)、编制脚本
  • 3)、运行脚本
  • 4)、验证
  • 3、Bmjava命令的应用
  • 4、注入正在运行的类(jvm类)
  • 1)、创建示例类
  • 2)、编制脚本
  • 3)、建立监控
  • 4)、提交脚本
  • 5)、验证
  • 5、如何查看在运行的规则
  • 6、如何在一个运行的程序中安装一个代理
  • 7、如何检查规则的正确性
  • 1)、示例规则-thread.btm
  • 2)、示例规则-App1.btm
  • 3)、验证
  • 8、如何确定规则是否运行
  • 1)、示例类
  • 2)、规则



本文介绍了byteman的其他几种应用场景及示例,比如javaagent、监控jvm、bmjava命令、如何查看运行的规则、检查规则的正确性、检查规则是否在运行中等。
本文分为2个部分,即运行中方法耗时监控和其他示例。

一、 统计方法耗时(程序运行中)

该类是实时显示控制台输入的结果以及输入的是end时退出。
程序运行中是表示程序处于运行中进行某些方法的耗时监控。

1、创建示例类

package com.win.byteman;
 
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
 
/**
 * @author alan 2018年12月26日
 */
public class WorkerDemo {
   public static void main(String[] args) {
      WorkerDemo workerDemo = new WorkerDemo();
      DataInputStream dataInputStream = new DataInputStream(System.in);
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(dataInputStream));
      try {
         String next;
         while ((next = bufferedReader.readLine()) != null) {
            System.out.println(
                   "==========================================开始调用==========================================");
            workerDemo.working(next);
            System.out.println(
                   "==========================================结束调用==========================================");
            if (next.contains("end")) {
                break;
            }
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
 
   private void working(String input) {
      System.out.println("输入内容:" + input);
//    try {
//       TimeUnit.SECONDS.sleep(2);
//    } catch (InterruptedException e) {
//       e.printStackTrace();
//    }
   }
}

2、建立监控

1)、获取运行程序的进程号

在cmd中输入jps,结果如下图:

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_java

2)、建立监控

在cmd中执行命令

bminstall -b -Dorg.jboss.byteman.tranform.all 13456

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_java byteman_02

3、编制脚本

WorkerDemo.btm
文件存储在:D:\application\byteman-download-4.0.5\sample\testing
规则如下:

RULE trace worker time start
 
CLASS WorkerDemo
METHOD working(String)
AT ENTRY
IF TRUE
DO createTimer($0)
ENDRULE
 
RULE trace worker time stop
CLASS WorkerDemo
METHOD working(String)
AT EXIT
IF TRUE
DO traceln("                           working method  spent [" + getElapsedTimeFromTimer($0) + "] ms                            ");
    deleteTimer($0);
ENDRULE

4、检测脚本

脚本检测需要建立起脚本与需要监控的类之间的关系。
目录需要切换到classes所在的目录,btm文件所在的目录以实际的为准,本示例中所在的地址是D:\application\byteman-download-4.0.5\sample\testing。
在cmd中将目录cd到classes所在的目录,然后执行命令

bmcheck -p com.win.byteman -cp . D:\application\byteman-download-4.0.5\sample\testing\WorkerDemo.btm

如果执行成功则如下图所示

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_jvm_03


否则则可能有异常抛出,例如

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_java_04


该异常的原因是在btm所在的目录找不到classes对应的包目录。

当然,如果方便起见,也可以将btm放在与classes目录下,统一切换到classes目录下操作即可。

5、提交脚本

同样,需要在classes目录下提交脚本,执行命令

bmsubmit -i D:\application\byteman-download-4.0.5\sample\testing\WorkerDemo.btm

如果成功则如下图所示

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_java_05

6、验证

在运行程序控制台输入任意参数,查看其结果

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_jvm监控_06

7、卸载脚本

卸载脚本就是不再对程序进行监控。在cmd中执行命令

bmsubmit -u D:\application\byteman-download-4.0.5\sample\testing\WorkerDemo.btm

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_java byteman_07

二、其他示例

1、javaagent示例(程序未运行)

1)、创建示例类

package com.win.byteman;
 
class App1
{
     public static void main(String[] args)
     {
         for (int i = 0; i < args.length; i++) {
             System.out.println(args[i]);
         }
     }
}

2)、编译及测试

通过cmd命令行进行编译。
cd到classes所在的目录(即包文件夹所在的目录)或者直接到类所在的目录进行编译,即
D:\application\byteman-download-4.0.5\sample\testing

D:\application\byteman-download-4.0.5\sample\testing\com\win\byteman
执行编译命令:

Javac com/win/byteman/App1.java
# 或
Java App1.java

完成上述步骤后,在cmd中运行编译后的classes文件,执行命令:

Java com.win.byteman.App1 testing

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_java byteman_08


执行java命令时需要带上包名,同时需要切换目录至classes所在的目录

3)、编制脚本

该脚本放在与classes目录下,当然也可以放在其他地方,但是在执行脚本的时候需要加上脚本所在目录。
脚本中如果有中文,会出现乱码,具体不知道是规则脚本中不能有中文字符还是其他的原因。
脚本名称:app1.btm

RULE trace main entry

CLASS App1
METHOD main
AT ENTRY
IF true
DO traceln("entering main")
ENDRULE
 
RULE trace main exit
CLASS App1
METHOD main
AT EXIT
IF true
DO traceln("exiting main")
ENDRULE

关于脚本说明:
该脚本有针对App1类的main方法两个规则。
第一个规则是进入该方法时输出:entering main
第二个规则是退出该方法时输出:exiting main

This script contains two rules both of which specify code to be injected into METHOD main of CLASS AppMain.
The first rule is injected AT ENTRY i.e. at the start of the method. The code to be injected is the IF DO part. In the first rule it calls builtin operation traceln(String) which prints its argument to System.out() followed by a newline .
The second rule is injected AT EXIT i.e. at the point(s) where control returns from method main.
Both rules specify condition IF true which means the DO part is always executed. You can supply a different Java expression if you want to compute whether or not the actions following DO are run.

4)、运行脚本

运行脚本的命令根据实际需要而定。
运行命令时需要关注btm文件所在的位置,本示例是放在classes所在的目录,如果不在该目录下则直接带上绝对地址即可。
当然在运行脚本前也可以通过bmcheck命令检查脚本是否合法,具体参考本文的第一个示例中的检测脚本章节。
The -javaagent option used to run the progarm with these Byteman rules is supported by all the main desktop and server JVMs. The syntax is

-javaagent : path_to_agent_jar = agent_option1 , agent_option_2 , . . .

The Linux command to run the program with Byteman and this rule set is

java -javaagent:${BYTEMAN_HOME}/lib/byteman.jar=script:app1.btm com.win.byteman.App1 foo bar baz

or on Windows

java -javaagent:%BYTEMAN_HOME%\lib\byteman.jar=script:app1.btm com.win.byteman.App1 testing again

命令说明:
告诉虚拟机在哪里找到agent的jar,本机是%BYTEMAN_HOME%\lib\byteman.jar
本示例中仅是the = sign,指定规则script:app1.btm。agent通过加载的btm文件读取操作,如果需要加载更多的btm文件则配置更多的btm文件即可。
-javaagent是java命令的一个参数,com.win.byteman.App1 foo bar baz 是java执行的具体的类及传递的参数。

The value after the : tells the JVM where to find the Byteman agent jar, ${BYTEMAN_HOME}/lib/byteman.jar. We only supply one agent option following the = sign, script:app1.btm, specifying the location of the Byteman rule script. The Byteman agent reads this option then loads and injects the rules from file app1.btm. If we wanted to load more than one script we could provide multiple script:file agent options, separated by a comma.

When you pass -javaagent on the command line the Byteman agent starts executing during JVM startup before the application is run. So, it will read the rules and inject side effects into App1.main() before this method gets called. The output should be as follows.

5)、测试

运行脚本的结果正常的情况如下图:

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_java byteman_09


异常的结果(之一)如下图:

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_jvm监控_10

2、监控jvm的类

1)、创建示例类

package com.win.byteman;
 
class App2
{
    public static void main(String[] args)
    {
        for (int i = 0; i < args.length; i++) {
            final String arg = args[i];
            Thread thread = new Thread(arg) {
                public void run() {
                System.out.println(arg);
                }
            };
 
            thread.start();
            try {
                thread.join();
            } catch (Exception e) {
            }
        }
    }
}

2)、编制脚本

该脚本放在与classes目录下,当然也可以放在其他地方,但是在执行脚本的时候需要加上脚本所在目录。
脚本名称:thread.btm

RULE trace thread start
CLASS java.lang.Thread
METHOD start()
IF true
DO traceln("*** start for thread: "+ $0.getName())
ENDRULE

规则说明:
该规则是监控Thread的start方法,输出跟踪的内容。

This rule is injected into METHOD start() of the JVM runtime CLASS java.lang.Thread. It prints a trace message pasted together using the String + operator. Now start() is an instance method so when it is called there is a specific Thread instance which is the target for the method call.

The special variable $0 can be used to refer to this target object. start() has no arguments but in other cases where there are the arguments to the call which triggers the rule they can be referenced using $1, $2 etc.

Byteman knows that $0 references a Thread object so it type checks the method invocation $0.getName() and verifies that the result type is String. The injected code makes a call this method, appends the result to the constant String and passes the result to method traceln() to be written to System.out.

3)、运行脚本

运行脚本,由于是监控jvm的类,所以需要按照如下的命令进行。
To run this program using the new script we modify the script: agent option to reference file thread.btm. But that’s not enough if we want to inject code into JVM classes. We need to provide some extra options/arguments. On Linux:

java -javaagent:${BYTEMAN_HOME}/lib/byteman.jar=script:thread.btm,boot:${BYTEMAN_HOME}/lib/byteman.jar -Dorg.jboss.byteman.transform.all com.win.byteman.App2 foo bar baz

or on Windows:

java -javaagent:%BYTEMAN_HOME%\lib\byteman.jar=script:thread.btm,boot:%BYTEMAN_HOME%\lib\byteman.jar -Dorg.jboss.byteman.transform.all com.win.byteman.App2 foo bar baz

本示例是针对jvm的Thread进行监控,所以通过bootstarp classloader加载。

Class Thread is a JVM class which means it gets loaded by the bootstrap classloader. Byteman can only inject code into this class if the Byteman agent classes are also loaded by the bootstrap classloader. The extra agent option boot:${BYTEMAN_HOME}/lib/byteman.jar is appended after the script option (note the comma used as a separator). This makes sure that the byteman agent jar is installed into the bootstrap classpath.

Class Thread also happens to be in package java.lang. Normally Byteman is super-cautious and will not inject code into this package in case it beaks the JVM. If you really want to change methods of classes in this package you need to define the system property org.jboss.byteman.transform.all.

4)、验证

运行脚本的结果正常的情况如下图:

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_jvm监控_11

3、Bmjava命令的应用

例子参考监控jvm示例和本文中的统计方法耗时示例。
On Linux you can use the command script bmjava.sh to wrap up the -javaagent options for you. It looks very much like the java command but it accepts Byteman rule scripts on the command line and bundles them up as -javaagent script: options. It also automatically bundles in the byteman jar using the boot: agent option. So, using bmjava.sh the previous command line simplifies to

bmjava.sh -i thread.btm com.win.byteman.App2 foo bar baz

Notice that the flag used there is -i for load.
On Windows if you are using byteman release 2.0.1 or later there is an equivalent script called bmjava.bat which you can execute using command bjava. So the previous command simplifies to

bmjava -i thread.btm com.win.byteman.App2 foo bar baz

Note that you need to add the installed bin directory ${BYTEMAN_HOME}/bin to your path in orderto be able to execute the script by name (on windows use %BYETMAN_HOME%/bin)

4、注入正在运行的类(jvm类)

本示例是监控运行中的Thread,监控普通的类是否可以使用本方式没有测试(理论上是可以的),同时,监控运行中的类也可以采用本文的统计方法耗时(程序运行中)部分的说明。

1)、创建示例类

package com.win.byteman;
 
import java.io.DataInputStream;
 
class App3
{
    public static void main(String[] args)
    {
        try {
        DataInputStream in = new DataInputStream(System.in);
        String next = in.readLine();
        while (next != null && next.length() > 0 && !next.contains("end")) {
        final String arg = next;
        Thread thread = new Thread(arg) {
            public void run() {
                System.out.println(arg);
            }
            };
        thread.start();
        try {
            thread.join();
        } catch (Exception e){
        }
        next = in.readLine();
        }
    } catch (Exception e) {
    }
    }
}

编译略。

2)、编制脚本

该文件在classes所在目录。
脚本名称:thread.btm

RULE trace thread start
CLASS java.lang.Thread
METHOD start()
IF true
DO traceln("----------------------- start for thread: "+ $0.getName())
ENDRULE

3)、建立监控

本示例中建立监控的方式,与本文中其他的方式有所不同,理论上应该都可以,但没有做测试。
The agent listener is enabled on the java command line using agent option listener:true. On Linux the command is this

java -javaagent:${BYTEMAN_HOME}/lib/byteman.jar=listener:true,boot:${BYTEMAN_HOME}/lib/byteman.jar -Dorg.jboss.byteman.transform.all com.win.byteman.App3

or on Windows

java -javaagent:%BYTEMAN_HOME%\lib\byteman.jar=listener:true,boot:%BYTEMAN_HOME%\lib\byteman.jar -Dorg.jboss.byteman.transform.all com.win.byteman.App3

建立监控成功后测试,如下图:

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_java_12

4)、提交脚本

java -classpath %BYTEMAN_HOME%\lib\byteman-submit.jar org.jboss.byteman.agent.submit.Submit -l thread.btm

提交成功,则出现如下界面

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_jvm监控_13

5)、验证

在cmd中输入需要测试的内容,测试内容如下图红框中所示

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_java byteman_14

5、如何查看在运行的规则

Running bmsubmit.sh again we can see that the rule has been successfully compiled.
执行命令:

bmsubmit.sh

输出:

# File thread.btm line 4
RULE trace thread start
CLASS java.lang.Thread
METHOD start()
AT ENTRY
IF true
DO traceln("*** start for thread: "+ $0.getName())
ENDRULE
Transformed in:
loader: sun.misc.Launcher$AppClassLoader@5acac268
trigger method: java.lang.Thread.start() void
compiled successfully

This time there is an extra line at the end of the output saying compiled successfully. This means the rule has been type-checked and executed. Type checking only happens when the rule is first triggered – in this case when Thread.start() is called after typing in the line containing the word baz. If type checking had failed then execution of the injected code would be inhibited and the listing would include details of the type error. Injected code is only removed when the rule is unloaded.

6、如何在一个运行的程序中安装一个代理

参考本文的使用示例中统计方法耗时(运行中)的例子。

7、如何检查规则的正确性

使用bmcheck命令进行检查。

1)、示例规则-thread.btm

由于本示例使用的是Thread,jvm的类,所以不需要。

RULE trace thread start
CLASS java.lang.Thread
METHOD start()
IF true
DO traceln("----------------------- start for thread: "+ $0.getName())
ENDRULE
另外一种形式的规则设置
RULE trace thread start
CLASS Thread
METHOD start()
IF true
DO traceln("----------------------- start for thread: "+ $0.getName())
ENDRULE

On Linux you run command script bmcheck.sh

>bmcheck.sh thread.btm
#或者
>bmcheck.sh -p java.lang -cp . thread.btm

checking rule trace thread start
parsed rule “trace thread start” for class java.lang.Thread
type checked rule “trace thread start”

TestScript: no errors
On Windows if you are usiing release 2.0.1 or later use the equivalent script bmcheck.bat.

> bmcheck thread.btm
# 或者
> bmcheck  -p java.lang -cp . thread.btm

checking rule trace thread start
parsed rule “trace thread start” for class java.lang.Thread
type checked rule “trace thread start”

TestScript: no errors

2)、示例规则-App1.btm

示例类:

package com.win.byteman;
 
class App1
{
     public static void main(String[] args)
     {
         for (int i = 0; i < args.length; i++) {
             System.out.println(args[i]);
         }
     }
}

编译完成后,做下面的操作。

This rule does not use the fully qualified name of the target class. That’s ok because the agent notices when com.win.byteman.App1 gets loaded and realises that the rule applies to it. But when we are checking rules offline the application is not run so Byteman does not know which package to use to lookup the class mentioned in the rule. The -p flag can be used to suggest one or more package prefixes for the type checker to try.

RULE trace main entry
CLASS App1
METHOD main
AT ENTRY
IF true
DO traceln("进入 main")
ENDRULE
 
RULE trace main exit
CLASS App1
METHOD main
AT EXIT
IF true
DO traceln("退出 main")
ENDRULE
或者另外一种形式
RULE trace main entry
CLASS com.win.byteman.App1
METHOD main
AT ENTRY
IF true
DO traceln("进入 main")
ENDRULE
 
RULE trace main exit
CLASS com.win.byteman.App1
METHOD main
AT EXIT
IF true
DO traceln("退出 main")
ENDRULE

执行如下命令

bmcheck -p com.win.byteman -cp . app1.btm
#或者
bmcheck app1.btm

3)、验证

8、如何确定规则是否运行

1)、示例类

package com.win.byteman;
 
class App1
{
     public static void main(String[] args)
     {
         for (int i = 0; i < args.length; i++) {
             System.out.println(args[i]);
         }
     }
}

2)、规则

app1.btm

RULE trace main entry
CLASS com.win.byteman.App1
METHOD main
AT ENTRY
IF true
DO traceln("entry main")
ENDRULE
 
RULE trace main exit
CLASS com.win.byteman.App1
METHOD main
AT EXIT
IF true
DO traceln("exit main")
ENDRULE

Sometimes you may be unsure whether your rules are being injected correctly. Perhaps the target method is never executed. Perhaps the rule condition is always false. Or maybe a parse or type error is stopping them being executed. If you run Byteman in verbose mode you will see trace output telling you what Byteman is doing. Verbose mode is enabled by setting a system property
执行命令:

java -Dorg.jboss.byteman.verbose -javaagent:%BYTEMAN_HOME%/lib/byteman.jar=script:app1.btm com.win.byteman.App1 foo bar baz

2、【java程序运行监控byteman】使用示例(运行中方法耗时监控、javaagent监控、jvm监控、规则的检查、是否运行以及查看等)_javaagent_15


The trace is quite verbose but all the information you need is there if you look for it.

  • When class AppMain is loaded the trigger locations for each rule is identified and the rule code is injected

Next the main method gets called and you can see an execute message for the entry rule (you can ignore the messages about helper activation and rule installation just now or read the Ptrogrammer’s Guide if you want them explained)

  • The execute message is followed by the the enter rule’s trace message.
  • The main method prints all its its ouptut
  • Just before it returns there is another execute message for the exit rule (again, just ignore the messages about rule installation)
  • The second execute message is followed by the exit rule’s trace message .

以上,本文介绍了byteman的其他几种应用场景及示例,比如javaagent、监控jvm、bmjava命令、如何查看运行的规则、检查规则的正确性、检查规则是否在运行中等。


标签:程序运行,byteman,thread,示例,rule,start,监控,main
From: https://blog.51cto.com/alanchan2win/6909721

相关文章

  • Linux集群监控部署: prometheus 普罗米修斯 + Grafana
    前言之前我们有用到top、free、iostat等等命令,去监控服务器的性能,但是这些命令,我们只针对单台服务器进行监控,通常我们线上都是一个集群的项目,难道我们需要每一台服务器都去敲命令监控吗?这样显然不是符合逻辑的,Linux中就提供了一个集群监控工具–prometheus。prometheus监......
  • 使用prometheus监控mysql数据库性能指标
    目标:需要实现mysql的性能监控,如cpu占用率,内存占用率,连接数,执行效率等等.......如图所示: 实现思路一:使用linux的top命令,定时查看mysql的cup占用率,内存占用率........,然后将得到的数据存放进入数据库,后端拿到数据库数据,前端拿到数据后,进行数据重组,结合种种图表(echa......
  • redis monitor 监控说明
    1、监视器Redis监视器是用于监控或观察Redis服务器指令执行的一种特殊的客户端。创建Redis监视器的方式也很简单,启动一个客户端后,执行monitor指令,客户端将进入监视器状态。进入监视器状态的客户端将不再接受Redis指令输入,而称为了一个实时接受服务器指令执行信息的消费者。如下图......
  • 文件监控脚本
    先给脚本发了吧先贴个效果图完整代码如下:1#!/bin/bash23#指定要监控的文件夹路径4WATCH_DIR=$156#检查参数是否为空7if[-z"$WATCH_DIR"];then8echo"请输入要监控的文件夹路径"9exit110fi1112#备份文件13if[-d"bak/$WATCH......
  • Python elasticsearch 使用示例
    这里简单的罗列了些关于ES的自动化运维过程中可能用到的脚本DEMO创建索引并设置shards数#省略部分代码fromelasticsearchimportElasticsearchsrc_es=Elasticsearch(hosts=configs.es_source_host,maxsize=16)dest_es=Elasticsearch(hosts=configs.es_dest_host,ma......
  • 2023-7-28、29 文件监控和ssrf
    27晚上+28、29写了个文件监控的脚本,目前除了基本的监控只有自动删除新增文件和自动恢复被删文件的功能这点ssrf是28号的,先发了,要不不知道要拖到啥时候,等明天把脚本和剩下的发了ssrf 进去之后是这样的 让我们访问flag.php 只能来自127.0.0.1伪协议  直接读试试......
  • 智能视频分析技术烟火检测在视频监控场景中的应用
    智能视频分析技术烟火检测在视频监控场景中的应用随着炎夏到来,气温不断升高,生产、生活中一些细节稍不留意,就容易引发火灾、酿成灾害。夏季引发火灾事故主要包括电气火灾、汽车火灾、施工现场火灾、危化品火灾、物质自燃火灾、液化石油气火灾、电瓶车火灾、违章动火作业火灾等。根据......
  • 关于视频监控平台云台远程控制的重要意义
    关于视频监控平台云台远程控制的重要意义SkeyeVSS国标视频融合云平台可在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,平台可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、集群、电子地图、H.265视频自动转码、智能分析等视频......
  • 设计模式-迭代器模式在Java中使用示例
    场景为开发一套销售管理系统,在对该系统进行分析和设计时,发现经常需要对系统中的商品数据、客户数据等进行遍历,为了复用这些遍历代码,开发人员设计了一个抽象的数据集合类AbstractObjectList,而将存储商品和客户等数据的类作为其子类AbstractObjectList类的子类ProductList和Custo......
  • ffmpeg + SDL2播放音频示例
    在网上搜罗了各种各样的样例代码,都存在各种各样的问题,调了好长时间终于能无杂音播放了由于个人场景需要本样例加了选择扬声器的功能不过有的可能还会有问题,目前ogg的文件都能播,mp3有的不行写一下网上的其他代码可能存在的问题和我的修改注:代码是C++17,如果编不过需要小改一下......