Commit 1d418ca8e80762bc68e90398807269ac171f0e43

Authored by 王彪总
1 parent 0675583f

fix(config): 更新配置文件和修复分页计算问题

- 在.gitignore中添加.mcp.json文件忽略
- 更新application-dev.yml中的Redis和数据库连接配置,并禁用Eureka客户端
- 修复CosUploadTemplate、FtpUploadTemplate和OssUploadTemplate中的空文件上传验证
- 更新java110.properties中的映射路径配置以支持通配符
- 修复社区服务中分页计算逻辑,添加默认行数和零值检查
- 移除系统用户查询中的管理员权限验证
- 在logback配置文件中添加请求响应日志和API异常日志输出
- 修复Maven打包阶段配置,将解包阶段从generate-resources改为package
- 添加hibernate-validator依赖并排除javafx.base冲突
- 扩展文件上传组件以支持multipart文件上传和IP地址获取功能
java110-core/src/main/java/com/java110/core/cache/Java110RedisConfig.java
... ... @@ -138,7 +138,7 @@ public class Java110RedisConfig extends CachingConfigurerSupport {
138 138 public RedisCacheConfiguration redisCacheConfiguration() {
139 139  
140 140 RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
141   - configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new JdkSerializationRedisSerializer())).entryTtl(Duration.ofSeconds(30));
  141 + configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new JdkSerializationRedisSerializer())).entryTtl(Duration.ofSeconds(300));
