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

了解了spring mvc web容器中一个http请求的全过程,能给我们提升多少武力值

 继上一篇文章什么,这年头还有人不知道404_cow__sky的博客-CSDN博客后,有些同学发现,学了之后有啥用,有什么实际场景可以用到吗?程序员就是这样,不习惯于纸上谈兵,给一个场景show me code才是最实在的,好了,不扯淡了,回归正文吧!

一、场景

有这么一个场景,大家看看怎么来实现,在咱们使用sentinel(熔断限流器)alibaba/Sentinel: A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件) (github.com)时,需要在dashboard展示和编辑各种各样的数据,比如展示某个应用下集群机器列表、展示实时监控数据、规则展示、规则编辑等等。

dashboard展示图如下:

二、需求拆解

看到这个场景后,我们能想到的就是这些数据从哪里来?又流向哪里?清楚这个后,才能制定具体的事实施方案。

  1. 这些需要展示的数据从哪里来?

    客户端

  2. 在dashboard上编辑规则后,这些数据流向哪里?

    客户端

三、需求实现

那么在清楚需求之后,总结起来就是一句话,客户端有数据需要传到dashborad,同样dashborad也有数据需要传到客户端。那么如何实现呢?

  1. dashboard 如何知道某个app下某个接口的通讯 ip + port

  2. dashboard 如何接受客户端的请求

  3. 同样,客户端如何接受dashboard的请求(这是本文讲解的重点)

sentinel 的实现逻辑如下:

根据上图,如果换做我们,那估计就是分别在客户端和dashboard上开几个接口就ok了,那么sentinel 是这么做的吗?是,也不是。我们拿dashboard从客户端读/写数据为例,在早期的sentinel版本中,并没有在客户端使用web容器开启http接口,因为它觉得使用web容器的方式太重了。不信,你看sentinel官方给出的解释

使用web容器太过于重要级我理解有两层含义,第一就是web框架本身就比较重,其次就是有些客户端并不是使用的spring或者spring mvc 框架,为了减小依赖,sentinel提供了比较原生的实现方式。从图中可以看出,sentinel 专门写了一个transport模块用来通信,早期的transport中包含sentinel-transport-simple-httpsentinel-transport-netty-http两个模块,sentinel-transport-simple-http 使用的是jdk原生的socket 而sentinel-transport-netty-http采用的netty来实现http server。那么怎么实现的呢?可以简单看看,以 sentinel-transport-simple-http 模块为例,其大概得执行过程是:

可以简单看看代码:

// HttpEventTask 类public void run() {if (socket == null) {return;}PrintWriter printWriter = null;InputStream inputStream = null;try {long start = System.currentTimeMillis();inputStream = new BufferedInputStream(socket.getInputStream());OutputStream outputStream = socket.getOutputStream();printWriter = new PrintWriter(new OutputStreamWriter(outputStream, Charset.forName(SentinelConfig.charset())));String firstLine = readLine(inputStream);CommandCenterLog.info("[SimpleHttpCommandCenter] Socket income: " + firstLine+ ", addr: " + socket.getInetAddress());CommandRequest request = processQueryString(firstLine);if (firstLine.length() > 4 && StringUtil.equalsIgnoreCase("POST", firstLine.substring(0, 4))) {// Deal with post methodprocessPostRequest(inputStream, request);}// Validate the target command.String commandName = HttpCommandUtils.getTarget(request);if (StringUtil.isBlank(commandName)) {writeResponse(printWriter, StatusCode.BAD_REQUEST, INVALID_COMMAND_MESSAGE);return;}// Find the matching command handler.CommandHandler<?> commandHandler = SimpleHttpCommandCenter.getHandler(commandName);if (commandHandler != null) {CommandResponse<?> response = commandHandler.handle(request);handleResponse(response, printWriter);} else {// No matching command handler.writeResponse(printWriter, StatusCode.BAD_REQUEST, "Unknown command `" + commandName + '`');}long cost = System.currentTimeMillis() - start;CommandCenterLog.info("[SimpleHttpCommandCenter] Deal a socket task: " + firstLine+ ", address: " + socket.getInetAddress() + ", time cost: " + cost + " ms");} catch (RequestException e) {writeResponse(printWriter, e.getStatusCode(), e.getMessage());} catch (Throwable e) {CommandCenterLog.warn("[SimpleHttpCommandCenter] CommandCenter error", e);try {if (printWriter != null) {String errorMessage = SERVER_ERROR_MESSAGE;e.printStackTrace();if (!writtenHead) {writeResponse(printWriter, StatusCode.INTERNAL_SERVER_ERROR, errorMessage);} else {printWriter.println(errorMessage);}printWriter.flush();}} catch (Exception e1) {CommandCenterLog.warn("Failed to write error response", e1);}} finally {closeResource(inputStream);closeResource(printWriter);closeResource(socket);}}

CommandHandler<?> commandHandler = SimpleHttpCommandCenter.getHandler(commandName); 这行代码就是根据commandName 获取 CommandHandler,CommandHandler 是一个顶层接口,其实现类上定义了一个@CommandMapping,该注解中有个name字段,用来定义command路径,这里有点类似 @RequestMapping的味道,具体代码如下:

@CommandMapping(name = "tree", desc = "get metrics in tree mode, use id to specify detailed tree root")
public class FetchTreeCommandHandler implements CommandHandler<String> {@Overridepublic CommandResponse<String> handle(CommandRequest request) {String id = request.getParam("id");StringBuilder sb = new StringBuilder();DefaultNode start = Constants.ROOT;if (id == null) {visitTree(0, start, sb);} else {boolean exactly = false;for (Node n : start.getChildList()) {DefaultNode dn = (DefaultNode)n;if (dn.getId().getName().equals(id)) {visitTree(0, dn, sb);exactly = true;break;}}if (!exactly) {for (Node n : start.getChildList()) {DefaultNode dn = (DefaultNode)n;if (dn.getId().getName().contains(id)) {visitTree(0, dn, sb);}}}}sb.append("\r\n\r\n");sb.append("t:threadNum  pq:passQps  bq:blockQps  tq:totalQps  rt:averageRt  prq: passRequestQps 1mp:1m-pass "+ "1mb:1m-block 1mt:1m-total").append("\r\n");return CommandResponse.ofSuccess(sb.toString());}private void visitTree(int level, DefaultNode node, /*@NonNull*/ StringBuilder sb) {for (int i = 0; i < level; ++i) {sb.append("-");}if (!(node instanceof EntranceNode)) {sb.append(String.format("%s(t:%s pq:%s bq:%s tq:%s rt:%s prq:%s 1mp:%s 1mb:%s 1mt:%s)",node.getId().getShowName(), node.curThreadNum(), node.passQps(),node.blockQps(), node.totalQps(), node.avgRt(), node.successQps(),node.totalRequest() - node.blockRequest(), node.blockRequest(),node.totalRequest())).append("\n");} else {sb.append(String.format("EntranceNode: %s(t:%s pq:%s bq:%s tq:%s rt:%s prq:%s 1mp:%s 1mb:%s 1mt:%s)",node.getId().getShowName(), node.curThreadNum(), node.passQps(),node.blockQps(), node.totalQps(), node.avgRt(), node.successQps(),node.totalRequest() - node.blockRequest(), node.blockRequest(),node.totalRequest())).append("\n");}for (Node n : node.getChildList()) {DefaultNode dn = (DefaultNode)n;visitTree(level + 1, dn, sb);}}
}

这样我们请求接口http://localhost:10000/tree?type=root时,其返回结果如下:

同样,sentinel-transport-netty-http 也是类似的逻辑!这样看来一切安好。

四、spring-mvc 模式通信兼容

直到有一天有人提出以下问题:

总的来看就是现在和dashboard交互的端口需要和sprinboot web 应用共用一个端口。那现在有个难题。由于已经存在 sentinel-transport-simple-httpsentinel-transport-netty-http 模块,底层设计采用的是 CommandHandler 来适配各类请求,那么如果是以web容器来执行mvc模式的请求该如何兼容呢?

江湖中不缺好手,时隔半年后,有人提出,在不改变底层设计的情况下,只需要实现HandlerAdapter 和 HandlerMapping 即可,看到这里是不是觉得很熟悉,HandlerAdapter 和 HandlerMapping不就是大名鼎鼎的处理器适配器和处理器映射器吗?咱们回顾下,用大白话说HandlerMapping的作用就是根据url路径找handler, HandlerAdapter就是对handler进行装饰,忽略底层细节,对上层提供统一的调用方法来进行handler处理。那么sentinel是怎么做的呢?我们看看

public class SentinelApiHandlerAdapter implements HandlerAdapter, Ordered {private int order = Ordered.LOWEST_PRECEDENCE;public void setOrder(int order) {this.order = order;}@Overridepublic int getOrder() {return order;}@Overridepublic boolean supports(Object handler) {return handler instanceof SentinelApiHandler;}@Overridepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {SentinelApiHandler sentinelApiHandler = (SentinelApiHandler) handler;// 调用底层的CommandHandler接口sentinelApiHandler.handle(request, response);return null;}@Overridepublic long getLastModified(HttpServletRequest request, Object handler) {return -1;}
}
public class SentinelApiHandlerMapping extends AbstractHandlerMapping implements ApplicationListener {private static final String SPRING_BOOT_WEB_SERVER_INITIALIZED_EVENT_CLASS = "org.springframework.boot.web.context.WebServerInitializedEvent";private static Class webServerInitializedEventClass;static {try {webServerInitializedEventClass = ClassUtils.forName(SPRING_BOOT_WEB_SERVER_INITIALIZED_EVENT_CLASS, null);RecordLog.info("[SentinelApiHandlerMapping] class {} is present, this is a spring-boot app, we can auto detect port", SPRING_BOOT_WEB_SERVER_INITIALIZED_EVENT_CLASS);} catch (ClassNotFoundException e) {RecordLog.info("[SentinelApiHandlerMapping] class {} is not present, this is not a spring-boot app, we can not auto detect port", SPRING_BOOT_WEB_SERVER_INITIALIZED_EVENT_CLASS);}}final static Map<String, CommandHandler> handlerMap = new ConcurrentHashMap<>();private boolean ignoreInterceptor = true;public SentinelApiHandlerMapping() {setOrder(Ordered.LOWEST_PRECEDENCE - 10);}@Overrideprotected Object getHandlerInternal(HttpServletRequest request) throws Exception {String commandName = request.getRequestURI();if (commandName.startsWith("/")) {commandName = commandName.substring(1);}// 获取底层CommandHandlerCommandHandler commandHandler = handlerMap.get(commandName);return commandHandler != null ? new SentinelApiHandler(commandHandler) : null;}@Overrideprotected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {return ignoreInterceptor ? new HandlerExecutionChain(handler) : super.getHandlerExecutionChain(handler, request);}public void setIgnoreInterceptor(boolean ignoreInterceptor) {this.ignoreInterceptor = ignoreInterceptor;}public static void registerCommand(String commandName, CommandHandler handler) {if (StringUtil.isEmpty(commandName) || handler == null) {return;}if (handlerMap.containsKey(commandName)) {CommandCenterLog.warn("[SentinelApiHandlerMapping] Register failed (duplicate command): " + commandName);return;}handlerMap.put(commandName, handler);}public static void registerCommands(Map<String, CommandHandler> handlerMap) {if (handlerMap != null) {for (Map.Entry<String, CommandHandler> e : handlerMap.entrySet()) {registerCommand(e.getKey(), e.getValue());}}}@Overridepublic void onApplicationEvent(ApplicationEvent applicationEvent) {if (webServerInitializedEventClass != null && webServerInitializedEventClass.isAssignableFrom(applicationEvent.getClass())) {Integer port = null;try {BeanWrapper beanWrapper = new BeanWrapperImpl(applicationEvent);port = (Integer) beanWrapper.getPropertyValue("webServer.port");} catch (Exception e) {RecordLog.warn("[SentinelApiHandlerMapping] resolve port from event " + applicationEvent + " fail", e);}if (port != null && TransportConfig.getPort() == null) {RecordLog.info("[SentinelApiHandlerMapping] resolve port {} from event {}", port, applicationEvent);TransportConfig.setRuntimePort(port);}}}
}

后来sentinel官方也采用了这种方法做了升级,sentinel 1.8.2 升级说明如下:

好了,看到这里,你是否对spring mvc web容器下的http请求过程有了更深的理解呢?

相关文章:

了解了spring mvc web容器中一个http请求的全过程,能给我们提升多少武力值

继上一篇文章什么&#xff0c;这年头还有人不知道404_cow__sky的博客-CSDN博客后&#xff0c;有些同学发现&#xff0c;学了之后有啥用&#xff0c;有什么实际场景可以用到吗&#xff1f;程序员就是这样&#xff0c;不习惯于纸上谈兵&#xff0c;给一个场景show me code才是最实…...

【BBC新闻文章分类】使用 TF 2.0和 LSTM 的文本分类

一、说明 NLP上的许多创新是如何将上下文添加到词向量中。常见的方法之一是使用递归神经网络...

set和map的封装

目录 介绍 红黑树代码 set insert的迭代器转换问题 为什么会有这样的问题? 如何解决 代码 map 注意点 代码 介绍 set和map的底层都是红黑树,所以我们可以在自己实现的红黑树(简易版)的基础上,进行封装,成为简易的set和map 红黑树代码 #pragma once#include <…...

java基础练习--基础语法

预备知识:Java基本语法、分支、循环、数组和字符串 7-1 累加器 请你实现一个累加器。输入n个非负整数&#xff0c;输出他们的和。 1<n<1000&#xff0c;而每个数则<10000。 输入格式: 输入包括两行。 第一行:包括一个整数n&#xff0c;表示总共有n个数。 第二行:包…...

Android12 OTA编译差分包报错问题

前言 在Ubuntu 20.04.4 LTS系统中编译Android12 OTA差分包的时候提示如下报错log: Warning: releasetools script should be invoked as hermetic Python executable -- build and run ota_from_target_files directly. Traceback (most recent call last):File "./bu…...

现代c++手撸2309神经网络最简化版230901

用c++输入数据:vector<vector<float>> inputs = { {1, 1}, {1, 0} };数据targets={0,1}; 测试:vector<vector<float>> inputs22 = { {1, 0}, {1,1} }; 构建神经网络,例如:NeuralNetwork nn({ 2, 4, 1 }); 则网络有四层、输入层2个节点、输出层1个节…...

Qt之显示PDF文件

之前使用过mupdf库&#xff0c;能够成功显示pdf&#xff0c;但是我用着有BUG&#xff0c;不太理解它的代码&#xff0c;搞了好久都不行。后面又试了其他库&#xff0c;如pdfium、popler、下载了很多例程&#xff0c;都跑不起来&#xff01;后面偶然得知xpdf库&#xff0c;看起来…...

[极客大挑战 2019]FinalSQL - 异或盲注

1、这题的关键是找注入点&#xff0c;如果选择用户名、密码作为输入点就麻烦了 2、注入点&#xff1a;按钮&#xff0c;点击就传id&#xff1b;当id1时&#xff0c;提示Click others   可以利用id的特性&#xff0c;构造异或匹配   payload: f"1^(ord(substr((select…...

【Go语言实战】(25) 分布式算法 MapReduce

MapReduce 写在前面 身为大数据专业的学生&#xff0c;其实大学我也多多少少接触过mapreduce&#xff0c;但是当时觉得这玩意太老了&#xff0c;觉得这和php一样会被时代淘汰。只能说当时确实太年轻了&#xff0c;没有好好珍惜那时候的学习资源… 现在回过头来看mapreduce&a…...

【网络安全-信息收集】网络安全之信息收集和信息收集工具讲解(提供工具)

工具下载百度网盘链接(包含所有用到的工具&#xff09;&#xff1a; 百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固&#xff0c;支持教育网加速&#xff0c;支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.…...

战火使命ssr排名,战火使命角色强度排行

在战火使命中&#xff0c;很多玩家都在关注SSR角色的强度排行&#xff0c;那么&#xff0c;下面就为大家分享一下小编整理的最新战火使命ssr排名&#xff0c;一起来看看吧。 关注【娱乐天梯】&#xff0c;获取内部福利号 一、SSR角色排名榜&#xff1a; 1. 克拉拉、艾蕾娜、杰西…...

CSS之linear-gradient( ) 函数—背景颜色渐变设计

目录 linear-gradient( ) 函数 简介&#xff1a; 语法&#xff1a; 详解&#xff1a; 例如&#xff1a; linear-gradient( ) 函数 简介&#xff1a; linear-gradient 函数是 CSS 中用于创建线性渐变的函数。它接受一个或多个参数&#xff0c;并使用这些参数创建一个渐变。…...

[Unity]未能加载一个或多个断点问题

【背景】 大家2023国庆快乐&#xff0c;虽然是假期&#xff0c;我还是继续码些文章。 今天写项目时遇到个环境问题&#xff0c;新建脚本时双击调起VS编辑器&#xff0c;忽然提示无法加载一个或多个断点&#xff08;当时忘记截图了&#xff0c;现在已解决&#xff0c;就不上图了…...

Qt中的基础数据类型

1.基础类型 因为Qt是一个C++ 框架, 因此C++中所有的语法和数据类型在Qt中都是被支持的, 但是Qt中也定义了一些属于自己的数据类型, 下边给大家介绍一下这些基础的数类型 QT基本数据类型定义在#include <QtGlobal> 中,QT基本数据类型有: 类型名称注释备注qint8signed ch…...

2023阿里云域名优惠口令大全

2023年阿里云域名优惠口令&#xff0c;com域名续费优惠口令“com批量注册更享优惠”&#xff0c;cn域名续费优惠口令“cn注册多个价格更优”&#xff0c;cn域名注册优惠口令“互联网上的中国标识”&#xff0c;阿里云优惠口令是域名专属的优惠码&#xff0c;可用于域名注册、续…...

湖南软件测评公司简析:软件功能测试和非功能测试的联系和区别

一、软件功能测试   软件功能测试旨在验证软件是否按照需求规格说明书的要求正常工作。具体而言&#xff0c;功能测试会对软件的所有功能进行测试&#xff0c;以确保其满足用户的需求和预期。在进行功能测试时&#xff0c;根据需求规格说明书编写测试用例&#xff0c;并在测试…...

HuggingFace Transformers教程(1)--使用AutoClass加载预训练实例

知识的搬运工又来啦 ☆*: .&#xff61;. o(≧▽≦)o .&#xff61;.:*☆ 【传送门>原文链接:】https://huggingface.co/docs/transformers/autoclass_tutorial &#x1f697;&#x1f693;&#x1f695;&#x1f6fa;&#x1f699;&#x1f6fb;&#x1f68c;&#x1f6…...

Qt获取当前所用的Qt版本、编译器、位数等信息

//详细的Qt版本编译器位数 QString compilerString "<unknown>"; { #if defined(Q_CC_CLANG)QString isAppleString; #if defined(__apple_build_version__)isAppleString QLatin1String(" (Apple)"); #endifcompilerString QLatin1String("…...

《C和指针》笔记31:多维数组的数组名、指向多维数组的指针、作为函数参数的多维数组

文章目录 1. 指向多维数组的数组名2. 指向多维数组的指针3. 作为函数参数的多维数组 1. 指向多维数组的数组名 我们知道一维数组名的值是一个指针常量&#xff0c;它的类型是“指向元素类型的指针”&#xff0c;它指向数组的第1个元素。那么多维数组的数组名代表什么呢&#x…...

【伪彩色图像处理】将灰度图像转换为彩色图像研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Go Gin Gorm Casbin权限管理实现 - 2. 使用Gorm存储Casbin权限配置以及`增删改查`

文章目录 0. 背景1. 准备工作2. 权限配置以及增删改查2.1 策略和组使用规范2.2 用户以及组关系的增删改查2.2.1 获取所有用户以及关联的角色2.2.2 角色组中添加用户2.2.3 角色组中删除用户 2.3 角色组权限的增删改查2.3.1 获取所有角色组权限2.3.2 创建角色组权限2.3.3 修改角色…...

DNDC模型的温室气体排放分析

DNDC&#xff08;Denitrification-Decomposition&#xff0c;反硝化-分解模型&#xff09;是目前国际上最为成功的模拟生物地球化学循环的模型之一&#xff0c;自开发以来&#xff0c;经过不断完善和改进&#xff0c;从模拟简单的农田生态系统发展成为可以模拟几乎所有陆地生态…...

vue、全局前置守卫

需求&#xff1a;在使用商城app的时候&#xff0c;游客&#xff08;没有登录的用户&#xff09;可以看到商品信息&#xff0c;当游客点击添加购物车的时候&#xff0c;我们需要把游客“拦”到登录页面&#xff0c;登陆后&#xff0c;才可以添加商品。 游客只可以看得到部分页面…...

OpenWRT、Yocto 、Buildroot和Ubuntu有什么区别

OpenWRT&#xff1a; 用途&#xff1a;OpenWRT 是一个专注于路由器和嵌入式网络设备的Linux发行版。它提供了一个优化的Linux环境&#xff0c;旨在将网络设备变成功能丰富、高度可定制的路由器。 包管理器&#xff1a;OpenWRT 使用 opkg 包管理器&#xff0c;它是一个轻量级的…...

数据挖掘(3)特征化

从数据分析角度&#xff0c;DM分为两类&#xff0c;描述式数据挖掘&#xff0c;预测式数据挖掘。描述式数据挖掘是以简介概要的方式描述数据&#xff0c;并提供数据的一般性质。预测式数据挖掘分析数据建立模型并试图预测新数据集的行为。 DM的分类&#xff1a; 描述式DM&#…...

【RabbitMQ 实战】08 集群原理剖析

上一节&#xff0c;我们用docker-compose搭建了一个RabbitMQ集群&#xff0c;这一节我们来分析一下集群的原理 一、基础概念 1.1 元数据 前面我们有介绍到 RabbitMQ 内部有各种基础构件&#xff0c;包括队列、交换器、绑定、虚拟主机等&#xff0c;他们组成了 AMQP 协议消息…...

2023年 2月3月 工作经历

2月 #pragma make_public(type) 托管C导出传统C类&#xff0c;另一个托管C项目使用不了。传统C类make_public后&#xff0c;就可以使用了。对模板类无效&#xff0c;比如&#xff1a;std::string。 C#线程绑定CPU 我的方案&#xff1a; 假定我们想把 CPU0 设置成专有CPU。 定…...

selenium京东商城爬取

该项目主要参考与:http://c.biancheng.net/python_spider/selenium-case.html 你看完上述项目内容之后&#xff0c;会发现京东登录是一个比较坑的点&#xff0c;selenium控制浏览器没有登录京东,导致我们自动爬取网页被重定向到京东登录注册页面。 因此&#xff0c;我们要单独…...

用pandas处理数据时,使变量能够在不同的Notebook会话页面进行传递,魔法命令%store

【需求来源】 在使用pandas时&#xff0c;有的时候我想将.ipynb文件分开写 其中一个写清洗数据代码另外一个写数据可视化代码 【解决方案】 但是会涉及到变量转移问题&#xff0c;这个时候我通常使用的方法是&#xff1a; 1、在清洗完数据后导出到本地 2、在文件后面增加当…...

选择适合户外篷房企业的企业云盘解决方案

“户外篷房企业用什么企业云盘好&#xff1f;Zoho WorkDrive企业网盘可以帮助户外篷房企业实现文档统一管理、提高工作效率、加强团队协作&#xff0c;并且支持各种文件类型的预览和编辑。” S公司是一家注重管理规范的大型户外篷房企业&#xff0c;已经有10余年的经验。作为设…...

搜索网站内容/青岛seo搜索优化

内容列表&#xff1a; 结构概述用来构建卷积神经网络的各种层 卷积层汇聚层归一化层全连接层将全连接层转化成卷积层 卷积神经网络的结构 层的排列规律层的尺寸设置规律案例学习&#xff08;LeNet / AlexNet / ZFNet / GoogLeNet / VGGNet&#xff09;计算上的考量 拓展资源 卷…...

做网站需求报告/成都搜狗seo

文章目录1.执行顺序-ID2. 查询类型-SELECT TYPEType - 索引Possible_keys - 可能使用的索引KeyKey_lenRefRowsExtra使用Explain关键字可以模拟优化器执行SQL查询语句&#xff0c;从而知道MySQL是如何处理你的SQL语句的&#xff0c;分析你的查询语句或表结构的性能瓶颈 这也是我…...

库存网站建设公司/百度竞价推广方案

// Exam032703.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 //#include <iostream> using namespace std;enum Color{red,green,blue}; int main() {cout << "input c" << endl;int c;cin >> c;Color clr (Colo…...

师德师风建设网站/百度网站提交收录入口

1、关于页面元素的引用通过jquery的$()引用元素包括通过id、class、元素名以及元素的层级关系及dom或者xpath条件等方法&#xff0c;且返回的对象为jquery对象&#xff08;集合对象&#xff09;&#xff0c;不能直接调用dom定义的方法。2、jQuery对象与dom对象的转换只有jquery…...

网站建设 开发的团队需要几个人/谷歌浏览器搜索引擎入口

JavaScript引擎是基于单线程 (Single-threaded) 事件循环的概念构建的&#xff0c;同一时刻只允许一个代码块在执行&#xff0c;所以需要跟踪即将运行的代码&#xff0c;那些代码被放在一个任务队列 (job queue) 中&#xff0c;每当一段代码准备执行时&#xff0c;都会被添加到…...

招商网站平台/百度竞价排名事件分析

文章目录组件的创建与引用自定义组件的样式自定义组件的数据、方法和属性data数据methods 方法properties 属性数据监听器纯数据字段组件的生命周期组件所在页面的生命周期插槽单个插槽多个插槽父子组件之间的通信behaviors组件的创建与引用 创建一个组件的步骤&#xff1a; …...