SpringMVC 反射型跨站点脚本攻击

解决方案:

服务端校验,添加拦截器

配置web,xml

  <filter><filter-name>xssFilter </filter-name><filter-class>com.fh.filter.XssFilter </filter-class></filter>

XssFilter

package com.fh.filter;import com.fh.controller.base.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;@Slf4j
public class XssFilter extends BaseController implements Filter {/*** 不需要过滤的链接*/public List<String> excludes = new ArrayList<>();/*** xss过滤开关*/public boolean enabled = false;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {String tempExcludes = filterConfig.getInitParameter("excludes");String tempEnabled = filterConfig.getInitParameter("enabled");if (StringUtils.isNotEmpty(tempExcludes)) {String[] url = tempExcludes.split(",");for (int i = 0; url != null && i < url.length; i++) {excludes.add(url[i]);}}if (StringUtils.isNotEmpty(tempEnabled)) {enabled = Boolean.valueOf(tempEnabled);}}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse resp = (HttpServletResponse) response;if (handleExcludeURL(req, resp)) {filterChain.doFilter(request, response);return;}filterChain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);}@Overridepublic void destroy() {// noop}private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {if (!enabled) {return true;}if (excludes == null || excludes.isEmpty()) {return false;}String url = request.getServletPath();for (String pattern : excludes) {Pattern p = Pattern.compile("^" + pattern);Matcher m = p.matcher(url);if (m.find()){return true;}}return false;}
}

XssHttpServletRequestWrapper

package com.fh.filter;import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.*;@Slf4j
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {private HttpServletRequest orgRequest;// html过滤private final static HTMLFilter htmlFilter = new HTMLFilter();public XssHttpServletRequestWrapper(HttpServletRequest request) {super(request);orgRequest = request;}@Overridepublic ServletInputStream getInputStream() throws IOException {// 非json类型,直接返回if (!isJsonRequest()) {return super.getInputStream();}// 为空,直接返回String json = IOUtils.toString(super.getInputStream(), "utf-8");if (StringUtils.isBlank(json)) {return super.getInputStream();}// xss过滤json = xssEncode(json);final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8"));return new ServletInputStream() {@Overridepublic int read() throws IOException {return bis.read();}};}/*** 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/>*/@Overridepublic String getParameter(String rawName) {String value = super.getParameter(xssEncode(rawName));if (StringUtils.isNotBlank(value)) {value = xssEncode(value);}return value;}@Overridepublic String[] getParameterValues(String name) {String[] parameters = super.getParameterValues(name);if (parameters == null || parameters.length == 0) {return null;}for (int i = 0; i < parameters.length; i++) {parameters[i] = xssEncode(parameters[i]);}return parameters;}@Overridepublic Enumeration<String> getParameterNames() {Enumeration<String> parameterNames = super.getParameterNames();List<String> list = new LinkedList<>();if (parameterNames != null) {while (parameterNames.hasMoreElements()) {String rawName = parameterNames.nextElement();String safetyName = xssEncode(rawName);if (!Objects.equals(rawName, safetyName)){log.warn("请求路径: {},参数键: {}, xss过滤后: {}. 疑似xss攻击",orgRequest.getRequestURI(), rawName, safetyName);}list.add(safetyName);}}return Collections.enumeration(list);}@Overridepublic Map<String, String[]> getParameterMap() {Map<String, String[]> map = new LinkedHashMap<>();Map<String, String[]> parameters = super.getParameterMap();for (String key : parameters.keySet()) {String[] values = parameters.get(key);for (int i = 0; i < values.length; i++) {values[i] = xssEncode(values[i]);}map.put(key, values);}return map;}/*** 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/>* 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/>* getHeaderNames 也可能需要覆盖*/@Overridepublic String getHeader(String name) {String value = super.getHeader(xssEncode(name));if (StringUtils.isNotBlank(value)) {value = xssEncode(value);}return value;}private String xssEncode(String input) {return htmlFilter.filter(input);}/*** 是否是Json请求*/public boolean isJsonRequest(){String header = super.getHeader(HttpHeaders.CONTENT_TYPE);return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);}
}

 HTMLFilter