142 142 return configuration;
143 143  
144 144  
... ...
java110-core/src/main/java/com/java110/core/trace/Java110RestTemplateInterceptor.java
1 1 package com.java110.core.trace;
2 2  
3   -import com.java110.core.log.LoggerFactory;
4 3 import com.java110.dto.trace.TraceAnnotationsDto;
5 4 import com.java110.dto.trace.TraceDto;
6 5 import com.java110.utils.constant.CommonConstant;
7   -import org.slf4j.Logger;
8 6 import org.springframework.http.HttpHeaders;
9 7 import org.springframework.http.HttpRequest;
10 8 import org.springframework.http.client.ClientHttpRequestExecution;
... ... @@ -19,11 +17,9 @@ import java.io.IOException;
19 17 */
20 18 @Component
21 19 public class Java110RestTemplateInterceptor implements ClientHttpRequestInterceptor {
22   - private static Logger logger = LoggerFactory.getLogger(Java110RestTemplateInterceptor.class);
23 20  
24 21 @Override
25 22 public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
26   - logger.debug("进入拦截器" + new String(body));
27 23 TraceDto traceDto = Java110TraceFactory.getTraceDto();
28 24 if (traceDto != null) {
29 25 HttpHeaders httpHeaders = request.getHeaders();
... ... @@ -31,10 +27,12 @@ public class Java110RestTemplateInterceptor implements ClientHttpRequestIntercep
31 27 httpHeaders.remove(CommonConstant.PARENT_SPAN_ID);
32 28 httpHeaders.add(CommonConstant.TRACE_ID, traceDto.getTraceId());
33 29 httpHeaders.add(CommonConstant.PARENT_SPAN_ID, traceDto.getId());
  30 + Java110TraceFactory.putAnnotations(TraceAnnotationsDto.VALUE_SERVER_SEND);
  31 + ClientHttpResponse clientHttpResponse = execution.execute(request, body);
  32 + Java110TraceFactory.putAnnotations(TraceAnnotationsDto.VALUE_SERVER_RECEIVE);
  33 + return clientHttpResponse;
34 34 }
35   - Java110TraceFactory.putAnnotations(TraceAnnotationsDto.VALUE_SERVER_SEND);
36   - ClientHttpResponse clientHttpResponse = execution.execute(request, body);
37   - Java110TraceFactory.putAnnotations(TraceAnnotationsDto.VALUE_SERVER_RECEIVE);
38   - return clientHttpResponse;
  35 + //追踪未开启时直接放行,避免不必要的ThreadLocal操作和Annotation对象创建
  36 + return execution.execute(request, body);
39 37 }
40 38 }
... ...
java110-core/src/main/java/com/java110/core/trace/Java110TraceSqlInterceptor.java
... ... @@ -34,6 +34,11 @@ public class Java110TraceSqlInterceptor implements Interceptor {
34 34  
35 35 @Override
36 36 public Object intercept(Invocation invocation) throws Throwable {
  37 + //追踪开关未打开时直接放行,避免不必要的SQL解析和参数提取开销
  38 + if (Java110TraceFactory.getTraceDto() == null) {
  39 + return invocation.proceed();
  40 + }
  41 +
37 42 MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
38 43 Object parameterObject = null;
39 44 if (invocation.getArgs().length > 1) {
... ...
java110-db/src/main/java/com/java110/db/DruidDataSourceConfig.java
... ... @@ -65,11 +65,20 @@ public class DruidDataSourceConfig {
65 65 //配置获取连接等待超时的时间
66 66 dataSource.setMaxWait(maxWait);
67 67  
68   - // 配置Druid的SQL监控和日志打印
69   - dataSource.setLogAbandoned(true);
70   - dataSource.setRemoveAbandoned(true);
71   - dataSource.setRemoveAbandonedTimeout(180);
72   - dataSource.setFilters("stat,log4j2"); // 配置Log4j2作为日志实现
  68 + //连接验证 - 防止使用已断开的连接
  69 + dataSource.setValidationQuery("SELECT 1");
  70 + dataSource.setTestWhileIdle(true);
  71 + dataSource.setTestOnBorrow(true);
  72 + dataSource.setTestOnReturn(false);
  73 + dataSource.setTimeBetweenEvictionRunsMillis(60000);
  74 + dataSource.setMinEvictableIdleTimeMillis(300000);
  75 +
  76 + //PSCache - 缓存PreparedStatement避免重复解析SQL
  77 + dataSource.setPoolPreparedStatements(true);
  78 + dataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
  79 +
  80 + // 配置Druid的SQL监控,移除log4j2减少日志开销
  81 + dataSource.setFilters("stat");
73 82  
74 83  
75 84  
... ...
java110-db/src/main/java/com/java110/db/Java110MybatisInterceptor.java
... ... @@ -24,6 +24,10 @@ import org.springframework.http.*;
24 24 import java.sql.Timestamp;
25 25 import java.text.DateFormat;
26 26 import java.util.*;
  27 +import java.util.concurrent.ExecutorService;
  28 +import java.util.concurrent.LinkedBlockingQueue;
  29 +import java.util.concurrent.ThreadPoolExecutor;
  30 +import java.util.concurrent.TimeUnit;
27 31  
28 32 @Intercepts({
29 33 @Signature(type = Executor.class, method = "update", args = {MappedStatement.class,
... ... @@ -32,6 +36,17 @@ import java.util.*;
32 36 public class Java110MybatisInterceptor implements Interceptor {
33 37 private static Logger logger = LoggerFactory.getLogger(Java110MybatisInterceptor.class);
34 38  
  39 + private static final ExecutorService ASYNC_LOG_EXECUTOR = new ThreadPoolExecutor(
  40 + 2, 4, 60L, TimeUnit.SECONDS,
  41 + new LinkedBlockingQueue<>(1000),
  42 + r -> {
  43 + Thread t = new Thread(r, "async-tx-log");
  44 + t.setDaemon(true);
  45 + return t;
  46 + },
  47 + new ThreadPoolExecutor.CallerRunsPolicy()
  48 + );
  49 +
35 50 IQueryServiceDAO queryServiceDAOImpl;
36 51 RestTemplate restTemplate;
37 52  
... ... @@ -106,7 +121,7 @@ public class Java110MybatisInterceptor implements Interceptor {
106 121 logText.put("preValue", preValues);
107 122 logText.put("afterValue", afterValues);
108 123  
109   - OrderItemDto orderItemDto = new OrderItemDto();
  124 + final OrderItemDto orderItemDto = new OrderItemDto();
110 125 orderItemDto.setbId("-1");
111 126 orderItemDto.setAction("DEL");
112 127 orderItemDto.setActionObj(tmpTable.trim());
... ... @@ -114,17 +129,22 @@ public class Java110MybatisInterceptor implements Interceptor {
114 129 orderItemDto.setServiceName(ApplicationContextFactory.getApplicationName());
115 130 orderItemDto.setoId(Java110TransactionalFactory.getOId());
116 131  
117   - String url = ServiceConstant.SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
118   - HttpHeaders httpHeaders = new HttpHeaders();
119   - HttpEntity httpEntity = new HttpEntity(orderItemDto.toString(), httpHeaders);
120   - if(Environment.isStartBootWay()){
121   - url = ServiceConstant.BOOT_SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
122   - }
123   - ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
124   -
125   - if (responseEntity.getStatusCode() != HttpStatus.OK) {
126   - throw new IllegalArgumentException("注册事务回滚日志失败" + responseEntity);
127   - }
  132 + final boolean isBoot = Environment.isStartBootWay();
  133 + final RestTemplate rt = this.restTemplate;
  134 + ASYNC_LOG_EXECUTOR.submit(() -> {
  135 + try {
  136 + String url = isBoot ? ServiceConstant.BOOT_SERVICE_ORDER_URL : ServiceConstant.SERVICE_ORDER_URL;
  137 + url += "/order/oIdApi/createOrderItem";
  138 + HttpHeaders httpHeaders = new HttpHeaders();
  139 + HttpEntity httpEntity = new HttpEntity(orderItemDto.toString(), httpHeaders);
  140 + ResponseEntity<String> responseEntity = rt.exchange(url, HttpMethod.POST, httpEntity, String.class);
  141 + if (responseEntity.getStatusCode() != HttpStatus.OK) {
  142 + logger.error("异步注册事务回滚日志失败(DEL): {}", responseEntity.getBody());
  143 + }
  144 + } catch (Exception e) {
  145 + logger.error("异步注册事务回滚日志异常(DEL)", e);
  146 + }
  147 + });
128 148 }
129 149  
130 150 /**
... ... @@ -168,7 +188,7 @@ public class Java110MybatisInterceptor implements Interceptor {
168 188 logText.put("preValue", preValues);
169 189 logText.put("afterValue", afterValues);
170 190  
171   - OrderItemDto orderItemDto = new OrderItemDto();
  191 + final OrderItemDto orderItemDto = new OrderItemDto();
172 192 orderItemDto.setbId("-1");
173 193 orderItemDto.setAction("MOD");
174 194 orderItemDto.setActionObj(tmpTable.trim());
... ... @@ -176,18 +196,22 @@ public class Java110MybatisInterceptor implements Interceptor {
176 196 orderItemDto.setServiceName(ApplicationContextFactory.getApplicationName());
177 197 orderItemDto.setoId(Java110TransactionalFactory.getOId());
178 198  
179   - String url = ServiceConstant.SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
180   - HttpHeaders httpHeaders = new HttpHeaders();
181   - HttpEntity httpEntity = new HttpEntity(orderItemDto.toString(), httpHeaders);
182   - ResponseEntity<String> responseEntity = null;
183   - if(Environment.isStartBootWay()){
184   - url = ServiceConstant.BOOT_SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
185   - }
186   - responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
187   -
188   - if (responseEntity.getStatusCode() != HttpStatus.OK) {
189   - throw new IllegalArgumentException("注册事务回滚日志失败" + responseEntity);
190   - }
  199 + final boolean isBoot = Environment.isStartBootWay();
  200 + final RestTemplate rt = this.restTemplate;
  201 + ASYNC_LOG_EXECUTOR.submit(() -> {
  202 + try {
  203 + String url = isBoot ? ServiceConstant.BOOT_SERVICE_ORDER_URL : ServiceConstant.SERVICE_ORDER_URL;
  204 + url += "/order/oIdApi/createOrderItem";
  205 + HttpHeaders httpHeaders = new HttpHeaders();
  206 + HttpEntity httpEntity = new HttpEntity(orderItemDto.toString(), httpHeaders);
  207 + ResponseEntity<String> responseEntity = rt.exchange(url, HttpMethod.POST, httpEntity, String.class);
  208 + if (responseEntity.getStatusCode() != HttpStatus.OK) {
  209 + logger.error("异步注册事务回滚日志失败(MOD): {}", responseEntity.getBody());
  210 + }
  211 + } catch (Exception e) {
  212 + logger.error("异步注册事务回滚日志异常(MOD)", e);
  213 + }
  214 + });
191 215 }
192 216  
193 217 private void dealReturnMap(Map<String, Object> map) {
... ... @@ -241,7 +265,7 @@ public class Java110MybatisInterceptor implements Interceptor {
241 265 logText.put("preValue", preValues);
242 266 logText.put("afterValue", afterValues);
243 267  
244   - OrderItemDto orderItemDto = new OrderItemDto();
  268 + final OrderItemDto orderItemDto = new OrderItemDto();
245 269 orderItemDto.setbId("-1");
246 270 orderItemDto.setAction("ADD");
247 271 orderItemDto.setActionObj(tmpTable.trim());
... ... @@ -249,17 +273,22 @@ public class Java110MybatisInterceptor implements Interceptor {
249 273 orderItemDto.setServiceName(ApplicationContextFactory.getApplicationName());
250 274 orderItemDto.setoId(Java110TransactionalFactory.getOId());
251 275  
252   - String url = ServiceConstant.SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
253   - HttpHeaders httpHeaders = new HttpHeaders();
254   - HttpEntity httpEntity = new HttpEntity(orderItemDto.toString(), httpHeaders);
255   - if(Environment.isStartBootWay()){
256   - url = ServiceConstant.BOOT_SERVICE_ORDER_URL + "/order/oIdApi/createOrderItem";
257   - }
258   - ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
259   -
260   - if (responseEntity.getStatusCode() != HttpStatus.OK) {
261   - throw new IllegalArgumentException("注册事务回滚日志失败" + responseEntity);
262   - }
  276 + final boolean isBoot = Environment.isStartBootWay();
  277 + final RestTemplate rt = this.restTemplate;
  278 + ASYNC_LOG_EXECUTOR.submit(() -> {
  279 + try {
  280 + String url = isBoot ? ServiceConstant.BOOT_SERVICE_ORDER_URL : ServiceConstant.SERVICE_ORDER_URL;
  281 + url += "/order/oIdApi/createOrderItem";
  282 + HttpHeaders httpHeaders = new HttpHeaders();
  283 + HttpEntity httpEntity = new HttpEntity(orderItemDto.toString(), httpHeaders);
  284 + ResponseEntity<String> responseEntity = rt.exchange(url, HttpMethod.POST, httpEntity, String.class);
  285 + if (responseEntity.getStatusCode() != HttpStatus.OK) {
  286 + logger.error("异步注册事务回滚日志失败(ADD): {}", responseEntity.getBody());
  287 + }
  288 + } catch (Exception e) {
  289 + logger.error("异步注册事务回滚日志异常(ADD)", e);
  290 + }
  291 + });
263 292  
264 293 }
265 294  
... ...
java110-interface/src/main/resources/logback-prod.xml
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <configuration scan="true" scanPeriod="60 seconds">
3 3  
4   -<!-- <include resource="org/springframework/boot/logging/logback/base.xml"/>-->
  4 + <!-- 异步日志appender,大幅减少日志I/O对业务的阻塞 -->
  5 + <appender name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender">
  6 + <queueSize>512</queueSize>
  7 + <discardingThreshold>0</discardingThreshold>
  8 + <neverBlock>true</neverBlock>
  9 + <appender-ref ref="STDOUT_FILE"/>
  10 + </appender>
5 11  
6 12 <!-- 控制台输出 -->
7 13 <appender name="STDOUT_FILE" class="ch.qos.logback.core.ConsoleAppender">
8 14 <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
9   - <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
10 15 <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
11 16 </encoder>
12 17 </appender>
13 18  
14   - <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
15   - <File>./logs/debug.log</File>
16   - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
17   - <fileNamePattern>./logs/debug-%d{yyyyMMdd}.log.%i</fileNamePattern>
18   - <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
19   - <maxFileSize>500MB</maxFileSize>
20   - </timeBasedFileNamingAndTriggeringPolicy>
21   - <maxHistory>2</maxHistory>
22   - </rollingPolicy>
23   - <layout class="ch.qos.logback.classic.PatternLayout">
24   - <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
25   - </Pattern>
26   - </layout>
  19 + <appender name="ASYNC_INFO" class="ch.qos.logback.classic.AsyncAppender">
  20 + <queueSize>512</queueSize>
  21 + <discardingThreshold>0</discardingThreshold>
  22 + <neverBlock>true</neverBlock>
  23 + <appender-ref ref="INFO_FILE"/>
27 24 </appender>
28 25  
29 26 <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  27 + <immediateFlush>false</immediateFlush>
30 28 <File>./logs/info.log</File>
31 29 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
32 30 <fileNamePattern>./logs/info-%d{yyyyMMdd}.log.%i</fileNamePattern>
... ... @@ -36,33 +34,44 @@
36 34 <maxHistory>2</maxHistory>
37 35 </rollingPolicy>
38 36 <layout class="ch.qos.logback.classic.PatternLayout">
39   - <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
40   - </Pattern>
  37 + <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n</Pattern>
41 38 </layout>
42 39 </appender>
43 40  
  41 + <appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender">
  42 + <queueSize>256</queueSize>
  43 + <discardingThreshold>0</discardingThreshold>
  44 + <neverBlock>false</neverBlock>
  45 + <appender-ref ref="ERROR_FILE"/>
  46 + </appender>
  47 +
44 48 <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
45 49 <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
46 50 <level>ERROR</level>
47 51 </filter>
48 52 <File>./logs/error.log</File>
49 53 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
50   - <fileNamePattern>${LOG_PATH}/error-%d{yyyyMMdd}.log.%i
51   - </fileNamePattern>
  54 + <fileNamePattern>${LOG_PATH}/error-%d{yyyyMMdd}.log.%i</fileNamePattern>
52 55 <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
53 56 <maxFileSize>500MB</maxFileSize>
54 57 </timeBasedFileNamingAndTriggeringPolicy>
55 58 <maxHistory>2</maxHistory>
56 59 </rollingPolicy>
57 60 <layout class="ch.qos.logback.classic.PatternLayout">
58   - <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
59   -
60   - </Pattern>
  61 + <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n</Pattern>
61 62 </layout>
62 63 </appender>
63 64  
64 65 <!-- 请求响应日志 -->
  66 + <appender name="ASYNC_REQUEST" class="ch.qos.logback.classic.AsyncAppender">
  67 + <queueSize>512</queueSize>
  68 + <discardingThreshold>0</discardingThreshold>
  69 + <neverBlock>true</neverBlock>
  70 + <appender-ref ref="REQUEST_FILE"/>
  71 + </appender>
  72 +
65 73 <appender name="REQUEST_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  74 + <immediateFlush>false</immediateFlush>
66 75 <File>./logs/request.log</File>
67 76 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
68 77 <fileNamePattern>./logs/request-%d{yyyyMMdd}.log.%i</fileNamePattern>
... ... @@ -77,6 +86,13 @@
77 86 </appender>
78 87  
79 88 <!-- API异常日志单独输出 -->
  89 + <appender name="ASYNC_API_ERROR" class="ch.qos.logback.classic.AsyncAppender">
  90 + <queueSize>256</queueSize>
  91 + <discardingThreshold>0</discardingThreshold>
  92 + <neverBlock>false</neverBlock>
  93 + <appender-ref ref="API_ERROR_FILE"/>
  94 + </appender>
  95 +
80 96 <appender name="API_ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
81 97 <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
82 98 <level>ERROR</level>
... ... @@ -95,53 +111,40 @@
95 111 </appender>
96 112  
97 113 <logger name="org.springframework" level="ERROR">
98   - <appender-ref ref="STDOUT_FILE"/>
99   - </logger>
100   -
101   - <!--myibatis log configure-->
102   - <logger name="com.apache.ibatis" level="ERROR">
103   - <appender-ref ref="STDOUT_FILE"/>
104   - </logger>
105   -
106   - <logger name="org.mybatis" level="ERROR">
107   - <appender-ref ref="STDOUT_FILE"/>
108   - </logger>
109   - <logger name="druid.sql.Statement" level="ERROR">
110   - <appender-ref ref="STDOUT_FILE"/>
111   - </logger>
112   - <logger name="druid.sql.ResultSet" level="ERROR">
113   - <appender-ref ref="STDOUT_FILE"/>
  114 + <appender-ref ref="ASYNC_STDOUT"/>
114 115 </logger>
115 116  
  117 + <!-- MyBatis/Druid SQL日志在生产环境关闭 -->
  118 + <logger name="com.apache.ibatis" level="ERROR"/>
  119 + <logger name="org.mybatis" level="ERROR"/>
  120 + <logger name="druid.sql.Statement" level="ERROR"/>
  121 + <logger name="druid.sql.ResultSet" level="ERROR"/>
  122 + <logger name="druid.sql.Connection" level="ERROR"/>
116 123  
117 124 <logger name="com.java110" level="INFO">
118   - <appender-ref ref="STDOUT_FILE"/>
  125 + <appender-ref ref="ASYNC_STDOUT"/>
119 126 </logger>
120 127  
121 128 <!-- API请求/响应/异常日志 -->
122 129 <logger name="com.java110.api.aop" level="INFO" additivity="false">
123   - <appender-ref ref="STDOUT_FILE"/>
124   - <appender-ref ref="REQUEST_FILE"/>
125   - <appender-ref ref="API_ERROR_FILE"/>
126   - <appender-ref ref="ERROR_FILE"/>
  130 + <appender-ref ref="ASYNC_STDOUT"/>
  131 + <appender-ref ref="ASYNC_REQUEST"/>
  132 + <appender-ref ref="ASYNC_API_ERROR"/>
  133 + <appender-ref ref="ASYNC_ERROR"/>
127 134 </logger>
128 135  
129   - <logger name="io.shardingsphere" level="ERROR">
130   - <appender-ref ref="STDOUT_FILE"/>
131   - </logger>
  136 + <logger name="io.shardingsphere" level="ERROR"/>
132 137  
133   - <logger name="org.thymeleaf" level="ERROR">
134   - <appender-ref ref="STDOUT_FILE"/>
135   - </logger>
  138 + <logger name="org.thymeleaf" level="ERROR"/>
136 139  
137   - <logger name="org.apache.kafka" level="ERROR">
138   - <appender-ref ref="STDOUT_FILE"/>
139   - </logger>
  140 + <logger name="org.apache.kafka" level="ERROR"/>
  141 +
  142 + <logger name="org.quartz" level="ERROR"/>
140 143  
141 144 <root level="INFO">
142   - <appender-ref ref="STDOUT_FILE"/>
143   - <appender-ref ref="INFO_FILE"/>
144   - <appender-ref ref="ERROR_FILE"/>
  145 + <appender-ref ref="ASYNC_STDOUT"/>
  146 + <appender-ref ref="ASYNC_INFO"/>
  147 + <appender-ref ref="ASYNC_ERROR"/>
145 148 </root>
146 149  
147 150 </configuration>
... ...
java110-interface/src/main/resources/logback.xml
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <configuration scan="true" scanPeriod="60 seconds">
3 3  
4   - <!--<include resource="org/springframework/boot/logging/logback/base.xml"/>-->
  4 + <!-- 异步日志appender,减少日志I/O对业务的阻塞 -->
  5 + <appender name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender">
  6 + <queueSize>512</queueSize>
  7 + <discardingThreshold>0</discardingThreshold>
  8 + <neverBlock>true</neverBlock>
  9 + <appender-ref ref="STDOUT_FILE"/>
  10 + </appender>
5 11  
6 12 <!-- 控制台输出 -->
7 13 <appender name="STDOUT_FILE" class="ch.qos.logback.core.ConsoleAppender">
8 14 <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
9   - <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
10 15 <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
11 16 </encoder>
12 17 </appender>
13 18  
14   - <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
15   - <File>./logs/debug.log</File>
16   - <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
17   - <fileNamePattern>./logs/debug-%d{yyyyMMdd}.log.%i</fileNamePattern>
18   - <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
19   - <maxFileSize>500MB</maxFileSize>
20   - </timeBasedFileNamingAndTriggeringPolicy>
21   - <maxHistory>2</maxHistory>
22   - </rollingPolicy>
23   - <layout class="ch.qos.logback.classic.PatternLayout">
24   - <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
25   - </Pattern>
26   - </layout>
  19 + <appender name="ASYNC_INFO" class="ch.qos.logback.classic.AsyncAppender">
  20 + <queueSize>512</queueSize>
  21 + <discardingThreshold>0</discardingThreshold>
  22 + <neverBlock>true</neverBlock>
  23 + <appender-ref ref="INFO_FILE"/>
27 24 </appender>
28 25  
29 26 <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  27 + <immediateFlush>false</immediateFlush>
30 28 <File>./logs/info.log</File>
31 29 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
32 30 <fileNamePattern>./logs/info-%d{yyyyMMdd}.log.%i</fileNamePattern>
... ... @@ -36,33 +34,44 @@
36 34 <maxHistory>2</maxHistory>
37 35 </rollingPolicy>
38 36 <layout class="ch.qos.logback.classic.PatternLayout">
39   - <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
40   - </Pattern>
  37 + <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n</Pattern>
41 38 </layout>
42 39 </appender>
43 40  
  41 + <appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender">
  42 + <queueSize>256</queueSize>
  43 + <discardingThreshold>0</discardingThreshold>
  44 + <neverBlock>false</neverBlock>
  45 + <appender-ref ref="ERROR_FILE"/>
  46 + </appender>
  47 +
44 48 <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
45 49 <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
46 50 <level>ERROR</level>
47 51 </filter>
48 52 <File>./logs/error.log</File>
49 53 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
50   - <fileNamePattern>${LOG_PATH}/error-%d{yyyyMMdd}.log.%i
51   - </fileNamePattern>
  54 + <fileNamePattern>${LOG_PATH}/error-%d{yyyyMMdd}.log.%i</fileNamePattern>
52 55 <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
53 56 <maxFileSize>500MB</maxFileSize>
54 57 </timeBasedFileNamingAndTriggeringPolicy>
55 58 <maxHistory>2</maxHistory>
56 59 </rollingPolicy>
57 60 <layout class="ch.qos.logback.classic.PatternLayout">
58   - <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n
59   -
60   - </Pattern>
  61 + <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n</Pattern>
61 62 </layout>
62 63 </appender>
63 64  
64 65 <!-- 请求响应日志 -->
  66 + <appender name="ASYNC_REQUEST" class="ch.qos.logback.classic.AsyncAppender">
  67 + <queueSize>512</queueSize>
  68 + <discardingThreshold>0</discardingThreshold>
  69 + <neverBlock>true</neverBlock>
  70 + <appender-ref ref="REQUEST_FILE"/>
  71 + </appender>
  72 +
65 73 <appender name="REQUEST_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  74 + <immediateFlush>false</immediateFlush>
66 75 <File>./logs/request.log</File>
67 76 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
68 77 <fileNamePattern>./logs/request-%d{yyyyMMdd}.log.%i</fileNamePattern>
... ... @@ -76,7 +85,14 @@
76 85 </layout>
77 86 </appender>
78 87  
79   - <!-- API异常日志单独输出 -->
  88 + <!-- API异常日志 -->
  89 + <appender name="ASYNC_API_ERROR" class="ch.qos.logback.classic.AsyncAppender">
  90 + <queueSize>256</queueSize>
  91 + <discardingThreshold>0</discardingThreshold>
  92 + <neverBlock>false</neverBlock>
  93 + <appender-ref ref="API_ERROR_FILE"/>
  94 + </appender>
  95 +
80 96 <appender name="API_ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
81 97 <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
82 98 <level>ERROR</level>
... ... @@ -94,57 +110,38 @@
94 110 </layout>
95 111 </appender>
96 112  
97   - <logger name="org.springframework" level="ERROR">
98   - <appender-ref ref="STDOUT_FILE"/>
99   - </logger>
100   - <logger name="org.quartz" level="DEBUG">
101   - <appender-ref ref="STDOUT_FILE"/>
102   - </logger>
103   - <logger name="com.java110.order" level="ERROR">
104   - <appender-ref ref="STDOUT_FILE"/>
105   - </logger>
  113 + <!-- Spring框架日志 -->
  114 + <logger name="org.springframework" level="ERROR"/>
106 115  
  116 + <!-- MyBatis/Druid SQL日志关闭,避免大量DEBUG日志 -->
  117 + <logger name="com.apache.ibatis" level="ERROR"/>
  118 + <logger name="org.mybatis" level="ERROR"/>
  119 + <logger name="druid.sql.Statement" level="ERROR"/>
  120 + <logger name="druid.sql.ResultSet" level="ERROR"/>
  121 + <logger name="druid.sql.Connection" level="ERROR"/>
107 122  
108   - <logger name="org.mybatis" level="DEBUG">
109   - <appender-ref ref="STDOUT_FILE"/>
110   - </logger>
111   - <logger name="druid.sql.Statement" level="DEBUG" additivity="false">
112   - <appender-ref ref="STDOUT_FILE"/>
113   - </logger>
114   - <logger name="druid.sql.ResultSet" level="DEBUG" additivity="false">
115   - <appender-ref ref="STDOUT_FILE"/>
116   - </logger>
117   - <logger name="druid.sql.Connection" level="DEBUG" additivity="false">
118   - <appender-ref ref="STDOUT_FILE"/>
119   - </logger>
120   -
121   -
122   - <logger name="com.java110" level="DEBUG">
123   - <appender-ref ref="STDOUT_FILE"/>
  123 + <!-- 业务日志 INFO级别 -->
  124 + <logger name="com.java110" level="INFO">
  125 + <appender-ref ref="ASYNC_STDOUT"/>
124 126 </logger>
125 127  
126 128 <!-- API请求/响应/异常日志 -->
127 129 <logger name="com.java110.api.aop" level="INFO" additivity="false">
128   - <appender-ref ref="STDOUT_FILE"/>
129   - <appender-ref ref="REQUEST_FILE"/>
130   - <appender-ref ref="API_ERROR_FILE"/>
131   - <appender-ref ref="ERROR_FILE"/>
132   - </logger>
133   -
134   - <logger name="org.thymeleaf" level="ERROR">
135   - <appender-ref ref="STDOUT_FILE"/>
136   - </logger>
137   -
138   - <logger name="org.apache.kafka" level="ERROR">
139   - <appender-ref ref="STDOUT_FILE"/>
  130 + <appender-ref ref="ASYNC_STDOUT"/>
  131 + <appender-ref ref="ASYNC_REQUEST"/>
  132 + <appender-ref ref="ASYNC_API_ERROR"/>
  133 + <appender-ref ref="ASYNC_ERROR"/>
140 134 </logger>
141 135  
  136 + <logger name="io.shardingsphere" level="ERROR"/>
  137 + <logger name="org.thymeleaf" level="ERROR"/>
  138 + <logger name="org.apache.kafka" level="ERROR"/>
  139 + <logger name="org.quartz" level="ERROR"/>
142 140  
143 141 <root level="INFO">
144   - <appender-ref ref="STDOUT_FILE"/>
145   - <appender-ref ref="DEBUG_FILE"/>
146   - <appender-ref ref="INFO_FILE"/>
147   - <appender-ref ref="ERROR_FILE"/>
  142 + <appender-ref ref="ASYNC_STDOUT"/>
  143 + <appender-ref ref="ASYNC_INFO"/>
  144 + <appender-ref ref="ASYNC_ERROR"/>
148 145 </root>
149 146  
150 147 </configuration>
... ...
service-api/src/main/java/com/java110/api/listener/CmdListener.java
... ... @@ -4,13 +4,16 @@ import com.alibaba.fastjson.JSONObject;
4 4 import com.aliyuncs.utils.StringUtils;
5 5 import com.java110.core.annotation.Java110Listener;
6 6 import com.java110.core.context.DataFlowContext;
  7 +import com.java110.core.context.Environment;
7 8 import com.java110.core.event.service.api.ServiceDataFlowEvent;
8 9 import com.java110.core.log.LoggerFactory;
9 10 import com.java110.dto.order.OrderDto;
10 11 import com.java110.dto.system.AppService;
11 12 import com.java110.intf.job.IDataBusInnerServiceSMO;
  13 +import com.java110.service.smo.ICmdServiceSMO;
12 14 import com.java110.utils.constant.CommonConstant;
13 15 import com.java110.utils.constant.ServiceCodeConstant;
  16 +import com.java110.utils.factory.ApplicationContextFactory;
14 17 import com.java110.utils.util.StringUtil;
15 18 import com.java110.vo.ResultVo;
16 19 import org.slf4j.Logger;
... ... @@ -19,6 +22,7 @@ import org.springframework.http.*;
19 22 import org.springframework.web.client.HttpStatusCodeException;
20 23 import org.springframework.web.client.RestTemplate;
21 24  
  25 +import java.util.HashMap;
22 26 import java.util.Map;
23 27  
24 28 @Java110Listener("cmdListener")
... ... @@ -45,16 +49,7 @@ public class CmdListener extends AbstractServiceApiListener {
45 49  
46 50 AppService service = event.getAppService();
47 51 Map<String, String> reqHeader = context.getRequestCurrentHeaders();
48   - HttpHeaders header = new HttpHeaders();
49   - for (String key : context.getRequestCurrentHeaders().keySet()) {
50   - if("user-name".equals(key)){
51   - continue;
52   - }
53   - if("userName".equals(key)){
54   - continue;
55   - }
56   - header.add(key, reqHeader.get(key));
57   - }
  52 +
58 53 if (reqHeader.containsKey(CommonConstant.USER_ID)
59 54 && (!reqJson.containsKey("userId") || StringUtil.isEmpty(reqJson.getString("userId")))) {
60 55 reqJson.put("userId", reqHeader.get(CommonConstant.USER_ID));
... ... @@ -76,48 +71,62 @@ public class CmdListener extends AbstractServiceApiListener {
76 71 reqJson.put("userName", reqHeader.get(CommonConstant.LOGIN_USER_NAME));
77 72 }
78 73  
79   - HttpEntity<String> httpEntity = new HttpEntity<String>(reqJson.toJSONString(), header);
80   - String orgRequestUrl = context.getRequestHeaders().get("REQUEST_URL");
81   -
82 74 String serviceCode = service.getServiceCode();
83   -
84 75 serviceCode = serviceCode.startsWith("/") ? serviceCode : ("/" + serviceCode);
85 76  
86   - String requestUrl = service.getUrl() + "/cmd" + serviceCode;
87   - //
88 77 ResponseEntity responseEntity = null;
89   - if (!StringUtil.isNullOrNone(orgRequestUrl)) {
90   - String param = orgRequestUrl.contains("?") ? orgRequestUrl.substring(orgRequestUrl.indexOf("?") + 1, orgRequestUrl.length()) : "";
91   - requestUrl += ("?" + param);
92   - }
93   - try {
94   - responseEntity = restTemplate.exchange(requestUrl, HttpMethod.POST, httpEntity, String.class);
95   - HttpHeaders headers = responseEntity.getHeaders();
96   - String oId = "-1";
97   - if (headers.containsKey(OrderDto.O_ID)) {
98   - oId = headers.get(OrderDto.O_ID).get(0);
99   - }
100 78  
  79 + // Boot模式下直接调用CmdServiceSMO,避免HTTP loopback开销
  80 + if (Environment.isStartBootWay()) {
  81 + try {
  82 + Map<String, String> headers = new HashMap<>();
  83 + headers.put(CommonConstant.HTTP_SERVICE, serviceCode);
  84 + headers.put(CommonConstant.HTTP_METHOD, CommonConstant.HTTP_METHOD_POST);
  85 + ICmdServiceSMO cmdServiceSMO = ApplicationContextFactory.getBean("cmdServiceSMOImpl", ICmdServiceSMO.class);
  86 + responseEntity = cmdServiceSMO.cmd(reqJson.toJSONString(), headers);
  87 + } catch (Exception e) {
  88 + logger.error("Boot模式直接调用cmd失败【{}】", serviceCode, e);
  89 + responseEntity = new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
  90 + }
  91 + } else {
  92 + // 微服务模式下走HTTP调用
  93 + HttpHeaders header = new HttpHeaders();
  94 + for (String key : context.getRequestCurrentHeaders().keySet()) {
  95 + if("user-name".equals(key)){
  96 + continue;
  97 + }
  98 + if("userName".equals(key)){
  99 + continue;
  100 + }
  101 + header.add(key, reqHeader.get(key));
  102 + }
101 103  
102   - } catch (HttpStatusCodeException e) { //这里spring 框架 在4XX 或 5XX 时抛出 HttpServerErrorException 异常,需要重新封装一下
103   - logger.error("请求下游服务【" + requestUrl + "】异常,参数为" + httpEntity + e.getResponseBodyAsString(), e);
104   - String body = e.getResponseBodyAsString();
  104 + HttpEntity<String> httpEntity = new HttpEntity<String>(reqJson.toJSONString(), header);
  105 + String orgRequestUrl = context.getRequestHeaders().get("REQUEST_URL");
105 106  
106   - if (StringUtil.isJsonObject(body)) {
107   - JSONObject bodyObj = JSONObject.parseObject(body);
108   - if (bodyObj.containsKey("message") && !StringUtil.isEmpty(bodyObj.getString("message"))) {
109   - body = bodyObj.getString("message");
  107 + String requestUrl = service.getUrl() + "/cmd" + serviceCode;
  108 + if (!StringUtil.isNullOrNone(orgRequestUrl)) {
  109 + String param = orgRequestUrl.contains("?") ? orgRequestUrl.substring(orgRequestUrl.indexOf("?") + 1, orgRequestUrl.length()) : "";
  110 + requestUrl += ("?" + param);
  111 + }
  112 + try {
  113 + responseEntity = restTemplate.exchange(requestUrl, HttpMethod.POST, httpEntity, String.class);
  114 + } catch (HttpStatusCodeException e) {
  115 + logger.error("请求下游服务【" + requestUrl + "】异常,参数为" + httpEntity + e.getResponseBodyAsString(), e);
  116 + String body = e.getResponseBodyAsString();
  117 + if (StringUtil.isJsonObject(body)) {
  118 + JSONObject bodyObj = JSONObject.parseObject(body);
  119 + if (bodyObj.containsKey("message") && !StringUtil.isEmpty(bodyObj.getString("message"))) {
  120 + body = bodyObj.getString("message");
  121 + }
110 122 }
  123 + responseEntity = new ResponseEntity<String>(body, e.getStatusCode());
111 124 }
112   - responseEntity = new ResponseEntity<String>(body, e.getStatusCode());
113 125 }
114 126  
115   - logger.debug("API 服务调用下游服务请求:{},返回为:{}", httpEntity, responseEntity);
116   -
117 127 if (responseEntity.getStatusCode() != HttpStatus.OK) {
118 128 responseEntity = ResultVo.createResponseEntity(ResultVo.CODE_ERROR, String.valueOf(responseEntity.getBody()));
119 129 context.setResponseEntity(responseEntity);
120   -
121 130 return;
122 131 }
123 132 if (StringUtils.isEmpty(responseEntity.getBody() + "")) {
... ...
service-api/src/main/java/com/java110/api/smo/impl/ApiServiceSMOImpl.java
... ... @@ -15,6 +15,7 @@ import com.java110.core.factory.GenerateCodeFactory;
15 15 import com.java110.core.log.LoggerFactory;
16 16 import com.java110.core.smo.ISaveTransactionLogSMO;
17 17 import com.java110.core.trace.Java110TraceLog;
  18 +import com.java110.service.smo.ICmdServiceSMO;
18 19 import com.java110.dto.order.OrderDto;
19 20 import com.java110.dto.system.AppRoute;
20 21 import com.java110.dto.system.AppService;
... ... @@ -42,6 +43,7 @@ import org.springframework.stereotype.Service;
42 43 import org.springframework.web.client.HttpStatusCodeException;
43 44  
44 45 import java.util.Date;
  46 +import java.util.HashMap;
45 47 import java.util.List;
46 48 import java.util.Map;
47 49  
... ... @@ -613,21 +615,24 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
613 615 requestUrl += ("?" + param);
614 616 }
615 617 try {
616   - //todo http的方式调用微服务,相应的java类可以到相应微服务下的cmd下根据serviceCode 的寻找
617   - //todo 这里会调用到 java110-service 模块下的 CmdApi 类,这个类各个微服务都会集成
  618 + // Boot模式下直接调用CmdServiceSMO,避免HTTP loopback开销(~400ms)
618 619 if (Environment.isStartBootWay()) {
  620 + Map<String, String> headers = new HashMap<>();
  621 + headers.put(CommonConstant.HTTP_SERVICE, serviceCode);
  622 + headers.put(CommonConstant.HTTP_METHOD, CommonConstant.HTTP_METHOD_POST);
  623 + ICmdServiceSMO cmdServiceSMO = ApplicationContextFactory.getBean("cmdServiceSMOImpl", ICmdServiceSMO.class);
  624 + responseEntity = cmdServiceSMO.cmd(reqJson.toJSONString(), headers);
  625 + } else {
619 626 requestUrl = Environment.BOOT_PATH + requestUrl;
620 627 restTemplate = ApplicationContextFactory.getBean("outRestTemplate", RestTemplate.class);
621 628 responseEntity = restTemplate.exchange(requestUrl, HttpMethod.POST, httpEntity, String.class);
622   - } else {
623   - requestUrl = appService.getUrl() + requestUrl;
624   - restTemplate = ApplicationContextFactory.getBean("restTemplate", RestTemplate.class);
625   - responseEntity = restTemplate.exchange(requestUrl, HttpMethod.POST, httpEntity, String.class);
626 629 }
627   - HttpHeaders headers = responseEntity.getHeaders();
628   - String oId = "-1";
629   - if (headers.containsKey(OrderDto.O_ID)) {
630   - oId = headers.get(OrderDto.O_ID).get(0);
  630 + if (responseEntity != null) {
  631 + HttpHeaders headers = responseEntity.getHeaders();
  632 + String oId = "-1";
  633 + if (headers.containsKey(OrderDto.O_ID)) {
  634 + oId = headers.get(OrderDto.O_ID).get(0);
  635 + }
631 636 }
632 637  
633 638 } catch (HttpStatusCodeException e) { //todo 这里spring 框架 在4XX 或 5XX 时抛出 HttpServerErrorException 异常,需要重新封装一下
... ... @@ -641,6 +646,9 @@ public class ApiServiceSMOImpl extends LoggerEngine implements IApiServiceSMO {
641 646 }
642 647 }
643 648 responseEntity = new ResponseEntity<String>(body, e.getStatusCode());
  649 + } catch (Exception e) {
  650 + logger.error("直接调用cmd异常【{}】", serviceCode, e);
  651 + responseEntity = new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
644 652 }
645 653  
646 654 logger.debug("API 服务调用下游服务请求:{},返回为:{}", httpEntity, responseEntity);
... ...
service-common/src/main/java/com/java110/common/smo/impl/AttendanceLogInnerServiceSMOImpl.java
... ... @@ -70,9 +70,15 @@ public class AttendanceLogInnerServiceSMOImpl extends BaseServiceSMO implements
70 70 return attendanceLogs;
71 71 }
72 72 String imgUrl = MappingCache.getValue(MappingConstant.FILE_DOMAIN, "IMG_PATH");
  73 + if (imgUrl == null) {
  74 + imgUrl = "";
  75 + }
73 76  
74 77 for (AttendanceLogDto tmpAttendanceLogDto : attendanceLogs) {
75   - tmpAttendanceLogDto.setFacePath(imgUrl + tmpAttendanceLogDto.getFacePath());
  78 + String facePath = tmpAttendanceLogDto.getFacePath();
  79 + if (facePath != null && !facePath.isEmpty()) {
  80 + tmpAttendanceLogDto.setFacePath(imgUrl + facePath);
  81 + }
76 82 }
77 83  
78 84 return attendanceLogs;
... ...
springboot/src/main/java/com/java110/boot/BootApplicationStart.java
... ... @@ -149,9 +149,9 @@ public class BootApplicationStart {
149 149  
150 150 //设置超时时间
151 151 HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
152   - httpRequestFactory.setConnectionRequestTimeout(10000);
153   - httpRequestFactory.setConnectTimeout(10000);
154   - httpRequestFactory.setReadTimeout(10000);
  152 + httpRequestFactory.setConnectionRequestTimeout(3000);
  153 + httpRequestFactory.setConnectTimeout(3000);
  154 + httpRequestFactory.setReadTimeout(5000);
155 155 restTemplate.setRequestFactory(httpRequestFactory);
156 156 return restTemplate;
157 157 }
... ... @@ -178,9 +178,9 @@ public class BootApplicationStart {
178 178 restTemplate.getInterceptors().add(java110RestTemplateInterceptor);
179 179 //设置超时时间
180 180 HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
181   - httpRequestFactory.setConnectionRequestTimeout(10000);
182   - httpRequestFactory.setConnectTimeout(10000);
183   - httpRequestFactory.setReadTimeout(10000);
  181 + httpRequestFactory.setConnectionRequestTimeout(3000);
  182 + httpRequestFactory.setConnectTimeout(3000);
  183 + httpRequestFactory.setReadTimeout(5000);
184 184 restTemplate.setRequestFactory(httpRequestFactory);
185 185 return restTemplate;
186 186 }
... ...
springboot/src/main/resources/application-prod.yml
... ... @@ -2,6 +2,10 @@ server:
2 2 port: 8008
3 3 tomcat:
4 4 uri-encoding: UTF-8
  5 + threads:
  6 + max: 200
  7 + min-spare: 20
  8 + accept-count: 100
5 9 spring:
6 10 servlet:
7 11 multipart:
... ... @@ -29,15 +33,15 @@ spring:
29 33 activiti:
30 34 database-schema-update: false
31 35 datasource:
32   - url: jdbc:mysql://rm-2zeo2635t3c592h2ywo.mysql.rds.aliyuncs.com:3306/estate?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
  36 + url: jdbc:mysql://rm-2zeo2635t3c592h2ywo.mysql.rds.aliyuncs.com:3306/estate?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false&cachePrepStmts=true&useServerPrepStmts=true&cacheCallableStmts=true&prepStmtCacheSize=256&prepStmtCacheSqlLimit=2048&socketTimeout=30000&connectTimeout=10000
33 37 username: estate
34 38 password: MySQL57@123
35 39 type: com.alibaba.druid.pool.DruidDataSource
36 40 driver-class-name: com.mysql.cj.jdbc.Driver
37 41 druid:
38   - initial-size: 5
39   - max-active: 20
40   - min-idle: 5
  42 + initial-size: 10
  43 + max-active: 50
  44 + min-idle: 10
41 45 max-wait: 60000
42 46  
43 47 eureka:
... ...