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

厦门找一家做网站的公司好做一个网上商城需要多少钱

厦门找一家做网站的公司好,做一个网上商城需要多少钱,小公司建设网站,wordpress 301怎么写一、背景 2024 年 4 月的一个宁静的夜晚#xff0c;正当大家忙完一天的工作准备休息时#xff0c;应急群里“咚咚咚”开始报警#xff0c;提示我们余利宝业务的赎回接口成功率下降。 通过 Monitor 监控发现#xff0c;该接口的耗时已经超过了网关配置的超时阈值(2s)#… 一、背景 2024 年 4 月的一个宁静的夜晚正当大家忙完一天的工作准备休息时应急群里“咚咚咚”开始报警提示我们余利宝业务的赎回接口成功率下降。 通过 Monitor 监控发现该接口的耗时已经超过了网关配置的超时阈值(2s)我们临时调整超时阈值止血后就在排查问题的根因。具体排查过程不是我这篇文章的重点故忽略但最终我们发现最近上线新加的相邻两行的日志中时间相差近 1.5s难道这就是问题的根源吗 后来我们去掉了这两行日志后紧急发布事实证明我们的思路是对的。紧急发布后该接口的耗时由之前的 2s 左右优化到了 600ms 左右。后来我们分析发现该接口在打印日志时由于要实现日志脱敏故在 Logger.info 入口处实现了脱敏功能但是大日志脱敏比较耗时从而导致该接口的同步调用耗时激增到 1.5s 左右后面我们会说如何解决这个问题。我的天呐一行日志竟是性能优化的金钥匙 但这里有一个问题我们是去掉了日志的打印侵入了业务同时该应用还是用的 log4j 的日志框架log4j 原生框架是不支持日志异步化的因此要从根本上业务无侵入的解决因日志而导致的性能问题需要熟悉 log4j2 的框架原理。 二、原理 2.1 Log4j2 的优势 1性能: Log4j2 使用基于 Lambda 的异步记录器显著提高了日志记录的速度减少了日志操作对应用性能的影响。相比之下Logback 虽然也支持异步记录但实现上不如 Log4j2 高效。通过减少对象创建、高效的字符串处理和池化技术Log4j2 在高并发场景下表现更佳。 2配置灵活性: 支持多种配置方式包括 XML、JSON、YAML、properties 文件甚至编程式配置提供更大的灵活性。动态重新配置能力允许在不重启应用的情况下修改日志配置。 3插件架构: Log4j2 采用插件架构几乎所有组件如 Appenders、Layouts、Filters都是可插拔的易于扩展和自定义。内置丰富的插件库开箱即用简化集成过程。 4内存和资源管理: 更高效的内存管理减少内存泄漏的风险尤其是在大量日志输出时。支持垃圾回收友好的设计比如基于 Disrupter 的 RingBuffer 等数据结构减少 GC 压力。 5可靠性: 强大的故障恢复机制如重试和备用 Appenders确保日志能够被记录下来即使主要的日志输出目的地不可用。 6先进的特性: 支持条件日志记录Conditionals可以根据运行时条件决定是否记录日志。 自动重新加载配置文件变化无需重启应用。 支持 JMX 监控和管理日志系统状态。 7与 SLF4J 的集成:虽然这不是特有优势但 Log4j2 提供了与 SLF4JSimple Logging Facade for Java的良好集成使得从其他日志框架迁移更加平滑。 总的来说Log4j2 的设计更现代化强调高性能、易用性和灵活性特别是在大规模分布式系统和高性能应用中表现突出。而 Logback 和 Log4j 1.x 虽有各自的优点但在这些方面逐渐显得力不从心。至于 Java Util Logging (JUL)它是 Java 标准库的一部分但功能相对基础配置和扩展性不如 Log4j2 和 Logback 灵活。 2.2 Log4j2 的结构 Log4j2 的结构主要包括以下几个核心组件 1Logger: 这是开发者直接使用的接口用于记录不同级别的日志信息如 DEBUG, INFO, ERROR 等。每个 Logger 都有一个名称并且支持继承性形成一个名为 Logger Hierarchy 的树状结构根 Logger 的名称为root。 2LoggerContext: 是日志系统的上下文环境管理着一组 Logger 实例以及它们的配置。每个应用程序通常只有一个 LoggerContext但它支持多个上下文以实现更细粒度的控制。 3Configuration: 每个 LoggerContext 都关联一个有效的 Configuration定义了日志的输出目的地Appenders、日志的过滤规则Filters、日志的格式化方式Layouts等。Configuration 可以通过配置文件如 XML、JSON、properties或编程方式动态加载。 4Appender: 负责将日志事件发送到指定的目标如控制台Console、文件File、数据库、网络 Socket 等。 5Layout: 定义了日志信息的格式化方式如模式字符串Pattern String决定了日期、时间、日志级别、线程名、日志信息等内容的排列和格式。 6Filter: 可以在日志事件从 Logger 传递到 Appender 的过程中进行过滤根据特定条件决定日志是否被输出。 7Lookup: 提供动态值解析机制如 ${ctx:variable}可以在日志中插入上下文变量的值。 那么Log4j2 的日志是怎么将日志输出到文件/数据库/控制台等地方的 2.3 Log4j2 日志输出流程 关键步骤源码分析 11.1 主要是针对日志级别 Level 和指定的全局 Filter 组件进行过滤 2ReliabilityStrategy 是 Log4j2 的日志可靠性策略实现目前主要有以下四种 AwaitCompletionReliabilityStrategy: 等待日志接收完成策略。这种策略主要是在应用关闭时尽可能要等应用日志接收完成后再结束 Appender 的生命周期这种策略只是说尽可能所有日志等待调用 Appender.append 方法完成但在异步日志场景下Appender.append 其实是落了 ringbuffer 或者其他队列里实际上未持久化。因此该策略是尽可能保证接收完成而非处理完成 AwaitUnconditionallyReliabilityStrategy: 无条件等待策略。这种策略会在 rootLogger 关闭时无条件等待一段时间具体等待时间可以配置 log4j2.component.properties 文件的 log4j.waitMillisBeforeStopOldConfig 属性。 DefaultReliabilityStrategy: 默认策略。该策略不做任何等待。 LockingReliabilityStrategy: 锁等待策略。该策略当正在写入日志时则会等待否则即会停止等待。 31.2.1.3.1append 操作是将日志写入到对应的目的地如 kafka、本地文件、邮件等。这里如果是异步日志则会将日志追加到异步队列里进而提高日志记录的性能。 41.2.1.3.1.1 调用 Layout encode 日志是根据 log4j2.xml 中配置的 Layout 对日志进行格式化输出。 那么如果有一些个性化的日志输出需求log4j2 能否帮我们实现 2.4 如何实现日志脱敏 上面提到了 log4j2 的各种组件以及日志输出流程log4j2 的强大很大程度上得益于其清晰且高度解耦的架构设计。例如其具有很强的扩展性log4j2 的很多组件都可以自己定制插件如Appender、Filter、Layout 等。那么这里我结合我们实际业务中一个很常见的 case 去分析如何定制一个组件。 首先作为一家强监管的金融公司日志脱敏涉及数据保护和隐私安全等问题非常重要。过去我们很多业务系统在实现业务脱敏时很容易想到在打日志的入口统一封装一个格式化方法造成日志输出在无形中把异步日志输出变成了同步输出日志脱敏的耗时往往比日志集中持久化到磁盘耗时要高。 那么如何优雅的实现日志脱敏的功能既能实现其功能又可以保证日志的性能是 log4j2 插件化的一个很重要的应用场景。前面我们提到日志输出流程中会使用 Layout encode 日志而 PatternConverter 是 Layout 非常重要的组成部分。其通过定义一系列的占位符如 %d、%m、 %t 等帮助我们自定义格式输出日志对象同时 PatternConverter 支持以高度可定制的插件集成到 Log4j2 框架中因此我们可以借助其去定制脱敏组件。 话不多说我们直接上日志脱敏 PatternConverter 插件源码 // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // import java.util.Arrays;import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.pattern.ConverterKeys; import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; import org.apache.logging.log4j.message.FormattedMessage; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.message.MessageFormatMessage; import org.apache.logging.log4j.message.ParameterizedMessage; import org.apache.logging.log4j.message.StringFormattedMessage; import org.apache.logging.log4j.util.PerformanceSensitive;/*** author baichun* version ShieldMessagePatternConverter.java, v 0.1 2024年04月09日 21:13 baichun*/ Plugin(name ShieldPatternConverter,category Converter ) ConverterKeys({shield, sd, shieldMessage, sm}) PerformanceSensitive({allocation}) public final class ShieldMessagePatternConverter extends LogEventPatternConverter {private final String[] options;private ShieldMessagePatternConverter(String[] options) {super(Shield, shield);this.options options null ? null : (String[])Arrays.copyOf(options, options.length);}//必须要有newInstance方法log4j2会调用该方法进行初始化public static ShieldMessagePatternConverter newInstance(String[] options) {return new ShieldMessagePatternConverter(options);}Overridepublic void format(LogEvent logEvent, StringBuilder output) {Message message logEvent.getMessage();String format message.getFormat();if (isFormatMessage(message)) {//在这里格式化脱敏日志String msgInfo ShieldUtils.format(format, message.getParameters());output.append(msgInfo);} else {output.append(message.getFormattedMessage());}}private boolean isFormatMessage(Message message) {return message instanceof ParameterizedMessage || message instanceof StringFormattedMessage|| message instanceof FormattedMessage || message instanceof MessageFormatMessage;} } 定义好组件后log4j2 即能够自动扫描识别到不需要其他定义和配置。接下来看看如何使用。ConverterKeys 这个注解指定了在 log4j2.xml 中应如何使用该插件。以下是 log4j2.xml 应用示例 RollingFile nameTEST_APPENDER fileNametest.log filePatterntest.log.%d{yyyy-MM-dd} appendtrue !-- %sm即为脱敏组件 -- PatternLayout pattern%d %sm%n charsetUTF-8/ TimeBasedTriggeringPolicy/ DefaultRolloverStrategy/ /RollingFile2.5 Log4j2 的异步日志 异步日志原理概述 前面提到了 Log4j2 的高可扩展性同时 Log4j2 的性能也是极高的下面是 Log4j2 官方的 benchmark 数据仅供参考 Log4j2 之所以性能如此之高其中一个很重要的原因就是其基于 Disrupter 的环形缓冲区的无锁化结构 Ringbuffer 设计。Disruptor 是英国外汇交易公司 LMAX 开发的一个高性能队列基于 Disruptor 开发的系统单线程能支撑每秒 600 万订单。目前包括 Apache Strom、Log4j2 在内的很多知名项目都应用了 Disruptor 来获取高性能。关于 Disruptor 的原理这里不再赘述大家可以自行查阅https://lmax-exchange.github.io/disruptor/#_what_is_the_disruptor Disrupter 组件构成 Disrupter 性能测试结果 如何使用异步日志 log4j2 开启异步日志的方法主要有以下两种方式 1全局异步日志 通过 JVM 启动参数来全局启用异步日志功能。在启动应用程序时向 JVM 传递以下系统属性 -DLog4jContextSelectororg.apache.logging.log4j.core.async.AsyncLoggerContextSelector 在类路径classpath中添加一个名为 log4j2.component.properties 的文件并包含以下内容这个文件会在 Log4j2 初始化时被读取 -DLog4jContextSelectororg.apache.logging.log4j.core.async.AsyncLoggerContextSelector Log4jContextSelectororg.apache.logging.log4j.core.async.AsyncLoggerContextSelector 复制代码 这两种方式下所有 Logger 都会自动使用异步处理。 2混合异步日志 在 log4j2.xml 配置文件中可以手动指定特定的 Logger 使用异步处理通过将 Root或Logger元素替换为AsyncRoot或AsyncLogger。例如 Configuration statusWARN Appenders... !-- your appenders here -- /Appenders Loggers AsyncRoot levelinfo includeLocationfalse AppenderRef refyourAppenderName/ /AsyncRoot !-- 或者为特定logger配置 -- AsyncLogger namecom.example.MyClass leveldebug AppenderRef refyourAppenderName/ /AsyncLogger /Loggers /Configuration异步日志的潜在问题及解决方案 潜在问题 日志丢失问题如果机器发生意外重启、发布、掉电导致的 jvm 进程停止停留在队列的未来得及输出到目的地的 LogEvent 可能会丢失 日志顺序问题由于日志事件是在不同的线程中异步处理的因此日志条目可能不会严格按照它们产生的顺序出现在日志文件中这对于需要严格按时间顺序追踪日志的应用可能是个问题。 其他问题如增加资源损耗、配置复杂度和调试复杂度等问题 解决方案 对于日志丢失问题 原生 Log4j2 有完整的生命周期管理并监听了 jvm 关闭的事件。当 jvm 关闭时Log4j2 会监听 Disrupter 队列中的 RingbufferLogEvent 数量直到日志打印完或超时才释放关闭 Log4j2jvm 才得以正常关闭。但是自然灾害或者机房掉电等不可抗力因素无法避免丢失问题。 我们基于 Log4j2 定制的 AsyncAbleRollingFileAppender其中有独立的 Disrupter且不在 Log4j2 生命周期管理当中存在日志丢失风险。可以采用类似方案解决 try {LoggerContextFactory factory LogManager.getFactory();if (!(factory instanceof Log4jContextFactory)) {return;}Log4jContextFactory log4jContextFactory (Log4jContextFactory) factory;ShutdownCallbackRegistry registry log4jContextFactory.getShutdownCallbackRegistry();if (!(registry instanceof DefaultShutdownCallbackRegistry)) {return;}DefaultShutdownCallbackRegistry defaultShutdownCallbackRegistry (DefaultShutdownCallbackRegistry) registry;Field hooksField DefaultShutdownCallbackRegistry.class.getDeclaredField(hooks);hooksField.setAccessible(true);CollectionCancellable hooks (CollectionCancellable) hooksField.get(defaultShutdownCallbackRegistry);CollectionCancellable newHooks new CopyOnWriteArrayList();//将对Appender的队列消费监听和卸载放在首要位置避免log4j2关闭后再卸载AppendernewHooks.add(new Log4j2Cancellable(() - {//负责监听AsyncAbleRollingFileAppender的队列消费情况并在消费完成后关闭AsyncAbleRollingFileAppendernew AppenderUnInstaller(register).run();}));newHooks.addAll(hooks);hooksField.set(defaultShutdownCallbackRegistry, newHooks);} catch (NoSuchFieldException e) {// This catch statement is intentionally empty} catch (IllegalAccessException e) {// This catch statement is intentionally empty} AsyncAbleRollingFileAppender 使用独立的 disrupter且 RingBufferLogEvent 未及时清理对象容易导致内存泄漏异步日志场景请慎用。 对于日志顺序性问题 异步线程池大小设置为 1但是会影响日志打印的速度现在的普遍做法。 延迟打印 三、效果 4 月份的这一问题发生后我们从原理出发对理财的核心应用做了升级和优化整体服务耗时上取得了不错的性能优化效果。 应用 rpc 耗时 应用网关耗时 但与此同时我们也发现升级后应用的 fgc 次数更多了经过 heapdump 分析后发现 AsyncAbleRollingFileAppender 内部实现的 RingBufferLogEvent 执行后不会释放引用的 LogEvent导致 Disrupter 一直持有已打印的 LogEvent 的引用关系进而导致了内存泄漏。后来我们采取主动释放对象引用RingBufferLogEvent.setLogEvent(null)优化的方案发布以后前后 fgc 对比如下 GC 优化前 GC 优化后 四、建议 日志作为诊断问题、监控系统健康状况与优化服务效能不可或缺的一环其重要性不言而喻。熟练掌握并有效利用如 Log4j2 这样的高性能日志框架以及注意一些打印日志的策略如动静分离、合理分割、合理设置日志级别等对于开发者而言至关重要 1动静分离 在一些大日志输出场景中即使是异步日志也会给系统带来性能风险。因此建议合理识别大日志中的动态数据和静态数据。静态数据定时输出动态数据关联唯一静态标识输出在降低性能风险的同时又满足监控分析的需要 2合理分割 日志文件需要合理分割并设置合理的保留策略及时释放磁盘空间。 3合理设置日志级别 避免日志滥用尤其是 debug 日志既有利于日志定位问题的速度又能提高性能。
http://www.hkea.cn/news/14373448/