package com.fh.filter;import lombok.extern.slf4j.Slf4j;import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;@Slf4j
public final class HTMLFilter {/** regex flag union representing /si modifiers in php **/private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;private static final Pattern P_COMMENTS = Pattern.compile("<!--(.*?)-->", Pattern.DOTALL);private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI);private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL);private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI);private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI);private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI);private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI);private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI);private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?");private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?");private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?");private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))");private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL);private static final Pattern P_END_ARROW = Pattern.compile("^>");private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)");private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)");private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)");private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)");private static final Pattern P_AMP = Pattern.compile("&");private static final Pattern P_QUOTE = Pattern.compile("<");private static final Pattern P_LEFT_ARROW = Pattern.compile("<");private static final Pattern P_RIGHT_ARROW = Pattern.compile(">");private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>");// @xxx could grow large... maybe use sesat's ReferenceMapprivate static final ConcurrentMap<String,Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<String, Pattern>();private static final ConcurrentMap<String,Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<String, Pattern>();/** set of allowed html elements, along with allowed attributes for each element **/private final Map<String, List<String>> vAllowed;/** counts of open tags for each (allowable) html element **/private final Map<String, Integer> vTagCounts = new HashMap<String, Integer>();/** html elements which must always be self-closing (e.g. "<img />") **/private final String[] vSelfClosingTags;/** html elements which must always have separate opening and closing tags (e.g. "<b></b>") **/private final String[] vNeedClosingTags;/** set of disallowed html elements **/private final String[] vDisallowed;/** attributes which should be checked for valid protocols **/private final String[] vProtocolAtts;/** allowed protocols **/private final String[] vAllowedProtocols;/** tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />") **/private final String[] vRemoveBlanks;/** entities allowed within html markup **/private final String[] vAllowedEntities;/** flag determining whether comments are allowed in input String. */private final boolean stripComment;private final boolean encodeQuotes;private boolean vDebug = false;/*** flag determining whether to try to make tags when presented with "unbalanced"* angle brackets (e.g. "<b text </b>" becomes "<b> text </b>").  If set to false,* unbalanced angle brackets will be html escaped.*/private final boolean alwaysMakeTags;/** Default constructor.**/public HTMLFilter() {vAllowed = new HashMap<>();final ArrayList<String> a_atts = new ArrayList<String>();a_atts.add("href");a_atts.add("target");vAllowed.put("a", a_atts);final ArrayList<String> img_atts = new ArrayList<String>();img_atts.add("src");img_atts.add("width");img_atts.add("height");img_atts.add("alt");vAllowed.put("img", img_atts);final ArrayList<String> no_atts = new ArrayList<String>();vAllowed.put("b", no_atts);vAllowed.put("strong", no_atts);vAllowed.put("i", no_atts);vAllowed.put("em", no_atts);vSelfClosingTags = new String[]{"img"};vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"};vDisallowed = new String[]{};vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp.vProtocolAtts = new String[]{"src", "href"};vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"};vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"};stripComment = true;encodeQuotes = true;alwaysMakeTags = true;}/** Set debug flag to true. Otherwise use default settings. See the default constructor.** @param debug turn debug on with a true argument*/public HTMLFilter(final boolean debug) {this();vDebug = debug;}/** Map-parameter configurable constructor.** @param conf map containing configuration. keys match field names.*/@SuppressWarnings("unchecked")public HTMLFilter(final Map<String,Object> conf) {assert conf.containsKey("vAllowed") : "configuration requires vAllowed";assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags";assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags";assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed";assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols";assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts";assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks";assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities";vAllowed = Collections.unmodifiableMap((HashMap<String, List<String>>) conf.get("vAllowed"));vSelfClosingTags = (String[]) conf.get("vSelfClosingTags");vNeedClosingTags = (String[]) conf.get("vNeedClosingTags");vDisallowed = (String[]) conf.get("vDisallowed");vAllowedProtocols = (String[]) conf.get("vAllowedProtocols");vProtocolAtts = (String[]) conf.get("vProtocolAtts");vRemoveBlanks = (String[]) conf.get("vRemoveBlanks");vAllowedEntities = (String[]) conf.get("vAllowedEntities");stripComment =  conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true;encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true;alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true;}private void reset() {vTagCounts.clear();}private void debug(final String msg) {if (vDebug) {log.info(msg);}}//---------------------------------------------------------------// my versions of some PHP library functionspublic static String chr(final int decimal) {return String.valueOf((char) decimal);}public static String htmlSpecialChars(final String s) {String result = s;result = regexReplace(P_AMP, "&amp;", result);result = regexReplace(P_QUOTE, "&quot;", result);result = regexReplace(P_LEFT_ARROW, "&lt;", result);result = regexReplace(P_RIGHT_ARROW, "&gt;", result);return result;}//---------------------------------------------------------------/*** given a user submitted input String, filter out any invalid or restricted* html.** @param input text (i.e. submitted by a user) than may contain html* @return "clean" version of input, with only valid, whitelisted html elements allowed*/public String filter(final String input) {reset();String s = input;debug("************************************************");debug("              INPUT: " + input);s = escapeComments(s);debug("     escapeComments: " + s);s = balanceHTML(s);debug("        balanceHTML: " + s);s = checkTags(s);debug("          checkTags: " + s);s = processRemoveBlanks(s);debug("processRemoveBlanks: " + s);s = validateEntities(s);debug("    validateEntites: " + s);debug("************************************************\n\n");return s;}public boolean isAlwaysMakeTags(){return alwaysMakeTags;}public boolean isStripComments(){return stripComment;}private String escapeComments(final String s) {final Matcher m = P_COMMENTS.matcher(s);final StringBuffer buf = new StringBuffer();if (m.find()) {final String match = m.group(1); //(.*?)m.appendReplacement(buf, Matcher.quoteReplacement("<!--" + htmlSpecialChars(match) + "-->"));}m.appendTail(buf);return buf.toString();}private String balanceHTML(String s) {if (alwaysMakeTags) {//// try and form html//s = regexReplace(P_END_ARROW, "", s);s = regexReplace(P_BODY_TO_END, "<$1>", s);s = regexReplace(P_XML_CONTENT, "$1<$2", s);} else {//// escape stray brackets//s = regexReplace(P_STRAY_LEFT_ARROW, "&lt;$1", s);s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2&gt;<", s);//// the last regexp causes '<>' entities to appear// (we need to do a lookahead assertion so that the last bracket can// be used in the next pass of the regexp)//s = regexReplace(P_BOTH_ARROWS, "", s);}return s;}private String checkTags(String s) {Matcher m = P_TAGS.matcher(s);final StringBuffer buf = new StringBuffer();while (m.find()) {String replaceStr = m.group(1);replaceStr = processTag(replaceStr);m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr));}m.appendTail(buf);s = buf.toString();// these get tallied in processTag// (remember to reset before subsequent calls to filter method)for (String key : vTagCounts.keySet()) {for (int ii = 0; ii < vTagCounts.get(key); ii++) {s += "</" + key + ">";}}return s;}private String processRemoveBlanks(final String s) {String result = s;for (String tag : vRemoveBlanks) {if(!P_REMOVE_PAIR_BLANKS.containsKey(tag)){P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?></" + tag + ">"));}result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result);if(!P_REMOVE_SELF_BLANKS.containsKey(tag)){P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>"));}result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result);}return result;}private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) {Matcher m = regex_pattern.matcher(s);return m.replaceAll(replacement);}private String processTag(final String s) {// ending tagsMatcher m = P_END_TAG.matcher(s);if (m.find()) {final String name = m.group(1).toLowerCase();if (allowed(name)) {if (!inArray(name, vSelfClosingTags)) {if (vTagCounts.containsKey(name)) {vTagCounts.put(name, vTagCounts.get(name) - 1);return "</" + name + ">";}}}}// starting tagsm = P_START_TAG.matcher(s);if (m.find()) {final String name = m.group(1).toLowerCase();final String body = m.group(2);String ending = m.group(3);//debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );if (allowed(name)) {String params = "";final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body);final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body);final List<String> paramNames = new ArrayList<String>();final List<String> paramValues = new ArrayList<String>();while (m2.find()) {paramNames.add(m2.group(1)); //([a-z0-9]+)paramValues.add(m2.group(3)); //(.*?)}while (m3.find()) {paramNames.add(m3.group(1)); //([a-z0-9]+)paramValues.add(m3.group(3)); //([^\"\\s']+)}String paramName, paramValue;for (int ii = 0; ii < paramNames.size(); ii++) {paramName = paramNames.get(ii).toLowerCase();paramValue = paramValues.get(ii);//          debug( "paramName='" + paramName + "'" );
//          debug( "paramValue='" + paramValue + "'" );
//          debug( "allowed? " + vAllowed.get( name ).contains( paramName ) );if (allowedAttribute(name, paramName)) {if (inArray(paramName, vProtocolAtts)) {paramValue = processParamProtocol(paramValue);}params += " " + paramName + "=\"" + paramValue + "\"";}}if (inArray(name, vSelfClosingTags)) {ending = " /";}if (inArray(name, vNeedClosingTags)) {ending = "";}if (ending == null || ending.length() < 1) {if (vTagCounts.containsKey(name)) {vTagCounts.put(name, vTagCounts.get(name) + 1);} else {vTagCounts.put(name, 1);}} else {ending = " /";}return "<" + name + params + ending + ">";} else {return "";}}// commentsm = P_COMMENT.matcher(s);if (!stripComment && m.find()) {return  "<" + m.group() + ">";}return "";}private String processParamProtocol(String s) {s = decodeEntities(s);final Matcher m = P_PROTOCOL.matcher(s);if (m.find()) {final String protocol = m.group(1);if (!inArray(protocol, vAllowedProtocols)) {// bad protocol, turn into local anchor link insteads = "#" + s.substring(protocol.length() + 1, s.length());if (s.startsWith("#//")) {s = "#" + s.substring(3, s.length());}}}return s;}private String decodeEntities(String s) {StringBuffer buf = new StringBuffer();Matcher m = P_ENTITY.matcher(s);while (m.find()) {final String match = m.group(1);final int decimal = Integer.decode(match).intValue();m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));}m.appendTail(buf);s = buf.toString();buf = new StringBuffer();m = P_ENTITY_UNICODE.matcher(s);while (m.find()) {final String match = m.group(1);final int decimal = Integer.valueOf(match, 16).intValue();m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));}m.appendTail(buf);s = buf.toString();buf = new StringBuffer();m = P_ENCODE.matcher(s);while (m.find()) {final String match = m.group(1);final int decimal = Integer.valueOf(match, 16).intValue();m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));}m.appendTail(buf);s = buf.toString();s = validateEntities(s);return s;}private String validateEntities(final String s) {StringBuffer buf = new StringBuffer();// validate entities throughout the stringMatcher m = P_VALID_ENTITIES.matcher(s);while (m.find()) {final String one = m.group(1); //([^&;]*)final String two = m.group(2); //(?=(;|&|$))m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two)));}m.appendTail(buf);return encodeQuotes(buf.toString());}private String encodeQuotes(final String s){if(encodeQuotes){StringBuffer buf = new StringBuffer();Matcher m = P_VALID_QUOTES.matcher(s);while (m.find()) {final String one = m.group(1); //(>|^)final String two = m.group(2); //([^<]+?)final String three = m.group(3); //(<|$)m.appendReplacement(buf, Matcher.quoteReplacement(one + regexReplace(P_QUOTE, "&quot;", two) + three));}m.appendTail(buf);return buf.toString();}else{return s;}}private String checkEntity(final String preamble, final String term) {return ";".equals(term) && isValidEntity(preamble)? '&' + preamble: "&amp;" + preamble;}private boolean isValidEntity(final String entity) {return inArray(entity, vAllowedEntities);}private static boolean inArray(final String s, final String[] array) {for (String item : array) {if (item != null && item.equals(s)) {return true;}}return false;}private boolean allowed(final String name) {return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed);}private boolean allowedAttribute(final String name, final String paramName) {return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName));}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/100248.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot

前言 什么是Spring Boot&#xff1f;为什么要学Spring Boot&#xff1f; Spring 的诞⽣是为了简化Java 程序的开发的&#xff0c;⽽Spring Boot 的诞⽣是为了简化Spring 程序开发 的。Spring就像汽车&#xff0c;相比以前人只能其自行车走路&#xff0c;汽车可以帮助人们更快…

C#__使用Type类反射数据的基本用法

// 简单介绍 // 元数据&#xff08;metadata&#xff09;&#xff1a;与程序及其类型有关的数据。 // 反射&#xff1a;一个运行的程序查看本身元数据或其他程序集中的元数据的行为 // Assembly类&#xff1a;允许访问给定程序集的元数据&#xff0c;包含了可以加载和执行程序…

数字化客户运营过程中,保险企业如何释放客户旅程编排的价值?

近两年&#xff0c;受获客成本高企、转化率却没有相应提升等因素的影响&#xff0c;越来越多的企业开始重点关注存量客户经营&#xff0c;希望尽快寻找更高效的存量线索价值挖掘路径。 在此背景下&#xff0c;某保险企业与神策数据展开深度合作&#xff0c;结合存量客户转化过程…

C语言刷题训练DAY.9

1.菱形图案 解题思路&#xff1a; 这里我们先打印上面的三角&#xff0c;再打印下面的三角。 解题代码&#xff1a; #include<stdio.h> int main() {int n 0;while ((scanf("%d", &n)) ! EOF){int i 0;for (i 0; i < n; i){//先打印上面的三角int …

