发表于: 2021-05-25 23:30:32
4 1392
一,今天完成的事情
任务三9
任务三条目9.查看Nginx的响应时间,每一个请求不超过200MS,查看每一个Service的响应时间,列出来每一个请求的时耗分解图
1, 我先检查nginx的logs文件夹是否存在,里面有什么文件。如图正常
还是nginx.conf文件
截图带行号。本图都是默认配置。
21行中的 “main”是一个名字,是给log_format起的名字;25行的“main”就是引用名字是main的log_format的格式。
25行的最中间部分是日志相对位置,如最上方的图。
不去掉井号,我就重新配置。
21-23行的配置,一般就是指如果写了这个$符号的变量,日志就输出这个内容。而且按变量要求输出的顺序。如下面access.log的内容,能对上
因为需要找的是“查看Nginx的响应时间”,到http://nginx.org/自己找到和“响应”和“时间”有关的关键字,对应response 和 time。
特别相关的有四大时间:
$request_time – Full request time, starting when NGINX reads the first byte from the client and ending when NGINX sends the last byte of the response body
$upstream_connect_time – Time spent establishing a connection with an upstream server
$upstream_header_time – Time between establishing a connection to an upstream server and receiving the first byte of the response header
$upstream_response_time – – Time between establishing a connection to an upstream server and receiving the last byte of the response body
阿里云有日志服务可以参考
时间中,request_time和upstream_response_time比较常用。
如果把整个过程补充起来的话 应该是:
[1用户请求][2建立 Nginx 连接][3发送响应][4接收响应][5关闭 Nginx 连接]
那么 upstream_response_time 就是 2+3+4+5
但是 一般这里面可以认为 [5关闭 Nginx 连接] 的耗时接近 0
所以 upstream_response_time 实际上就是 2+3+4
而 request_time 是 1+2+3+4
二者之间相差的就是 [1用户请求]的时间。
程序真正的运行时间 = $upstream_header_time - $upstream_connect_time 。
$request_time 中包含了数据返回时间
$request_time 中包含了日志打印的时间
所以四大时间 全部加入
其它默认的都放在前面,其它变量不加入,关注四大时间。the time is kept in seconds with millisecond resolution.
保存。./nginx -s reload
部署任务三war包,运行,查看日志
intellij打包,上传,配置resin再来一次。设置mysql软连接,或者直接进入 mysql/bin/mysql运行命令。
create database art_room;
use
导出sql语句文件,在云linux运行。
在source 后应加上文件的绝对路径art_room.sql
运行若干命令,和在本地一样,除了用外部地址。查看发现需要的log已经自动生成
查看,目前在服务器上列出的4个请求,包括200,和400系列HTTP_CODE的请求都在200ms内。目前数据量每个表不到100条。
关注时间,还有其它 $变量名 能加入到log_format中,按照需求加入
2,需要查看每一个Service的响应时间,首选AOP。@Before @Around @After 能在前后执行时间判断,又不影响原程序执行。
有若干方式在Spring中使用AOP。我选用的方法是 Aspectj 。
<!--AOP相关jar包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
新包aspectj。Aspectj的相关代码可以用 .aj 为结尾的Aspect 文件。但是,我用
@Aspect
注解,使用java语法。
spring-mvc.xml 文件加入
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--包含切面类的包-->
<context:component-scan base-package="com.nicole.ssm.aspectj"/>
<aop:aspectj-autoproxy/>
上面最后一行开启AOP
@Pointcut
可以使用正则表达式
在我在项目中如果需要看所有的service,连带正则表达式可以写成
@Pointcut("execution(* com.nicole.ssm.service.*Service.*(..))")
private void logRecordServiceTime(){};
日志记录可以用
Logger.getLogger
LoggerFactory.getLogger
前后记录时间,用around方法。joinPoint.proceed() 前后记录时间,计算差值即可
@Around("logRecordServiceTime()")
日志的输出格式如下
http://localhost:8080/art_room/artstudio/1 请求正好需要2个service配合,都顺利列出,很好。
其它请求用Postman一一访问,统计时间
运行各API接口的表格统计如下
service名字 | 耗时毫秒 |
com.nicole.ssm.service.ArtstudioImageService.queryByArtstudioId | 5 |
com.nicole.ssm.service.ArtstudioService.queryById(Long) | 11 |
com.nicole.ssm.service.ArtstudioService.queryAllShow() | 5 |
com.nicole.ssm.service.ArtworkService.queryArtworksNewUpdate() | 91 |
com.nicole.ssm.service.ArtworkService.queryArtworksManuId(long) | 4 |
com.nicole.ssm.service.ArtworkService.queryById(Long) | 5 |
com.nicole.ssm.service.BannerService.queryLimitBanners() | 18 |
com.nicole.ssm.service.CommentReplyService.queryShowByArtworkId(long) | 28 |
com.nicole.ssm.service.CommentReplyService.queryArtworkIdCommentAndReply(long) | 19 |
com.nicole.ssm.service.CommentReplyService.insert(CommentReply) | 44 |
com.nicole.ssm.service.ManuService.queryAllChildrenManus(Long) | 47 |
com.nicole.ssm.service.ManuService.queryAllChildrenManuVos(Long) | 62 |
3,验收标准5.日志完整,入参,返回值,关键判断语句都有对应日志
在controller等可以加入logger,记录关键判断语句日志
private Logger logger = LoggerFactory.getLogger(ArtstudioController.class);
参数,返回值处理
/**
* 定义切入点,记录入参,返回值。选择记录controller入参和返回值
*/
@Around("logRecordArgs()")
private Object getControllerLog(ProceedingJoinPoint jPoint) {
//return val, package name, class name, method name
String fullMethodName = jPoint.getSignature().toString();
StringBuilder sb = new StringBuilder();
// 下面两个数组中,参数值和参数名的个数和位置是一一对应的。
// 参数值
Object[] argsVal = jPoint.getArgs();
// 参数名
String[] paramsName = ((MethodSignature) jPoint.getSignature()).getParameterNames();
sb.append( fullMethodName ).append( " parameter(s) are : { ");
if( argsVal != null && paramsName != null && argsVal.length > 0 && paramsName.length > 0 ) {
for (int i = 0 ; i < paramsName.length ; i++ ) {
sb.append(" ").append( paramsName[i] ).append(" = ")
.append(argsVal[i]).append(",");
}
sb.deleteCharAt(sb.length()-1);
}
sb.append(" } ");
Object result = null;
try {
result = jPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
logger.error("error message : "+throwable.getMessage());
}
sb.append(" return (result) :{ ").append(result).append(" } ");
// 记录日志
logger.info(sb.toString());
// 调用结果返回
return result;
}
如果列举导航栏列表:http://localhost:8080/art_room/manu/manuVoTree/0
正确,成功
二,今天问题
任务三代码在这个日报提交。
况师兄好,请问现在是做修真院复盘?还是跟着敏捷做修真院的真实?
三,今天的收获
当科学家很难。当国家栋梁难。我不能免俗,12岁前,甚至18岁前,第一选择的愿望就是科学家。不是科学家,没有什么论文引用,更没有顶级会议。自己有弱项,当然也有相对强的地方。
这个月我感觉市场招人很多,今年是个好机会。就连旅游,都Flush with venture funding, travel startups are hiring again。
四,明天的计划
任务三深度思考
评论