当前位置: 首页 > news >正文

摄影网站制作教程公司测名

摄影网站制作教程,公司测名,成都如何寻找做网站的,装饰行业做网站需求 在访问量较大的分布式系统中#xff0c;时时刻刻在打印着巨量的日志#xff0c;当我们需要排查问题时#xff0c;需要从巨量的日志信息中找到本次排查内容的日志是相对复杂的#xff0c;那么#xff0c;如何才能使日志看起来逻辑清晰呢#xff1f;如果每一次请求都…需求 在访问量较大的分布式系统中时时刻刻在打印着巨量的日志当我们需要排查问题时需要从巨量的日志信息中找到本次排查内容的日志是相对复杂的那么如何才能使日志看起来逻辑清晰呢如果每一次请求都有一个全局唯一的id当我们需要排查时根据其他日志打印关键字定位到对应请求的全局唯一id再根据id去搜索、筛选即可找到对应请求全流程的日志信息。接下来就是需要找一种方案可以生成全局唯一id和在不同的线程中存储这个id。 解决方案 LogBack这个日志框架提供了MDC( Mapped Diagnostic Context映射调试上下文 ) 这个功能MDC可以理解为与线程绑定的数据存储器。数据可以被当前线程访问当前线程的子线程会继承其父线程中MDC的内容。MDC 在 Spring Boot 中的作用是为日志事件提供上下文信息并将其与特定的请求、线程或操作关联起来。通过使用 MDC可以更好地理解和分析日志并在多线程环境中确保日志的准确性和一致性。此外MDC 还可以用于日志审计、故障排查和跟踪特定操作的执行路径。 代码 实现日志打印全局链路唯一id的功能需要三个信息 全局唯一ID生成器请求拦截器自定义线程池可选日志配置 全局唯一ID生成器 生成器可选方案有 UUID快速随机生成、极小概率重复Snowflake有序递增时间戳 雪花算法Snowflake更适用于需要自增的业务场景如数据库主键、订单号、消息队列的消息ID等 时间戳一般是微秒级别极限情况下一微秒内可能同时多个请求进来导致重复。系统时钟回拨时UUID可能会重复但是一般不会出现该情况因此UUID这种方案的缺点可以接受本案例使用UUID方案。 /*** 全局链路id生成工具类** author Ltx* version 1.0*/ public class RequestIdUtil {public RequestIdUtil() {}public static void setRequestId() {//往MDC中存入UUID唯一标识MDC.put(Constant.TRACE_ID, UUID.randomUUID().toString());}public static void setRequestId(String requestId) {MDC.put(Constant.TRACE_ID, requestId);}public static String getRequestId() {return MDC.get(Constant.TRACE_ID);}public static void clear() {//需要释放避免OOMMDC.clear();} }/*** Author: liu_pc* Date: 2023/8/8* Description: 常量定义类* Version: 1.0*/ public class Constant {/*** 全局唯一链路id*/public final static String TRACE_ID traceId; }自定义全局唯一拦截器 Filter是Java Servlet 规范定义的一种过滤器接口它的主要作用是在 Servlet 容器中对请求和响应进行拦截和处理实现对请求和响应的预处理、后处理和转换等功能。通过实现 Filter 接口开发人员可以自定义一些过滤器来实现各种功能如身份验证、日志记录、字符编码转换、防止 XSS 攻击、防止 CSRF 攻击等。那么这里我们使用它对请求做MDC赋值处理。 Component public class RequestIdFilter implements Filter {Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException{try {HttpServletRequest httpServletRequest (HttpServletRequest) servletRequest;String requestId httpServletRequest.getHeader(requestId);if (StringUtils.isBlank(requestId)) {RequestIdUtil.setRequestId();} else {RequestIdUtil.setRequestId(requestId);}// 继续将请求传递给下一个过滤器或目标资源比如ControllerfilterChain.doFilter(servletRequest, servletResponse);} finally {RequestIdUtil.clear();}}Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}Overridepublic void destroy() {Filter.super.destroy();} }/*** 测试MDC异步任务全局链路** param param 请求参数* return new String Info*/public String test(String param) {logger.info(测试MDC test 接口开始请求参数:{}, param);String requestId RequestIdUtil.getRequestId();logger.info(MDC RequestId :{}, requestId);return hello;}日志配置 输出到控制台: ?xml version1.0 encodingUTF-8? configuration!-- 配置输出到控制台可选输出到文件 --appender nameCONSOLE classch.qos.logback.core.ConsoleAppenderencoder!-- 配置日志格式 --pattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %mdc %msg%n/pattern/encoder/appender!-- 配置根日志记录器 --root levelINFOappender-ref refCONSOLE//root!-- 配置MDC --contextListener classch.qos.logback.classic.jul.LevelChangePropagatorresetJULtrue/resetJUL/contextListener!-- 配置MDC插件 --conversionRule conversionWord%mdc converterClassorg.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter/ /configuration输出到文件 configuration!-- 配置输出到文件 --appender nameFILE classch.qos.logback.core.FileAppender!-- 指定日志文件路径和文件名 --file/Users/liu_pc/Documents/code/mdc_logback/logs/app.log/fileencoder!-- 配置日志格式 --pattern%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %mdc %msg%n/pattern/encoder/appender!-- 配置根日志记录器 --root levelINFOappender-ref refFILE//root!-- 其他配置... -- /configuration功能实现。 子线程获取traceId问题 使用多线程时子线程打印日志拿不到traceId。如果在子线程中获取traceId那么就相当于往各自线程中的MDC赋值了traceId会导致子线程traceId不一致的问题。 public void wrongHelloAsync(String param) {logger.info(helloAsync 开始执行异步操作,请求参数:{}, param);ListInteger simulateThreadList new ArrayList(5);for (int i 0; i 5; i) {simulateThreadList.add(i);}for (Integer thread : simulateThreadList) {CompletableFuture.runAsync(() - {//在子线程中赋值String requestId RequestIdUtil.getRequestId();logger.info(子线程信息:{},traceId:{} , thread, requestId);}, executor);}} }子线程获取traceId方案 使用子线程时可以使用自定义线程池重写部分方法在重写的方法中获取当前MDC数据副本再将副本信息赋值给子线程的方案。 /*** Author: liu_pc* Date: 2023/8/7* Description: 自定义异步线程池配置* Version: 1.0*/ Configuration EnableAsync public class AsyncConfiguration implements AsyncConfigurer {private final Logger logger LoggerFactory.getLogger(AsyncConfiguration.class);private final TaskExecutionProperties taskExecutionProperties;public AsyncConfiguration(TaskExecutionProperties taskExecutionProperties) {this.taskExecutionProperties taskExecutionProperties;}OverrideBean(name taskExecutor)public Executor initAsyncExecutor() {logger.debug(Creating Async Task Executor);ThreadPoolTaskExecutor executor new MdcThreadPoolTaskExecutor();executor.setCorePoolSize(taskExecutionProperties.getPool().getCoreSize());executor.setMaxPoolSize(taskExecutionProperties.getPool().getMaxSize());executor.setQueueCapacity(taskExecutionProperties.getPool().getQueueCapacity());executor.setThreadNamePrefix(taskExecutionProperties.getThreadNamePrefix());return executor;}Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return new SimpleAsyncUncaughtExceptionHandler();} }/*** Author: liu_pc* Date: 2023/8/7* Description: 自定义携带MDC信息线程池* Version: 1.0*/ public class MdcThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {Overridepublic void execute(Nonnull Runnable task) {MapString, String copyOfContextMap MDC.getCopyOfContextMap();super.execute(() - {if (Objects.nonNull(copyOfContextMap)) {String requestId RequestIdUtil.getRequestId();if (StringUtils.isBlank(requestId)) {copyOfContextMap.put(traceId, UUID.randomUUID().toString());}//主线程MDC赋值子线程MDC.setContextMap(copyOfContextMap);} else {RequestIdUtil.setRequestId();}try {task.run();} finally {RequestIdUtil.clear();}});} }测试代码 /*** 测试MDC异步任务全局链路** param param 请求参数* return new String Info*/public String test(String param) {logger.info(测试MDC test 接口开始请求参数:{}, param);String requestId RequestIdUtil.getRequestId();logger.info(MDC RequestId :{}, requestId);helloAsyncService.helloAsync(param, requestId);return hello;}/*** 使用异步数据测试打印日志** param param 请求参数* param requestId 全局唯一id*/Async(taskExecutor)public void helloAsync(String param, String requestId) {logger.info(helloAsync 开始执行异步操作,请求参数:{}, param);ListInteger simulateThreadList new ArrayList(5);for (int i 0; i 5; i) {simulateThreadList.add(i);}for (Integer thread : simulateThreadList) {CompletableFuture.runAsync(() - {//在子线程中赋值RequestIdUtil.setRequestId(requestId);logger.info(子线程信息:{},traceId:{} , thread, requestId);}, executor);}}MDC原理
http://www.yutouwan.com/news/222008/

