原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

在日常开发中,我们经常会使用logback打印日志,还会包含一些敏感内容。比如手机号卡号、邮箱等,这对数据安全而言是有风险的。

但是如果让业务去处理这些问题,则需要在每个打印日志的地方,进行重复的脱敏操作,不仅繁琐影响代码风格,还会有遗漏情况。

这个时候,我们就需要考虑一个相对统一的解决方案,通过增强logback,在日志message落盘之前,统一进行检测、脱敏。

一、需求来源

我们通常的日志处理,面临的通用诉求:

1)超长日志message截取: 程序打印的日志message可能非常大,比如超过1M,这种message极大的影响系统的性能,而且通常数据价值比较低。我们应该对这种message进行截取或者直接抛弃。

2)日志格式统一: 通常情况下,生产环境的业务日志通过会按需采集、分析、存储,那么日志格式的统一对下游数据处理是非常必要的。

为了避免错误配置了日志格式,我们应该将日志格式规范,默认进行集成且限制修改。

日志格式中,通常包含一些用于数据分拣的系统信息(例如,项目名、部署集群名、IP、云平台、rack等),也包含一些运行时的MDC动态参数值,最终格式要求是一致的。

3)脱敏: 日志中存在特定规则的字符串时,比如手机号,需要对其进行脱敏处理。

二、设计核心思想

我们可以基于PatternLayoutEncoder来实现日志格式的限定,不再使用默认的pattern参数指定格式,而是固定字段格式 + 自定义字段,最终拼接成格式规范。

其中,局部可控字段,可以是系统变量、也可以MDC字段列表;固定格式部分,通常是message的头部,包含时间、IP、项目名等等。

基于logback提供的MessageConverter特性,在message打印之前,允许对“参数格式化之后的message”(formattedMessage)进行转换,最终logger打印的实际内容是converter返回的整形后的结果。

那么,我们就可以基于此特性,在convert方法中执行“超长message截取”、“内容脱敏”两个主要操作。

三、设计编码

设计理念

**CommonPatternLayoutEncoder:**父类为PatternLayoutEncoder,用于定义日志格式,包括固定字段部分自定义字段部分,将系统属性、MDC属性等,进行拼接。

同时,基于logbackoption特性,将动态参数传递给MessageConverter,最终拼接成一个字符串,作为pattern属性。同时converter所需要的配置参数,比如消息最大长度、正则表达式、替换策略,都需要通过Encoder声明。

ComplexMessageConverter:

message转换,只会操作logger.info(String message,Throwable ex)传递的message部分。其中,throwable栈信息不会被操作(其实也无法修改)。

Converter可以获取Encoder传递的option参数列表,并初始化相关的处理类;内部实现基于正则表达式来匹配敏感信息。

DataSetPatternLayoutEncoder(可选):

主要用于限定数据集类的日志格式,它本身不能对敏感信息进行过滤;数据格式主要为了便于数据分析。

image

主要代码

下面是CommonPatternLayoutEncoder.java的主要代码,详细参见注释。

