服务运行问题
解压缩cat.zip
问题1:
描述:
解压cat.zip出现:
cat-3.0.0\lib\cpp\src\ccat - 以管理员身份运行 Bandizip 并创建符号链接.
cat-3.0.0\lib\cpp\src\lib - 以管理员身份运行 Bandizip 并创建符号链接.
cat-3.0.0\lib\python\lib - 以管理员身份运行 Bandizip 并创建符号链接.
分析:
在 Windows 操作系统中,“以管理员身份运行”指的是使用管理员级别的权限来执行某个程序,这通常用于需要对系统进行更改或访问受保护资源的情况
符号链接(Symbolic Link,简称 Symlink)是一种文件系统特性,它允许一个文件或者目录在不同的位置出现,实际上只是指向同一个文件系统的入口。
如果你想要创建符号链接,通常会使用命令行工具如 mklink(Windows 版本的命令),并且确实需要管理员权限来执行这个命令。
解决:
将Bandizip使用管理员权限打开,然后再解压cat.zip;
appdatas文件问题
描述:
安装cat过程中,目录data/appdatas/cat 和 data/applogs/cat 配置
解决:
与tomcat项目之间的关系为:
tomcat:D:\xx\tomcat\apache-tomcat-9.0.17\apache-tomcat-9.0.17
两个文件:D:\data\appdatas\cat 和 D:\data\applogs\cat
Error when try connecting to /127.0.0.1:2280
描述:
在日志中描述,即D:\data\applogs\cat文件中;
Error when try connecting to /127.0.0.1:2280
分析:
给datasource.xml配置文件的url添加<![CDATA[]]>
<url><![CDATA[jdbc:mysql://127.0.0.1:3307/catdb]]></url>
error when connect cat server config url
描述:
error when connect cat server config url http://127.0.0.1:8080/cat/s/router?domain=cat&ip=172.23.16.1&op=json
分析:
需要将client.xml文件的server ip不能是127.0.0.1 而得是内网ip 但是修改之后,仍旧显示拒绝连接;
排查过程:
查看CAT服务的状态;netstat -ano | findstr "2280"
检查网络联通性;ping ip
测试端口连接情况:telnet ip port
查看端口8080是否被监听;netstat -ano | findstr "8080"
检查jdk环境变量;
检查tomcat环境变量;// 添加环境变量;https://blog.csdn.net/Manta_ss/article/details/107541328
修改tomcat配置文件中的端口号,从8080改成80,即将D:\xxx\tomcat\apache-tomcat-9.0.17\apache-tomcat-9.0.17\conf\server.xml文件中的服务端口号从8080改成80;
修改hosts文件;将C:\Windows\System32\drivers\etc 文件中的127.0.0.1前面的#号删除;
结果:
可以顺利访问cat服务;
选择其他功能报500
问题描述:选择功能报500错误
分析:
错误日志为:
Error occured when handling uri: /cat/r/t
java.lang.RuntimeException: Error occured during handling outbound action(t)
点击页面的configs,出现登录窗口,CAT管理员默认账密是admin-admin;
通过上述点击configs,实现登录之后,选择页面左侧的选项就不报错了。但是不是之前的功能点模块;
页面左侧是:项目配置信息;应用监控配置;应用告警配置;全局系统配置
该问题通过修改tomcat的端口号得到解决;
修改tomcat配置文件中的端口号,从8080改成80,即将D:\xxx\tomcat\apache-tomcat-9.0.17\apache-tomcat-9.0.17\conf\server.xml文件中的服务端口号从8080改成80; 将该过程维持8080,不改成80;
Dashboard显示:出问题的CAT
描述:
访问http://12.0.0.1:8080/cat/r/ 的dashboard 出现如下内容:
出问题CAT的服务端:[127.0.0.1]
分析:
视频讲解中也出现该问题了。
https://www.bilibili.com/video/BV1m64y127f3?spm_id_from=333.788.videopod.episodes&vd_source=c901ae3ff497a02016ba7bada52b2e3b&p=8
参照该博客修改:
https://blog.csdn.net/sndayYU/article/details/108256438
端口80和端口8080
80端口;
是http协议的默认端口,使用浏览器就是默认80端口如访问百度https://www.baidu.com:80,不过80可以省略
8080端口:
一般是连接代理服务器的端口;
代理是什么?浏览器客户端——代理——服务器
代理在我们与服务器之间,我们与服务器通信的数据要经过代理。我们常见的代理可以是抓包软件burpsuite
开启burp的proxy代理功能要配置相应的端口,就是8080端口。
无前兆异常
描述1:
java.lang.NullPointerException
at com.dianping.cat.consumer.state.model.transform.BaseVisitor.visitStateReport(BaseVisitor.java:39)
at com.dianping.cat.report.task.DefaultRemoteServersUpdater.buildServers(DefaultRemoteServersUpdater.java:53)
at com.dianping.cat.report.server.ServersUpdaterManager$1.handle(ServersUpdaterManager.java:57)
at com.dianping.cat.task.TimerSyncTask$1.run(TimerSyncTask.java:82)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
at org.unidal.helper.Threads$RunnableThread.run(Threads.java:294)
描述2:
Started Netty Server Failed:2280
java.net.BindException: Address already in use: bind
分析:
端口占用的问题;
问题检索到是因为本地启动了zookeeper这个服务;
zookeeper启动后,日志显示:Started AdminServer on address 0.0.0.0, port 8080 and command URL /commands
这个是zookeeper的服务访问地址:http://127.0.0.1:8080/commands
告警问题总结
波动上升百分比(当前值)持续告警情况
功能实现
CAT+Springboot+Transaction
catFilter实现
优势
配置简单;
劣势
只能统计以getMapping区分的请求;
1. 依赖jar包直接导入idea项目
参考:https://blog.csdn.net/wutrg1502/article/details/122957533
但是该方法不能直接导入到项目中,存在问题,没有解决;
2. pom文件依赖:
参考:https://blog.csdn.net/m0_37527542/article/details/105354021
通过查看https://mvnrepository.com/artifact/com.dianping.cat/cat-client 发现版本3.0.0没有,需要修改成3.0.1
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-client</artifactId>
<version>3.0.1</version>
</dependency>
3. 创建过滤器配置类
@Configuration
public class CatFilterConfigure {
// 添加过滤器对象
@Bean
public FilterRegistrationBean catFilter() {
// 创建过滤器Bean
FilterRegistrationBean registration = new FilterRegistrationBean();
CatFilter filter = new CatFilter();
registration.setFilter(filter); // 将过滤器注册到过滤器Bean中
registration.addUrlPatterns("/*"); // 生效地址
registration.setName("catFilter");
registration.setOrder(1);
return registration;
}
}
4. cat配置
需要在项目如下位置添加文件,src/main/resources/META-INF/app.properties
内容:
### cat配置
cat.server=ip:2280
### 项目名称
cat.app=name
已经过测试:
将上述配置信息,放入application-xxx中以及application中都不可行。
该配置文件,只能是静态配置文件,不能采用如下形式:
cat.server=${CAT_SERVER:172.23.16.1:2280}
app.name=${CAT_NAME:cat-lz-server}
5. 运行springboot项目,再触发接口访问;
问题1:
在cat中监控不到本地运行的项目,即Transaction中没有项目;
Aspect实现即SpringMVC方式
🍇优势
通过定义注解,可以更灵活,不仅仅是可以在接口调用mapping中使用,还可以在方法前使用;
1. pom依赖引入
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-client</artifactId>
<version>3.0.1</version>
</dependency>
2. 定义注解
@Retention(RUNTIME) // 注解用于指定注解的保留策略,运行时仍有效
@Target(ElementType.METHOD) // 用于指定该注解的作用范围,只能作用于方法
public @interface CatTransaction {
String type() default "";
String name() default "";
}
3. 定义切面
@Component // 修饰类,将该类注解为Bean,交由spring管理
@Aspect // 修饰为切面
@Order(1) // 设置优先级,值越小优先级越高,默认为5
public class CatTransactionAop {
@Around(value = "@annotation(com.CatTransaction)")
// 用于环绕通知,用于拦截带有CatTransaction注解的方法
// @annotation = 指定环绕通知只应用于带有特定注解的方法
public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
// ProceedingJoinPoint 是 AOP 中的一个接口,表示一个连接点(join point),可以用来调用目标方法。
Object o = null;
MethodSignature joinPointObject = (MethodSignature) pjp.getSignature();
// pjp.getSignature 获取签名
// MethodSignature 是 Signature 的子类,专门用于方法签名
// 将签名对象转换为 MethodSignature 类型,以便后续获取方法对象
Method method = joinPointObject.getMethod();
// 获取当前连接点对应的方法对象
CatTransaction catTransaction = method.getAnnotation(CatTransaction.class);
// 获取方法上的 @CatTransaction 注解
// 如果没有该注解,直接执行原有方法
if (catTransaction == null) {
o = pjp.proceed();
// 调用目标方法,执行原有的业务逻辑。
return o;
}
// 如果有注解,则执行下述方法
String type = catTransaction.type();
String name = catTransaction.name();
if (StringUtils.isEmpty(type)) {
type = "method";
}
if (StringUtils.isEmpty(name)) {
name = method.getName();
}
Transaction t = Cat.newTransaction(type, name);// 创建事务对象
try {
o = pjp.proceed(); //继续执行方法
t.setStatus(Transaction.SUCCESS); // 设置事务状态为成功
} catch (Throwable e) {
t.setStatus(e); // 设置事务状态为失败
Cat.logError(e); // 记录异常信息
} finally {
t.complete(); // 完成事务
}
return o;
}
}
4. 注解使用
@RequestMapping(value = "url")
@CatTransaction(type = "xxxtype", name = "xxxname")
public Result function(){}
CAT + Spring AOP
1. pom依赖引入
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-client</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>3.2.1</version>
</dependency>
2. 定义注解
@Retention(RUNTIME) // 用于指定注解的保留策略,运行时仍有效
@Target(ElementType.METHOD) // 用于指定该注解的作用范围,只能作用于方法
public @interface TransactionAop {
}
3. 定义切面
@Component // 修饰类,将该类注解为Bean,交由spring管理
@Aspect // 修饰为切面
@Order(1) // 设置优先级,值越小优先级越高,默认为5
public class CatTransactionAop {
@Around(value = "@annotation(com.TransactionAop)")
// 用于环绕通知,用于拦截带有TransactionAop注解的方法
// @annotation = 指定环绕通知只应用于带有特定注解的方法
public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
// ProceedingJoinPoint 是 AOP 中的一个接口,表示一个连接点(join point),可以用来调用目标方法。
Object o = null;
MethodSignature joinPointObject = (MethodSignature) pjp.getSignature();
// pjp.getSignature 获取签名
// MethodSignature 是 Signature 的子类,专门用于方法签名
// 将签名对象转换为 MethodSignature 类型,以便后续获取方法对象
Method method = joinPointObject.getMethod();
// 获取当前连接点对应的方法对象
Transaction t = Cat.newTransaction("method", method.getName());// 创建事务对象
try {
o = pjp.proceed(); //继续执行方法
t.setStatus(Transaction.SUCCESS); // 设置事务状态为成功
} catch (Throwable e) {
t.setStatus(e); // 设置事务状态为失败
Cat.logError(e); // 记录异常信息
} finally {
t.complete(); // 完成事务
}
return o;
}
}
4. 注解使用
@CatTransaction
public String function(HttpServletRequest request, String name) {
return "test";
}
CAT + Springboot + Mybatis
1. springboot和mybatis整合
2. cat服务中的mybatis插件CatMybatisPlugin.java文件放入springboot项目中
3. 提供配置文件加载插件,编写mybatis-config.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PuBLIc "-//mybatis.org//DTD config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<plugins>
<plugin interceptor="com.itcast.mybatiscat.cat.catMybatisPlugin">
</plugin>
// 路径是catMybatisPlugin类所在路径
</plugins>
</configuration>
4. 修改项目mybatis的配置文件application.yml
mybatis:
mapper-locations:classpath:mapper/*Mapper.xml */(为了匹配前一个)
type-aliases-package:com.itcast.mybatiscat.entity
config-location: classpath:mybatis-config.xml
5. 查询sql语句运行时长,分析提升业务执行效率;
CAT + Springboot + 日志
日志采用log4、log4j2 或者 默认的logback日志框架;
1. pom文件导入依赖:
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-client</artifactId>
<version>3.0.1</version>
</dependency>
2. logback-spring.xml文件配置
需要传入异常对象,不传无法在cat中的problem展示错误;
<appender name="CatAppender" class="com.platform.catmonitor.logback.CatLogbackAppender"></appender>
// 日志追加器(appender),负责将日志信息输出到指定的目的地,如控制台、文件或者通过网络发送给其他系统等;
// CatAppender使用了自定义的类com.platform.catmonitor.logback.CatLogbackAppender来实现特定的日志记录逻辑。
// 上述文件在哪里?
<root level="ERROR">
<appender-ref ref="CatAppender"/>
// 所有符合ERROR及以上级别的日志都会通过CatAppender进行处理,并按照CatLogbackAppender类所定义的方式进行输出。
</root>
3. 编写CatLogbackAppender文件
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import com.dianping.cat.Cat;
import com.dianping.cat.message.Event;
public class CatLogbackAppender extends AppenderBase<ILoggingEvent> {
// 用于将日志信息发送到CAT监控系统;
private String domain; // CAT的域名,区分不同应用的关键标识;
public void setDomain(String domain) {
this.domain = domain;
}
// 允许外部设置CAT的域名;
@Override
// 重写了AppenderBase中的append方法,每当有新的日志事件发生时,Logback就会调用这个方法。
protected void append(ILoggingEvent eventObject) {
// 设置当前线程上下文中的CAT域名;
Cat.getManager().setDomain(domain);
// 创建一个事件
Event catEvent = Cat.newEvent("Log", "LogEntry");
try {
// 记录日志级别
catEvent.addData("level", eventObject.getLevel().toString());
// 记录日志消息
catEvent.addData("message", eventObject.getMessage());
// 如果有异常信息,也记录下来
if (eventObject.getThrowableProxy() != null) {
catEvent.addData("exception", eventObject.getThrowableProxy().getClassName());
}
// eventObject.getThrowableProxy() --> 获取异常代理对象,并将其类名作为数据添加到CAT事件中。
// 标记事件成功
catEvent.setStatus(Event.SUCCESS);
} catch (Exception e) {
// 如果发生错误,标记事件失败
catEvent.setStatus(e);
} finally {
// 完成事件,结束这个CAT事件。
catEvent.complete();
}
}
}
transaction报表数据化
在cat的url后面添加:forceDownload=json 或者 forceDownload=xml
url为:http://ip:8080/cat/r/t?domain=opn-api&type=URL&date=2024110615&queryname=&ip=All
更改为:
url+&forceDownload=json
url+&forceDownload=xml
CAT+告警
🍟具体操作过程
告警配置
应用告警配置-->Transaction告警
告警策略配置
全局系统配置-->告警策略、默认告警人、告警服务器;
🍎界面
Transaction追踪
作用:
使用一个名为 Cat 的性能监控工具,用于追踪和记录应用程序中的事务(Transaction)。
创建了一个新的事务对象,并根据执行的结果来标记该事务的状态为成功或失败。
最后,无论结果如何,都会调用 complete() 方法来结束这个事务的追踪。
实现:
Transaction transaction = Cat.newTransaction(API_TYPE_NAME, Function_NAME);
try(成功) {
transaction.setStatus(Transaction.SUCCESS);
}catch(有异常) {
transaction.setStatus(e);
}finally{
transaction.complete();
}