Commit 1d418ca8e80762bc68e90398807269ac171f0e43
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地址获取功能
Showing
12 changed files
with
297 additions
and
229 deletions
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: | ... | ... |