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

NanoLog起步笔记-5-客户端简要描述

nonolog起步笔记-5-客户端简要描述

  • 客户端的简要的设计图路
    • notify模式
    • 服务端最好分两个核
  • NanoLog::setLogLevel(NOTICE);
  • 从 NANO_LOG 开始
    • NANO_LOG
    • compiling time的语句
      • getNumNibblesNeeded:得到prompt中,number的数量
      • countFmtParams:得到所有的参数的个数
      • analyzeFormatString:制作参数队列
      • NanoLogInternal::checkFormat 暂时略过。
    • 这一段注释的意思:
      • NanoLogInternal::log
  • NanoLogInternal::log 的定义
    • 函数的模板参数
      • 模板参数N
      • 模板参数M
      • 模板参数Ts
      • StaticLogInfo info

客户端是大头。nanolog的服务端中规中矩,没有太多需要描述之处。但客户端相对复杂得多。

客户端的简要的设计图路

Nanolog客户端,是以线程为最小粒度设计的、压入数据不管,由server端来取走的的模式设计的。
所以,客户端有最大等待时长。超时则抛弃。

notify模式

当然,要注意,有notifiy模式,这种模式下,服务端不再是轮询。而是等待客户端通知。
在数据量小的时候、核心特别紧张时,可以考虑。
在这里插入图片描述

服务端最好分两个核

因为,默认情况下,server端,不论客户端的buffer有无数据,都要忙轮询,在外界看来,这个核 的用户占CPU占用率是100。
另外注意,如果核心相对充裕,至少要给log服务端编两个核,以免服务线程和异步io线程相互干扰。
上面这些不是我们要讲的,所以,还是到正题。

NanoLog::setLogLevel(NOTICE);

这个没什么好说的。

    // Optional: Set the minimum LogLevel that log messages must have to be// persisted. Valid from least to greatest values are// DEBUG, NOTICE, WARNING, ERRORNanoLog::setLogLevel(NOTICE);

不过可以看到,返回的时间很早。
这里我需要自我反省一下,最初看到这段代码,当时忙别的,没仔细看,以后是很靠后。
后来仔细看才明白,前面的话,都是在编译阶段固化的。
所以,这段是没有问题的,几乎确是在第一句就检查log打印级别。已经做到了最快。
在这里插入图片描述

从 NANO_LOG 开始

NANO_LOG

    NANO_LOG(DEBUG, "This message wont be logged since it is lower ""than the current log level.");

宏展开


/*** NANO_LOG macro used for logging.** \param severity*      The LogLevel of the log invocation (must be constant)* \param format*      printf-like format string (must be literal)* \param ...UNASSIGNED_LOGID*      Log arguments associated with the printf-like string.*/
#define NANO_LOG(severity, format, ...) do { \constexpr int numNibbles = NanoLogInternal::getNumNibblesNeeded(format); \constexpr int nParams = NanoLogInternal::countFmtParams(format); \\/*** Very Important*** These must be 'static' so that we can save pointers* to these variables and have them persist beyond the invocation.* The static logId is used to forever associate this local scope (tied* to an expansion of #NANO_LOG) with an id and the paramTypes array is* used by the compression function, which is invoked in another thread* at a much later time. */ \static constexpr std::array<NanoLogInternal::ParamType, nParams> paramTypes = \NanoLogInternal::analyzeFormatString<nParams>(format); \static int logId = NanoLogInternal::UNASSIGNED_LOGID; \\if (NanoLog::severity > NanoLog::getLogLevel()) \break; \\/* Triggers the GNU printf checker by passing it into a no-op function.* Trick: This call is surrounded by an if false so that the VA_ARGS don't* evaluate for cases like '++i'.*/ \if (false) { NanoLogInternal::checkFormat(format, ##__VA_ARGS__); } /*NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg)*/\\NanoLogInternal::log(logId, __FILE__, __LINE__, NanoLog::severity, format, \numNibbles, paramTypes, ##__VA_ARGS__); \
} while(0)