package ch.qos.logback.classic.encoder;import ch.qos.logback.classic.PolicyEnum;
import ch.qos.logback.classic.Utils;import java.text.MessageFormat;importstatic ch.qos.logback.classic.Utils.DOMAIN_DELIMITER;
importstatic ch.qos.logback.classic.Utils.FIELD_DELIMITER;/*** 适用于基于File的Appender* <p>* 限定我司日志规范,增加有关敏感信息的过滤。* 可以通过regex指定需要匹配和过滤的表达式,对于符合表达式的字符串,则采用policy进行处理。* 1)replace:替换,将字符串替换为facade,比如:18611001100 > 186****1100* 2) drop:抛弃整条日志* 3)erase:擦除字符串,全部替换成等长度的"****",18611001100 > ************ <p>* depth:正则匹配深度,默认为12,即匹配成功次数达到此值以后终止匹配,主要考虑是性能。如果一个超长的日志,我们不应该全部替换,否则可能引入性能问题。* maxLength:单条message的最大长度(不计算throwable),超长则截取,并在message尾部追加终止符。* <p>* 考虑到扩展性,用户仍然可以直接配置pattern,此时regex、policy、depth等option则不生效。但是maxLength会一致生效。* 格式样例:* %d{yyyy-MM-dd/HH:mm:ss.SSS}|IP_OR_HOSTNAME|REQUEST_ID|REQUEST_SEQ|^_^|* SYS_K1:%property{SYS_K1}|SYS_K2:%property{SYS_K2}|MDC_K1:%X{MDC_K1:--}|MDC_K2:%X{MDC_K2:--}|^_^|* [%t] %-5level %logger{50} %line - %m{o1,o2,o3,o4}%n* 格式中domain1是必选,而且限定无法扩展* domain2根据配置文件指定的system properties和mdcKeys动态拼接,K-V结构,便于解析;可以为空。* domain3是常规message部分,其中%m携带options,此后Converter可以获取这些参数。**/
publicclass CommonPatternLayoutEncoder extends PatternLayoutEncoder {protectedstaticfinal String PATTERN_D1 = "%d'{'yyyy-MM-dd/HH:mm:ss.SSS'}'|{0}|%X'{'requestId:--'}'|%X'{'requestSeq:--'}'";protectedstaticfinal String PATTERN_D2_S1 = "{0}:%property'{'{1}'}'";protectedstaticfinal String PATTERN_D2_S2 = "{0}:%X'{'{1}:--'}'";protectedstaticfinal String PATTERN_D3_S1 = "[%t] %-5level %logger{50} %line - ";//0:message最大长度(超出则截取),1:正则表达式,2:policy,3:查找深度(超过深度后停止正则匹配)protectedstaticfinal String PATTERN_D3_S2 = "%m'{'{0},{1},{2},{3}'}'%n";protected String mdcKeys;//来自MDC的key,多个key用逗号分隔。protected String regex = "-";//匹配的正则表达式,如果此值为null或者"-",那么policy、deep参数都将无效protectedint maxLength = 2048;//单条消息的最大长度,主要是messageprotected String policy = "replace";//如果匹配成功,字符串的策略。protectedint depth = 128;protectedboolean useDefaultRegex = true;protectedstaticfinal String DEFAULT_REGEX = "'((?<\\d)1[3-9]\\d{9}(?!\\d))'";//手机号,11位数字,并且前后位不再是数字。//系统参数,如果未指定,则使用default;protected String systemProperties;protectedstaticfinal String DEFAULT_SYSTEM_PROPERTIES = "project,profiles,cloudPlatform,clusterName";@Overridepublic void start() {if (getPattern() == null) {StringBuilder sb = new StringBuilder();String d1 = MessageFormat.format(PATTERN_D1, Utils.getHostName());sb.append(d1);sb.append(FIELD_DELIMITER).append(DOMAIN_DELIMITER).append(FIELD_DELIMITER);//拼装系统参数,如果当前数据视图不存在,则先set一个默认值if (systemProperties == null || systemProperties.isEmpty()) {systemProperties = DEFAULT_SYSTEM_PROPERTIES;}//系统参数String[] properties = systemProperties.split(",");for (String property : properties) {String value = Utils.getSystemProperty(property);if (value == null) {System.setProperty(property, "-");//初始化}sb.append(MessageFormat.format(PATTERN_D2_S1, property, property)).append(FIELD_DELIMITER);}//拼接MDC参数if (mdcKeys != null) {String[] keys = mdcKeys.split(",");for (String key : keys) {sb.append(MessageFormat.format(PATTERN_D2_S2, key, key));sb.append(FIELD_DELIMITER);}sb.append(DOMAIN_DELIMITER).append(FIELD_DELIMITER);}sb.append(PATTERN_D3_S1);if (PolicyEnum.codeOf(policy) == null) {policy = "-";}if (maxLength < 0 || maxLength > 10240) {maxLength = 2048;}//如果设定了自定义regex,则优先生效;否则使用默认if (!regex.equalsIgnoreCase("-")) {useDefaultRegex = false;}if (useDefaultRegex) {regex = DEFAULT_REGEX;}sb.append(MessageFormat.format(PATTERN_D3_S2, String.valueOf(maxLength), regex, policy, String.valueOf(depth)));setPattern(sb.toString());}super.start();}public String getMdcKeys() {return mdcKeys;}public void setMdcKeys(String mdcKeys) {this.mdcKeys = mdcKeys;}public String getRegex() {return regex;}public void setRegex(String regex) {this.regex = regex;}public int getMaxLength() {return maxLength;}public void setMaxLength(int maxLength) {this.maxLength = maxLength;}public String getPolicy() {return policy;}public void setPolicy(String policy) {this.policy = policy;}public int getDepth() {return depth;}public void setDepth(int depth) {this.depth = depth;}public Boolean getUseDefaultRegex() {return useDefaultRegex;}public boolean isUseDefaultRegex() {return useDefaultRegex;}public void setUseDefaultRegex(boolean useDefaultRegex) {this.useDefaultRegex = useDefaultRegex;}@Overridepublic String getPattern() {returnsuper.getPattern();}@Overridepublic void setPattern(String pattern) {super.setPattern(pattern);}public String getSystemProperties() {return systemProperties;}public void setSystemProperties(String systemProperties) {this.systemProperties = systemProperties;}
}

