【APM】Pinpoint 監控告警(三)


  本例介紹Pinpoint告警的相關內容,Pinpoint參考【APM】Pinpoint 安裝部署(一)

  Pinpoint Web會定期檢查應用程序的狀態,並在滿足某些預配置條件(規則)的情況下觸發警報。

  這些條件(默認情況下)由Web模塊中的后台批處理過程每3分鍾檢查一次(默認情況下),使用的是最后5分鍾的數據。一旦滿足條件,批處理過程就會向注冊到用戶組的用戶發送短信/電子郵件。

  本例Pinpoint版本是:1.8.5,下載地址:https://github.com/naver/pinpoint/releases/tag/1.8.5

  參考git文檔:https://naver.github.io/pinpoint/alarm.html

  參考博客:https://skyao.gitbooks.io/learning-pinpoint/content/alarm/code_implementation.html

Pinpoint告警原理

  1、下載源碼,通過源碼解析:

    Pinpoint中有一個匹處理類,BatchConfiguration.java,此類會進行批任務處理

 1 @Configuration
 2 @Conditional(BatchConfiguration.Condition.class)
 3 @ImportResource("classpath:/batch/applicationContext-batch-schedule.xml")
 4 public class BatchConfiguration{
 5     static class Condition implements ConfigurationCondition {
 6         @Override
 7         public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
 8             ......
 9             Resource resource = context.getResourceLoader().getResource("classpath:/batch.properties")
10             ......
11             final String enable = properties.getProperty("batch.enable");
12             ......
13         }
14     }
15 }

    Condition中會讀取配置文件batch.properties中的配置項batch.enable,默認是false。因此如果要開啟批處理功能,必須設置batch.enable=true。

  2、在Pinpoint中,在批處理任務配置文件(applicationContext-batch-schedule.xml)中,文件路徑為:pinpoint/web/src/main/resources/batch/applicationContext-batch-schedule.xml,可以找到定義的任務

1 <task:scheduled-tasks scheduler="scheduler">
2     <task:scheduled ref="batchJobLauncher" method="alarmJob" cron="0 0/3 * * * *" />
3     <task:scheduled ref="batchJobLauncher" method="agentCountJob" cron="0 0 2 * * *" />
4     <task:scheduled ref="batchJobLauncher" method="flinkCheckJob" cron="0 0/10 * * * *" />
5 </task:scheduled-tasks>
6 
7 <task:scheduler id="scheduler" pool-size="1"/>

    配置文件中,定義了執行告警Job的時間。定義了一個線程池大小為1的調度器scheduler

  3、在Pinpoint中,在告警任務配置文件(applicationContext-alarmJob.xml)中,文件路徑為:pinpoint/web/src/main/resources/batch/applicationContext-alarmJob.xml,

    reader:讀取數據 => 通過用戶配置的規則提供Checker,即異常校驗器。

    processor:處理數據 => 用Checker進行校驗,標記異常狀態。

    writer:回寫數據 => 判斷Checker是否有異常情況,有則報警。

 1 <batch:job id="alarmJob">
 2 <batch:step id="alarmPartitionStep">
 3     <batch:partition step="alarmStep" partitioner="alarmPartitioner">
 4         <batch:handler task-executor="alarmPoolTaskExecutorForPartition" />
 5     </batch:partition>
 6 </batch:step>
 7 <batch:listeners>
 8     <batch:listener ref="jobFailListener"/>
 9 </batch:listeners>