compiling time的语句

getNumNibblesNeeded:得到prompt中,number的数量

类似%d,%ld,%7.2f这类的。
constexpr int numNibbles = NanoLogInternal::getNumNibblesNeeded(format);

countFmtParams:得到所有的参数的个数

constexpr int nParams = NanoLogInternal::countFmtParams(format);

analyzeFormatString:制作参数队列

static constexpr std::array<NanoLogInternal::ParamType, nParams> paramTypes = NanoLogInternal::analyzeFormatString<nParams>(format)

这句话中,NanoLogInternal::ParamType, 是模板参数,它本身是一个枚举。所以,类似com编程中的variant类型,为所有的不同的类型,提供一个相同的锚点。
nParams,这个呢是重点。
这里被用到了至少两次,后面在NanoLogInternal::log那里,又被用到。
因为static constexpr std::array相当于定义了静态的数组。要记住,在编译阶段,一切都是静态的,这到什么时候,C++体系也是这样。
多态的VTable虽然是在runtime赋值,但其空间分配,则在编译时就定好的。
因为是静态数组,所以,一切都需要明确。
所以,nParams这里被第一次用到:告知这个数据有多大。
第二次用到是这里,注意,nParams在这里只是一个模板参数,编译器在这里要的不是它的值,而是它的类型:
NanoLogInternal::analyzeFormatString(format)
在后面,一会我们看到,NanoLogInternal::log的调用中,nParams再一次作为类型被这个模板函数所引用。

NanoLogInternal::checkFormat 暂时略过。

if (false) { NanoLogInternal::checkFormat(format, ##VA_ARGS); }
这次我学习nanolog,一方面,是为了将之转化为ctf格式,另外两个方面,一是思考如何进一步优化,例如全面内存化;二是我们在使用中,确有错误发生。

这个错误,显然是某个程序员写的某句NANO_LOG导致,但这句话,pass过了编译器,也pass的log这个数数,直到准备将之解压为人类可读的动作时,才失败。目前我还没有时间去定位。但这也是目标之一。
这么来看,这个check,似乎也没有尽职尽责。

这一段注释的意思:

    /*** Very Important*** These must be 'static' so that we can save pointers* to these variables and have them persist beyond the invocation.* The static logId is used to forever associate this local scope (tied* to an expansion of #NANO_LOG) with an id and the paramTypes array is* used by the compression function, which is invoked in another thread* at a much later time. */ \static constexpr std::array<NanoLogInternal::ParamType, nParams> paramTypes = \NanoLogInternal::analyzeFormatString<nParams>(format); static int logId = NanoLogInternal::UNASSIGNED_LOGID; \

这一段代码,用了两个前置的保留字来修饰:static constexpr
意思是上下文相关的compiling time代码展开。
例如,这一句,作者的意图是在编译时,展开NANO_LOG时,预留一个全局变量,在运行时,将之赋值,而且是唯一的值。
static int logId = NanoLogInternal::UNASSIGNED_LOGID;
注意,logId后面被以引用,或者传址的方式,传给了log函数,由该函数,为该变量在第一次运行时赋永久值。
log(int &logId,
再强调logId是注册号,一旦注册,在程序运行阶段不会再改变。是类型序号,是唯一的,不是log序号。

NanoLogInternal::log

这句显然是重点。我们详细解读之。

NanoLogInternal::log 的定义

这个主函数,我们看到内容并不多


/*** Logs a log message in the NanoLog system given all the static and dynamic* information associated with the log message. This function is meant to work* in conjunction with the #define-d NANO_LOG() and expects the caller to* maintain a permanent mapping of logId to static information once it's* assigned by this function.** \tparam N*      length of the format string (automatically deduced)* \tparam M*      length of the paramTypes array (automatically deduced)* \tparam Ts*      Types of the arguments passed in for the log (automatically deduced)** \param logId[in/out]*      LogId that should be permanently associated with the static information.*      An input value of -1 indicates that NanoLog should persist the static*      log information and assign a new, globally unique identifier.* \param filename*      Name of the file containing the log invocation* \param linenum*      Line number within filename of the log invocation.* \param severity*      LogLevel severity of the log invocation* \param format*      Static printf format string associated with the log invocation* \param numNibbles*      Number of nibbles needed to store all the arguments (derived from*      the format string).* \param paramTypes*      An array indicating the type of the n-th format parameter associated*      with the format string to be processed.*      *** THIS VARIABLE MUST HAVE A STATIC LIFETIME AS PTRS WILL BE SAVED **** \param args*      Argument pack for all the arguments for the log invocation*/
template<long unsigned int N, int M, typename... Ts>
inline void
log(int &logId,const char *filename,const int linenum,const LogLevel severity,const char (&format)[M],const int numNibbles,const std::array<ParamType, N>& paramTypes,Ts... args)
{using namespace NanoLogInternal::Log;assert(N == static_cast<uint32_t>(sizeof...(Ts)));if (logId == UNASSIGNED_LOGID) {const ParamType *array = paramTypes.data();StaticLogInfo info(&compress<Ts...>,filename,linenum,severity,format,sizeof...(Ts),numNibbles,array);RuntimeLogger::registerInvocationSite(info, logId);}uint64_t previousPrecision = -1;uint64_t timestamp = PerfUtils::Cycles::rdtsc();size_t stringSizes[N + 1] = {}; //HACK: Zero length arrays are not allowedsize_t allocSize = getArgSizes(paramTypes, previousPrecision,stringSizes, args...) + sizeof(UncompressedEntry);char *writePos = NanoLogInternal::RuntimeLogger::reserveAlloc(allocSize);auto originalWritePos = writePos;UncompressedEntry *ue = new(writePos) UncompressedEntry();writePos += sizeof(UncompressedEntry);store_arguments(paramTypes, stringSizes, &writePos, args...);ue->fmtId = logId;ue->timestamp = timestamp;ue->entrySize = downCast<uint32_t>(allocSize);#ifdef ENABLE_DEBUG_PRINTINGprintf("\r\nRecording %d:'%s' of size %u\r\n",logId, info.formatString, ue->entrySize);
#endifassert(allocSize == downCast<uint32_t>((writePos - originalWritePos)));NanoLogInternal::RuntimeLogger::finishAlloc(allocSize);
}

该函数,我们看到内容并不多。

函数的模板参数

模板参数N

这个容易理解,因为上面我们解释过了。就是上面解释的nParams。
这是它第三次再次被用到。
模板元编程,要理清,代码中用的是它的值,还是类型,这第三是引用它的类型。
template<long unsigned int N, int M, typename… Ts>
这句话,我并没有完全看懂,毕竟有几年没用C++了。
这里是预期的类型。反正我是觉得有点怪,模板的作用主要是类型的泛型,这里又指定,其实有点难以理解,但是这个在C++中叫预期类型,其实你也可以叫它脱了裤子放屁,无非是想编译器帮你报错(这个错,可能让它的设计整体上陷入自己怀疑)。
反正,你要信我,相认这里编译器并不是从模型预定的类型来计算大小,而是根据nParams的类型。
这就是这句代码的解释:
const std::array<ParamType, N>& paramTypes

个人的看法是,之所以写得这么复杂,是因为我们现在的编译器,目前也只能到这个水平。
因为这个参数,是在编译时就全面完成了初始化工作。所以,我们用了泛型,但却是为了能编译过。也许人类未来的编译器,将更加强大,写出更让人容易理解的代码。

再啰嗦一句,在最初没有C++17时,google就开发了nanolog,所以,相对旧一点的代码,是允许不用C++17的,所以,C++17的这些新特性,对于google团队来说,也是新的知识。所以,现在我看这些代码,也不那么觉得奇怪写得有时不那么让人能直观地理解。
之前google是利用编译前的预处理来实现的。这个我不清楚,可能是相当于自己写了编译器的插件,编译之后,进行了处理。

模板参数M

这个,确实第一时间,我不敢肯定,现在基本肯定,确实是编译器会根据用户(业务程序员)编写代码,自动计算出可变参数的数量。
M:表示paramTypes数组的长度,同样由编译器自动推断。这个参数与N的作用相似,它确保了数组的大小与格式字符串中的参数数量相匹配。

模板参数Ts

Ts…:这是一个模板参数包,它包含了传递给log函数的所有参数的类型。这个参数包用于在编译时进行类型检查和类型相关的操作,例如计算参数的数量(sizeof…(Ts))以及在运行时存储参数的实际值。
好吧,这一项我去查了查。并没有完全理解。
…这样的可变参数,我印象中,C语言的解释是双指针数组,似乎。
这样也就能理解为什么sizeof不会错。
即为什么函数第二行的断言能通过的原因:
assert(N == static_cast<uint32_t>(sizeof…(Ts)));
我是这么猜的。

StaticLogInfo info

这一段,是精华中的精华。后现我打算专门在一篇中来写。
它的作用是注册。
具体作用,如果看过CTF,基实这段,与ctf的metadata,或者schema,或者在TMN中被称为MIB(主信息库),是一样的。
所不同的是,一般的schema是,用户手工定义,并且在系统启动前,喂给系统的;
这里的是动态制作出来的。

if (logId == UNASSIGNED_LOGID) {const ParamType *array = paramTypes.data();StaticLogInfo info(&compress<Ts...>,filename,linenum,severity,format,sizeof...(Ts),numNibbles,array);RuntimeLogger::registerInvocationSite(info, logId);}

然后它被注册。
之后是分配内存。
这些内存是在当前的线程的客户端的私有块中分配。

相关文章:

NanoLog起步笔记-5-客户端简要描述

nonolog起步笔记-5-客户端简要描述 客户端的简要的设计图路notify模式服务端最好分两个核 NanoLog::setLogLevel(NOTICE);从 NANO_LOG 开始NANO_LOGcompiling time的语句getNumNibblesNeeded&#xff1a;得到prompt中&#xff0c;number的数量countFmtParams&#xff1a;得到所…...

Flink:入门介绍

目录 一、Flink简介 2.1 Flink 架构 2.2 Flink 应用程序 运行模式 二、Flink 集群 部署 2.1 本地集群模式 2.1.1 安装JDK​编辑 2.1.2 下载、解压 Flink 2.1.3 启动集群 2.1.4 停止集群 2.2 Standalone 模式 2.2.0 集群规划 2.2.1 安装JDK 2.2.2 设置免密登录 2…...

目标跟踪领域经典论文解析

亲爱的小伙伴们&#x1f618;&#xff0c;在求知的漫漫旅途中&#xff0c;若你对深度学习的奥秘、JAVA 、PYTHON与SAP 的奇妙世界&#xff0c;亦或是读研论文的撰写攻略有所探寻&#x1f9d0;&#xff0c;那不妨给我一个小小的关注吧&#x1f970;。我会精心筹备&#xff0c;在…...

网络编程 | TCP套接字通信及编程实现经验教程

1、TCP基础铺垫 TCP/IP协议簇中包含了如TCP、UDP、IP、ICMP、ARP、HTTP等通信协议。TCP协议是TCP/IP协议簇中最为常见且重要的通信方式之一&#xff0c;它为互联网上的数据传输提供了可靠性和连接管理。 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议…...

SAP导出表结构并保存到Excel 源码程序

SAP导出表结构并保存到Excel,方便写代码时复制粘贴 经常做接口,需要copy表结构,找到了这样一个程程,特别有用。 01. 先看结果...

Linux下redis环境的搭建

1.redis的下载 redis官网下载redis的linux压缩包&#xff0c;官网地址:Redis下载 网盘链接&#xff1a; 通过网盘分享的文件&#xff1a;redis-5.0.4.tar.gz 链接: https://pan.baidu.com/s/1cz3ifYrDcHWZXmT1fNzBrQ?pwdehgj 提取码: ehgj 2.redis安装与配置 将包上传到 /…...

REDMI瞄准游戏赛道,推出小屏平板

近日&#xff0c;REDMI推出了一款8.8英寸的小屏平板&#xff0c;引发市场关注。该平板采用LCD屏幕&#xff0c;搭载天玑9400处理器&#xff0c;定位游戏市场&#xff0c;意在开拓小屏平板的新领域‌。 ‌小屏平板新尝试‌ 这款REDMI平板未追随大屏潮流&#xff0c;而是选择了8…...

springai结合ollama

目录 ollama 介绍 使用 下载&#xff1a; 安装&#xff1a; 点击这个玩意next就行了。 运行 spring ai使用ollama调用本地部署的大模型 加依赖 配置yml 写代码 ollama 介绍 官网&#xff1a;Ollama Ollama是一个用于部署和运行各种开源大模型的工具&#xff1b; …...

React第十三节开发中常见问题之(视图更新、事件处理)

一、视图更新有哪些方案&#xff1f; useState用法介绍 1、对于数据变量 正常的增删改查&#xff0c;只会让数据更新&#xff0c;但是不会触发 React 视图的更新&#xff1b; 如&#xff1a; <script lang"jsx">const baseTable [{name:Andy, age: 18, id…...

【Appium报错】安装uiautomator2失败

目录 1、通过nmp安装uiautomator2&#xff1a;失败 2、通过 Appium 的平台直接安装驱动程序 3、通过pip 来安装 uiautomator2 1、通过nmp安装uiautomator2&#xff1a;失败 我先是通过npm安装的uiautomator2&#xff0c;也显示已经安装成功了&#xff1a; npm install -g …...

DataSophon集成CMAK KafkaManager

本次集成基于DDP1.2.1 集成CMAK-3.0.0.6 设计的json和tar包我放网盘了. 通过网盘分享的文件&#xff1a;DDP集成CMAK 链接: https://pan.baidu.com/s/1BR70Ajj9FxvjBlsOX4Ivhw?pwdcpmc 提取码: cpmc CMAK github上提供了zip压缩包.将压缩包解压之后 在根目录下加入启动脚本…...

Ubuntu22.04深度学习环境安装【显卡驱动安装】

前言 使用Windows配置环境失败&#xff0c;其中有一个包只有Linux版本&#xff0c;Windows版本的只有python3.10的&#xff0c;所以直接选用Linux来配置环境&#xff0c;显卡安装比较麻烦&#xff0c;单独出一期。 显卡驱动安装 方法一&#xff1a;在线安装&#xff08;操作…...

21届秋/校招面经

开篇先说一下我自身情况&#xff0c;东南大学本科计算机科学与技术专业毕业&#xff0c;gpa3.2/4.8。零零散散搞过一年多ACM&#xff0c;去年&#xff08;2019&#xff09;在icpc上海站拿了铜之后增加了信心&#xff08;因为当时训练总时间半年不到&#xff09;&#xff0c;于是…...

相机动态/在线标定

图1 图2 基本原理 【原理1】平行线在射影变换后会交于一点。如图所示,A为相机光心,蓝色矩形框为归一化平面,O为平面中心。地面四条黄色直线为平行且等距的车道线。HI交其中两条车道线于H、I, 过G作HI的平行线GM交车道线于M。HI、GM在归一化平面上的投影分别为JK、PN,二者会…...

MySQL 8.0 新特性汇总

文章目录 前言1. 运维管理 1.1 可持久化变量1.2 管理员端口1.3 资源组1.4 数据库粒度只读1.5 show processlist 实现方式1.6 加速索引创建速度1.7 控制连接的内存使用量1.8 克隆插件1.9 mysqldump 新增参数1.10 慢日志增强1.11 快速加列1.12 InnoDB 隐藏主键1.13 Redo 配置1.14…...

Resnet C ++ 部署 tensort 部署(四)

Resnet C 部署 pytorch功能测试&#xff08;一&#xff09; Resnet C 部署 模型训练&#xff08;二&#xff09; Resnet C 部署 模型测试&转 onnx&#xff08;三&#xff09; Resnet C 部署 tensort 部署&#xff08;四&#xff09; 之后&#xff0c;开始onnx 转trt 部…...

《Java核心技术I》对并发散列映射的批操作

对并发散列映射的批操作 Java API提供了批处理&#xff0c;计时其他线程处理映射&#xff0c;这些操作也能安全的执行。 3种不同操作&#xff1a; search(搜索)&#xff0c;为每个键或值应用一个函数&#xff0c;直到函数生成一个非null的结果&#xff0c;然后搜索终止&…...

记录一次使用git无权限的问题排查

正常的配置了公私钥之后&#xff0c;在gitlab中也存储了配对的公钥&#xff0c;但当使用git clone 时&#xff0c;总是报无权限 由于在这台机器中添加了多个公私钥&#xff0c;有点复杂&#xff0c;我们可以使用命令 ssh -vvvT 调试一下 ssh -vvvT yourGitlabAddr...

appium学习之二:adb命令

1、查看设备 adb devices 2、连接 adb connect IP:端口 3、安装 adb install xxx.apk 4、卸载 adb uninstall 【包名】 5、把对应目录下的1.txt文件传到手机sdcard下 adb push 1.txt /sdcard 6、进入对应的设备里 adb shell 7、切入sdcard目录 cd /sdcard 8、ls 查…...

Linux Vi/Vim使用 ⑥

掌握 CentOS 7 下的 Vi/Vim 编辑器&#xff1a;从安装到精通 在 CentOS 7 系统的日常运维、编程开发以及各类文本处理场景中&#xff0c;Vi/Vim 编辑器都是不可或缺的得力工具。它以轻量、高效、功能强大著称&#xff0c;虽然初次上手有一定学习门槛&#xff0c;但掌握之后便能…...

JCR一区牛顿-拉夫逊优化算法+分解对比!VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测

JCR一区牛顿-拉夫逊优化算法分解对比&#xff01;VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测 目录 JCR一区牛顿-拉夫逊优化算法分解对比&#xff01;VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.中科院…...

easyExcel实现表头批注

背景&#xff1a; 网上大部分都不能直接使用&#xff0c;为此总结一个方便入手且可用的工具&#xff0c;用自定义注解实现 依赖包&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>…...

Pytest测试用例使用小结

基础使用 Pytest 测试用例实现代码 import pytest from server.service import Servicepytest.fixture def service():return Service(logger)class TestService:classmethoddef setup_class(cls):"""初始化设置一次:return:"""logger.info(&q…...

LeetCode题练习与总结:132 模式--456

一、题目描述 给你一个整数数组 nums &#xff0c;数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成&#xff0c;并同时满足&#xff1a;i < j < k 和 nums[i] < nums[k] < nums[j] 。 如果 nums 中存在 132 模式的子序列 &a…...

IdentityServer4框架、ASP.NET core Identity

OAuth2.0 IdentityServer4 官网 中文官网 ASP.NET Core Identity提供了一个用来管理和存储用户账户的框架. IdentityServer4是基于ASP.NET Core实现的认证和授权框架&#xff0c;是对OpenID Connect和OAuth 2.0协议的实现。 IdentityServer是一个中间件,它可以添加符合OpenID…...

【分子材料发现】——GAP:催化过程中吸附构型的多模态语言和图学习(数据集处理详解)(二)

Multimodal Language and Graph Learning of Adsorption Configuration in Catalysis https://arxiv.org/abs/2401.07408Paper Data: https://doi.org/10.6084/m9.figshare.27208356.v2 1 Dataset CatBERTa训练的文本字符串输入来源于Open Catalyst 2020 &#xff08;OC20…...

SpringBoot开发过程中经常遇到问题解决方案分享

目录 1. Spring Boot应用启动缓慢 2. 数据库连接池配置问题 3. Spring Boot应用无法连接外部服务 4. 配置文件读取不生效 5. Spring Boot应用的日志输出不完整 6. Spring Boot中的Transactional事务管理问题 1. Spring Boot应用启动缓慢 问题原因&#xff1a; Spring Boo…...

AR眼镜_消费级工业AR智能眼镜主板硬件解决方案

AR眼镜的研发是一项复杂的软硬件集成工程&#xff0c;它需要在摄影、音频、交互和连接等多个方面提供卓越的基础体验&#xff0c;因此产品的每个细节都显得尤为重要。 在设计AR眼镜时&#xff0c;重量、体积和散热性能都是必须认真考量的关键因素。在芯片平台的选择上&#xff…...

Springboot 核心注解

Spring Boot 是一个基于 Spring 框架的扩展&#xff0c;旨在简化新 Spring 应用的初始搭建以及开发过程。它通过自动配置和约定优于配置的原则&#xff0c;减少了开发者的工作量。Spring Boot 提供了一组核心注解和 Starter 依赖管理工具来帮助开发者快速启动项目。 1. Spring…...

Nacos集群搭建【Oracle作外部数据源】

一、知识点分析 1.Nocas是什么&#xff1f; Nacos是一个动态服务发现、配置管理和服务管理平台‌。 1‌.1定义与背景‌&#xff1a; Nacos&#xff0c;全称为Dynamic Naming and Configuration Service&#xff0c;是由阿里巴巴开源的云原生应用配套工具。它旨在简化微服务架…...

网站seo站外优化/网页设计可以自学吗

大家都知道网站对一个企业的网络营销和推广来说非常重要&#xff0c;现在越来越多的企业选择自助建站&#xff0c;最大优点的节约费用&#xff0c;没有建站经验也能做出一个功能强大&#xff0c;甚至比专业网站建设公司更专业的网站&#xff0c;自助建站分为自助建站系统和在线…...

电子商务网站建设规划心得/江西seo

2019独角兽企业重金招聘Python工程师标准>>> JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象&#xff0d;关系表的映射关系&#xff0c;并将运行期的实体对象持久化到数据库中。 JPA 的目标之一是制定一个可以由很多供应商实现的API&#xff0c;并且…...

网站建设报告实训步骤/百度客服电话号码

统一项目管理平台&#xff08;UMPlatForm.NET&#xff09; 4.10 用户权限管理模块 统一项目管理平台&#xff08;UMPlatForm.NET&#xff09;,基于.NET的快速开发、整合框架。 4.10用户权限管理模块 在实际应用中我们会发现&#xff0c;权限控制会经常变动&#xff0c;如&#…...

临沂做网站的在哪里/网红推广一般怎么收费

需求:将商品表的相同型号的商品中价格为[[0,0]]的异常数据标记为404 //collection_name MongoDB集合名 //ModelName 字段名 //Tiered 字段名,值[[0,0]]db.collection_name.find({"error":404}).count(); var arr db.collection_name.aggregate([{ $group: { _id : $…...

建网站和建小程序多少钱/谷歌seo外链平台

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼昂达v975w双系统(win10x86安卓5.1R1)安装教程微软也确实令人失望&#xff0c;在win10下&#xff0c;app还是这样子&#xff0c;所以楼主萌生了在不刷v975i的bios状况刷安卓&#xff0c;而是在win下的bios装上x86安卓玩耍安卓的海量…...

一级a做愛网站伦理片/互联网平台

本文实例讲述了yii2控制器Controller Ajax操作的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;public function actionSample(){if (Yii::$app->request->isAjax) {$data Yii::$app->request->post();$searchname explode(":", $data[se…...