代码介绍

下面简单介绍一下上面的代码。

MDC参数声明格式为:%X{key},如果上下文中key不存在,则打印"";我们通过使用:-来声明其默认值。比如,%X{key:--}表示,如果key不存在则将打印“-”。

根据logback的规定,option参数列表需要声明在某个字段中,并配合<conversionRule>才能生效,以本文为例,我们主要对message进行整形。所以option参数声明在%m上,其格式为:%m{o1,o2...},多个option之间以,分割。o1,o2的字面值,可以在Converter中获取。简单来说,你需要将参数传递给Converter时,这些参数必须以option方式声明在某个字段上,否则没法做。

特别注意,如果option参数中包含{}时,必须将option参数使用''包括。比如%m{2048,'\\d{11}','replace','128'},为了便于理解,建议所有的option参数都使用''逐个包含。

此外,如果你对日志格式中,还需要使用系统参数(System Property),可以使用%property{key}来声明。比如,

MessageFormat.format("展示一下'{'{0}'}'格式化的效果。","hello")

输出>>

展示一下{hello}格式化效果。

还有一些比较重要的参数。

useDefaultRegex

是否使用默认表达式,即手机号数字(连续11位数字,且后位不再跟进数字)。

regex

我们也允许用户自定义表达式。此时需要将useDefaultRegex设定为false才能生效。

maxLength

默认值为2048,即message的最大长度超过此值后将会被截取,可配置。

policy

对于regex匹配成功的字符串,如何处理。(处理规则,参见下文ComplexMessageConverter)

A)drop 直接抛弃,将message重置为一个“终止符号”。比如:

我的手机号为18611001100

将会被整形为:

><

B)replace 替换,将敏感信息除去前三、后四位字符之外的其他字符用“*”替换,也是默认策略。比如:

我的手机号为18611001100

将会被整形为

我的手机号为186****1100

C)erase:参数,将匹配成功的字符串,全部替换为等长度的“*”,比如:

我的手机号为18611001100

将会被整形为:

我的手机号为***********

depth

匹配深度,即message中,最多匹配成功的次数,超过之后将会终止匹配,主要考虑性能,默认值为128。假如message中有200个手机号,那么匹配和替换到128个之后,将会终止操作,剩余的手机号将不会再替换。

mdcKeys