10 </batch:job>
11 
12 <batch:step id="alarmStep">
13 <batch:tasklet>
14     <batch:chunk reader="reader" processor="processor" writer="writer" commit-interval="1"/>
15 </batch:tasklet>
16 </batch:step>
17 
18 <bean id="alarmPartitioner" class="com.navercorp.pinpoint.web.alarm.AlarmPartitioner"/>
19 <bean id="reader" class="com.navercorp.pinpoint.web.alarm.AlarmReader" scope="step"/>
20 <bean id="processor" class="com.navercorp.pinpoint.web.alarm.AlarmProcessor" scope="step"/>
21 <bean id="writer" class="com.navercorp.pinpoint.web.alarm.AlarmWriter" scope="step"/>
22 
23 <task:executor id="alarmPoolTaskExecutorForPartition" pool-size="1" />

  4、在回寫數據類中AlarmWriter.java中發現,是通過注入AlarmMessageSender來發送消息

 1 public class AlarmWriter implements ItemWriter<AlarmChecker> {
 2 
 3     @Autowired(required = false)
 4     private AlarmMessageSender alarmMessageSender = new EmptyMessageSender();
 5 
 6     @Autowired
 7     private AlarmService alarmService;
 8 
 9     ......
10 
11     // 發送消息
12     private void sendAlarmMessage(CheckerResult beforeCheckerResult, AlarmChecker checker) {
13         if (isTurnToSendAlarm(beforeCheckerResult)) {
14             if (checker.isSMSSend()) {
15                 alarmMessageSender.sendSms(checker, beforeCheckerResult.getSequenceCount() + 1);
16             }
17             if (checker.isEmailSend()) {
18                 alarmMessageSender.sendEmail(checker, beforeCheckerResult.getSequenceCount() + 1);
19             }
20         }
21 
22     }
23 
24     ......
25 }

   5、在AlarmMessageSender初始化的值是EmptyMessageSender,通過查看EmptyMessageSender發現此類只是一個空的實現,所有這里只要我們自己實現AlarmMessageSender就能發送告警消息

 1 public class EmptyMessageSender implements AlarmMessageSender {
 2 
 3     @Override
 4     public void sendSms(AlarmChecker checker, int sequenceCount) {
 5     }
 6 
 7     @Override
 8     public void sendEmail(AlarmChecker checker, int sequenceCount) {
 9     }
10 
11 }

Pinpoint告警開發

  1、下載源碼,導入Idea中。

  2、由於查看pom文件,發現源碼編譯構建需要用到Maven3.5,JDK1.8,Java6,Java7,Java8,Java9,在開發環境中安裝好對應的Maven版本,以及配置好JDK版本

    

    下面是pom.xml文件中的內容,需要Maven 3.5,Maven不是3.5可以進行修改

 1 <requireMavenVersion>
 2     <version>3.5</version>
 3 </requireMavenVersion>
 4 <requireJavaVersion>
 5     <version>1.8</version>
 6 </requireJavaVersion>
 7 <requireEnvironmentVariable>
 8     <variableName>JAVA_HOME</variableName>
 9 </requireEnvironmentVariable>
10 <requireEnvironmentVariable>
11     <variableName>JAVA_6_HOME</variableName>
12 </requireEnvironmentVariable>
13 <requireEnvironmentVariable>
14     <variableName>JAVA_7_HOME</variableName>
15 </requireEnvironmentVariable>
16 <requireEnvironmentVariable>
17     <variableName>JAVA_8_HOME</variableName>
18 </requireEnvironmentVariable>
19 <requireEnvironmentVariable>
20     <variableName>JAVA_9_HOME</variableName>
21 </requireEnvironmentVariable>

  3、查看依賴,下載依賴jar包(部分依賴可以用相似版本替代),且對pinpoint/pom.xml文件進行修改,是項目能運行打包。

    a、修改spotbugs-exclude.xml,位子,此內容有2個地方要替換

1 <!--<excludeFilterFile>${maven.multiModuleProjectDirectory}/spotbugs-exclude.xml</excludeFilterFile>-->
2 <!-- 改為 -->
3 <excludeFilterFile>${basedir}/spotbugs-exclude.xml</excludeFilterFile>

    b、插件注釋掉

 1 <!--<plugin>-->
 2     <!--<groupId>org.apache.maven.plugins</groupId>-->
 3     <!--<artifactId>maven-jxr-plugin</artifactId>-->
 4     <!--<version>2.5</version>-->
 5     <!--<inherited>false</inherited>-->
 6     <!--<configuration>-->
 7         <!--<aggregate>true</aggregate>-->
 8         <!--<inputEncoding>${encoding}</inputEncoding>-->
 9         <!--<outputEncoding>${encoding}</outputEncoding>-->
10         <!--<windowTitle>Pinpoint ${project.version} Cross Reference</windowTitle>-->
11         <!--<docTitle>Pinpoint ${project.version} Cross Reference</docTitle>-->
12     <!--</configuration>-->
13 <!--</plugin>-->

    c、下載不下來直接注釋掉

 1 <!-- 注釋 -->
 2 <!--<profile>-->
 3     <!--<id>klocwork</id>-->
 4     <!--<build>-->
 5         <!--<plugins>-->
 6             <!--<plugin>-->
 7                 <!--<groupId>com.klocwork.ps</groupId>-->
 8                 <!--<artifactId>kwmaven</artifactId>-->
 9                 <!--<version>2.1.1</version>-->