相关文章:

  • 技术网站有哪些网站设计制作规范
  • 海南手机网站建设公司哪家好互联网营销课程体系
  • 个人网站建设代码一个thinkphp搭建的微网站
  • 深圳网站建设 推广网站设计自已申请
  • 推荐聊城做网站的公司郑州建站模板厂家
  • 百度显示网站正在建设中专业集团门户网站建设企业
  • wordpress 数据站深圳网站制作公司兴田德润官网多少
  • 网站后台开发费用领卷网站如何做代理
  • wordpress建站主题做AE视频素材在哪些网站上可以找
  • 局网站建设制度昆明比较好的网站开发公司
  • 网站关键词多少个合适房山网站制作
  • 齐齐哈尔网站建设展会设计公司简介
  • 医疗号网站开发wordpress 显示word文档
  • 电子商务网站建设策划书的流程合肥网站商城开发
  • 重庆seo网站如何开发移动网站
  • 网站logo素材怎么做淘客网站推广
  • 怎么申请自己的网站网址北京产品网站建设
  • 住房和城乡建设部网站 上海河北婚庆网站建设定制
  • 网站建设与管理报告wordpress文章页面图片自动适应
  • 天津市建设教育培训中心网站网站cms分站系统
  • 建外贸网站用什么主机建筑人才网代码
  • 内蒙古高等级公路建设开发有限责任公司网站数据库修改wordpress文章浏览量
  • 做网站商家网站开发js不更新
  • 山东天成水利建设有限公司网站中国污水处理工程网
  • ppt模板网站开发福建省建设执业资格注册管理中心网站
  • 可以做任务的网站有哪些内容企业门户网站方案
  • 音乐视频怎么做mp3下载网站深圳网站建设模板乐云seo
  • 网站备案帐号是什么成品源码1688网站免费
  • 秦皇岛网站开发价格在国内的服务器上建设国外网站
  • 景安网站备案要多久ico 众筹网站开发