指定pattern拼接时,需要植入的mdc参数列表,比如mdcKeys=“name,address”,那么在pattern中将会包含:

name:%X{name:--}|address:%X{address:--}

其实大家主要关注的是option部分,Encoder的主要作用就是拼接一个pattern大概样例:

%d{yyyy-MM-dd/HH:mm:ss.SSS}|IP_OR_HOSTNAME|REQUEST_ID|REQUEST_SEQ|^_^|SYS_K1:%property{SYS_K1}|SYS_K2:%property{SYS_K2}|MDC_K1:%X{MDC_K1:--}|MDC_K
%X{MDC_K2:--}|^_^|[%t] %-5level %logger{50} %line - %m{2048,'(\\d{11})','replace',128}

格式中,domain1是必选,而且限定无法扩展 。

domain2根据配置文件指定的system properties和mdcKeys动态拼接,K-V结构,便于解析;可以为空。

domain3是常规message部分,其中%m携带options,此后Converter可以获取这些参数。

日志格式转换器

package ch.qos.logback.classic.pattern;import ch.qos.logback.classic.PolicyEnum;
import ch.qos.logback.classic.spi.ILoggingEvent;import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** <p>* 日志格式转换器,会为每个appender创建一个实例,所以在配置层面需要考虑兼容。* 主要目的是,根据配置的regex来匹配message,对于匹配成功的字符串进行替换操作,并返回修正后的message。**/
publicclass ComplexMessageConverter extends MessageConverter {protected String regex = "-";protectedint depth = 0;protected String policy = "-";protectedint maxLength = 2048;private ReplaceMatcher replaceMatcher = null;@Overridepublic void start() {List<String> options = getOptionList();//如果存在参数选项,则提取if (options != null && options.size() == 4) {maxLength = Integer.valueOf(options.get(0));regex = options.get(1);policy = options.get(2);depth = Integer.valueOf(options.get(3));if ((regex != null && !regex.equals("-"))&& (PolicyEnum.codeOf(policy) != null)&& depth > 0) {replaceMatcher = new ReplaceMatcher();}}super.start();}@Overridepublic String convert(ILoggingEvent event) {String source = event.getFormattedMessage();if (source == null || source.isEmpty()) {return source;}//复杂处理的原因:尽量少的字符串转换、空间重建、字符移动。共享一个builderif (source.length() > maxLength || replaceMatcher != null) {StringBuilder sb = null;//如果超长截取if (source.length() > maxLength) {sb = new StringBuilder(maxLength + 6);sb.append(source.substring(0, maxLength)).append("❮❮❮");//后面增加三个终止符}//如果启动了matcherif (replaceMatcher != null) {//如果没有超过maxLengthif (sb == null) {sb = new StringBuilder(source);}return replaceMatcher.execute(sb, policy);}return sb.toString();}return source;}class ReplaceMatcher {Pattern pattern;ReplaceMatcher() {pattern = Pattern.compile(regex);}String execute(StringBuilder source, String policy) {Matcher matcher = pattern.matcher(source);int i = 0;while (matcher.find() && (i < depth)) {i++;int start = matcher.start();int end = matcher.end();if (start < 0 || end < 0) {break;}String group = matcher.group();switch (policy) {case"drop":return"❯❮";//只要匹配,立即返回case"replace":source.replace(start, end, facade(group, true));break;case"erase":default:source.replace(start, end, facade(group, false));break;}}return source.toString();}}/*** 混淆,但是不能改变字符串的长度** @param source* @param included* @return */public static String facade(String source, boolean included) {int length = source.length();StringBuilder sb = new StringBuilder();//长度超过11的,保留前三、后四,中间全部*替换//低于11位或者included=false,全部*替换if (length >= 11) {if (included) {sb.append(source.substring(0, 3));} else {sb.append("***");}sb.append(repeat('*', length - 7));if (included) {sb.append(source.substring(length - 4));} else {sb.append(repeat('*', 4));}} else {sb.append(repeat('*', length));}return sb.toString();}private static String repeat(char t, int times) {char[] r = newchar[times];for (int i = 0; i < times; i++) {r[i] = t;}returnnew String(r);}
}

这个类,主要是从CommonPatternLayoutEncoder声明的options(即regix、maxLength、policy、depth)初始化一个Matcher,针对message进行匹配和替换。正则比较消耗CPU。我门还要避免在message处理过程中,新建太多的字符串,否则会大量消耗内存;在处理时,尽可能确保主message只有一个,replace时不改变message的长度,可以避免因为重建String导致一些空间浪费。

之所以Converter能够发挥作用,离不开<conversionRule>,参看下文的配置样例。不过还需要注意,每个Appender都会根据<conversionRule>创建一个Converter实例,所以Converter设计时注意代码兼容。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>...<conversionRule conversionWord="m" converterClass="ch.qos.logback.classic.pattern.ComplexMessageConverter"/><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level></filter><file>你的日志文件名</file><Append>true</Append><prudent>false</prudent><encoder class="ch.qos.logback.classic.encoder.CommonPatternLayoutEncoder"><useDefaultRegex>true</useDefaultRegex><policy>replace</policy><maxLength>2048</maxLength></encoder><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><FileNamePattern>你的日志名.%d{yyyy-MM-dd}.%i</FileNamePattern><maxFileSize>64MB</maxFileSize><maxHistory>7</maxHistory><totalSizeCap>6GB</totalSizeCap></rollingPolicy></appender><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.ConsolePatternLayoutEncoder"/></appender>...
</configuration>

注意<conversionRule>节点中的conversionWord='m',其中m就是对应pattern中的%m,可以从%m获取options列表。

因为CommonPatternLayoutEncoder中已经限定了pattern的格式,所以我们在logback.xml中也不需要再显示的声明pattern参数。基于此,可以限定业务日志的格式保持统一。当然,如果有特殊情况需要自定义,仍然可以使用<pattern>来声明以覆盖默认格式。

服务推荐

  • 蜻蜓代理
  • ip代理服务器
  • 企业级代理ip
  • 微信域名检测
  • 微信域名拦截检测
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 【Linux网络编程】read返回值总结以及封装nread

    函数示例 慢速系统可能造成进程阻塞,慢速系统调用调用被系统中断后 可以选择重启 int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr) {int n;again:if ( (n = accept(fd, sa, salenptr)) < 0) {if ((errno == ECONNABORTED) || (errno == EINTR))goto again;e…...

    2024/4/25 0:26:55
  2. Vue 之实现小米商城购物车

    实现步骤 1、静态页面准备页面使用了元件的UI的Icon 图标, ,el-checkbox,el-input-number,el-popover,el-button所有在main.js需要引入元件的UI。 import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; Vue.use(ElementUI);页面代码如下: 说…...

    2024/4/25 0:26:55
  3. Python可视化matplotlib07-更靓的单颜色(二)

    如果您感觉上篇介绍的python内置1000+种颜色太丑,请看本篇;本篇汇总几个个人感觉比较好的颜色网站色号,主要是比较接近生活,譬如说胡萝卜的黄色,合欢花的红色,竹子的绿色,海水的蓝色等等。我的公众号:“pythonic生物人“,持续分享数据科学和生物信息干货。版权声明:“…...

    2024/5/1 23:58:48
  4. 【编程实践】Joyful-Pandas(下)Task02(第七章):文本数据

    【编程实践】Joyful-Pandas(下)Task02(第七章):文本数据string类型的性质string与object的区别String类型的转换拆分与拼接str.split方法分割符与str的位置元素选取其他参数str.cat方法不同对象的拼接模式cat中的索引对齐替换子串匹配与提取常用字符串方法问题与练习问题练…...

    2024/5/1 21:29:22
  5. 解决H5发送短信被脚本恶意盗刷(java)

    之前在写h5的发送短信业务的时候,发现有人通过脚本生成手机号,然后不断的调用发送短信的业务。这里没有做对相同手机的业务校验。解决方案有两种一,在发送短信的时候,需要获取对方的ip,然后通过ip去进行限制,每一个ip每天只能发送多少条数据,这种方案能够解决一些问题。…...

    2024/5/1 22:29:40
  6. 渗透测试----书单

    《0day安全软件漏洞分析技术》 《Android 软件安全与逆向分析》 《Android安全攻防权威指南》 《http://ASP.NET从入门到精通》 《C Primer Plus》 《C++黑客编程揭秘与防范》 《C和指针》 《go语言编程》 《ajax权威指南》 《hadoop权威指南》 《HTTP权威指南》 《HTML5+CSS3从…...

    2024/4/14 20:38:38
  7. 1077 互评成绩计算

    1077 互评成绩计算解题代码测试结果问题整理 解题代码 #include<iostream> int main() {int n, m;double gT, gC;scanf("%d %d", &n, &m);for (int i = 0; i < n; i++) {int cnt = 0;double score = 0.0, max = -1.0, min = 101.0;scanf("%lf&…...

    2024/5/2 0:39:49
  8. VirtualBox 复制虚拟机 克隆系统

    打开 VirtualBox,在想要复制的虚拟机上,右键,点击 - 复制 - 。修改 - 名称 - 和 - 存储路径 - 。MAC地址设定 建议使用 - 为所有网卡重新生成MAC地址 - ,毕竟谁也不希望看到同时运行的两个虚拟机的 MAC是一样的。点击 - 下一步 - 。使用默认的 - 完全复制 - 选项。点击 - 复…...

    2024/5/1 22:49:32
  9. Action:Consider defining a bean of type“org.springframework.web.client.RestTemplate”in your conf

    报错代码: 很低级的错误,代码是copy过来的,但是启动类是我自己手动创建的,导致没有观察到需要创建一个bean Description:Field restTemplate in com.changgou.oauth.service.impl.AuthServiceImpl required a bean of type org.springframework.web.client.RestTemplate th…...

    2024/4/14 20:38:36
  10. 一、PDF搜索网站推荐

    昨天看到的分享记录一下:对于大部分程序员来说,电子书的需求量还是很大的,介绍几个不错的免费搜电子书的网站吧。1、鸠摩搜书这个网址可以用来搜索一些pdf的书,有了这个网址,就不用百度全网搜索pdf的书了。虽然可能没有像百度全网搜索那么全,但大部分也都有了。注意每种搜…...

    2024/5/2 2:02:00
  11. 【单调栈】 42接雨水

    题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。输入: [0,1,0,2,1,0,1,3,2,1,2,1] 输出: 6 思路 单调递减栈:当找到一根比前面高的柱子,就可以接雨水,当后面的比前面的低就不可以接。因此相当于寻找右边第一个更大的,…...

    2024/4/28 8:39:37
  12. MapReduce Shuffle流程

    Map端Shuffle过程每个map task都有一个内存缓冲区,存储着map的输出结果,当缓冲区快满的时候需要将缓冲区的数据以一个临时文件的方式存放到磁盘,当整个map task结束后再对磁盘中这个map task产生的所有临时文件做合并,生成最终的正式输出文件,然后等待reduce task来拉数据…...

    2024/5/1 23:52:44
  13. Java小白修炼手册--第二阶段--Java SE--集合框架-Collection 和集合操作-Map

    集合框架Java集合框架(Java Collections Framework,JCF)是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。集合框架-Collection:Collection集合框架* java.util.Collection接口,该接口是所有…...

    2024/5/1 21:48:56
  14. 数据库(二)之关系模型介绍

    一、关系模型概述关系模型用表表示;行指代一个数据元组;列指代数据属性; 关系模式图: department(dept_name, building, budget);二、码超码:一个或多个属性的集合,这些属性的组合可以使我们在一个关系中唯一标识一个元组; 候选码:最小的超码; 主码:被数据库设计者选中…...

    2024/5/2 1:31:11
  15. deepin,真好用-08-VS Code编译运行调试C/C++

    作为一个程序员,调试C/C++程序的能力还是要有的。推荐使用vscode(vs,真好用) 安装 vs code 安装方法有三:应用商店里有,可以一键安装 官网下载deb文件安装 命令行sudo apt install code插件安装C/C++(制作者是microsoft,最基础的插件) Code Runner(实用工具,可以选中…...

    2024/4/25 0:26:49
  16. 求旋转体体积

    1.圆盘法将图形想象成无数个超级小的圆柱体叠在一起,则dV=πr^2dx或dy,其中r根据函数和旋转轴确定,dx或dy由旋转轴的选择确定。一般情况下(即y用x表示),绕x轴或y=a旋转时,用圆盘法例如y=x^2与y=2和y轴围成的图形绕y轴旋转,则r=√(y),选择dy,积分上下限为0到2y=x^2与x…...

    2024/4/25 0:26:51
  17. Docker学习笔记九:初识Dockerfile

    由于commit在构建镜像时,很容易将无关内容添加到镜像且维护起来十分困难。所以我们不推荐使用commit来构建一个镜像。官方推荐使用Dockerfile来构建一个镜像。 Dockerfile简介 镜像的定制实际上就是定制每一层所添加的配置、文件。那么如果我们可以把每一层修改、安装、构建、…...

    2024/4/25 0:26:47
  18. 3.1.4 使用Actuator管理你的Spring程序

    Actuator介绍端点配置Http端点配置端点讲解 - Health健康检查端口讲解 - 日志配置端口讲解 - metrics自定义端点快速理解JMX机制...

    2024/4/25 0:26:47
  19. KVO实现原理分析

    在开发过程中,很多时候会用到KVO键值观察,它能够很轻松地去监听某对象属性的变化,监听一些带状态的控件的状态变化,字符串的改变等等,今天就来探讨一下KVO的使用及实现原理。 先来引用一下苹果官方文档对KVO的定义:Key-value observing is a mechanism that allows objec…...

    2024/4/25 0:26:48
  20. 信息技术-计算机程序计算

    信息技术选修部分计算机程序算法...

    2024/4/25 0:26:47

最新文章

  1. Linux migrate_type初步探索

    1、基础知识 我们都知道Linux内存组织管理结构架构&#xff0c;顶层是struct pglist_data&#xff0c;然后再到struct zone&#xff0c;最后是struct page。大概的管理结构是这样的&#xff1a; 根据物理内存的地址范围可划分不同的zone&#xff0c;每个zone里的内存由buddy…...

    2024/5/2 2:51:44
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. ssm框架中各层级介绍

    1、Spring&#xff08;业务逻辑层&#xff09;&#xff1a; Spring框架提供了依赖注入&#xff08;DI&#xff09;和面向切面编程&#xff08;AOP&#xff09;等功能&#xff0c;可以帮助管理Java应用程序中的对象依赖关系和提供横切关注点的支持。 在SSM框架中&#xff0c;S…...

    2024/4/30 2:49:54
  4. 16个Python接单平台,做私活爽歪歪!(附100个爬虫源码)

    一、python爬虫是可以做副业的&#xff0c;主要是爬取网站、小程序或者APP的数据&#xff0c;对数据进行分析与处理&#xff0c;或者直接向客户提供爬虫程序与技术支持。 当初学会Python那会儿&#xff0c;有朋友来介绍我去接私活&#xff0c;是为一家公司做网站&#xff0c;那…...

    2024/5/1 13:37:03
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/1 17:30:59
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/30 18:14:14
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/30 18:21:48
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/25 18:39:16
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/30 22:21:04
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/1 4:32:01
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/30 9:43:22
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57