10                 <!--<configuration>-->
11                     <!--<buildspec_filename>${KWINJECT_OUT_PATH}</buildspec_filename>-->
12                 <!--</configuration>-->
13                 <!--<executions>-->
14                     <!--<execution>-->
15                         <!--<phase>validate</phase>-->
16                         <!--<goals>-->
17                             <!--<goal>run</goal>-->
18                         <!--</goals>-->
19                     <!--</execution>-->
20                 <!--</executions>-->
21             <!--</plugin>-->
22 
23         <!--</plugins>-->
24     <!--</build>-->
25 <!--</profile>-->

    d、修改bootsrap-java9.pom文件

1 <!-- <jdk.version>9</jdk.version> -->
2 <!-- 修改為 -->
3 <jdk.version>1.9</jdk.version>

  4、實現和配置告警發消息類

    為了使用告警功能,必須通過實現 com.navercorp.pinpoint.web.alarm.AlarmMessageSender並注冊為spring managed bean 來實現自己的邏輯以便發送短信和郵件。當告警被觸發時, AlarmMessageSender#sendEmail, 和 AlarmMessageSender#sendSms 方法將被調用。

    AlarmMessageSenderImple.java 如下:

 1 public class AlarmMessageSenderImple implements AlarmMessageSender {
 2 
 3     private final Logger logger = LoggerFactory.getLogger(this.getClass());
 4 
 5     @Autowired
 6     UserGroupService userGroupService;
 7 
 8     @Override
 9     public void sendSms(AlarmChecker checker, int sequenceCount) {
10 
11         List<String> receivers = userGroupService.selectPhoneNumberOfMember(checker.getuserGroupId());
12         logger.info(" =============准備發送消息=============== " + receivers.size());
13 
14         if (receivers.size() == 0) {
15             return;
16         }
17         List<String> smsList = checker.getSmsMessage();
18         for (String message : smsList) {
19             logger.info("send SMS : {}", message);
20             // TODO Implement logic for sending SMS
21             for (String receiver : receivers) {
22                 logger.info("send email receiver : {}", receiver);
23             }
24         }
25     }
26 
27     @Override
28     public void sendEmail(AlarmChecker checker, int sequenceCount) {
29 
30         List<String> receivers = userGroupService.selectEmailOfMember(checker.getuserGroupId());
31         logger.info(" ==============准備發送郵件=============== " + receivers.size());
32 
33         if (receivers.size() == 0) {
34             return;
35         }
36 
37         String message = checker.getEmailMessage();
38         logger.info("send email : {}", message);
39 
40         // TODO Implement logic for sending email
41         for (String receiver : receivers) {
42             logger.info("send email receiver : {}", receiver);
43         }
44     }
45 }

    發郵件方法,可以參考:【Mail】JavaMail介紹及發送郵件(一)

    發短信需要對接第三方運營商。

    注冊AlarmMessageSenderImple,在applicationContext-batch.xml文件中注冊

1 <bean id="alarmMessageSenderImple" class="com.navercorp.pinpoint.web.alarm.AlarmMessageSenderImple"/>

    還在可以發郵件信息做成可配置形式,在batch.properties文件中提供smtp服務器信息和發送者的地址。在AlarmMessageSenderImple中進行使用

 1 pinpoint.url= #pinpoint-web server url
 2 alarm.mail.server.url= #smtp server address
 3 alarm.mail.server.port= #smtp server port
 4 alarm.mail.server.username= #username for smtp server authentication
 5 alarm.mail.server.password= #password for smtp server authentication
 6 alarm.mail.sender.address= #sender's email address
 7 
 8 ex)
 9 pinpoint.url=http://pinpoint.com
10 alarm.mail.server.url=stmp.server.com
11 alarm.mail.server.port=587
12 alarm.mail.server.username=pinpoint
13 alarm.mail.server.password=pinpoint
14 alarm.mail.sender.address=pinpoint_operator@pinpoint.com

    在AlarmMessageSenderImple時,注入相關參數

 1 @Value("#{batchProps['alarm.mail.server.url'] ?: ''}")
 2 String host;
 3 @Value("#{batchProps['alarm.mail.server.port'] ?: 587}")
 4 String port;
 5 @Value("#{batchProps['alarm.mail.server.username'] ?: ''}")
 6 String username;
 7 @Value("#{batchProps['alarm.mail.server.password'] ?: ''}")
 8 String password;
 9 @Value("#{batchProps['alarm.mail.sender.address'] ?: ''}")