相关文章:

  • 鸿扬家装网站建设广东深圳职业技术学校
  • 做西班牙语网站shopee东南亚跨境电商平台
  • 专题网站建设意义何在深圳珠宝网站设计
  • 多语种网站创意字体设计生成器
  • 做重视频网站wordpress备份文章
  • 家居网站建设素材wordpress怎么建表格
  • 自己能建设网站京东网上购物商城购物
  • 网站设计是用ps做图吗seo综合查询怎么回事
  • 社区网站开发进度表郑州百姓网免费征婚
  • 专业做高端网站做文案应该关注的网站推荐
  • 有哪些网站可以做设计竞标网站小视频怎么做代理
  • 顺德网站建设效果wordpress不显示媒体库图片
  • 响应式科技公司网站模板如何用asp编写网站后台
  • 南宁网站建设咨询云尚网络网站友链查询源码
  • c2c网站开发策划品牌推广费用预算
  • 界面设计是做什么的windows优化大师的特点
  • 深圳联雅网站建设公司注册步骤流程
  • 网站修改东莞建设造价信息网站
  • 全景网站制作教程天津搜索引擎优化公司
  • 电子商务网站的运营一般需要做哪些准备wordpress 多说 代码
  • 大丰网站建设公司WordPress怎么改主题页脚
  • 网站免费下载安装WordPress和微信同步
  • 一级a做爰网站wordpress主题选项
  • 地方门户网站盈利创联互动建设网站
  • 沈阳网站建设优化ps做网站字体用多大的
  • 建设商城网站制作科技网站建设分析
  • 织梦关闭网站北京通州网站设计公司
  • 建设网站的目的爱站网功能
  • 做网站制作的wordpress做在线编辑图片大小
  • 网站查询seo长沙模板网站建设企业