Ubuntu 20.04使用Livox mid 360 测试 FAST_LIO

前言 Livox mid360需要使用Livox-SDK2&#xff0c;而非Livox-SDK&#xff0c;以及对应的livox_ros_driver2 。并需要修改FAST_LIO中部分代码。 1. 安装Livox-SDK2 参考官方教程。 1.1. 安装CMake sudo apt install cmake1.2. 安装编译Livox-SDK2 git clone https://github…

1. HBase中文学习手册之揭开Hbase的神秘面纱

揭开Hbase的神秘面纱 1.1 欢迎使用 Apache Hbase1.1.1 什么是 Hbase?1.1.2 Hbase的前世今生1.1.3 HBase的技术选型&#xff1f;1.1.3.1 不适合使用 HBase的场景1.1.3.2 适合使用 HBase的场景 1.1.4 HBase的特点1.1.4.1 HBase的优点1.1.4.2 HBase的缺点 1.1.5 HBase设计架构 1.…

苹果电脑怎么录屏?步骤详解,看到就是赚到

苹果电脑作为一款受欢迎的高性能设备&#xff0c;不仅在日常工作中发挥着重要作用&#xff0c;还可以用于创造内容&#xff0c;如录制屏幕内容。录屏功能能够帮助用户将屏幕上的活动记录成视频&#xff0c;方便分享、演示或存档。可是您知道苹果电脑怎么录屏吗&#xff1f;通过…

Redis分布式缓存

分布式缓存 -- 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题&#xff1a; 1.Redis持久化 Redis有两种持久化方案&#xff1a; RDB持久化 AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#x…

HTTP连接管理

基础知识&#xff1a;非持久连接 HTTP初始时1.0版本在浏览器每一次向服务器请求完资源都会立即断开TCP连接&#xff0c;如果想要请求多个资源&#xff0c;就必须建立多个连接&#xff0c;这就导致了服务端和客户端维护连接的开销。 例如&#xff1a;一个网页中包含文字资源也包…

每日两题 83删除排序链表的重复元素 82删除排序链表的重复元素||

83 题目 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2]示例 2&#xff1a; 输入&#xff1a;head [1,1,2,3,3] 输出&…

k8s service (二)

K8s service (二) Endpoint Endpoint是kubernetes中的一个资源对象&#xff0c;存储在etcd中&#xff0c;用来记录一个service对应的所有pod访问地址&#xff0c;它是根据service匹配文件中selector描述产生的。 一个Service由一组Pod组成&#xff0c;这些Pod通过Endpoints…

防火墙firewall

一、什么是防火墙 二、iptables 1、iptables介绍 2、实验 138的已经被拒绝&#xff0c;1可以 三、firewalld 1、firewalld简介 关闭iptables&#xff0c;开启firewalld&#xff0c;curl不能使用&#xff0c;远程连接ssh可以使用 添加80端口 这样写也可以&#xff1a;添加http…

腾讯云 CODING 荣获 TiD 质量竞争力大会 2023 软件研发优秀案例

点击链接了解详情 8 月 13-16 日&#xff0c;由中关村智联软件服务业质量创新联盟主办的第十届 TiD 2023 质量竞争力大会在北京国家会议中心召开。本次大会以“聚焦数字化转型 探索智能软件研发”为主题&#xff0c;聚焦智能化测试工程、数据要素、元宇宙、数字化转型、产融合作…

结构型(六) - 组合模式

一、概念 组合模式&#xff08;Composite Pattern&#xff09;&#xff1a;将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 使用场景&#xff1a;组合结构不常用&#xff0c;需要部分与整体的层次关系为树形结…

ElasticSearch集群

ElasticSearch集群 1、相关概念 1. 单节点故障问题  单台服务器&#xff0c;往往都有最大的负载能力&#xff0c;超过这个阈值&#xff0c;服务器性能就会大大降低甚至不可用。单点的elasticsearch也是一样&#xff0c;那单点的es服务器存在哪些可能出现的问题呢&#xff1…

对象存储服务-MinIO基本集成

是什么 MinIO 是一个高性能的分布式对象存储服务&#xff0c;适合存储非结构化数据&#xff0c;如图片&#xff0c;音频&#xff0c;视频&#xff0c;日志等。对象文件最大可以达到5TB。 安装启动 mkdir -p /usr/local/minio cd /usr/local/minio# 下载安装包 wget https:/…

解决Windows下的docker desktop无法启动问题

以管理员权限运行cmd 报错&#xff1a; docker: error during connect: Post http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.40/containers/create: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows,…

【C++初阶】vector容器

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

C++day1(笔记整理)

一、Xmind整理&#xff1a; 二、上课笔记整理&#xff1a; 1.第一个c程序&#xff1a;hello world #include <iostream> //#:预处理标识符 //<iostream>:输入输出流类所在的头文件 //istream:输入流类 //ostream:输出流类using namespace std; //std&#x…

编写一个俄罗斯方块

编写俄罗斯方块 思路。 1、创建容器数组&#xff0c;方块&#xff0c; 2、下落&#xff0c;左右移动&#xff0c;旋转&#xff0c;判断结束&#xff0c;消除。 定义一个20行10列的数组表示游戏区。初始这个数组里用0填充&#xff0c;1表示有一个方块&#xff0c;2表示该方块固…