10 String mailfrom;

  5、修改配置文件batch.properties

    在batch.properties中將batch.enable標志設置為true,開啟批處理功能

1 batch.enable=true

    batch.server.ip當有多個精確的Web服務器時,可以進行配置以防止並發批處理操作。僅當服務器的IP地址與中設置的值相同時,才執行批處理batch.server.ip(將此設置為127.0.0.1將在所有Web服務器中啟動批處理)

1 batch.server.ip=X.X.X.X

  6、配置mysql,需要用到MYSQL來存儲用戶信息以告警規則等,設置MYSQL服務器並在jdbc.properties文件中配置連接信息

    在resources/sql中有2個文件,CreateTableStatement-mysql.sql和SpringBatchJobRepositorySchema-mysql.sql,用來創建表。

1 jdbc.driverClassName=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://localhost:13306/pinpoint?characterEncoding=UTF-8
3 jdbc.username=admin
4 jdbc.password=admin

  7、其他

    a、可以在單獨的過程中啟動警報批處理 -只需使用Pinpoint-web模塊內的applicationContext-alarmJob.xml文件啟動彈簧批處理作業即可。

    b、可以通過修改applicationContext-batch-schedule.xml文件中的cron表達式來更改批處理執行時間

1 <task:scheduled-tasks scheduler="scheduler">
2     <task:scheduled ref="batchJobLauncher" method="alarmJob" cron="0 0/3 * * * *" />
3 </task:scheduled-tasks>

    c、改善警報批處理性能的方法 -警報批處理設計為可同時運行。如果您有許多注冊了警報的應用程序,則可以通過pool-size在applicationContext-batch.xml文件中進行修改來增加執行程序的線程池的大小。

1 <task:executor id="poolTaskExecutorForPartition" pool-size="1" />

  8、修改配置文件信息,配置Hbase及Zookeeper,參考:【APM】Pinpoint 安裝部署(一),然后使用Maven打包項目,打包后,將pinpoint-web-1.8.5.war,放入tomcat中運行

Pinpoint告警使用

  1、打開pinpoint網頁,打開pinpoint配置

    

  2、新增用戶信息

    

  3、新增用戶組

    

  4、添加用戶到用戶組

    

  5、設置告警規則,測試可以使用TOTAL COUNT / 請求總數量超過多少就報警

    

  6、頁面上發起請求,超過請求次數

  7、通過后台查看日志,或者是郵箱,可以發現告警已經實現

    

告警規則

  • SLOW COUNT / 慢請求數

    當應用發出的慢請求數量超過配置閾值時觸發。

  • SLOW RATE / 慢請求比例

    當應用發出的慢請求百分比超過配置閾值時觸發。

  • ERROR COUNT / 請求失敗數

    當應用發出的失敗請求數量超過配置閾值時觸發。

  • ERROR RATE / 請求失敗率

    當應用發出的失敗請求百分比超過配置閾值時觸發。

  • TOTAL COUNT / 總數量

    當應用發出的所有請求數量超過配置閾值時觸發。

    以上規則中,請求是當前應用發送出去的,當前應用是請求的發起者。 以下規則中,請求是發送給當前應用的,當前應用是請求的接收者。

  • SLOW COUNT TO CALLEE / 被調用的慢請求數量

    當發送給應用的慢請求數量超過配置閾值時觸發。

  • SLOW RATE TO CALLEE / 被調用的慢請求比例

    當發送給應用的慢請求百分比超過配置閾值時觸發。

  • ERROR COUNT TO CALLEE / 被調用的請求錯誤數

    當發送給應用的請求失敗數量超過配置閾值時觸發。

  • ERROR RATE TO CALLEE / 被調用的請求錯誤率

    當發送給應用的請求失敗百分比超過配置閾值時觸發。

  • TOTAL COUNT TO CALLEE / 被調用的總數量

    當發送給應用的所有請求數量超過配置閾值時觸發。

    下面兩條規則和請求無關,只涉及到應用的狀態

  • HEAP USAGE RATE / 堆內存使用率

    當應用的堆內存使用率超過配置閾值時觸發。

  • JVM CPU USAGE RATE / JVM CPU使用率

    當應用的CPU使用率超過配置閾值時觸發。

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM